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.
This commit is contained in:
parent
9933641cce
commit
5b61c092e7
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user