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