Annotation of embedaddon/rsync/wildtest.c, revision 1.1.1.3
1.1 misho 1: /*
2: * Test suite for the wildmatch code.
3: *
1.1.1.3 ! misho 4: * Copyright (C) 2003-2015 Wayne Davison
1.1 misho 5: *
6: * This program is free software; you can redistribute it and/or modify
7: * it under the terms of the GNU General Public License as published by
8: * the Free Software Foundation; either version 3 of the License, or
9: * (at your option) any later version.
10: *
11: * This program is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License along
17: * with this program; if not, visit the http://fsf.org website.
18: */
19:
20: /*#define COMPARE_WITH_FNMATCH*/
21:
22: #define WILD_TEST_ITERATIONS
23: #include "lib/wildmatch.c"
24:
25: #include <popt.h>
26:
27: #ifdef COMPARE_WITH_FNMATCH
28: #include <fnmatch.h>
29:
30: int fnmatch_errors = 0;
31: #endif
32:
33: int wildmatch_errors = 0;
34:
35: typedef char bool;
36:
37: int output_iterations = 0;
38: int explode_mod = 0;
39: int empties_mod = 0;
40: int empty_at_start = 0;
41: int empty_at_end = 0;
42:
43: static struct poptOption long_options[] = {
44: /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
45: {"iterations", 'i', POPT_ARG_NONE, &output_iterations, 0, 0, 0},
46: {"empties", 'e', POPT_ARG_STRING, 0, 'e', 0, 0},
47: {"explode", 'x', POPT_ARG_INT, &explode_mod, 0, 0, 0},
48: {0,0,0,0, 0, 0, 0}
49: };
50:
51: /* match just at the start of string (anchored tests) */
52: static void
53: run_test(int line, bool matches,
54: #ifdef COMPARE_WITH_FNMATCH
55: bool same_as_fnmatch,
56: #endif
57: const char *text, const char *pattern)
58: {
59: bool matched;
60: #ifdef COMPARE_WITH_FNMATCH
61: bool fn_matched;
62: int flags = strstr(pattern, "**")? 0 : FNM_PATHNAME;
63: #endif
64:
65: if (explode_mod) {
66: char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
67: int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
68:
69: if (empty_at_start)
70: texts[ndx++] = "";
71: /* An empty string must turn into at least one empty array item. */
72: while (1) {
73: texts[ndx] = buf + ndx * (explode_mod + 1);
74: strlcpy(texts[ndx++], text + pos, explode_mod + 1);
75: if (pos + explode_mod >= len)
76: break;
77: pos += explode_mod;
78: if (!(++cnt % empties_mod))
79: texts[ndx++] = "";
80: }
81: if (empty_at_end)
82: texts[ndx++] = "";
83: texts[ndx] = NULL;
84: matched = wildmatch_array(pattern, (const char**)texts, 0);
85: } else
86: matched = wildmatch(pattern, text);
87: #ifdef COMPARE_WITH_FNMATCH
88: fn_matched = !fnmatch(pattern, text, flags);
89: #endif
90: if (matched != matches) {
91: printf("wildmatch failure on line %d:\n %s\n %s\n expected %s match\n",
92: line, text, pattern, matches? "a" : "NO");
93: wildmatch_errors++;
94: }
95: #ifdef COMPARE_WITH_FNMATCH
96: if (fn_matched != (matches ^ !same_as_fnmatch)) {
97: printf("fnmatch disagreement on line %d:\n %s\n %s\n expected %s match\n",
98: line, text, pattern, matches ^ !same_as_fnmatch? "a" : "NO");
99: fnmatch_errors++;
100: }
101: #endif
102: if (output_iterations) {
103: printf("%d: \"%s\" iterations = %d\n", line, pattern,
104: wildmatch_iteration_count);
105: }
106: }
107:
108: int
109: main(int argc, char **argv)
110: {
111: char buf[2048], *s, *string[2], *end[2];
112: const char *arg;
113: FILE *fp;
114: int opt, line, i, flag[2];
115: poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
116: long_options, 0);
117:
118: while ((opt = poptGetNextOpt(pc)) != -1) {
119: switch (opt) {
120: case 'e':
121: arg = poptGetOptArg(pc);
122: empties_mod = atoi(arg);
123: if (strchr(arg, 's'))
124: empty_at_start = 1;
125: if (strchr(arg, 'e'))
126: empty_at_end = 1;
127: if (!explode_mod)
128: explode_mod = 1024;
129: break;
130: default:
131: fprintf(stderr, "%s: %s\n",
132: poptBadOption(pc, POPT_BADOPTION_NOALIAS),
133: poptStrerror(opt));
134: exit(1);
135: }
136: }
137:
138: if (explode_mod && !empties_mod)
139: empties_mod = 1024;
140:
141: argv = (char**)poptGetArgs(pc);
142: if (!argv || argv[1]) {
143: fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
144: exit(1);
145: }
146:
147: if ((fp = fopen(*argv, "r")) == NULL) {
148: fprintf(stderr, "Unable to open %s\n", *argv);
149: exit(1);
150: }
151:
152: line = 0;
153: while (fgets(buf, sizeof buf, fp)) {
154: line++;
155: if (*buf == '#' || *buf == '\n')
156: continue;
157: for (s = buf, i = 0; i <= 1; i++) {
158: if (*s == '1')
159: flag[i] = 1;
160: else if (*s == '0')
161: flag[i] = 0;
162: else
163: flag[i] = -1;
164: if (*++s != ' ' && *s != '\t')
165: flag[i] = -1;
166: if (flag[i] < 0) {
167: fprintf(stderr, "Invalid flag syntax on line %d of %s:\n%s",
168: line, *argv, buf);
169: exit(1);
170: }
171: while (*++s == ' ' || *s == '\t') {}
172: }
173: for (i = 0; i <= 1; i++) {
174: if (*s == '\'' || *s == '"' || *s == '`') {
175: char quote = *s++;
176: string[i] = s;
177: while (*s && *s != quote) s++;
178: if (!*s) {
179: fprintf(stderr, "Unmatched quote on line %d of %s:\n%s",
180: line, *argv, buf);
181: exit(1);
182: }
183: end[i] = s;
184: }
185: else {
186: if (!*s || *s == '\n') {
187: fprintf(stderr, "Not enough strings on line %d of %s:\n%s",
188: line, *argv, buf);
189: exit(1);
190: }
191: string[i] = s;
192: while (*++s && *s != ' ' && *s != '\t' && *s != '\n') {}
193: end[i] = s;
194: }
195: while (*++s == ' ' || *s == '\t') {}
196: }
197: *end[0] = *end[1] = '\0';
198: run_test(line, flag[0],
199: #ifdef COMPARE_WITH_FNMATCH
200: flag[1],
201: #endif
202: string[0], string[1]);
203: }
204:
205: if (!wildmatch_errors)
206: fputs("No", stdout);
207: else
208: printf("%d", wildmatch_errors);
209: printf(" wildmatch error%s found.\n", wildmatch_errors == 1? "" : "s");
210:
211: #ifdef COMPARE_WITH_FNMATCH
212: if (!fnmatch_errors)
213: fputs("No", stdout);
214: else
215: printf("%d", fnmatch_errors);
216: printf(" fnmatch error%s found.\n", fnmatch_errors == 1? "" : "s");
217:
218: #endif
219:
220: return 0;
221: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>