1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: File and other globbing (included by utils.cpp)
4 // Author: Karsten Ballueder
8 // Copyright: (c) Karsten Ballueder
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // This file includes:
13 // wxIsWild(const char *pattern)
14 // wxMatchWild(const char *pattern, const char *str, bool dot_special)
17 //---------------------------------------------------------------------------------
28 # error "Can't use Unix file globbing under Windows!"
32 /*************************************************************************
34 * wxIsWild checks whether the pattern contains wildcards, and
35 * returns TRUE if it does, and FALSE if it does not (or if the
36 * pattern is NULL -- i.e. no string).
40 * 1) pattern - a character string
43 wxIsWild (const char *pattern)
73 // -----------------------------------------------------
74 // '*' = match 0 or more occurances of anything
75 // "[abc]" = match anyof "abc" (ranges supported)
76 // "{xx,yy,zz}" = match anyof "xx", "yy", or "zz"
77 // '?' = match any character
79 // '\' is used to "escape" special characters
83 wxMatchWild (const char *pattern, const char *str, bool dot_special)
87 bool done = FALSE, ret_code, ok;
88 // Below is for vi fans
89 const char OB = '{', CB = '}';
92 if (strcmp(pattern, "*.*") == 0)
93 pattern = "*"; // Hack for MS-DOS compat.
96 // dot_special means '.' only matches '.'
97 if (dot_special && *str == '.' && *pattern != *str)
100 while ((*pattern != '\0') && (!done) && (((*str == '\0') &&
101 ((*pattern == OB) || (*pattern == '*'))) || (*str != '\0')))
107 if (*pattern != '\0')
113 while ((*str != '\0') && (!(ret_code = wxMatchWild (pattern, str++, FALSE))));
118 while (*pattern != '\0')
125 if ((*pattern == '\0') || (*pattern == ']'))
130 if (*pattern == '\\')
133 if (*pattern == '\0')
139 if (*(pattern + 1) == '-')
148 if (*pattern == '\\')
151 if (*pattern == '\0')
157 if ((*str < c) || (*str > *pattern))
163 else if (*pattern != *str)
169 while ((*pattern != ']') && (*pattern != '\0'))
171 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
175 if (*pattern != '\0')
186 while ((*pattern != CB) && (*pattern != '\0'))
190 while (ok && (*cp != '\0') && (*pattern != '\0') &&
191 (*pattern != ',') && (*pattern != CB))
193 if (*pattern == '\\')
195 ok = (*pattern++ == *cp++);
197 if (*pattern == '\0')
206 while ((*pattern != CB) && (*pattern != '\0'))
208 if (*++pattern == '\\')
210 if (*++pattern == CB)
217 while (*pattern != CB && *pattern != ',' && *pattern != '\0')
219 if (*++pattern == '\\')
221 if (*++pattern == CB || *pattern == ',')
226 if (*pattern != '\0')
231 if (*str == *pattern)
241 while (*pattern == '*')
243 return ((*str == '\0') && (*pattern == '\0'));
246 #else /* MS-DOS/Windows glob() */
247 /*************************************************************************
249 * wxMatchWild matches the given pattern string against
250 * a text string, and returns TRUE if it matches, FALSE otherwise.
252 * A match means that the entire text string is used up in the matching.
253 * The pattern can contain the following wildcards.
255 * * -- matches any sequence of characters
256 * ? -- matches one character
258 * If one or other or both of the string arguments to wxMatchWild function is
259 * NULL (i.e. there isn't a string), then the function returns FALSE.
262 static bool wxPatternMatch (const char *pattern, const char *text, size_t i, size_t j);
264 // @@@@ dotSpecial is ignored by MS-DOS
266 wxMatchWild (const char *pattern, const char *text, bool /* dotSpecial */ )
268 if (pattern == NULL || text == NULL || *pattern == '\0' || *text == '\0')
270 return wxPatternMatch (pattern, text, 0, 0);
273 /*************************************************************************
275 * wxPatternMatch does the work for wxMatchWild. wxPatternMatch matches
276 * the given pattern string against a text string, and returns TRUE if
277 * it matches, FALSE otherwise. It is assumed that the string arguments
278 * to wxPatternMatch exist.
280 * A match means that the entire text string is used up in the matching.
281 * The pattern can contain the following wildcards.
283 * * -- matches any sequence of characters
284 * ? -- matches one character
286 * wxPatternMatch works by going down the pattern trying to match the
287 * the same index character in the pattern and string arrays, and stops
288 * when the end of the pattern or text string is reached. However, if a
289 * '*' wildcard is met, the algorithm checks to see whether the remaining
290 * pattern (after the wildcard) matches the rest of the text (i.e. the
291 * wxPatternMatch function is called recursively).
295 wxPatternMatch (const char *pattern, const char *text, size_t i, size_t j)
297 size_t pattern_length = strlen (pattern);
298 size_t text_length = strlen (text);
302 // MS-DOS file system is case INDEPENDENT
303 # define EQU(x,y) (wxToLower(x) == wxToLower(y))
305 # define EQU(x,y) ((x) == (y))
308 while (j < pattern_length && i < text_length)
310 if (EQU(text[i], pattern[j]) || pattern[j] == '?')
315 else if (pattern[j] == '*')
317 // If pattern ends in '*'
318 if (++j == pattern_length)
326 // after wildcard check to see whether rest of pattern matches
327 // up with rest of text
328 while (i < text_length && match != TRUE)
330 match = wxPatternMatch (pattern, text, i, j);
333 // text index is decremented so that it points to where
334 // the text string starts to match the rest of the pattern
338 else if (! EQU(text[i], pattern[j]))
344 if (j == pattern_length && i == text_length && match == TRUE)
349 // special case where pattern and text are the same except that pattern
350 // also only has '*' wildcards on the end
351 if (i == text_length && pattern[j] == '*' && match == TRUE)
353 for (; j < pattern_length; j++)
355 if (pattern[j] != '*')
366 #endif /* UNIX_GLOB */
367 //-----------------------------------------------------------------------------