]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/subversion/subversion/libsvn_subr/version.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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_list2(const svn_version_t *my_version,
79                      const svn_version_checklist_t *checklist,
80                      svn_boolean_t (*comparator)(const svn_version_t *,
81                                                  const svn_version_t *))
82 {
83   svn_error_t *err = SVN_NO_ERROR;
84   int i;
85
86   for (i = 0; checklist[i].label != NULL; ++i)
87     {
88       const svn_version_t *lib_version = checklist[i].version_query();
89       if (!comparator(my_version, lib_version))
90         err = svn_error_createf(SVN_ERR_VERSION_MISMATCH, err,
91                                 _("Version mismatch in '%s'%s:"
92                                   " found %d.%d.%d%s,"
93                                   " expected %d.%d.%d%s"),
94                                 checklist[i].label,
95                                 comparator == svn_ver_equal
96                                 ? _(" (expecting equality)")
97                                 : comparator == svn_ver_compatible
98                                 ? _(" (expecting compatibility)")
99                                 : "",
100                                 lib_version->major, lib_version->minor,
101                                 lib_version->patch, lib_version->tag,
102                                 my_version->major, my_version->minor,
103                                 my_version->patch, my_version->tag);
104     }
105
106   return err;
107 }
108
109
110 struct svn_version_extended_t
111 {
112   const char *build_date;       /* Compilation date */
113   const char *build_time;       /* Compilation time */
114   const char *build_host;       /* Build canonical host name */
115   const char *copyright;        /* Copyright notice (localized) */
116   const char *runtime_host;     /* Runtime canonical host name */
117   const char *runtime_osname;   /* Running OS release name */
118
119   /* Array of svn_version_ext_linked_lib_t describing dependent
120      libraries. */
121   const apr_array_header_t *linked_libs;
122
123   /* Array of svn_version_ext_loaded_lib_t describing loaded shared
124      libraries. */
125   const apr_array_header_t *loaded_libs;
126 };
127
128
129 const svn_version_extended_t *
130 svn_version_extended(svn_boolean_t verbose,
131                      apr_pool_t *pool)
132 {
133   svn_version_extended_t *info = apr_pcalloc(pool, sizeof(*info));
134
135   info->build_date = NULL;
136   info->build_time = NULL;
137   info->build_host = SVN_BUILD_HOST;
138   info->copyright = apr_pstrdup
139     (pool, _("Copyright (C) 2014 The Apache Software Foundation.\n"
140              "This software consists of contributions made by many people;\n"
141              "see the NOTICE file for more information.\n"
142              "Subversion is open source software, see "
143              "http://subversion.apache.org/\n"));
144
145   if (verbose)
146     {
147       info->runtime_host = svn_sysinfo__canonical_host(pool);
148       info->runtime_osname = svn_sysinfo__release_name(pool);
149       info->linked_libs = svn_sysinfo__linked_libs(pool);
150       info->loaded_libs = svn_sysinfo__loaded_libs(pool);
151     }
152
153   return info;
154 }
155
156
157 const char *
158 svn_version_ext_build_date(const svn_version_extended_t *ext_info)
159 {
160   return ext_info->build_date;
161 }
162
163 const char *
164 svn_version_ext_build_time(const svn_version_extended_t *ext_info)
165 {
166   return ext_info->build_time;
167 }
168
169 const char *
170 svn_version_ext_build_host(const svn_version_extended_t *ext_info)
171 {
172   return ext_info->build_host;
173 }
174
175 const char *
176 svn_version_ext_copyright(const svn_version_extended_t *ext_info)
177 {
178   return ext_info->copyright;
179 }
180
181 const char *
182 svn_version_ext_runtime_host(const svn_version_extended_t *ext_info)
183 {
184   return ext_info->runtime_host;
185 }
186
187 const char *
188 svn_version_ext_runtime_osname(const svn_version_extended_t *ext_info)
189 {
190   return ext_info->runtime_osname;
191 }
192
193 const apr_array_header_t *
194 svn_version_ext_linked_libs(const svn_version_extended_t *ext_info)
195 {
196   return ext_info->linked_libs;
197 }
198
199 const apr_array_header_t *
200 svn_version_ext_loaded_libs(const svn_version_extended_t *ext_info)
201 {
202   return ext_info->loaded_libs;
203 }
204
205 svn_error_t *
206 svn_version__parse_version_string(svn_version_t **version_p,
207                                   const char *version_string,
208                                   apr_pool_t *result_pool)
209 {
210   svn_error_t *err;
211   svn_version_t *version;
212   apr_array_header_t *pieces =
213     svn_cstring_split(version_string, ".", FALSE, result_pool);
214
215   if ((pieces->nelts < 2) || (pieces->nelts > 3))
216     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, NULL,
217                              _("Failed to parse version number string '%s'"),
218                              version_string);
219
220   version = apr_pcalloc(result_pool, sizeof(*version));
221   version->tag = "";
222
223   /* Parse the major and minor integers strictly. */
224   err = svn_cstring_atoi(&(version->major),
225                          APR_ARRAY_IDX(pieces, 0, const char *));
226   if (err)
227     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
228                              _("Failed to parse version number string '%s'"),
229                              version_string);
230   err = svn_cstring_atoi(&(version->minor),
231                          APR_ARRAY_IDX(pieces, 1, const char *));
232   if (err)
233     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
234                              _("Failed to parse version number string '%s'"),
235                              version_string);
236
237   /* If there's a third component, we'll parse it, too.  But we don't
238      require that it be present. */
239   if (pieces->nelts == 3)
240     {
241       const char *piece = APR_ARRAY_IDX(pieces, 2, const char *);
242       char *hyphen = strchr(piece, '-');
243       if (hyphen)
244         {
245           version->tag = apr_pstrdup(result_pool, hyphen + 1);
246           *hyphen = '\0';
247         }
248       err = svn_cstring_atoi(&(version->patch), piece);
249       if (err)
250         return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
251                                  _("Failed to parse version number string '%s'"
252                                   ),
253                                  version_string);
254     }
255
256   if (version->major < 0 || version->minor < 0 || version->patch < 0)
257     return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err,
258                              _("Failed to parse version number string '%s'"),
259                              version_string);
260
261   *version_p = version;
262   return SVN_NO_ERROR;
263 }
264
265
266 svn_boolean_t
267 svn_version__at_least(svn_version_t *version,
268                       int major,
269                       int minor,
270                       int patch)
271 {
272   /* Compare major versions. */
273   if (version->major < major)
274     return FALSE;
275   if (version->major > major)
276     return TRUE;
277
278   /* Major versions are the same.  Compare minor versions. */
279   if (version->minor < minor)
280     return FALSE;
281   if (version->minor > minor)
282     return TRUE;
283
284   /* Major and minor versions are the same.  Compare patch
285      versions. */
286   if (version->patch < patch)
287     return FALSE;
288   if (version->patch > patch)
289     return TRUE;
290
291   /* Major, minor, and patch versions are identical matches.  But tags
292      in our schema are always used for versions not yet quite at the
293      given patch level. */
294   if (version->tag && version->tag[0])
295     return FALSE;
296
297   return TRUE;
298 }