ms_fnmatch test program
[tridge/junkcode.git] / fnmatch / ms_fnmatch.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <time.h>
6 #include <ctype.h>
7
8 /*
9   the original, recursive function. Needs replacing, but with exactly
10   the same output
11 */
12 static int fnmatch_orig(const char *p, const char *n)
13 {
14         char c;
15
16         while ((c = *p++)) {
17                 switch (c) {
18                 case '?':
19                         if (! *n) return -1;
20                         n++;
21                         break;
22
23                 case '>':
24                         if (n[0] == '.') {
25                                 if (! n[1] && fnmatch_orig(p, n+1) == 0) return 0;
26                                 if (fnmatch_orig(p, n) == 0) return 0;
27                                 return -1;
28                         }
29                         if (! *n) return fnmatch_orig(p, n);
30                         n++;
31                         break;
32
33                 case '*':
34                         for (; *n; n++) {
35                                 if (fnmatch_orig(p, n) == 0) return 0;
36                         }
37                         break;
38
39                 case '<':
40                         for (; *n; n++) {
41                                 if (fnmatch_orig(p, n) == 0) return 0;
42                                 if (*n == '.' && !strchr(n+1,'.')) {
43                                         n++;
44                                         break;
45                                 }
46                         }
47                         break;
48
49                 case '"':
50                         if (*n == 0 && fnmatch_orig(p, n) == 0) return 0;
51                         if (*n != '.') return -1;
52                         n++;
53                         break;
54
55                 default:
56                         if (c != *n && toupper(c) != toupper(*n)) return -1;
57                         n++;
58                 }
59         }
60         
61         if (! *n) return 0;
62         
63         return -1;
64 }
65
66
67 /*
68   the new, hopefully better function. Fiddle this until it works and is fast
69 */
70 static int fnmatch_test(const char *p, const char *n)
71 {
72         char c;
73
74         while ((c = *p++)) {
75                 switch (c) {
76                 case '?':
77                         if (! *n) return -1;
78                         n++;
79                         break;
80
81                 case '>':
82                         if (n[0] == '.') {
83                                 if (! n[1] && fnmatch_test(p, n+1) == 0) return 0;
84                                 if (fnmatch_test(p, n) == 0) return 0;
85                                 return -1;
86                         }
87                         if (! *n) return fnmatch_test(p, n);
88                         n++;
89                         break;
90
91                 case '*':
92                         for (; *n; n++) {
93                                 if (fnmatch_test(p, n) == 0) return 0;
94                         }
95                         break;
96
97                 case '<':
98                         for (; *n; n++) {
99                                 if (fnmatch_test(p, n) == 0) return 0;
100                                 if (*n == '.' && !strchr(n+1,'.')) {
101                                         n++;
102                                         break;
103                                 }
104                         }
105                         break;
106
107                 case '"':
108                         if (*n == 0 && fnmatch_test(p, n) == 0) return 0;
109                         if (*n != '.') return -1;
110                         n++;
111                         break;
112
113                 default:
114                         if (c != *n && toupper(c) != toupper(*n)) return -1;
115                         n++;
116                 }
117         }
118         
119         if (! *n) return 0;
120         
121         return -1;
122 }
123
124
125 static void randstring(char *s, int len, const char *chars)
126 {
127         while (len--) {
128                 *s++ = chars[random() % strlen(chars)];
129         }
130         *s = 0;
131 }
132
133
134 int main(void)
135 {
136         int i;
137         srandom(time(NULL));
138
139         alarm(2);
140         fnmatch_test("********************************************.dat", "foobar.txt");
141         fnmatch_test("*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<*<.dat", "foobar.txt");
142         alarm(0);
143
144         for (i=0;i<100000;i++) {
145                 int len1 = random() % 20;
146                 int len2 = random() % 20;
147                 char *p = malloc(len1+1);
148                 char *n = malloc(len2+1);
149                 int ret1, ret2;
150
151                 randstring(p, len1, "*?<>\".abc");
152                 randstring(n, len2, "abc.");
153
154                 ret1 = fnmatch_orig(p, n);
155                 ret2 = fnmatch_test(p, n);
156
157                 if (ret1 != ret2) {
158                         printf("mismatch: ret1=%d ret2=%d pattern='%s' string='%s'\n",
159                                ret1, ret2, p, n);
160                         free(p);
161                         free(n);
162                         exit(0);
163                 }
164
165                 free(p);
166                 free(n);
167                 printf("%d\r", i);
168                 fflush(stdout);
169         }
170
171         printf("ALL OK\n");
172         return 0;
173 }