diff options
author | Bernd Eckenfels <net-tools@lina.inka.de> | 2004-06-03 22:49:17 +0000 |
---|---|---|
committer | Bernd Eckenfels <net-tools@lina.inka.de> | 2004-06-03 22:49:17 +0000 |
commit | d42c104c4fca69819a52e593d659a83b9f6cedc2 (patch) | |
tree | b487067c2c1621137f9b466a3f8d0f111d05d033 /lib | |
parent | merged debian patch to make it compile with new headers (diff) | |
download | net-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.c | 167 |
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 |