1 /* GLIB - Library of useful routines for C programming 2 * Copyright (C) 2001 Matthias Clasen <matthiasc (at) poet.de> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 #undef G_DISABLE_ASSERT 21 #undef G_LOG_DOMAIN 22 23 #include <string.h> 24 #include <glib.h> 25 26 static gboolean noisy = FALSE; 27 28 static void 29 verbose (const gchar *format, ...) 30 { 31 gchar *msg; 32 va_list args; 33 34 va_start (args, format); 35 msg = g_strdup_vprintf (format, args); 36 va_end (args); 37 38 if (noisy) 39 g_print (msg); 40 g_free (msg); 41 } 42 43 /* keep enum and structure of gpattern.c and patterntest.c in sync */ 44 typedef enum 45 { 46 G_MATCH_ALL, /* "*A?A*" */ 47 G_MATCH_ALL_TAIL, /* "*A?AA" */ 48 G_MATCH_HEAD, /* "AAAA*" */ 49 G_MATCH_TAIL, /* "*AAAA" */ 50 G_MATCH_EXACT, /* "AAAAA" */ 51 G_MATCH_LAST 52 } GMatchType; 53 54 struct _GPatternSpec 55 { 56 GMatchType match_type; 57 guint pattern_length; 58 guint min_length; 59 guint max_length; 60 gchar *pattern; 61 }; 62 63 64 static gchar * 65 match_type_name (GMatchType match_type) 66 { 67 switch (match_type) 68 { 69 case G_MATCH_ALL: 70 return "G_MATCH_ALL"; 71 break; 72 case G_MATCH_ALL_TAIL: 73 return "G_MATCH_ALL_TAIL"; 74 break; 75 case G_MATCH_HEAD: 76 return "G_MATCH_HEAD"; 77 break; 78 case G_MATCH_TAIL: 79 return "G_MATCH_TAIL"; 80 break; 81 case G_MATCH_EXACT: 82 return "G_MATCH_EXACT"; 83 break; 84 default: 85 return "unknown GMatchType"; 86 break; 87 } 88 } 89 90 static gboolean 91 test_compilation (gchar *src, 92 GMatchType match_type, 93 gchar *pattern, 94 guint min) 95 { 96 GPatternSpec *spec; 97 98 verbose ("compiling \"%s\" \t", src); 99 spec = g_pattern_spec_new (src); 100 101 if (spec->match_type != match_type) 102 { 103 g_print ("failed \t(match_type: %s, expected %s)\n", 104 match_type_name (spec->match_type), 105 match_type_name (match_type)); 106 g_pattern_spec_free (spec); 107 return FALSE; 108 } 109 110 if (strcmp (spec->pattern, pattern) != 0) 111 { 112 g_print ("failed \t(pattern: \"%s\", expected \"%s\")\n", 113 spec->pattern, 114 pattern); 115 g_pattern_spec_free (spec); 116 return FALSE; 117 } 118 119 if (spec->pattern_length != strlen (spec->pattern)) 120 { 121 g_print ("failed \t(pattern_length: %d, expected %d)\n", 122 spec->pattern_length, 123 (gint)strlen (spec->pattern)); 124 g_pattern_spec_free (spec); 125 return FALSE; 126 } 127 128 if (spec->min_length != min) 129 { 130 g_print ("failed \t(min_length: %d, expected %d)\n", 131 spec->min_length, 132 min); 133 g_pattern_spec_free (spec); 134 return FALSE; 135 } 136 137 verbose ("passed (%s: \"%s\")\n", 138 match_type_name (spec->match_type), 139 spec->pattern); 140 141 g_pattern_spec_free (spec); 142 143 return TRUE; 144 } 145 146 static gboolean 147 test_match (gchar *pattern, 148 gchar *string, 149 gboolean match) 150 { 151 verbose ("matching \"%s\" against \"%s\" \t", string, pattern); 152 153 if (g_pattern_match_simple (pattern, string) != match) 154 { 155 g_print ("failed \t(unexpected %s)\n", (match ? "mismatch" : "match")); 156 return FALSE; 157 } 158 159 verbose ("passed (%s)\n", match ? "match" : "nomatch"); 160 161 return TRUE; 162 } 163 164 static gboolean 165 test_equal (gchar *pattern1, 166 gchar *pattern2, 167 gboolean expected) 168 { 169 GPatternSpec *p1 = g_pattern_spec_new (pattern1); 170 GPatternSpec *p2 = g_pattern_spec_new (pattern2); 171 gboolean equal = g_pattern_spec_equal (p1, p2); 172 173 verbose ("comparing \"%s\" with \"%s\" \t", pattern1, pattern2); 174 175 if (expected != equal) 176 { 177 g_print ("failed \t{%s, %u, \"%s\"} %s {%s, %u, \"%s\"}\n", 178 match_type_name (p1->match_type), p1->pattern_length, p1->pattern, 179 expected ? "!=" : "==", 180 match_type_name (p2->match_type), p2->pattern_length, p2->pattern); 181 } 182 else 183 verbose ("passed (%s)\n", equal ? "equal" : "unequal"); 184 185 g_pattern_spec_free (p1); 186 g_pattern_spec_free (p2); 187 188 return expected == equal; 189 } 190 191 #define TEST_COMPILATION(src, type, pattern, min) { \ 192 total++; \ 193 if (test_compilation (src, type, pattern, min)) \ 194 passed++; \ 195 else \ 196 failed++; \ 197 } 198 199 #define TEST_MATCH(pattern, string, match) { \ 200 total++; \ 201 if (test_match (pattern, string, match)) \ 202 passed++; \ 203 else \ 204 failed++; \ 205 } 206 207 #define TEST_EQUAL(pattern1, pattern2, match) { \ 208 total++; \ 209 if (test_equal (pattern1, pattern2, match)) \ 210 passed++; \ 211 else \ 212 failed++; \ 213 } 214 215 int 216 main (int argc, char** argv) 217 { 218 gint total = 0; 219 gint passed = 0; 220 gint failed = 0; 221 gint i; 222 223 for (i = 1; i < argc; i++) 224 if (strcmp ("--noisy", argv[i]) == 0) 225 noisy = TRUE; 226 227 TEST_COMPILATION("*A?B*", G_MATCH_ALL, "*A?B*", 3); 228 TEST_COMPILATION("ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8); 229 TEST_COMPILATION("ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8); 230 TEST_COMPILATION("ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11); 231 TEST_COMPILATION("*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4); 232 TEST_COMPILATION("ABCD*", G_MATCH_HEAD, "ABCD", 4); 233 TEST_COMPILATION("*ABCD", G_MATCH_TAIL, "ABCD", 4); 234 TEST_COMPILATION("ABCDE", G_MATCH_EXACT, "ABCDE", 5); 235 TEST_COMPILATION("A?C?E", G_MATCH_ALL, "A?C?E", 5); 236 TEST_COMPILATION("*?x", G_MATCH_ALL_TAIL, "x?*", 2); 237 TEST_COMPILATION("?*x", G_MATCH_ALL_TAIL, "x?*", 2); 238 TEST_COMPILATION("*?*x", G_MATCH_ALL_TAIL, "x?*", 2); 239 TEST_COMPILATION("x*??", G_MATCH_ALL_TAIL, "??*x", 3); 240 241 TEST_EQUAL("*A?B*", "*A?B*", TRUE); 242 TEST_EQUAL("A*BCD", "A*BCD", TRUE); 243 TEST_EQUAL("ABCD*", "ABCD****", TRUE); 244 TEST_EQUAL("A1*", "A1*", TRUE); 245 TEST_EQUAL("*YZ", "*YZ", TRUE); 246 TEST_EQUAL("A1x", "A1x", TRUE); 247 TEST_EQUAL("AB*CD", "AB**CD", TRUE); 248 TEST_EQUAL("AB*?*CD", "AB*?CD", TRUE); 249 TEST_EQUAL("AB*?CD", "AB?*CD", TRUE); 250 TEST_EQUAL("AB*CD", "AB*?*CD", FALSE); 251 TEST_EQUAL("ABC*", "ABC?", FALSE); 252 253 TEST_MATCH("*x", "x", TRUE); 254 TEST_MATCH("*x", "xx", TRUE); 255 TEST_MATCH("*x", "yyyx", TRUE); 256 TEST_MATCH("*x", "yyxy", FALSE); 257 TEST_MATCH("?x", "x", FALSE); 258 TEST_MATCH("?x", "xx", TRUE); 259 TEST_MATCH("?x", "yyyx", FALSE); 260 TEST_MATCH("?x", "yyxy", FALSE); 261 TEST_MATCH("*?x", "xx", TRUE); 262 TEST_MATCH("?*x", "xx", TRUE); 263 TEST_MATCH("*?x", "x", FALSE); 264 TEST_MATCH("?*x", "x", FALSE); 265 TEST_MATCH("*?*x", "yx", TRUE); 266 TEST_MATCH("*?*x", "xxxx", TRUE); 267 TEST_MATCH("x*??", "xyzw", TRUE); 268 TEST_MATCH("*x", "\xc3\x84x", TRUE); 269 TEST_MATCH("?x", "\xc3\x84x", TRUE); 270 TEST_MATCH("??x", "\xc3\x84x", FALSE); 271 TEST_MATCH("ab\xc3\xa4\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE); 272 TEST_MATCH("ab\xc3\xa4\xc3\xb6", "abao", FALSE); 273 TEST_MATCH("ab?\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE); 274 TEST_MATCH("ab?\xc3\xb6", "abao", FALSE); 275 TEST_MATCH("ab\xc3\xa4?", "ab\xc3\xa4\xc3\xb6", TRUE); 276 TEST_MATCH("ab\xc3\xa4?", "abao", FALSE); 277 TEST_MATCH("ab??", "ab\xc3\xa4\xc3\xb6", TRUE); 278 TEST_MATCH("ab*", "ab\xc3\xa4\xc3\xb6", TRUE); 279 TEST_MATCH("ab*\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE); 280 TEST_MATCH("ab*\xc3\xb6", "aba\xc3\xb6x\xc3\xb6", TRUE); 281 TEST_MATCH("", "abc", FALSE); 282 283 TEST_MATCH("", "", TRUE); 284 TEST_MATCH("abc", "abc", TRUE); 285 TEST_MATCH("*fo1*bar", "yyyfoxfo1bar", TRUE); 286 TEST_MATCH("12*fo1g*bar", "12yyyfoxfo1gbar", TRUE); 287 TEST_MATCH("__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE); 288 TEST_MATCH("*abc*cde", "abcde", FALSE); 289 TEST_MATCH("*abc*cde", "abccde", TRUE); 290 TEST_MATCH("*abc*cde", "abcxcde", TRUE); 291 TEST_MATCH("*abc*?cde", "abccde", FALSE); 292 TEST_MATCH("*abc*?cde", "abcxcde", TRUE); 293 TEST_MATCH("*abc*def", "abababcdededef", TRUE); 294 TEST_MATCH("*abc*def", "abcbcbcdededef", TRUE); 295 TEST_MATCH("*acbc*def", "acbcbcbcdededef", TRUE); 296 TEST_MATCH("*a?bc*def", "acbcbcbcdededef", TRUE); 297 TEST_MATCH("*abc*def", "bcbcbcdefdef", FALSE); 298 TEST_MATCH("*abc*def*ghi", "abcbcbcbcbcbcdefefdefdefghi", TRUE); 299 TEST_MATCH("*abc*def*ghi", "bcbcbcbcbcbcdefdefdefdefghi", FALSE); 300 TEST_MATCH("_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_*abc*def*ghi", "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_abcbcbcbcbcbcdefefdefdefghi", TRUE); 301 TEST_MATCH("fooooooo*a*bc", "fooooooo_a_bd_a_bc", TRUE); 302 303 verbose ("\n%u tests passed, %u failed\n", passed, failed); 304 305 return failed; 306 } 307 308 309