From 3048fcf976fd576f80143260e20829063f7a746e Mon Sep 17 00:00:00 2001 Message-Id: <3048fcf976fd576f80143260e20829063f7a746e.1714496234.git.mdw@distorted.org.uk> From: Mark Wooding Date: Wed, 14 May 2008 15:13:39 +0100 Subject: [PATCH 1/1] versioncmp: Fix for `~' characters. Organization: Straylight/Edgeware From: Mark Wooding In the Debian version number ordering, `~' compares before end-of- string. Fix the function to actually cope with this, and introduce test cases to make sure we actually get it right. This is release 2.0.5. --- Makefile.am | 14 ++++++++++--- configure.in | 2 +- debian/changelog | 7 +++++++ versioncmp-test.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ versioncmp.c | 32 ++++++++++++++--------------- versioncmp.in | 14 +++++++++++++ 6 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 versioncmp-test.c create mode 100644 versioncmp.in diff --git a/Makefile.am b/Makefile.am index 381ba0b..36431e3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,7 +56,7 @@ pkginclude_HEADERS = \ ## --- Things to put in the library --- -libmLib_la_LDFLAGS = -version-info 2:4:0 +libmLib_la_LDFLAGS = -version-info 2:5:0 ## Middle number is the patchlevel. Final number is the minor version. The ## difference between the first and last numbers is major version. @@ -101,11 +101,11 @@ unihash_mkstatic_CFLAGS = $(AM_CFLAGS) ## --- Test code --- -noinst_PROGRAMS = da.t sym.t assoc.t bits.t +noinst_PROGRAMS = da.t sym.t assoc.t bits.t versioncmp.t check: \ da.test sym.test assoc.test bits.test base64.test hex.test \ - base32.test \ + base32.test versioncmp.test \ unihash.test da_t_SOURCES = da-test.c @@ -152,6 +152,14 @@ bits.o: bits.c bits.test: bits.t ./bits.t -f $(srcdir)/bits.in +versioncmp_t_SOURCES = versioncmp-test.c +versioncmp_t_LDADD = libmLib.la +versioncmp_t_LDFLAGS = -static +versioncmp-test.o: versioncmp-test.c + $(COMPILE) -c -DSRCDIR="\"$(srcdir)\"" $(srcdir)/versioncmp-test.c -o $@ +versioncmp.test: versioncmp.t + ./versioncmp.t -f $(srcdir)/versioncmp.in + base64.to: base64.c $(COMPILE) -c -DTEST_RIG -DSRCDIR=\"$(srcdir)\" \ $(srcdir)/base64.c -o base64.to diff --git a/configure.in b/configure.in index 39ca6b5..6e250ba 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, dnl MA 02111-1307, USA. AC_INIT(exc.c) -AM_INIT_AUTOMAKE(mLib, 2.0.4) +AM_INIT_AUTOMAKE(mLib, 2.0.5) AC_PROG_CC AM_PROG_LIBTOOL diff --git a/debian/changelog b/debian/changelog index 2d18770..067f84f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +mlib (2.0.5) experimental; urgency=low + + * Fix versioncmp to deal with `~' characters properly, in line with + Debian policy. + + -- Mark Wooding Wed, 14 May 2008 15:10:32 +0100 + mlib (2.0.4) experimental; urgency=low * Switch over to pkgconfig. This is largely a stopgap release, to stop diff --git a/versioncmp-test.c b/versioncmp-test.c new file mode 100644 index 0000000..0927f46 --- /dev/null +++ b/versioncmp-test.c @@ -0,0 +1,51 @@ +/* -*-c-*- + * + * Test rig for versioncmp + * + * (c) 2008 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "testrig.h" +#include "versioncmp.h" + +static int t_vcmp(dstr *v) +{ + int ok = 1; + int rc = versioncmp(v[0].buf, v[1].buf); + if (rc != *(int *)v[2].buf) { + fprintf(stderr, "\nversioncmp(%s, %s) returns %d != %d\n", + v[0].buf, v[1].buf, rc, *(int *)v[2].buf); + ok = 0; + } + return (ok); +} + +static const test_chunk tests[] = { + { "versioncmp", t_vcmp, { &type_string, &type_string, &type_int } }, + { 0 } +}; + +int main(int argc, char *argv[]) + { test_run(argc, argv, tests, SRCDIR "/versioncmp.in"); return (1); } + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/versioncmp.c b/versioncmp.c index 1b77ca9..7b67dc2 100644 --- a/versioncmp.c +++ b/versioncmp.c @@ -125,28 +125,26 @@ static int vcmp(const char *va, const char *val, pa = vchr(&va, val); pb = vchr(&vb, vbl); for (;;) { - if (pa == va && pb == vb) - break; - else if (pa == va) - return (-1); - else if (pb == vb) - return (+1); - else if (*pa == *pb) { - pa++; pb++; - continue; - } else if (isalpha((unsigned char)*pa) == isalpha((unsigned char)*pb)) - return (CMP(*pa, *pb)); - else if (isalpha((unsigned char)*pa)) - return (-1); - else - return (+1); + if (pa == va) ia = 1; + else if (isalpha((unsigned char)*pa)) ia = 2; + else if (*pa == '~') ia = 0; + else ia = 3; + + if (pb == vb) ib = 1; + else if (isalpha((unsigned char)*pb)) ib = 2; + else if (*pb == '~') ib = 0; + else ib = 3; + + if (ia != ib) return (CMP(ia, ib)); + else if (pa == va && pb == vb) break; + else if (*pa != *pb) return (CMP(*pa, *pb)); + pa++; pb++; } /* --- Compare digit portions --- */ ia = vint(&va, val); ib = vint(&vb, vbl); - if (ia != ib) - return (CMP(ia, ib)); + if (ia != ib) return (CMP(ia, ib)); } } diff --git a/versioncmp.in b/versioncmp.in new file mode 100644 index 0000000..421974a --- /dev/null +++ b/versioncmp.in @@ -0,0 +1,14 @@ +## test for versioncmp + +versioncmp { + 1.2 1.2 0; + 1.1 1.2 -1; + 1.1 1.0 +1; + 1.0 1.a -1; + 1:2.0 2:0.4 -1; + 1.2 1.2~pre0 +1; + 1~~ 1~~a -1; + 1~~a 1~ -1; + 1~ 1 -1; + 1 1a -1; +} -- [mdw]