diff options
author | Werner Koch <wk@gnupg.org> | 2013-02-22 19:34:25 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-02-22 19:34:25 +0100 |
commit | ab2e01598446120dac09e49c63a5c8fc27a1bc32 (patch) | |
tree | 8f4754f75299d38a2b2f7b2cfc4d85c20b5205b6 /src/assuan.c | |
parent | a4d64a06f9b80ed58cd8f9ca4a68393733c36b1f (diff) | |
download | libassuan-ab2e01598446120dac09e49c63a5c8fc27a1bc32.tar.gz |
Add assuan_check_version and ASSUAN_VERSION_NUMBER.
* src/assuan.c (assuan_check_version): New.
(digitp, parse_version_number, parse_version_string)
(compare_versions): New. Taken from libksba.
* configure.ac (VERSION_NUMBER): New ac_subst.
* src/Makefile.am (assuan.h): Pass VERSION and VERSION_NUMBER to
mkheader.
* src/assuan.h.in (ASSUAN_VERSION, ASSUAN_VERSION_NUMBER): New macros.
(assuan_check_version): New prototype.
* src/libassuan.def, src/libassuan.vers: Add assuan_check_version.
* src/mkheader.c (write_special, main): Support version and
version_number.
* tests/version.c: New.
* tests/Makefile.am (TESTS): Add version.
--
All our other libs have a version number check, thus we should have
one in Libassuan as well.
Diffstat (limited to 'src/assuan.c')
-rw-r--r-- | src/assuan.c | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/src/assuan.c b/src/assuan.c index b9d3143..5cbb86c 100644 --- a/src/assuan.c +++ b/src/assuan.c @@ -1,5 +1,6 @@ /* assuan.c - Global interface (not specific to context). Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2012, 2013 g10 Code GmbH This file is part of Assuan. @@ -26,7 +27,11 @@ #include "assuan-defs.h" #include "debug.h" - + + +#define digitp(a) ((a) >= '0' && (a) <= '9') + + /* Global default state. */ @@ -154,7 +159,7 @@ assuan_new (assuan_context_t *r_ctx) { return assuan_new_ext (r_ctx, _assuan_default_err_source, &_assuan_default_malloc_hooks, - _assuan_default_log_cb, + _assuan_default_log_cb, _assuan_default_log_cb_data); } @@ -187,3 +192,89 @@ assuan_release (assuan_context_t ctx) deallocation. */ _assuan_free (ctx, ctx); } + + + +/* + Version number stuff. + */ + +static const char* +parse_version_number (const char *s, int *number) +{ + int val = 0; + + if (*s == '0' && digitp (s[1])) + return NULL; /* Leading zeros are not allowed. */ + for (; digitp (*s); s++) + { + val *= 10; + val += *s - '0'; + } + *number = val; + return val < 0 ? NULL : s; +} + + +static const char * +parse_version_string (const char *s, int *major, int *minor, int *micro) +{ + s = parse_version_number (s, major); + if (!s || *s != '.') + return NULL; + s++; + s = parse_version_number (s, minor); + if (!s || *s != '.') + return NULL; + s++; + s = parse_version_number (s, micro); + if (!s) + return NULL; + return s; /* Patchlevel. */ +} + + +static const char * +compare_versions (const char *my_version, const char *req_version) +{ + int my_major, my_minor, my_micro; + int rq_major, rq_minor, rq_micro; + const char *my_plvl, *rq_plvl; + + if (!req_version) + return my_version; + if (!my_version) + return NULL; + + my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro); + if (!my_plvl) + return NULL; /* Very strange: our own version is bogus. */ + rq_plvl = parse_version_string(req_version, + &rq_major, &rq_minor, &rq_micro); + if (!rq_plvl) + return NULL; /* Requested version string is invalid. */ + + if (my_major > rq_major + || (my_major == rq_major && my_minor > rq_minor) + || (my_major == rq_major && my_minor == rq_minor + && my_micro > rq_micro) + || (my_major == rq_major && my_minor == rq_minor + && my_micro == rq_micro)) + { + return my_version; + } + return NULL; +} + + +/* + * Check that the the version of the library is at minimum REQ_VERSION + * and return the actual version string; return NULL if the condition + * is not met. If NULL is passed to this function, no check is done + * and the version string is simply returned. + */ +const char * +assuan_check_version (const char *req_version) +{ + return compare_versions (PACKAGE_VERSION, req_version); +} |