enable -fno-strict-aliasing until the code base gets a hefty clean up to fix all...
[platform/upstream/net-tools.git] / lib / nstrcmp.c
1 /* Copyright 1998 by Andi Kleen. Subject to the GPL. */
2 /* rewritten by bernd eckenfels because of complicated alias semantic */
3 /* $Id: nstrcmp.c,v 1.4 2004/06/03 22:49:17 ecki Exp $ */ 
4 #include <ctype.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "util.h"
8
9
10 /* return numerical :999 suffix or null. sideeffect: replace ':' with \0 */
11 char* cutalias(char* name)
12 {
13         int digit = 0;
14         int pos;
15         
16         for(pos=strlen(name); pos>0; pos--)
17         {
18                 if (name[pos-1]==':' && digit)
19                 {
20                         name[pos-1]='\0';
21                         return name+pos;
22                 }
23                 if (!isdigit(name[pos-1]))
24                         break;
25                 digit = 1;
26         }
27         return NULL;
28 }
29
30
31 /* return index of last non digit or -1 if it does not end with digits */
32 int rindex_nondigit(char *name)
33 {
34         int pos = strlen(name);
35
36         for(pos=strlen(name); pos>0; pos--)
37         {
38                 if (!isdigit(name[pos-1]))
39                         return pos;
40         }
41         return 0;
42 }
43
44
45 /* like strcmp(), but knows about numbers and ':' alias suffix */
46 int nstrcmp(const char *ap, const char *bp)
47 {
48         char *a = (char*)strdup(ap);
49         char *b = (char*)strdup(bp);
50         char *an, *bn;
51         int av = 0, bv = 0;
52         char *aalias=cutalias(a);
53         char *balias=cutalias(b);
54         int aindex=rindex_nondigit(a);
55         int bindex=rindex_nondigit(b);
56         int complen=(aindex<bindex)?aindex:bindex;
57         int res = strncmp(a, b, complen);
58
59         if (res != 0)
60                 { free(a); free(b); return res; }
61                 
62         if (aindex > bindex)
63                 { free(a); free(b); return 1; }
64                 
65         if (aindex < bindex)
66                 { free(a); free(b); return -1; }
67                 
68         an = a+aindex;
69         bn = b+bindex;
70         
71         av = atoi(an);
72         bv = atoi(bn);
73         
74         if (av < bv)
75                 { free(a); free(b); return -1; }
76                 
77         if (av > bv)
78                 { free(a); free(b); return 1; }
79                 
80         av = -1;
81         if (aalias != NULL)
82                 av = atoi(aalias);
83         
84         bv = -1;
85         if (balias != NULL)
86                 bv = atoi(balias);
87         
88         free(a); free(b);
89         
90         if (av < bv)
91                 return -1;
92                 
93         if (av > bv)
94                 return 1;
95                 
96         return 0;
97 }
98
99
100 #ifdef NSTRCMP_TEST
101
102 int cs(int s)
103 {
104         if (s < 0) return -1;
105         if (s > 0) return 1;
106         return 0;
107 }
108
109
110 int dotest(char* a, char* b, int exp)
111 {
112         int res = nstrcmp(a, b);
113         int err = (cs(res) != cs(exp));
114         printf("nstrcmp(\"%s\", \"%s\")=%d %d %s\n", a, b, res, exp, err?"WRONG":"OK");
115         return err;
116 }
117
118 int main()
119 {
120         int err = 0;
121         
122         err |= dotest("eth1", "eth1", 0);
123         err |= dotest("eth0:1", "eth0:1", 0);
124         err |= dotest("lan", "lan", 0);
125         err |= dotest("100", "100", 0);
126         err |= dotest("", "", 0);
127         err |= dotest(":", ":", 0);
128         err |= dotest("a:b:c", "a:b:c", 0);
129         err |= dotest("a:", "a:", 0);
130         err |= dotest(":a", ":a", 0);
131
132         err |= dotest("a", "aa", -1);   
133         err |= dotest("eth0", "eth1", -1);
134         err |= dotest("eth1", "eth20", -1);
135         err |= dotest("eth20", "eth100", -1);
136         err |= dotest("eth1", "eth13", -1);
137         err |= dotest("eth", "eth2", -1);
138         err |= dotest("eth0:1", "eth0:2", -1);
139         err |= dotest("eth1:10", "eth13:10", -1);
140         err |= dotest("eth1:1", "eth1:13", -1);
141         err |= dotest("a", "a:", -1);
142         
143         err |= dotest("aa", "a", 1);
144         err |= dotest("eth2", "eth1", 1);
145         err |= dotest("eth13", "eth1", 1);      
146         err |= dotest("eth2", "eth", 1);
147         err |= dotest("eth2:10", "eth2:1", 1);
148         err |= dotest("eth2:5", "eth2:4", 1);
149         err |= dotest("eth3:2", "eth2:3", 1);
150         err |= dotest("eth13:1", "eth1:0", 1);
151         err |= dotest("a:", "a", 1);
152         err |= dotest("a1b12", "a1b2", 1);
153
154         return err;
155 }
156
157 #endif