Okay, it runs at least on Windows 95
[gpgme.git] / gpgme / version.c
1 /* version.c -  version check
2  *      Copyright (C) 2000 Werner Koch (dd9jn)
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GPGME is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25
26 #include "gpgme.h"
27
28 static const char*
29 parse_version_number ( const char *s, int *number )
30 {
31     int val = 0;
32
33     if ( *s == '0' && isdigit(s[1]) )
34         return NULL; /* leading zeros are not allowed */
35     for ( ; isdigit(*s); s++ ) {
36         val *= 10;
37         val += *s - '0';
38     }
39     *number = val;
40     return val < 0? NULL : s;
41 }
42
43
44 static const char *
45 parse_version_string( const char *s, int *major, int *minor, int *micro )
46 {
47     s = parse_version_number ( s, major );
48     if ( !s || *s != '.' )
49         return NULL;
50     s++;
51     s = parse_version_number ( s, minor );
52     if ( !s || *s != '.' )
53         return NULL;
54     s++;
55     s = parse_version_number ( s, micro );
56     if ( !s )
57         return NULL;
58     return s; /* patchlevel */
59 }
60
61 /**
62  * gpgme_check_version:
63  * @req_version: A string with a version
64  * 
65  * Check that the the version of the library is at minimum the requested one
66  * and return the version string; return NULL if the condition is not
67  * met.  If a NULL is passed to this function, no check is done and
68  * the version string is simply returned.
69  * 
70  * Return value: The version string or NULL
71  **/
72 const char *
73 gpgme_check_version ( const char *req_version )
74 {
75     const char *ver = VERSION;
76     int my_major, my_minor, my_micro;
77     int rq_major, rq_minor, rq_micro;
78     const char *my_plvl, *rq_plvl;
79
80     if ( !req_version )
81         return ver;
82
83     my_plvl = parse_version_string ( ver, &my_major, &my_minor, &my_micro );
84     if ( !my_plvl )
85         return NULL;  /* very strange: our own version is bogus */
86     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
87                                     &rq_micro );
88     if ( !rq_plvl )
89         return NULL;  /* req version string is invalid */
90
91     if ( my_major > rq_major
92          || (my_major == rq_major && my_minor > rq_minor)
93          || (my_major == rq_major && my_minor == rq_minor
94              && my_micro > rq_micro)
95          || (my_major == rq_major && my_minor == rq_minor
96              && my_micro == rq_micro
97              && strcmp( my_plvl, rq_plvl ) >= 0) ) {
98         return ver;
99     }
100     return NULL;
101 }
102
103
104