1 /* Copyright 1986-1992 Emmet P. Gray.
2 * Copyright 1996-1998,2001,2002,2008,2009 Alain Knaff.
3 * This file is part of mtools.
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
18 * Do shell-style pattern matching for '?', '\', '[..]', and '*' wildcards.
19 * Returns 1 if match, 0 if not.
22 #include "sysincludes.h"
26 static int casecmp(wchar_t a, wchar_t b)
28 return towupper(a) == towupper(b);
31 static int exactcmp(wchar_t a,wchar_t b)
37 static int parse_range(const wchar_t **p, const wchar_t *s, wchar_t *out,
38 int (*compfn)(wchar_t a, wchar_t b))
62 for(i=first; i<=last; i++)
65 table[(int) *((*p)++)] = 1;
71 if(compfn == exactcmp)
73 if(table[tolower(*s)]) {
78 if(table[toupper(*s)]) {
87 static int _match(const wchar_t *s, const wchar_t *p, wchar_t *out, int Case,
89 int (*compfn) (wchar_t a, wchar_t b))
91 for (; *p != '\0' && length; ) {
93 case '?': /* match any one character */
99 case '*': /* match everything */
100 while (*p == '*' && length) {
105 /* search for next char in pattern */
107 if(_match(s, p, out, Case, length,
115 case '[': /* match range of characters */
118 if(!parse_range(&p, s, out++, compfn))
121 case '\\': /* Literal match with next character */
139 /* string ended prematurely ? */
147 int match(const wchar_t *s, const wchar_t *p, wchar_t *out, int Case, int length)
149 int (*compfn)(wchar_t a, wchar_t b);
154 /*compfn = exactcmp;*/
156 return _match(s, p, out, Case, length, compfn);