diff --git a/include/fnmatch.h b/include/fnmatch.h index 7a0e5824d39e..c664422bce68 100644 --- a/include/fnmatch.h +++ b/include/fnmatch.h @@ -41,6 +41,7 @@ #define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ #define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ #define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#define FNM_ICASE 0x08 /* case insensitive search */ #include diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3 index d533e09419e2..4363426c0e35 100644 --- a/lib/libc/gen/fnmatch.3 +++ b/lib/libc/gen/fnmatch.3 @@ -99,6 +99,11 @@ Additionally, if .Dv FNM_PATHNAME is set, a period is ``leading'' if it immediately follows a slash. +.It Dv FNM_ICASE +Ignore case distinctions in both the +.Fa pattern +and the +.Fa string . .El .Sh RETURN VALUES The diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 47bd40523234..1fa1db5f8b2b 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -43,9 +43,11 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; * Compares a filename or pathname to a pattern. */ +#include #include #include #include +#include #define EOS '\0' @@ -126,8 +128,14 @@ fnmatch(pattern, string, flags) } /* FALLTHROUGH */ default: - if (c != *string++) + if (c == *string) + ; + else if ((flags & FNM_ICASE) && + (tolower(c) == tolower(*string))) + ; + else return (FNM_NOMATCH); + string++; break; } /* NOTREACHED */ @@ -151,11 +159,18 @@ rangematch(pattern, test, flags) if ( (negate = (*pattern == '!' || *pattern == '^')) ) ++pattern; + if (flags & FNM_ICASE) + test = tolower(test); + for (ok = 0; (c = *pattern++) != ']';) { if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *pattern++; if (c == EOS) return (NULL); + + if (flags & FNM_ICASE) + c = tolower(c); + if (*pattern == '-' && (c2 = *(pattern+1)) != EOS && c2 != ']') { pattern += 2; @@ -163,6 +178,10 @@ rangematch(pattern, test, flags) c2 = *pattern++; if (c2 == EOS) return (NULL); + + if (flags & FNM_ICASE) + c2 = tolower(c2); + if ( collate_range_cmp(c, test) <= 0 && collate_range_cmp(test, c2) <= 0 ) diff --git a/sys/libkern/fnmatch.c b/sys/libkern/fnmatch.c index 47bd40523234..1fa1db5f8b2b 100644 --- a/sys/libkern/fnmatch.c +++ b/sys/libkern/fnmatch.c @@ -43,9 +43,11 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; * Compares a filename or pathname to a pattern. */ +#include #include #include #include +#include #define EOS '\0' @@ -126,8 +128,14 @@ fnmatch(pattern, string, flags) } /* FALLTHROUGH */ default: - if (c != *string++) + if (c == *string) + ; + else if ((flags & FNM_ICASE) && + (tolower(c) == tolower(*string))) + ; + else return (FNM_NOMATCH); + string++; break; } /* NOTREACHED */ @@ -151,11 +159,18 @@ rangematch(pattern, test, flags) if ( (negate = (*pattern == '!' || *pattern == '^')) ) ++pattern; + if (flags & FNM_ICASE) + test = tolower(test); + for (ok = 0; (c = *pattern++) != ']';) { if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *pattern++; if (c == EOS) return (NULL); + + if (flags & FNM_ICASE) + c = tolower(c); + if (*pattern == '-' && (c2 = *(pattern+1)) != EOS && c2 != ']') { pattern += 2; @@ -163,6 +178,10 @@ rangematch(pattern, test, flags) c2 = *pattern++; if (c2 == EOS) return (NULL); + + if (flags & FNM_ICASE) + c2 = tolower(c2); + if ( collate_range_cmp(c, test) <= 0 && collate_range_cmp(test, c2) <= 0 )