Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/usr.sbin/pkg_install/lib Pull up revisions 1.30-1.33 (r...



details:   https://anonhg.NetBSD.org/src/rev/3cc54a362e00
branches:  netbsd-1-5
changeset: 492847:3cc54a362e00
user:      he <he%NetBSD.org@localhost>
date:      Sat Feb 23 18:15:48 2002 +0000

description:
Pull up revisions 1.30-1.33 (requested by seb):
  Synchronize with recent developments:
   o Improve version number handling by recognizing "pl" and "rc"
   o Various internal cleanups, bugfixes, and API tweaks

diffstat:

 usr.sbin/pkg_install/lib/str.c |  384 +++++++++++++++++++++++-----------------
 1 files changed, 223 insertions(+), 161 deletions(-)

diffs (truncated from 491 to 300 lines):

diff -r 6690b8af3dc9 -r 3cc54a362e00 usr.sbin/pkg_install/lib/str.c
--- a/usr.sbin/pkg_install/lib/str.c    Sat Feb 23 18:15:10 2002 +0000
+++ b/usr.sbin/pkg_install/lib/str.c    Sat Feb 23 18:15:48 2002 +0000
@@ -1,11 +1,11 @@
-/*     $NetBSD: str.c,v 1.23.2.3 2001/05/01 11:01:09 he Exp $  */
+/*     $NetBSD: str.c,v 1.23.2.4 2002/02/23 18:15:48 he Exp $  */
 
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static const char *rcsid = "Id: str.c,v 1.5 1997/10/08 07:48:21 charnier Exp";
 #else
-__RCSID("$NetBSD: str.c,v 1.23.2.3 2001/05/01 11:01:09 he Exp $");
+__RCSID("$NetBSD: str.c,v 1.23.2.4 2002/02/23 18:15:48 he Exp $");
 #endif
 #endif
 
@@ -91,74 +91,203 @@
        }
 }
 
-typedef enum deweyop_t {
-       GT,
+/* pull in definitions and macros for resizing arrays as we go */
+#include "defs.h"
+
+/* do not modify these values, or things will NOT work */
+enum {
+        RC = -1,
+        Dot = 0,
+        Patch = 1
+};
+
+/* this struct defines a version number */
+typedef struct arr_t {
+       unsigned        c;              /* # of version numbers */
+       unsigned        size;           /* size of array */
+       int64_t        *v;              /* array of decimal numbers */
+       int64_t         netbsd;         /* any "nb" suffix */
+} arr_t;
+
+/* this struct describes a test */
+typedef struct test_t {
+       const char     *s;              /* string representation */
+       unsigned        len;            /* length of string */
+       int             t;              /* enumerated type of test */
+} test_t;
+
+enum {
+       LT,
+       LE,
+       EQ,
        GE,
-       LT,
-       LE
-}       deweyop_t;
+       GT,
+       NE
+};
+
+/* the tests that are recognised. */
+static test_t   tests[] = {
+        {      "<=",   2,      LE      },
+        {      "<",    1,      LT      },
+        {      ">=",   2,      GE      },
+        {      ">",    1,      GT      },
+        {      "==",   2,      EQ      },
+        {      "!=",   2,      NE      },
+        {      NULL,   0,      0       }
+};
+
+
+/* locate the test in the tests array */
+static int
+mktest(int *op, char *test)
+{
+       test_t  *tp;
+
+       for (tp = tests ; tp->s ; tp++) {
+               if (strncasecmp(test, tp->s, tp->len) == 0) {
+                       *op = tp->t;
+                       return tp->len;
+               }
+       }
+       warnx("relational test not found `%.10s'", test);
+       return -1;
+}
+
+/*
+ * make a component of a version number.
+ * '.' encodes as Dot which is '0'
+ * '_' encodes as 'patch level', or 'Dot', which is 0.
+ * 'pl' encodes as 'patch level', or 'Dot', which is 0.
+ * 'rc' encodes as 'release candidate', or RC, which is -1.
+ * 'nb' encodes as 'netbsd version', which is used after all other tests
+ */
+static int
+mkcomponent(arr_t *ap, char *num)
+{
+       static const char       alphas[] = "abcdefghijklmnopqrstuvwxyz";
+       int64_t                 n;
+       char                   *cp;
+
+       if (*num == 0) {
+               return 0;
+       }
+       ALLOC(int64_t, ap->v, ap->size, ap->c, 62, "mkver", exit(EXIT_FAILURE));
+       if (*num == '_') {
+               num += 1;
+               if (isdigit(*(num + 1))) {
+                       ap->v[ap->c++] = Dot;
+                       return 1;
+               }
+       }
+       if (isdigit(*num)) {
+               for (cp = num, n = 0 ; isdigit(*num) ; num++) {
+                       n = (n * 10) + (*num - '0');
+               }
+               ap->v[ap->c++] = n;
+               return (int)(num - cp);
+       }
+       if (strncasecmp(num, "rc", 2) == 0) {
+               ap->v[ap->c++] = RC;
+               return 2;
+       }
+       if (strncasecmp(num, "pl", 2) == 0) {
+               ap->v[ap->c++] = Dot;
+               return 2;
+       }
+       if (strncasecmp(num, "nb", 2) == 0) {
+               for (cp = num, num += 2, n = 0 ; isdigit(*num) ; num++) {
+                       n = (n * 10) + (*num - '0');
+               }
+               ap->netbsd = n;
+               return (int)(num - cp);
+       }
+       if (*num == '.') {
+               ap->v[ap->c++] = Dot;
+               return 1;
+       }
+       if (isalpha(*num)) {
+               ap->v[ap->c++] = Dot;
+               cp = strchr(alphas, tolower(*num));
+               ALLOC(int64_t, ap->v, ap->size, ap->c, 62, "mkver", exit(EXIT_FAILURE));
+               ap->v[ap->c++] = (int64_t)(cp - alphas) + 1;
+               return 1;
+       }
+       warnx("`%c' not recognised", *num);
+       return 1;
+}
+
+/* make a version number string into an array of comparable 64bit ints */
+static int
+mkversion(arr_t *ap, char *num)
+{
+       (void) memset(ap, 0, sizeof(arr_t));
+       while (*num) {
+               num += mkcomponent(ap, num);
+       }
+       return 1;
+}
+
+#define DIGIT(v, c, n) (((n) < (c)) ? v[n] : 0)
+
+/* compare the result against the test we were expecting */
+static int
+result(int64_t cmp, int tst)
+{
+       switch(tst) {
+       case LT:
+               return cmp < 0;
+       case LE:
+               return cmp <= 0;
+       case GT:
+               return cmp > 0;
+       case GE:
+               return cmp >= 0;
+       case EQ:
+               return cmp == 0;
+       case NE:
+               return cmp != 0;
+       default:
+               warnx("result: unknown test %d", tst);
+               return 0;
+       }
+}
+
+/* do the test on the 2 vectors */
+static int
+vtest(arr_t *lhs, int tst, arr_t *rhs)
+{
+       int64_t cmp;
+       int     c;
+       int     i;
+
+       for (i = 0, c = MAX(lhs->c, rhs->c) ; i < c ; i++) {
+               if ((cmp = DIGIT(lhs->v, lhs->c, i) - DIGIT(rhs->v, rhs->c, i)) != 0) {
+                       return result(cmp, tst);
+               }
+       }
+       return result(lhs->netbsd - rhs->netbsd, tst);
+}
 
 /*
  * Compare two dewey decimal numbers
  */
 static int
-deweycmp(char *a, deweyop_t op, char *b)
+deweycmp(char *lhs, int op, char *rhs)
 {
-       int     ad;
-       int     bd;
-       char    *a_nb;
-       char    *b_nb;
-       int     in_nb = 0;
-       int     cmp;
-
-       assert(a != NULL);
-       assert(b != NULL);
-
-       /* Null out 'n' in any "nb" suffixes for initial pass */
-       if ((a_nb = strstr(a, "nb")))
-           *a_nb = 0;
-       if ((b_nb = strstr(b, "nb")))
-           *b_nb = 0;
+       arr_t   right;
+       arr_t   left;
 
-       for (;;) {
-               if (*a == 0 && *b == 0) {
-                       if (!in_nb && (a_nb || b_nb)) {
-                               /*
-                                * If exact match on first pass, test
-                                * "nb<X>" suffixes in second pass
-                                */
-                               in_nb = 1;
-                               if (a_nb)
-                                   a = a_nb + 2;       /* Skip "nb" suffix */
-                               if (b_nb)
-                                   b = b_nb + 2;       /* Skip "nb" suffix */
-                       } else {
-                               cmp = 0;
-                               break;
-                       }
-               }
-
-               ad = bd = 0;
-               for (; *a && *a != '.'; a++) {
-                       ad = (ad * 10) + (*a - '0');
-               }
-               for (; *b && *b != '.'; b++) {
-                       bd = (bd * 10) + (*b - '0');
-               }
-               if ((cmp = ad - bd) != 0) {
-                       break;
-               }
-               if (*a == '.')
-                       ++a;
-               if (*b == '.')
-                       ++b;
+       (void) memset(&left, 0, sizeof(left));
+       if (!mkversion(&left, lhs)) {
+               warnx("Bad lhs version `%s'", lhs);
+               return 0;
        }
-       /* Replace any nulled 'n' */
-       if (a_nb)
-               *a_nb = 'n';
-       if (b_nb)
-               *b_nb = 'n';
-       return (op == GE) ? cmp >= 0 : (op == GT) ? cmp > 0 : (op == LE) ? cmp <= 0 : cmp < 0;
+       (void) memset(&right, 0, sizeof(right));
+       if (!mkversion(&right, rhs)) {
+               warnx("Bad rhs version `%s'", rhs);
+               return 0;
+       }
+        return vtest(&left, op, &right);
 }
 
 /*
@@ -216,22 +345,26 @@
 static int
 dewey_match(const char *pattern, const char *pkg)
 {
-       deweyop_t op;
        char   *cp;
        char   *sep;
        char   *ver;
        char    name[FILENAME_MAX];
+       int     op;
        int     n;
 
        if ((sep = strpbrk(pattern, "<>")) == NULL) {
                errx(1, "dewey_match(): '<' or '>' expected in `%s'", pattern);
        }
        (void) snprintf(name, sizeof(name), "%.*s", (int) (sep - pattern), pattern);
-       op = (*sep == '>') ? (*(sep + 1) == '=') ? GE : GT : (*(sep + 1) == '=') ? LE : LT;
-       ver = (op == GE || op == LE) ? sep + 2 : sep + 1;
+        if ((n = mktest(&op, sep)) < 0) {
+                warnx("Bad comparison `%s'", sep);



Home | Main Index | Thread Index | Old Index