]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_subr/version.c
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_subr / version.c
1 /*
2  * version.c:  library version number and utilities
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23
24
25 \f
26 #include "svn_error.h"
27 #include "svn_version.h"
28
29 #include "sysinfo.h"
30 #include "svn_private_config.h"
31 #include "private/svn_subr_private.h"
32
33 const svn_version_t *
34 svn_subr_version(void)
35 {
36   SVN_VERSION_BODY;
37 }
38
39
40 svn_boolean_t svn_ver_compatible(const svn_version_t *my_version,
41                                  const svn_version_t *lib_version)
42 {
43   /* With normal development builds the matching rules are strict, to
44      avoid inadvertantly using the wrong libraries.  For backward
45      compatibility testing use --disable-full-version-match to
46      configure 1.7 and then the libraries that get built can be used
47      to replace those in 1.6 or earlier builds.  */
48
49 #ifndef SVN_DISABLE_FULL_VERSION_MATCH
50   if (lib_version->tag[0] != '\0')
51     /* Development library; require exact match. */
52     return svn_ver_equal(my_version, lib_version);
53   else if (my_version->tag[0] != '\0')
54     /* Development client; must be newer than the library
55        and have the same major and minor version. */
56     return (my_version->major == lib_version->major
57             && my_version->minor == lib_version->minor
58             && my_version->patch > lib_version->patch);
59 #endif
60
61   /* General compatibility rules for released versions. */
62   return (my_version->major == lib_version->major
63           && my_version->minor <= lib_version->minor);
64 }
65
66
67 svn_boolean_t svn_ver_equal(const svn_version_t *my_version,
68                             const svn_version_t *lib_version)
69 {
70   return (my_version->major == lib_version->major
71           && my_version->minor == lib_version->minor
72           && my_version->patch == lib_version->patch
73           && 0 == strcmp(my_version->tag, lib_version->tag));
74 }
75
76
77 svn_error_t *
78 svn_ver_check_list(const svn_version_t *my_version,
79                    const svn_version_checklist_t *checklist)
80 {
81   svn_error_t *err = SVN_NO_ERROR;
82   int i;
83
84   for (i = 0; checklist[i].label != NULL; ++i)
85     {
86       const svn_version_t *lib_version = checklist[i].version_query();
87       if (!svn_ver_compatible(my_version, lib_version))
88         err = svn_error_createf(SVN_ERR_VERSION_MISMATCH, err,
89                                 _("Version mismatch in '%s':"
90                                   " found %d.%d.%d%s,"
91                                   " expected %d.%d.%d%s"),
92                                 checklist[i].label,
93                                 lib_version->major, lib_version->minor,
94                                 lib_version->patch, lib_version->tag,
95                                 my_version->major, my_version->minor,
96                                 my_version->patch, my_version->tag);
97     }
98
99   return err;
100 }
101
102
103 struct svn_version_extended_t
104 {
105   const char *build_date;       /* Compilation date */
106   const char *build_time;       /* Compilation time */
107   const char *build_host;       /* Build canonical host name */
108   const char *copyright;        /* Copyright notice (localized) */
109   const char *runtime_host;     /* Runtime canonical host name */
110   const char *runtime_osname;   /* Running OS release name */
111
112   /* Array of svn_version_ext_linked_lib_t describing dependent
113      libraries. */
114   const apr_array_header_t *linked_libs;
115
116   /* Array of svn_version_ext_loaded_lib_t describing loaded shared
117      libraries. */
118   const apr_array_header_t *loaded_libs;
119 };
120
121
122 const svn_version_extended_t *
123 svn_version_extended(svn_boolean_t verbose,
124                      apr_pool_t *pool)
125 {
126   svn_version_extended_t *info = apr_pcalloc(pool, sizeof(*info));
127
128   info->build_date = __DATE__;
129   info->build_time = __TIME__;
130   info->build_host = SVN_BUILD_HOST;
131   info->copyright = apr_pstrdup
132     (pool, _("Copyright (C) 2013 The Apache Software Foundation.\n"
133              "This software consists of contributions made by many people;\n"
134              "see the NOTICE file for more information.\n"
135              "Subversion is open source software, see "
136              "http://subversion.apache.org/\n"));
137
138   if (verbose)
139     {
140       info->runtime_host = svn_sysinfo__canonical_host(pool);
141       info->runtime_osname = svn_sysinfo__release_name(pool);
142       info->linked_libs = svn_sysinfo__linked_libs(pool);
143       info->loaded_libs = svn_sysinfo__loaded_libs(pool);
144     }
145
146   return info;
147 }
148
149
150 const char *
151 svn_version_ext_build_date(const svn_version_extended_t *ext_info)
152 {
153   return ext_info->build_date;
154 }
155
156 const char *
157 svn_version_ext_build_time(const svn_version_extended_t *ext_info)
158 {
159   return ext_info->build_time;
160 }
161
162 const char *
163 svn_version_ext_build_host(const svn_version_extended_t *ext_info)
164 {
165   return ext_info->build_host;
166 }
167
168 const char *
169 svn_version_ext_copyright(const svn_version_extended_t *ext_info)
170 {
171   return ext_info->copyright;
172 }
173
174 const char *
175 svn_version_ext_runtime_host(const svn_version_extended_t *ext_info)
176 {
177   return ext_info->runtime_host;
178 }
179
180 const char *
181 svn_version_ext_runtime_osname(const svn_version_extended_t *ext_info)
182 {
183   return ext_info->runtime_osname;
184 }
185
186 const apr_array_header_t *
187 svn_version_ext_linked_libs(const svn_version_extended_t *ext_info)
188 {
189   return ext_info->linked_libs;
190 }
191
192 const apr_array_header_t *
193 svn_version_ext_loaded_libs(const svn_version_extended_t *ext_info)
194 {
195   return ext_info->loaded_libs;
196 }
197
198 svn_error_t *
199 svn_version__parse_version_string(svn_version_t **version_p,
200                                   const char *version_string,
201                                   apr_pool_t *result_pool)
202 {
203   svn_error_t *err;
204   svn_version_t *version;
205   apr_array_header_t *pieces =
206     svn_cstring_split(version_string, ".", FALSE, result_pool);
207
208   if ((pieces->nelts < 2) || (pieces->nelts > 3))
209     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, NULL,
210                              _("Failed to parse version number string '%s'"),
211                              version_string);
212
213   version = apr_pcalloc(result_pool, sizeof(*version));
214   version->tag = "";
215
216   /* Parse the major and minor integers strictly. */
217   err = svn_cstring_atoi(&(version->major),
218                          APR_ARRAY_IDX(pieces, 0, const char *));
219   if (err)
220     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
221                              _("Failed to parse version number string '%s'"),
222                              version_string);
223   err = svn_cstring_atoi(&(version->minor),
224                          APR_ARRAY_IDX(pieces, 1, const char *));
225   if (err)
226     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
227                              _("Failed to parse version number string '%s'"),
228                              version_string);
229
230   /* If there's a third component, we'll parse it, too.  But we don't
231      require that it be present. */
232   if (pieces->nelts == 3)
233     {
234       const char *piece = APR_ARRAY_IDX(pieces, 2, const char *);
235       char *hyphen = strchr(piece, '-');
236       if (hyphen)
237         {
238           version->tag = apr_pstrdup(result_pool, hyphen + 1);
239           *hyphen = '\0';
240         }
241       err = svn_cstring_atoi(&(version->patch), piece);
242       if (err)
243         return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
244                                  _("Failed to parse version number string '%s'"
245                                   ),
246                                  version_string);
247     }
248
249   if (version->major < 0 || version->minor < 0 || version->patch < 0)
250     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
251                              _("Failed to parse version number string '%s'"),
252                              version_string);
253
254   *version_p = version;
255   return SVN_NO_ERROR;
256 }
257
258
259 svn_boolean_t
260 svn_version__at_least(svn_version_t *version,
261                       int major,
262                       int minor,
263                       int patch)
264 {
265   /* Compare major versions. */
266   if (version->major < major)
267     return FALSE;
268   if (version->major > major)
269     return TRUE;
270
271   /* Major versions are the same.  Compare minor versions. */
272   if (version->minor < minor)
273     return FALSE;
274   if (version->minor > minor)
275     return TRUE;
276
277   /* Major and minor versions are the same.  Compare patch
278      versions. */
279   if (version->patch < patch)
280     return FALSE;
281   if (version->patch > patch)
282     return TRUE;
283
284   /* Major, minor, and patch versions are identical matches.  But tags
285      in our schema are always used for versions not yet quite at the
286      given patch level. */
287   if (version->tag && version->tag[0])
288     return FALSE;
289
290   return TRUE;
291 }