]> git.gag.com Git - debian/sudo/blob - compat/regress/glob/globtest.c
Imported Upstream version 1.8.1p2
[debian/sudo] / compat / regress / glob / globtest.c
1 /*      $OpenBSD: globtest.c,v 1.1 2008/10/01 23:04:36 millert Exp $    */
2
3 /*
4  * Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com>
5  */
6
7 #include <config.h>
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #ifdef HAVE_STRING_H
12 # include <string.h>
13 #endif /* HAVE_STRING_H */
14 #ifdef HAVE_STRINGS_H
15 # include <strings.h>
16 #endif /* HAVE_STRINGS_H */
17 #ifdef HAVE_EXTENDED_GLOB
18 # include <glob.h>
19 #else
20 # include "compat/glob.h"
21 #endif
22 #include <errno.h>
23
24 #define MAX_RESULTS     256
25
26 #ifndef errno
27 extern int errno;
28 #endif
29
30 struct gl_entry {
31         int flags;
32         int nresults;
33         char pattern[1024];
34         char *results[MAX_RESULTS];
35 };
36
37 int test_glob(struct gl_entry *);
38
39 int
40 main(int argc, char **argv)
41 {
42         FILE *fp = stdin;
43         char buf[2048], *cp, *ep;
44         int errors = 0, tests = 0, lineno;
45         struct gl_entry entry;
46         size_t len;
47
48         if (argc > 1) {
49                 if ((fp = fopen(argv[1], "r")) == NULL) {
50                         perror(argv[1]);
51                         exit(1);
52                 }
53         }
54
55         /*
56          * Read in test file, which is formatted thusly:
57          *
58          * [pattern] <flags>
59          * result1
60          * result2
61          * result3
62          * ...
63          *
64          */
65         lineno = 0;
66         memset(&entry, 0, sizeof(entry));
67         while (fgets(buf, sizeof(buf), fp) != NULL) {
68                 lineno++;
69                 len = strlen(buf);
70                 if (len > 0) {
71                         if (buf[len - 1] != '\n') {
72                                 fprintf(stderr,
73                                     "globtest: missing newline at EOF\n");
74                                 exit(1);
75                         }
76                         buf[--len] = '\0';
77                 }
78                 if (len == 0)
79                         continue; /* blank line */
80
81                 if (buf[0] == '[') {
82                         /* check previous pattern */
83                         if (entry.pattern[0]) {
84                                 errors += test_glob(&entry);
85                                 tests++;
86                         }
87
88                         /* start new entry */
89                         if ((cp = strrchr(buf + 1, ']')) == NULL) {
90                                 fprintf(stderr,
91                                     "globtest: invalid entry on line %d\n",
92                                     lineno);
93                                 exit(1);
94                         }
95                         len = cp - buf - 1;
96                         if (len >= sizeof(entry.pattern)) {
97                                 fprintf(stderr,
98                                     "globtest: pattern too big on line %d\n",
99                                     lineno);
100                                 exit(1);
101                         }
102                         memcpy(entry.pattern, buf + 1, len);
103                         entry.pattern[len] = '\0';
104
105                         cp += 2;
106                         if (*cp++ != '<') {
107                                 fprintf(stderr,
108                                     "globtest: invalid entry on line %d\n",
109                                     lineno);
110                                 exit(1);
111                         }
112                         ep = strchr(cp, '>');
113                         if (ep == NULL) {
114                                 fprintf(stderr,
115                                     "globtest: invalid entry on line %d\n",
116                                     lineno);
117                                 exit(1);
118                         }
119                         *ep = '\0';
120                         entry.flags = 0;
121                         for ((cp = strtok(cp, "|")); cp != NULL; (cp = strtok(NULL, "|"))) {
122                                 if (strcmp(cp, "GLOB_APPEND") == 0)
123                                         entry.flags |= GLOB_APPEND;
124                                 else if (strcmp(cp, "GLOB_DOOFFS") == 0)
125                                         entry.flags |= GLOB_DOOFFS;
126                                 else if (strcmp(cp, "GLOB_ERR") == 0)
127                                         entry.flags |= GLOB_ERR;
128                                 else if (strcmp(cp, "GLOB_MARK") == 0)
129                                         entry.flags |= GLOB_MARK;
130                                 else if (strcmp(cp, "GLOB_NOCHECK") == 0)
131                                         entry.flags |= GLOB_NOCHECK;
132                                 else if (strcmp(cp, "GLOB_NOSORT") == 0)
133                                         entry.flags |= GLOB_NOSORT;
134                                 else if (strcmp(cp, "GLOB_NOESCAPE") == 0)
135                                         entry.flags |= GLOB_NOESCAPE;
136                                 else if (strcmp(cp, "GLOB_BRACE") == 0)
137                                         entry.flags |= GLOB_BRACE;
138                                 else if (strcmp(cp, "GLOB_TILDE") == 0)
139                                         entry.flags |= GLOB_TILDE;
140                                 else if (strcmp(cp, "NONE") != 0) {
141                                         fprintf(stderr,
142                                             "globtest: invalid flags on line %d\n",
143                                             lineno);
144                                         exit(1);
145                                 }
146                         }
147                         entry.nresults = 0;
148                         continue;
149                 }
150                 if (!entry.pattern[0]) {
151                         fprintf(stderr, "globtest: missing entry on line %d\n",
152                             lineno);
153                         exit(1);
154                 }
155
156                 if (entry.nresults + 1 > MAX_RESULTS) {
157                         fprintf(stderr,
158                             "globtest: too many results for %s, max %d\n",
159                             entry.pattern, MAX_RESULTS);
160                         exit(1);
161                 }
162                 entry.results[entry.nresults++] = strdup(buf);
163         }
164         if (entry.pattern[0]) {
165                 errors += test_glob(&entry); /* test last pattern */
166                 tests++;
167         }
168         if (tests != 0) {
169                 printf("glob: %d test%s run, %d errors, %d%% success rate\n",
170                     tests, tests == 1 ? "" : "s", errors,
171                     (tests - errors) * 100 / tests);
172         }
173         exit(errors);
174 }
175
176 int test_glob(struct gl_entry *entry)
177 {
178         glob_t gl;
179         char **ap;
180         int nmatches = 0, i = 0;
181
182         if (glob(entry->pattern, entry->flags, NULL, &gl) != 0) {
183                 fprintf(stderr, "glob failed: %s: %s\n", entry->pattern,
184                     strerror(errno));
185                 exit(1);
186         }
187
188         for (ap = gl.gl_pathv; *ap != NULL; ap++)
189                 nmatches++;
190
191         if (nmatches != entry->nresults)
192                 goto mismatch;
193
194         for (i = 0; i < entry->nresults; i++) {
195                 if (strcmp(gl.gl_pathv[i], entry->results[i]) != 0)
196                         goto mismatch;
197                 free(entry->results[i]);
198         }
199         return 0;
200  mismatch:
201         if (nmatches != entry->nresults) {
202                 fprintf(stderr,
203                     "globtest: mismatch in number of results (found %d, expected %d) for pattern %s\n",
204                     nmatches, entry->nresults, entry->pattern);
205         } else {
206                 fprintf(stderr, "globtest: mismatch for pattern %s, flags 0x%x "
207                     "(found \"%s\", expected \"%s\")\n", entry->pattern, entry->flags,
208                     gl.gl_pathv[i], entry->results[i]);
209                 while (i < entry->nresults)
210                         free(entry->results[i++]);
211         }
212         return 1;
213 }