about summary refs log tree commit diff
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
parent7239b3a4cfa50ecd088850d13202aeff5cf96e5f (diff)
downloadglibc-ecce00a971d2725175c4dc200e6b2c122363d810.tar.gz
glibc-ecce00a971d2725175c4dc200e6b2c122363d810.tar.xz
glibc-ecce00a971d2725175c4dc200e6b2c122363d810.zip
Update.
	* posix/fnmatch_loop.c: Implement equivalence class handling.
	* posix/tst-fnmatch.input: Add tests for equivalence class
	handling.
-rw-r--r--ChangeLog4
-rw-r--r--posix/fnmatch_loop.c106
-rw-r--r--posix/tst-fnmatch.input33
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