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