aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Heinecke <[email protected]>2018-11-14 13:50:57 +0000
committerAndre Heinecke <[email protected]>2018-11-14 13:50:57 +0000
commit5b61c092e7444749b08e39ac5aa9fb0818e1a076 (patch)
tree9368559f8f51030786e3ff5816ed57b3bb8c478e
parenttests,json: Improve verbose mode and add verbose 2 (diff)
downloadgpgme-5b61c092e7444749b08e39ac5aa9fb0818e1a076.tar.gz
gpgme-5b61c092e7444749b08e39ac5aa9fb0818e1a076.zip
tests,gpg: Add version check hlp to t-support
* t-support.h (parse_version_number, parse_version_string) (compare_versions): New. Copy&Paste from src/version.c (check_gpg_version): New helper to check for a gpg version. -- This should make it easier to write tests that e.g. rely on modern gnupg features.
-rw-r--r--tests/gpg/t-support.h104
1 files changed, 104 insertions, 0 deletions
diff --git a/tests/gpg/t-support.h b/tests/gpg/t-support.h
index ef5766a3..a1536c18 100644
--- a/tests/gpg/t-support.h
+++ b/tests/gpg/t-support.h
@@ -23,6 +23,8 @@
#include <errno.h>
#include <stdlib.h>
#include <locale.h>
+#include <limits.h>
+#include <ctype.h>
#ifdef HAVE_W32_SYSTEM
#include <windows.h>
@@ -215,3 +217,105 @@ print_import_result (gpgme_import_result_t r)
r->skipped_v3_keys);
}
+
+/* Read the next number in the version string STR and return it in
+ *NUMBER. Return a pointer to the tail of STR after parsing, or
+ *NULL if the version string was invalid. */
+static const char *
+parse_version_number (const char *str, int *number)
+{
+#define MAXVAL ((INT_MAX - 10) / 10)
+ int val = 0;
+
+ /* Leading zeros are not allowed. */
+ if (*str == '0' && isdigit(str[1]))
+ return NULL;
+
+ while (isdigit (*str) && val <= MAXVAL)
+ {
+ val *= 10;
+ val += *(str++) - '0';
+ }
+ *number = val;
+ return val > MAXVAL ? NULL : str;
+}
+
+
+/* Parse the version string STR in the format MAJOR.MINOR.MICRO (for
+ example, 9.3.2) and return the components in MAJOR, MINOR and MICRO
+ as integers. The function returns the tail of the string that
+ follows the version number. This might be the empty string if there
+ is nothing following the version number, or a patchlevel. The
+ function returns NULL if the version string is not valid. */
+static const char *
+parse_version_string (const char *str, int *major, int *minor, int *micro)
+{
+ str = parse_version_number (str, major);
+ if (!str || *str != '.')
+ return NULL;
+ str++;
+
+ str = parse_version_number (str, minor);
+ if (!str || *str != '.')
+ return NULL;
+ str++;
+
+ str = parse_version_number (str, micro);
+ if (!str)
+ return NULL;
+
+ /* A patchlevel might follow. */
+ return str;
+}
+
+
+/* Return true if MY_VERSION is at least REQ_VERSION, and false
+ otherwise. */
+static int
+compare_versions (const char *my_version,
+ const char *rq_version)
+{
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if (!rq_version)
+ return 1;
+ if (!my_version)
+ return 0;
+
+ my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+ if (!my_plvl)
+ return 0;
+
+ rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
+ if (!rq_plvl)
+ return 0;
+
+ 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 && strcmp (my_plvl, rq_plvl) >= 0))
+ return 1;
+
+ return 0;
+}
+
+/* Return true if we have the required gpg version. */
+static int
+check_gpg_version (const char *req_version)
+{
+ gpgme_engine_info_t engine_info;
+ init_gpgme (GPGME_PROTOCOL_OpenPGP);
+
+ fail_if_err (gpgme_get_engine_info (&engine_info));
+ for (; engine_info; engine_info = engine_info->next)
+ if (engine_info->protocol == GPGME_PROTOCOL_OpenPGP)
+ break;
+
+ test (engine_info);
+
+ return compare_versions (engine_info->version, req_version);
+}