summaryrefslogtreecommitdiffstats
path: root/common/stringhelp.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2016-11-02 16:24:58 +0100
committerWerner Koch <wk@gnupg.org>2016-11-02 17:58:11 +0100
commit488b183811fc25c1ae49b4730491accf1adf518e (patch)
tree1c86b55b957697b398f8320cb86c55055eed9dc1 /common/stringhelp.c
parentgpgscm: Fix inclusion of readline header. (diff)
downloadgnupg2-488b183811fc25c1ae49b4730491accf1adf518e.tar.xz
gnupg2-488b183811fc25c1ae49b4730491accf1adf518e.zip
common: Improve compare_string_versions.
* common/stringhelp.c: Include limits.h. (compare_version_strings): Change semantics to behave like strcmp. Include the patch lebel in the comparison. Allow checking a single version string. * common/t-stringhelp.c (test_compare_version_strings): Adjust test vectors and a few new vectors. * g10/call-agent.c (warn_version_mismatch): Adjust to new sematics. * g10/call-dirmngr.c (warn_version_mismatch): Ditto. * sm/call-agent.c (warn_version_mismatch): Ditto. * sm/call-dirmngr.c (warn_version_mismatch): Ditto. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'common/stringhelp.c')
-rw-r--r--common/stringhelp.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/common/stringhelp.c b/common/stringhelp.c
index b5d9f4cf6..f494bc5ad 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -49,6 +49,7 @@
# include <windows.h>
#endif
#include <assert.h>
+#include <limits.h>
#include "util.h"
#include "common-defs.h"
@@ -1356,9 +1357,9 @@ parse_version_number (const char *s, int *number)
/* This function breaks up the complete string-representation of the
version number S, which is of the following struture: <major
- number>.<minor number>.<micro number><patch level>. The major,
- minor and micro number components will be stored in *MAJOR, *MINOR
- and *MICRO.
+ number>.<minor number>[.<micro number>]<patch level>. The major,
+ minor, and micro number components will be stored in *MAJOR, *MINOR
+ and *MICRO. If MICRO is not given 0 is used instead.
On success, the last component, the patch level, will be returned;
in failure, NULL will be returned. */
@@ -1385,32 +1386,50 @@ parse_version_string (const char *s, int *major, int *minor, int *micro)
}
-/* Check that the version string MY_VERSION is greater or equal than
- REQ_VERSION. Returns true if the condition is satisfied or false
- if not. This works with 3 part and two part version strings; for a
- two part version string the micor part is assumed to be 0. */
+/* Compare the version string MY_VERSION to the version string
+ * REQ_VERSION. Returns -1, 0, or 1 if MY_VERSION is found,
+ * respectively, to be less than, to match, or be greater than
+ * REQ_VERSION. This function works for three and two part version
+ * strings; for a two part version string the micro part is assumed to
+ * be 0. Patch levels are compared as strings. If a version number
+ * is invalid INT_MIN is returned. If REQ_VERSION is given as NULL
+ * the function returns 0 if MY_VERSION is parsable version string. */
int
compare_version_strings (const char *my_version, const char *req_version)
{
int my_major, my_minor, my_micro;
int rq_major, rq_minor, rq_micro;
-
- if (!my_version || !req_version)
- return 0;
-
- if (!parse_version_string (my_version, &my_major, &my_minor, &my_micro))
- return 0;
- if (!parse_version_string(req_version, &rq_major, &rq_minor, &rq_micro))
- 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))
+ const char *my_patch, *rq_patch;
+ int result;
+
+ if (!my_version)
+ return INT_MIN;
+
+ my_patch = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+ if (!my_patch)
+ return INT_MIN;
+ if (!req_version)
+ return 0; /* MY_VERSION can be parsed. */
+ rq_patch = parse_version_string (req_version, &rq_major, &rq_minor,&rq_micro);
+ if (!rq_patch)
+ return INT_MIN;
+
+ if (my_major == rq_major)
{
- return 1;
+ if (my_minor == rq_minor)
+ {
+ if (my_micro == rq_micro)
+ result = strcmp (my_patch, rq_patch);
+ else
+ result = my_micro - rq_micro;
+ }
+ else
+ result = my_minor - rq_minor;
}
- return 0;
+ else
+ result = my_major - rq_major;
+
+ return !result? 0 : result < 0 ? -1 : 1;
}