[PATCH] New applet: vercmp (compare version strings)

wdlkmpx wdlkmpx at gmail.com
Fri May 27 16:08:09 UTC 2016


Usage: vercmp version1 lt|gt|le|ge|eq version2
return value 0 if true, else 1

It's a shorter version of this:
http://svn.openmoko.org/trunk/src/host/opkg-utils/opkg-compare-versions.c

It produces the same results..

It's meant to work like this:

ver1="3.1.2-9"
ver2="3.1.3-1"

if vercmp ${ver1} gt ${ver2} ; then
    ..actions..
fi

or you can uncomment this line:

//printf("%s\n", res == 0 ? "true" : "false");

Then it will print true or false, it's up to you..

This is just a suggestion in the form of a patch..
---
 miscutils/vercmp.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 miscutils/vercmp.c

diff --git a/miscutils/vercmp.c b/miscutils/vercmp.c
new file mode 100644
index 0000000..67af35b
--- /dev/null
+++ b/miscutils/vercmp.c
@@ -0,0 +1,83 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * libdpkg - Debian packaging suite library routines
+ * vercmp.c - comparison of version numbers
+ *
+ * Copyright (C) 1995 Ian Jackson <iwj10 at cus.cam.ac.uk>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree
+ */
+
+//applet:IF_VERCMP(APPLET(vercmp, BB_DIR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_VERCMP) += vercmp.o
+
+//config:config VERCMP
+//config:	bool "vercmp"
+//config:	default n
+//config:	help
+//config:	  Compare version strings
+
+//usage:#define vercmp_trivial_usage
+//usage:	"version1 lt|gt|le|ge|eq version2"
+//usage:#define vercmp_full_usage "\n\n"
+//usage:	"return value 0 if true, else 1\n\n"
+//usage:	"l = less, g = greater, t = than, e|eq = equal"
+
+#include "libbb.h"
+
+static int ver_cmp(const char *val, const char *ref)
+{
+	int vc, rc;
+	long vl, rl;
+	const char *vp, *rp;
+	const char *vsep, *rsep;
+
+	for (;;) {
+		vp= val;  while (*vp && !isdigit(*vp)) vp++;
+		rp= ref;  while (*rp && !isdigit(*rp)) rp++;
+		for (;;) {
+			vc= val == vp ? 0 : *val++;
+			rc= ref == rp ? 0 : *ref++;
+			if (!rc && !vc) break;
+			if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
+			if (rc && !isalpha(rc)) rc += 256;
+			if (vc != rc) return vc - rc;
+		}
+		val= vp;
+		ref= rp;
+		vl=0;  if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
+		rl=0;  if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
+		if (vl != rl) return vl - rl;
+
+		vc = *val;
+		rc = *ref;
+		vsep = strchr(".-", vc);
+		rsep = strchr(".-", rc);
+		if (vsep && !rsep) return -1;
+		if (!vsep && rsep) return +1;
+
+		if (!*val && !*ref) return 0;
+		if (!*val) return -1;
+		if (!*ref) return +1;
+	}
+}
+
+int vercmp_main (int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int vercmp_main (int argc, char **argv)
+{
+	int r, res;
+	if (argc < 4) bb_show_usage();
+	if (*argv[1] == '\0' || *argv[3] == '\0') bb_show_usage();
+	r = ver_cmp(argv[1], argv[3]);
+
+	if      (!strcmp(argv[2], "le")) res = !(r <= 0);
+	else if (!strcmp(argv[2], "ge")) res = !(r >= 0);
+	else if (!strcmp(argv[2], "lt")) res = !(r < 0);
+	else if (!strcmp(argv[2], "gt")) res = !(r > 0);
+	else if (!strcmp(argv[2], "eq")) res = !(r == 0);
+	else bb_error_msg_and_die("unknown operator: %s", argv[2]);
+
+	//printf("%s\n", res == 0 ? "true" : "false");
+	return res;
+}
-- 
2.8.3



More information about the busybox mailing list