Updating to version 1.13. Libgcrypt depends on libgpg-error
[platform/upstream/libgpg-error.git] / src / version.c
1 /* version.c - Version checking
2  * Copyright (C) 2001, 2002, 2012, 2013, 2014 g10 Code GmbH
3  *
4  * This file is part of libgpg-error.
5  *
6  * libgpg-error is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * libgpg-error is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include <gpg-error.h>
29
30
31 #define digitp(a) ((a) >= '0' && (a) <= '9')
32
33
34 /* This is actually a dummy function to make sure that is module is
35    not empty.  Some compilers barf on empty modules.  */
36 static const char *
37 cright_blurb (void)
38 {
39   static const char blurb[] =
40     "\n\n"
41     "This is Libgpg-error " PACKAGE_VERSION " - An error code library\n"
42     "Copyright 2003, 2004, 2010, 2013, 2014 g10 Code GmbH\n"
43     "\n"
44     "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
45     "\n\n";
46   return blurb;
47 }
48
49
50 static const char*
51 parse_version_number (const char *s, int *number)
52 {
53   int val = 0;
54
55   if (*s == '0' && digitp (s[1]))
56     return NULL;  /* Leading zeros are not allowed.  */
57   for (; digitp (*s); s++)
58     {
59       val *= 10;
60       val += *s - '0';
61     }
62   *number = val;
63   return val < 0 ? NULL : s;
64 }
65
66
67 static const char *
68 parse_version_string (const char *s, int *major, int *minor)
69 {
70   s = parse_version_number (s, major);
71   if (!s || *s != '.')
72     return NULL;
73   s++;
74   s = parse_version_number (s, minor);
75   if (!s)
76     return NULL;
77   return s;  /* Patchlevel.  */
78 }
79
80
81 static const char *
82 compare_versions (const char *my_version, const char *req_version)
83 {
84   int my_major, my_minor;
85   int rq_major, rq_minor;
86   const char *my_plvl, *rq_plvl;
87
88   if (!req_version)
89     return my_version;
90   if (!my_version)
91     return NULL;
92
93   my_plvl = parse_version_string (my_version, &my_major, &my_minor);
94   if (!my_plvl)
95     return NULL;        /* Very strange: our own version is bogus.  */
96   rq_plvl = parse_version_string(req_version, &rq_major, &rq_minor);
97   if (!rq_plvl)
98     return NULL;        /* Requested version string is invalid.  */
99
100   if (my_major > rq_major
101       || (my_major == rq_major && my_minor >= rq_minor))
102     {
103       return my_version;
104     }
105   return NULL;
106 }
107
108
109 /*
110  * Check that the the version of the library is at minimum REQ_VERSION
111  * and return the actual version string; return NULL if the condition
112  * is not met.  If NULL is passed to this function, no check is done
113  * and the version string is simply returned.
114  */
115 const char *
116 gpg_error_check_version (const char *req_version)
117 {
118   if (req_version && req_version[0] == 1 && req_version[1] == 1)
119     return cright_blurb ();
120   return compare_versions (PACKAGE_VERSION, req_version);
121 }