A testbed to stress the new wildmatch() routine.
[rsync/rsync.git] / wildtest.c
1 /*
2 **  wildmatch test suite.
3 */
4
5 #include "rsync.h"
6
7 #define COMPARE_WITH_FNMATCH
8
9 #ifdef COMPARE_WITH_FNMATCH
10 #include <fnmatch.h>
11 #endif
12
13 typedef char bool;
14
15 #define false 0
16 #define true 1
17
18 /* match just at the start of string (anchored tests) */
19 static void
20 beg(int n, const char *text, const char *pattern, bool matches, bool same_as_fnmatch)
21 {
22     bool matched;
23 #ifdef COMPARE_WITH_FNMATCH
24     bool fn_matched;
25     int flags = strstr(pattern, "**")? 0 : FNM_PATHNAME;
26 #endif
27
28     matched = wildmatch(pattern, text);
29 #ifdef COMPARE_WITH_FNMATCH
30     fn_matched = !fnmatch(pattern, text, flags);
31 #endif
32     if (matched != matches) {
33         printf("wildmatch failure on #%d:\n  %s\n  %s\n  expected %d\n",
34                n, text, pattern, matches);
35     }
36 #ifdef COMPARE_WITH_FNMATCH
37     if (fn_matched != (matches ^ !same_as_fnmatch)) {
38         printf("fnmatch disagreement on #%d:\n  %s\n  %s\n  expected %d\n",
39                n, text, pattern, matches ^ !same_as_fnmatch);
40     }
41 #endif
42 }
43
44 /* match after any slash (non-anchored tests) */
45 static void
46 end(int n, const char *text, const char *pattern, bool matches, bool same_as_fnmatch)
47 {
48     bool matched = false;
49 #ifdef COMPARE_WITH_FNMATCH
50     bool fn_matched = false;
51     int flags = strstr(pattern, "**")? 0 : FNM_PATHNAME;
52 #endif
53
54     if (strncmp(pattern, "**", 2) == 0) {
55         matched = wildmatch(pattern, text);
56 #ifdef COMPARE_WITH_FNMATCH
57         fn_matched = !fnmatch(pattern, text, flags);
58 #endif
59     }
60     else {
61         const char *t = text;
62         while (1) {
63 #ifdef COMPARE_WITH_FNMATCH
64             if (!fn_matched)
65                 fn_matched = !fnmatch(pattern, t, flags);
66 #endif
67             if (wildmatch(pattern, t)) {
68                 matched = true;
69                 break;
70             }
71 #ifdef COMPARE_WITH_FNMATCH
72             if (fn_matched)
73                 fn_matched = -1;
74 #endif
75             if (!(t = strchr(t, '/')))
76                 break;
77             t++;
78         }
79     }
80     if (matched != matches) {
81         printf("wildmatch failure on #%d:\n  %s\n  %s\n  expected %d\n",
82                n, text, pattern, matches);
83     }
84 #ifdef COMPARE_WITH_FNMATCH
85     if (fn_matched < 0 || fn_matched != (matches ^ !same_as_fnmatch)) {
86         printf("fnmatch disagreement on #%d:\n  %s\n  %s\n  expected %d\n",
87                n, text, pattern, matches ^ !same_as_fnmatch);
88     }
89 #endif
90 }
91
92 int
93 main(int argc, char **argv)
94 {
95     /* Use our args to avoid a compiler warning. */
96     if (argc)
97         argv++;
98
99     /* Basic wildmat features. */
100     /* TEST, "text",            "pattern",              MATCH?, SAME-AS-FNMATCH? */
101     beg(100, "foo",             "foo",                  true,   true);
102     beg(101, "foo",             "bar",                  false,  true);
103     beg(102, "",                "",                     true,   true);
104     beg(103, "foo",             "???",                  true,   true);
105     beg(104, "foo",             "??",                   false,  true);
106     beg(105, "foo",             "*",                    true,   true);
107     beg(106, "foo",             "f*",                   true,   true);
108     beg(107, "foo",             "*f",                   false,  true);
109     beg(108, "foo",             "*foo*",                true,   true);
110     beg(109, "foobar",          "*ob*a*r*",             true,   true);
111     beg(110, "aaaaaaabababab",  "*ab",                  true,   true);
112     beg(111, "foo*",            "foo\\*",               true,   true);
113     beg(112, "foobar",          "foo\\*bar",            false,  true);
114     beg(113, "f\\oo",           "f\\\\oo",              true,   true);
115     beg(114, "ball",            "*[al]?",               true,   true);
116     beg(115, "ten",             "[ten]",                false,  true);
117     beg(116, "ten",             "**[!te]",              true,   true);
118     beg(117, "ten",             "**[!ten]",             false,  true);
119     beg(118, "ten",             "t[a-g]n",              true,   true);
120     beg(119, "ten",             "t[!a-g]n",             false,  true);
121     beg(120, "ton",             "t[!a-g]n",             true,   true);
122     beg(121, "]",               "]",                    true,   true);
123     beg(122, "a]b",             "a[]]b",                true,   true);
124     beg(123, "a-b",             "a[]-]b",               true,   true);
125     beg(124, "a]b",             "a[]-]b",               true,   true);
126     beg(125, "aab",             "a[]-]b",               false,  true);
127     beg(126, "aab",             "a[]a-]b",              true,   true);
128
129     /* Extended slash-matching features */
130     /* TEST, "text",            "pattern",              MATCH?, SAME-AS-FNMATCH? */
131     beg(200, "foo/baz/bar",     "foo*bar",              false,  true);
132     beg(201, "foo/baz/bar",     "foo**bar",             true,   true);
133     beg(202, "foo/bar",         "foo?bar",              false,  true);
134     beg(203, "foo/bar",         "foo[/]bar",            true,   false);
135     beg(204, "foo",             "**/foo",               false,  true);
136     beg(205, "/foo",            "**/foo",               true,   true);
137     beg(206, "bar/baz/foo",     "**/foo",               true,   true);
138     beg(207, "bar/baz/foo",     "*/foo",                false,  true);
139     beg(208, "foo/bar/baz",     "**/bar*",              false,  false);
140     beg(209, "foo/bar/baz",     "**/bar**",             true,   true);
141
142     /* Various additional tests. */
143     /* TEST, "text",            "pattern",              MATCH?, SAME-AS-FNMATCH? */
144     beg(300, "acrt",            "a[c-c]st",             false,  true);
145     beg(301, "]",               "[!]-]",                false,  true);
146     beg(302, "a",               "[!]-]",                true,   true);
147     beg(303, "",                "\\",                   false,  true);
148     beg(304, "\\",              "\\",                   false,  true);
149     beg(305, "foo",             "foo",                  true,   true);
150     beg(306, "@foo",            "@foo",                 true,   true);
151     beg(307, "foo",             "@foo",                 false,  true);
152     beg(308, "[ab]",            "\\[ab]",               true,   true);
153     beg(309, "?a?b",            "\\??\\?b",             true,   true);
154     beg(310, "abc",             "\\a\\b\\c",            true,   true);
155     beg(311, "foo",             "",                     false,  true);
156
157     /* Tail-match tests */
158     /* TEST, "text",            "pattern",              MATCH?, SAME-AS-FNMATCH? */
159     end(400, "foo/bar/baz",     "baz",                  true,   true);
160     end(401, "foo/bar/baz",     "bar/baz",              true,   true);
161     end(402, "foo/bar/baz",     "ar/baz",               false,  true);
162     end(403, "foo/bar/baz",     "/bar/baz",             false,  true);
163     end(404, "foo/bar/baz",     "bar",                  false,  true);
164     end(405, "foo/bar/baz/to",  "t[o]",                 true,   true);
165
166     /* Additional tests, including some malformed wildmats. */
167     /* TEST, "text",            "pattern",              MATCH?, SAME-AS-FNMATCH? */
168     beg(500, "]",               "[\\-_]",               true,   false);
169     beg(501, "[",               "[\\-_]",               false,  true);
170     beg(502, ".",               "[\\\\-_]",             false,  true);
171     beg(503, "^",               "[\\\\-_]",             true,   false);
172     beg(504, "Z",               "[\\\\-_]",             false,  true);
173     beg(505, "\\",              "[\\]]",                false,  true);
174     beg(506, "ab",              "a[]b",                 false,  true);
175     beg(507, "a[]b",            "a[]b",                 false,  true);
176     beg(508, "ab[",             "ab[",                  false,  true);
177     beg(509, "ab",              "[!",                   false,  true);
178     beg(510, "ab",              "[-",                   false,  true);
179     beg(511, "-",               "[-]",                  true,   true);
180     beg(512, "-",               "[a-",                  false,  true);
181     beg(513, "-",               "[!a-",                 false,  true);
182     beg(514, "-",               "[--A]",                true,   true);
183     beg(515, "5",               "[--A]",                true,   true);
184     beg(516, "\303\206",        "[--A]",                false,  true);
185     beg(517, " ",               "[ --]",                true,   true);
186     beg(518, "$",               "[ --]",                true,   true);
187     beg(519, "-",               "[ --]",                true,   true);
188     beg(520, "0",               "[ --]",                false,  true);
189     beg(521, "-",               "[---]",                true,   true);
190     beg(522, "-",               "[------]",             true,   true);
191     beg(523, "j",               "[a-e-n]",              false,  true);
192     beg(524, "-",               "[a-e-n]",              true,   true);
193     beg(525, "a",               "[!------]",            true,   true);
194     beg(526, "[",               "[]-a]",                false,  true);
195     beg(527, "^",               "[]-a]",                true,   true);
196     beg(528, "^",               "[!]-a]",               false,  true);
197     beg(529, "[",               "[!]-a]",               true,   true);
198     beg(530, "^",               "[a^bc]",               true,   true);
199     beg(531, "-b]",             "[a-]b]",               true,   true);
200     beg(532, "\\]",             "[\\]]",                true,   false);
201     beg(533, "\\",              "[\\]",                 true,   false);
202     beg(534, "\\",              "[!\\]",                false,  false); /*FN?*/
203     beg(535, "G",               "[A-\\]",               true,   false);
204     beg(536, "aaabbb",          "b*a",                  false,  true);
205     beg(537, "aabcaa",          "*ba*",                 false,  true);
206     beg(538, ",",               "[,]",                  true,   true);
207     beg(539, ",",               "[\\,]",                true,   true);
208     beg(540, "\\",              "[\\,]",                true,   false);
209     beg(541, "-",               "[,-.]",                true,   true);
210     beg(542, "+",               "[,-.]",                false,  true);
211     beg(543, "-.]",             "[,-.]",                false,  true);
212
213     return 0;
214 }