diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | posix/fnmatch_loop.c | 106 | ||||
-rw-r--r-- | posix/tst-fnmatch.input | 33 |
3 files changed, 141 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog index 1dc63d3ba0..63a54abbbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2000-07-04 Ulrich Drepper <drepper@redhat.com> + * posix/fnmatch_loop.c: Implement equivalence class handling. + * posix/tst-fnmatch.input: Add tests for equivalence class + handling. + * posix/fnmatch_loop.c: Improve performance for single-byte character sets by not using btowc. diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c index ad729d2d8f..8b163be24f 100644 --- a/posix/fnmatch_loop.c +++ b/posix/fnmatch_loop.c @@ -302,6 +302,112 @@ FCT (pattern, string, no_leading_period, flags) #endif c = *p++; } +#ifdef _LIBC + else if (c == L('[') && *p == L('=')) + { + UCHAR str[1]; + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + const CHAR *startp = p; + + c = *++p; + if (c == L('\0')) + { + p = startp; + c = L('['); + goto normal_bracket; + } + str[0] = c; + + c = *++p; + if (c != L('=') || p[1] != L(']')) + { + p = startp; + c = L('['); + goto normal_bracket; + } + p += 2; + + if (nrules == 0) + { + if ((UCHAR) *n == str[0]) + goto matched; + } + else + { + const int32_t *table; +# if WIDE_CHAR_VERSION + const int32_t *weights; + const int32_t *extra; +# else + const unsigned char *weights; + const unsigned char *extra; +# endif + const int32_t *indirect; + int32_t idx; + const UCHAR *cp = (const UCHAR *) str; + + /* This #include defines a local function! */ +# if WIDE_CHAR_VERSION +# include <locale/weightwc.h> +# else +# include <locale/weight.h> +# endif + +# if WIDE_CHAR_VERSION + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); + weights = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); + extra = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); +# else + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); +# endif + + idx = findidx (&cp); + if (idx != 0) + { + /* We found a table entry. Now see whether the + character we are currently at has the same + equivalance class value. */ + int len = weights[idx]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; + + idx2 = findidx (&np); +# if !WIDE_CHAR_VERSION + if (idx2 != 0 && len == weights[idx2]) + { + int cnt = 0; + + while (cnt < len + && (weights[idx + 1 + cnt] + == weights[idx2 + 1 + cnt])) + ++cnt; + + if (cnt == len) + goto matched; + } +# else + if (idx2 != 0 && weights[idx] == weights[idx2]) + goto matched; +# endif + } + } + + c = *p++; + } +#endif else if (c == L('\0')) /* [ (unterminated) loses. */ return FNM_NOMATCH; diff --git a/posix/tst-fnmatch.input b/posix/tst-fnmatch.input index 52cf6775f6..9c3ae1f167 100644 --- a/posix/tst-fnmatch.input +++ b/posix/tst-fnmatch.input @@ -79,10 +79,14 @@ C "]]" "[!a]]" 0 # *** implement [. .] # B.6 015(C) -# *** implement [= =] +C "a" "[[=a=]]" 0 +C "b" "[[=a=]b]" 0 +C "b" "[[=a=][=b=]]" 0 # B.6 016(C) -# *** implement [= =] +C "=" "[[=a=]b]" NOMATCH +C "]" "[[=a=]b]" NOMATCH +C "a" "[[=b=]]" NOMATCH # B.6 017(C) C "a" "[[:alnum:]]" 0 @@ -385,3 +389,28 @@ de_DE.ISO-8859-1 "Z" "[[:alpha:]]" 0 de_DE.ISO-8859-1 "Ä" "[[:alpha:]]" 0 de_DE.ISO-8859-1 "Ö" "[[:alpha:]]" 0 de_DE.ISO-8859-1 "Ü" "[[:alpha:]]" 0 + +de_DE.ISO-8859-1 "a" "[[=a=]b]" 0 +de_DE.ISO-8859-1 "â" "[[=a=]b]" 0 +de_DE.ISO-8859-1 "à" "[[=a=]b]" 0 +de_DE.ISO-8859-1 "á" "[[=a=]b]" 0 +de_DE.ISO-8859-1 "b" "[[=a=]b]" 0 +de_DE.ISO-8859-1 "c" "[[=a=]b]" NOMATCH +de_DE.ISO-8859-1 "a" "[[=â=]b]" 0 +de_DE.ISO-8859-1 "â" "[[=â=]b]" 0 +de_DE.ISO-8859-1 "à" "[[=â=]b]" 0 +de_DE.ISO-8859-1 "á" "[[=â=]b]" 0 +de_DE.ISO-8859-1 "b" "[[=â=]b]" 0 +de_DE.ISO-8859-1 "c" "[[=â=]b]" NOMATCH +de_DE.ISO-8859-1 "a" "[[=à=]b]" 0 +de_DE.ISO-8859-1 "â" "[[=à=]b]" 0 +de_DE.ISO-8859-1 "à" "[[=à=]b]" 0 +de_DE.ISO-8859-1 "á" "[[=à=]b]" 0 +de_DE.ISO-8859-1 "b" "[[=à=]b]" 0 +de_DE.ISO-8859-1 "c" "[[=à=]b]" NOMATCH +de_DE.ISO-8859-1 "a" "[[=á=]b]" 0 +de_DE.ISO-8859-1 "â" "[[=á=]b]" 0 +de_DE.ISO-8859-1 "à" "[[=á=]b]" 0 +de_DE.ISO-8859-1 "á" "[[=á=]b]" 0 +de_DE.ISO-8859-1 "b" "[[=á=]b]" 0 +de_DE.ISO-8859-1 "c" "[[=á=]b]" NOMATCH |