aboutsummaryrefslogtreecommitdiff
path: root/posix/fnmatch_loop.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-07-04 23:27:39 +0000
committerUlrich Drepper <drepper@redhat.com>2000-07-04 23:27:39 +0000
commitecce00a971d2725175c4dc200e6b2c122363d810 (patch)
tree17d321ebc97681ad0bcd356433add82bfc76f55e /posix/fnmatch_loop.c
parent7239b3a4cfa50ecd088850d13202aeff5cf96e5f (diff)
downloadglibc-ecce00a971d2725175c4dc200e6b2c122363d810.tar
glibc-ecce00a971d2725175c4dc200e6b2c122363d810.tar.gz
glibc-ecce00a971d2725175c4dc200e6b2c122363d810.tar.bz2
glibc-ecce00a971d2725175c4dc200e6b2c122363d810.zip
Update.
* posix/fnmatch_loop.c: Implement equivalence class handling. * posix/tst-fnmatch.input: Add tests for equivalence class handling.
Diffstat (limited to 'posix/fnmatch_loop.c')
-rw-r--r--posix/fnmatch_loop.c106
1 files changed, 106 insertions, 0 deletions
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;