diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/regex/fnmatch.c | 36 | 
1 files changed, 25 insertions, 11 deletions
| diff --git a/src/regex/fnmatch.c b/src/regex/fnmatch.c index 4df10a3c..7f6b65f3 100644 --- a/src/regex/fnmatch.c +++ b/src/regex/fnmatch.c @@ -97,7 +97,13 @@ escaped:  	return pat[0];  } -static int match_bracket(const char *p, int k) +static int casefold(int k) +{ +	int c = towupper(k); +	return c == k ? towlower(k) : c; +} + +static int match_bracket(const char *p, int k, int kfold)  {  	wchar_t wc;  	int inv = 0; @@ -119,7 +125,10 @@ static int match_bracket(const char *p, int k)  			wchar_t wc2;  			int l = mbtowc(&wc2, p+1, 4);  			if (l < 0) return 0; -			if (wc<=wc2 && (unsigned)k-wc <= wc2-wc) return !inv; +			if (wc <= wc2) +				if ((unsigned)k-wc <= wc2-wc || +				    (unsigned)kfold-wc <= wc2-wc) +					return !inv;  			p += l-1;  			continue;  		} @@ -132,7 +141,9 @@ static int match_bracket(const char *p, int k)  				char buf[16];  				memcpy(buf, p0, p-1-p0);  				buf[p-1-p0] = 0; -				if (iswctype(k, wctype(buf))) return !inv; +				if (iswctype(k, wctype(buf)) || +				    iswctype(kfold, wctype(buf))) +					return !inv;  			}  			continue;  		} @@ -143,7 +154,7 @@ static int match_bracket(const char *p, int k)  			if (l < 0) return 0;  			p += l-1;  		} -		if (wc==k) return !inv; +		if (wc==k || wc==kfold) return !inv;  	}  	return inv;  } @@ -153,7 +164,7 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n  	const char *p, *ptail, *endpat;  	const char *s, *stail, *endstr;  	size_t pinc, sinc, tailcnt=0; -	int c, k; +	int c, k, kfold;  	if (flags & FNM_PERIOD) {  		if (*str == '.' && *pat != '.') @@ -173,10 +184,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n  				return (c==END) ? 0 : FNM_NOMATCH;  			str += sinc;  			n -= sinc; +			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;  			if (c == BRACKET) { -				if (!match_bracket(pat, k)) +				if (!match_bracket(pat, k, kfold))  					return FNM_NOMATCH; -			} else if (c != QUESTION && k != c) { +			} else if (c != QUESTION && k != c && kfold != c) {  				return FNM_NOMATCH;  			}  			pat+=pinc; @@ -233,10 +245,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n  			break;  		}  		s += sinc; +		kfold = flags & FNM_CASEFOLD ? casefold(k) : k;  		if (c == BRACKET) { -			if (!match_bracket(p-pinc, k)) +			if (!match_bracket(p-pinc, k, kfold))  				return FNM_NOMATCH; -		} else if (c != QUESTION && k != c) { +		} else if (c != QUESTION && k != c && kfold != c) {  			return FNM_NOMATCH;  		}  	} @@ -261,10 +274,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n  			k = str_next(s, endstr-s, &sinc);  			if (!k)  				return FNM_NOMATCH; +			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;  			if (c == BRACKET) { -				if (!match_bracket(p-pinc, k)) +				if (!match_bracket(p-pinc, k, kfold))  					break; -			} else if (c != QUESTION && k != c) { +			} else if (c != QUESTION && k != c && kfold != c) {  				break;  			}  			s += sinc; | 
