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