version.c revision 257286
1251881Speter/* 2251881Speter * version.c: library version number and utilities 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter 25251881Speter 26251881Speter#include "svn_error.h" 27251881Speter#include "svn_version.h" 28251881Speter 29251881Speter#include "sysinfo.h" 30251881Speter#include "svn_private_config.h" 31251881Speter#include "private/svn_subr_private.h" 32251881Speter 33251881Speterconst svn_version_t * 34251881Spetersvn_subr_version(void) 35251881Speter{ 36251881Speter SVN_VERSION_BODY; 37251881Speter} 38251881Speter 39251881Speter 40251881Spetersvn_boolean_t svn_ver_compatible(const svn_version_t *my_version, 41251881Speter const svn_version_t *lib_version) 42251881Speter{ 43251881Speter /* With normal development builds the matching rules are strict, to 44251881Speter avoid inadvertantly using the wrong libraries. For backward 45251881Speter compatibility testing use --disable-full-version-match to 46251881Speter configure 1.7 and then the libraries that get built can be used 47251881Speter to replace those in 1.6 or earlier builds. */ 48251881Speter 49251881Speter#ifndef SVN_DISABLE_FULL_VERSION_MATCH 50251881Speter if (lib_version->tag[0] != '\0') 51251881Speter /* Development library; require exact match. */ 52251881Speter return svn_ver_equal(my_version, lib_version); 53251881Speter else if (my_version->tag[0] != '\0') 54251881Speter /* Development client; must be newer than the library 55251881Speter and have the same major and minor version. */ 56251881Speter return (my_version->major == lib_version->major 57251881Speter && my_version->minor == lib_version->minor 58251881Speter && my_version->patch > lib_version->patch); 59251881Speter#endif 60251881Speter 61251881Speter /* General compatibility rules for released versions. */ 62251881Speter return (my_version->major == lib_version->major 63251881Speter && my_version->minor <= lib_version->minor); 64251881Speter} 65251881Speter 66251881Speter 67251881Spetersvn_boolean_t svn_ver_equal(const svn_version_t *my_version, 68251881Speter const svn_version_t *lib_version) 69251881Speter{ 70251881Speter return (my_version->major == lib_version->major 71251881Speter && my_version->minor == lib_version->minor 72251881Speter && my_version->patch == lib_version->patch 73251881Speter && 0 == strcmp(my_version->tag, lib_version->tag)); 74251881Speter} 75251881Speter 76251881Speter 77251881Spetersvn_error_t * 78251881Spetersvn_ver_check_list(const svn_version_t *my_version, 79251881Speter const svn_version_checklist_t *checklist) 80251881Speter{ 81251881Speter svn_error_t *err = SVN_NO_ERROR; 82251881Speter int i; 83251881Speter 84251881Speter for (i = 0; checklist[i].label != NULL; ++i) 85251881Speter { 86251881Speter const svn_version_t *lib_version = checklist[i].version_query(); 87251881Speter if (!svn_ver_compatible(my_version, lib_version)) 88251881Speter err = svn_error_createf(SVN_ERR_VERSION_MISMATCH, err, 89251881Speter _("Version mismatch in '%s':" 90251881Speter " found %d.%d.%d%s," 91251881Speter " expected %d.%d.%d%s"), 92251881Speter checklist[i].label, 93251881Speter lib_version->major, lib_version->minor, 94251881Speter lib_version->patch, lib_version->tag, 95251881Speter my_version->major, my_version->minor, 96251881Speter my_version->patch, my_version->tag); 97251881Speter } 98251881Speter 99251881Speter return err; 100251881Speter} 101251881Speter 102251881Speter 103251881Speterstruct svn_version_extended_t 104251881Speter{ 105251881Speter const char *build_date; /* Compilation date */ 106251881Speter const char *build_time; /* Compilation time */ 107251881Speter const char *build_host; /* Build canonical host name */ 108251881Speter const char *copyright; /* Copyright notice (localized) */ 109251881Speter const char *runtime_host; /* Runtime canonical host name */ 110251881Speter const char *runtime_osname; /* Running OS release name */ 111251881Speter 112251881Speter /* Array of svn_version_ext_linked_lib_t describing dependent 113251881Speter libraries. */ 114251881Speter const apr_array_header_t *linked_libs; 115251881Speter 116251881Speter /* Array of svn_version_ext_loaded_lib_t describing loaded shared 117251881Speter libraries. */ 118251881Speter const apr_array_header_t *loaded_libs; 119251881Speter}; 120251881Speter 121251881Speter 122251881Speterconst svn_version_extended_t * 123251881Spetersvn_version_extended(svn_boolean_t verbose, 124251881Speter apr_pool_t *pool) 125251881Speter{ 126251881Speter svn_version_extended_t *info = apr_pcalloc(pool, sizeof(*info)); 127251881Speter 128257286Scperciva info->build_date = NULL; 129257286Scperciva info->build_time = NULL; 130251881Speter info->build_host = SVN_BUILD_HOST; 131251881Speter info->copyright = apr_pstrdup 132251881Speter (pool, _("Copyright (C) 2013 The Apache Software Foundation.\n" 133251881Speter "This software consists of contributions made by many people;\n" 134251881Speter "see the NOTICE file for more information.\n" 135251881Speter "Subversion is open source software, see " 136251881Speter "http://subversion.apache.org/\n")); 137251881Speter 138251881Speter if (verbose) 139251881Speter { 140251881Speter info->runtime_host = svn_sysinfo__canonical_host(pool); 141251881Speter info->runtime_osname = svn_sysinfo__release_name(pool); 142251881Speter info->linked_libs = svn_sysinfo__linked_libs(pool); 143251881Speter info->loaded_libs = svn_sysinfo__loaded_libs(pool); 144251881Speter } 145251881Speter 146251881Speter return info; 147251881Speter} 148251881Speter 149251881Speter 150251881Speterconst char * 151251881Spetersvn_version_ext_build_date(const svn_version_extended_t *ext_info) 152251881Speter{ 153251881Speter return ext_info->build_date; 154251881Speter} 155251881Speter 156251881Speterconst char * 157251881Spetersvn_version_ext_build_time(const svn_version_extended_t *ext_info) 158251881Speter{ 159251881Speter return ext_info->build_time; 160251881Speter} 161251881Speter 162251881Speterconst char * 163251881Spetersvn_version_ext_build_host(const svn_version_extended_t *ext_info) 164251881Speter{ 165251881Speter return ext_info->build_host; 166251881Speter} 167251881Speter 168251881Speterconst char * 169251881Spetersvn_version_ext_copyright(const svn_version_extended_t *ext_info) 170251881Speter{ 171251881Speter return ext_info->copyright; 172251881Speter} 173251881Speter 174251881Speterconst char * 175251881Spetersvn_version_ext_runtime_host(const svn_version_extended_t *ext_info) 176251881Speter{ 177251881Speter return ext_info->runtime_host; 178251881Speter} 179251881Speter 180251881Speterconst char * 181251881Spetersvn_version_ext_runtime_osname(const svn_version_extended_t *ext_info) 182251881Speter{ 183251881Speter return ext_info->runtime_osname; 184251881Speter} 185251881Speter 186251881Speterconst apr_array_header_t * 187251881Spetersvn_version_ext_linked_libs(const svn_version_extended_t *ext_info) 188251881Speter{ 189251881Speter return ext_info->linked_libs; 190251881Speter} 191251881Speter 192251881Speterconst apr_array_header_t * 193251881Spetersvn_version_ext_loaded_libs(const svn_version_extended_t *ext_info) 194251881Speter{ 195251881Speter return ext_info->loaded_libs; 196251881Speter} 197251881Speter 198251881Spetersvn_error_t * 199251881Spetersvn_version__parse_version_string(svn_version_t **version_p, 200251881Speter const char *version_string, 201251881Speter apr_pool_t *result_pool) 202251881Speter{ 203251881Speter svn_error_t *err; 204251881Speter svn_version_t *version; 205251881Speter apr_array_header_t *pieces = 206251881Speter svn_cstring_split(version_string, ".", FALSE, result_pool); 207251881Speter 208251881Speter if ((pieces->nelts < 2) || (pieces->nelts > 3)) 209251881Speter return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, NULL, 210251881Speter _("Failed to parse version number string '%s'"), 211251881Speter version_string); 212251881Speter 213251881Speter version = apr_pcalloc(result_pool, sizeof(*version)); 214251881Speter version->tag = ""; 215251881Speter 216251881Speter /* Parse the major and minor integers strictly. */ 217251881Speter err = svn_cstring_atoi(&(version->major), 218251881Speter APR_ARRAY_IDX(pieces, 0, const char *)); 219251881Speter if (err) 220251881Speter return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err, 221251881Speter _("Failed to parse version number string '%s'"), 222251881Speter version_string); 223251881Speter err = svn_cstring_atoi(&(version->minor), 224251881Speter APR_ARRAY_IDX(pieces, 1, const char *)); 225251881Speter if (err) 226251881Speter return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err, 227251881Speter _("Failed to parse version number string '%s'"), 228251881Speter version_string); 229251881Speter 230251881Speter /* If there's a third component, we'll parse it, too. But we don't 231251881Speter require that it be present. */ 232251881Speter if (pieces->nelts == 3) 233251881Speter { 234251881Speter const char *piece = APR_ARRAY_IDX(pieces, 2, const char *); 235251881Speter char *hyphen = strchr(piece, '-'); 236251881Speter if (hyphen) 237251881Speter { 238251881Speter version->tag = apr_pstrdup(result_pool, hyphen + 1); 239251881Speter *hyphen = '\0'; 240251881Speter } 241251881Speter err = svn_cstring_atoi(&(version->patch), piece); 242251881Speter if (err) 243251881Speter return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err, 244251881Speter _("Failed to parse version number string '%s'" 245251881Speter ), 246251881Speter version_string); 247251881Speter } 248251881Speter 249251881Speter if (version->major < 0 || version->minor < 0 || version->patch < 0) 250251881Speter return svn_error_createf(SVN_ERR_MALFORMED_VERSION_STRING, err, 251251881Speter _("Failed to parse version number string '%s'"), 252251881Speter version_string); 253251881Speter 254251881Speter *version_p = version; 255251881Speter return SVN_NO_ERROR; 256251881Speter} 257251881Speter 258251881Speter 259251881Spetersvn_boolean_t 260251881Spetersvn_version__at_least(svn_version_t *version, 261251881Speter int major, 262251881Speter int minor, 263251881Speter int patch) 264251881Speter{ 265251881Speter /* Compare major versions. */ 266251881Speter if (version->major < major) 267251881Speter return FALSE; 268251881Speter if (version->major > major) 269251881Speter return TRUE; 270251881Speter 271251881Speter /* Major versions are the same. Compare minor versions. */ 272251881Speter if (version->minor < minor) 273251881Speter return FALSE; 274251881Speter if (version->minor > minor) 275251881Speter return TRUE; 276251881Speter 277251881Speter /* Major and minor versions are the same. Compare patch 278251881Speter versions. */ 279251881Speter if (version->patch < patch) 280251881Speter return FALSE; 281251881Speter if (version->patch > patch) 282251881Speter return TRUE; 283251881Speter 284251881Speter /* Major, minor, and patch versions are identical matches. But tags 285251881Speter in our schema are always used for versions not yet quite at the 286251881Speter given patch level. */ 287251881Speter if (version->tag && version->tag[0]) 288251881Speter return FALSE; 289251881Speter 290251881Speter return TRUE; 291251881Speter} 292