aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBernd Eckenfels <net-tools@lina.inka.de>2004-06-03 22:49:17 +0000
committerBernd Eckenfels <net-tools@lina.inka.de>2004-06-03 22:49:17 +0000
commitd42c104c4fca69819a52e593d659a83b9f6cedc2 (patch)
treeb487067c2c1621137f9b466a3f8d0f111d05d033 /lib
parentmerged debian patch to make it compile with new headers (diff)
downloadnet-tools-d42c104c4fca69819a52e593d659a83b9f6cedc2.tar.gz
net-tools-d42c104c4fca69819a52e593d659a83b9f6cedc2.tar.bz2
net-tools-d42c104c4fca69819a52e593d659a83b9f6cedc2.zip
debians version of nstrcmp - ugly but works
Diffstat (limited to 'lib')
-rw-r--r--lib/nstrcmp.c167
1 files changed, 150 insertions, 17 deletions
diff --git a/lib/nstrcmp.c b/lib/nstrcmp.c
index 2c78a41..37b85c6 100644
--- a/lib/nstrcmp.c
+++ b/lib/nstrcmp.c
@@ -1,24 +1,157 @@
-/*
- * Copyright 1998 by Andi Kleen. Subject to the GPL.
- * Copyright 2002 by Bruno Hall who contributed a shorter rewrite
- * which actually works
- *
- * $Id: nstrcmp.c,v 1.3 2002/12/10 00:37:33 ecki Exp $
- */
+/* Copyright 1998 by Andi Kleen. Subject to the GPL. */
+/* rewritten by bernd eckenfels because of complicated alias semantic */
+/* $Id: nstrcmp.c,v 1.4 2004/06/03 22:49:17 ecki Exp $ */
#include <ctype.h>
#include <stdlib.h>
+#include <string.h>
#include "util.h"
-/* like strcmp(), but knows about numbers */
-int nstrcmp(const char *a, const char *b)
+/* return numerical :999 suffix or null. sideeffect: replace ':' with \0 */
+char* cutalias(char* name)
{
- while (*a == *b && !isdigit(*a)) {
- if (*a++ == 0)
- return 0;
- b++;
- }
- if (isdigit(*a) && isdigit(*b))
- return atoi(a) - atoi(b);
- return *(const unsigned char *)a - *(const unsigned char *)b;
+ int digit = 0;
+ int pos;
+
+ for(pos=strlen(name); pos>0; pos--)
+ {
+ if (name[pos-1]==':' && digit)
+ {
+ name[pos-1]='\0';
+ return name+pos;
+ }
+ if (!isdigit(name[pos-1]))
+ break;
+ digit = 1;
+ }
+ return NULL;
}
+
+
+/* return index of last non digit or -1 if it does not end with digits */
+int rindex_nondigit(char *name)
+{
+ int pos = strlen(name);
+
+ for(pos=strlen(name); pos>0; pos--)
+ {
+ if (!isdigit(name[pos-1]))
+ return pos;
+ }
+ return 0;
+}
+
+
+/* like strcmp(), but knows about numbers and ':' alias suffix */
+int nstrcmp(const char *ap, const char *bp)
+{
+ char *a = (char*)strdup(ap);
+ char *b = (char*)strdup(bp);
+ char *an, *bn;
+ int av = 0, bv = 0;
+ char *aalias=cutalias(a);
+ char *balias=cutalias(b);
+ int aindex=rindex_nondigit(a);
+ int bindex=rindex_nondigit(b);
+ int complen=(aindex<bindex)?aindex:bindex;
+ int res = strncmp(a, b, complen);
+
+ if (res != 0)
+ { free(a); free(b); return res; }
+
+ if (aindex > bindex)
+ { free(a); free(b); return 1; }
+
+ if (aindex < bindex)
+ { free(a); free(b); return -1; }
+
+ an = a+aindex;
+ bn = b+bindex;
+
+ av = atoi(an);
+ bv = atoi(bn);
+
+ if (av < bv)
+ { free(a); free(b); return -1; }
+
+ if (av > bv)
+ { free(a); free(b); return 1; }
+
+ av = -1;
+ if (aalias != NULL)
+ av = atoi(aalias);
+
+ bv = -1;
+ if (balias != NULL)
+ bv = atoi(balias);
+
+ free(a); free(b);
+
+ if (av < bv)
+ return -1;
+
+ if (av > bv)
+ return 1;
+
+ return 0;
+}
+
+
+#ifdef NSTRCMP_TEST
+
+int cs(int s)
+{
+ if (s < 0) return -1;
+ if (s > 0) return 1;
+ return 0;
+}
+
+
+int dotest(char* a, char* b, int exp)
+{
+ int res = nstrcmp(a, b);
+ int err = (cs(res) != cs(exp));
+ printf("nstrcmp(\"%s\", \"%s\")=%d %d %s\n", a, b, res, exp, err?"WRONG":"OK");
+ return err;
+}
+
+int main()
+{
+ int err = 0;
+
+ err |= dotest("eth1", "eth1", 0);
+ err |= dotest("eth0:1", "eth0:1", 0);
+ err |= dotest("lan", "lan", 0);
+ err |= dotest("100", "100", 0);
+ err |= dotest("", "", 0);
+ err |= dotest(":", ":", 0);
+ err |= dotest("a:b:c", "a:b:c", 0);
+ err |= dotest("a:", "a:", 0);
+ err |= dotest(":a", ":a", 0);
+
+ err |= dotest("a", "aa", -1);
+ err |= dotest("eth0", "eth1", -1);
+ err |= dotest("eth1", "eth20", -1);
+ err |= dotest("eth20", "eth100", -1);
+ err |= dotest("eth1", "eth13", -1);
+ err |= dotest("eth", "eth2", -1);
+ err |= dotest("eth0:1", "eth0:2", -1);
+ err |= dotest("eth1:10", "eth13:10", -1);
+ err |= dotest("eth1:1", "eth1:13", -1);
+ err |= dotest("a", "a:", -1);
+
+ err |= dotest("aa", "a", 1);
+ err |= dotest("eth2", "eth1", 1);
+ err |= dotest("eth13", "eth1", 1);
+ err |= dotest("eth2", "eth", 1);
+ err |= dotest("eth2:10", "eth2:1", 1);
+ err |= dotest("eth2:5", "eth2:4", 1);
+ err |= dotest("eth3:2", "eth2:3", 1);
+ err |= dotest("eth13:1", "eth1:0", 1);
+ err |= dotest("a:", "a", 1);
+ err |= dotest("a1b12", "a1b2", 1);
+
+ return err;
+}
+
+#endif