summaryrefslogtreecommitdiff
path: root/src/assuan.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-02-22 19:34:25 +0100
committerWerner Koch <wk@gnupg.org>2013-02-22 19:34:25 +0100
commitab2e01598446120dac09e49c63a5c8fc27a1bc32 (patch)
tree8f4754f75299d38a2b2f7b2cfc4d85c20b5205b6 /src/assuan.c
parenta4d64a06f9b80ed58cd8f9ca4a68393733c36b1f (diff)
downloadlibassuan-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.c95
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);
+}