about summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/fnmatch_loop.c9
-rw-r--r--posix/tst-fnmatch.c374
-rw-r--r--posix/tst-fnmatch.input286
3 files changed, 666 insertions, 3 deletions
diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
index 831bd0631a..3a6dffb1e4 100644
--- a/posix/fnmatch_loop.c
+++ b/posix/fnmatch_loop.c
@@ -176,8 +176,8 @@ FCT (pattern, string, no_leading_period, flags)
 
 	case L('['):
 	  {
-	    /* Nonzero if the sense of the character class is inverted.  */
 	    static int posixly_correct;
+	    /* Nonzero if the sense of the character class is inverted.  */
 	    register int not;
 	    CHAR cold;
 
@@ -273,6 +273,7 @@ FCT (pattern, string, no_leading_period, flags)
 			|| (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n)))
 		      goto matched;
 #endif
+		    c = *p++;
 		  }
 		else if (c == L('\0'))
 		  /* [ (unterminated) loses.  */
@@ -415,13 +416,14 @@ FCT (pattern, string, no_leading_period, flags)
 
 	  matched:
 	    /* Skip the rest of the [...] that already matched.  */
-	    while (c != L(']'))
+	    do
 	      {
+		c = *p++;
+
 		if (c == L('\0'))
 		  /* [... (unterminated) loses.  */
 		  return FNM_NOMATCH;
 
-		c = *p++;
 		if (!(flags & FNM_NOESCAPE) && c == L('\\'))
 		  {
 		    if (*p == L('\0'))
@@ -439,6 +441,7 @@ FCT (pattern, string, no_leading_period, flags)
 		    c = *p;
 		  }
 	      }
+	    while (c != L(']'));
 	    if (not)
 	      return FNM_NOMATCH;
 	  }
diff --git a/posix/tst-fnmatch.c b/posix/tst-fnmatch.c
new file mode 100644
index 0000000000..b582a51889
--- /dev/null
+++ b/posix/tst-fnmatch.c
@@ -0,0 +1,374 @@
+/* Tests for fnmatch function.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <error.h>
+#include <fnmatch.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+
+static char *next_input (char **line, int first, int last);
+static int convert_flags (const char *str);
+static char *flag_output (int flags);
+static char *escape (const char *str, size_t *reslenp, char **resbuf);
+
+
+int
+main (void)
+{
+  char *linebuf = NULL;
+  size_t linebuflen = 0;
+  int ntests = 0;
+  int nfailed = 0;
+  char *escinput = NULL;
+  size_t escinputlen = 0;
+  char *escpattern = NULL;
+  size_t escpatternlen = 0;
+  int nr = 0;
+
+  /* Read lines from stdin with the following format:
+
+       locale  input-string  match-string  flags  result
+
+     where `result' is either 0 or 1.  If the first character of a
+     string is '"' we read until the next '"' and handled escaped '"'.  */
+  while (! feof (stdin))
+    {
+      ssize_t n = getline (&linebuf, &linebuflen, stdin);
+      char *cp;
+      const char *locale;
+      const char *input;
+      const char *pattern;
+      const char *result_str;
+      int result;
+      const char *flags;
+      int flags_val;
+      int fnmres;
+      char numbuf[24];
+
+      if (n == -1)
+	break;
+
+      if (n == 0)
+	/* Maybe an empty line.  */
+	continue;
+
+      /* Skip over all leading white spaces.  */
+      cp = linebuf;
+
+      locale = next_input (&cp, 1, 0);
+      if (locale == NULL)
+	continue;
+
+      input = next_input (&cp, 0, 0);
+      if (input == NULL)
+	continue;
+
+      pattern = next_input (&cp, 0, 0);
+      if (pattern == NULL)
+	continue;
+
+      result_str = next_input (&cp, 0, 0);
+      if (result_str == NULL)
+	continue;
+
+      if (strcmp (result_str, "0") == 0)
+	result = 0;
+      else if  (strcasecmp (result_str, "NOMATCH") == 0)
+	result = FNM_NOMATCH;
+      else
+	{
+	  char *endp;
+	  result = strtol (result_str, &endp, 0);
+	  if (*endp != '\0')
+	    continue;
+	}
+
+      flags = next_input (&cp, 0, 1);
+      if (flags == NULL)
+	/* We allow the flags missing.  */
+	flags = "";
+
+      /* Convert the text describing the flags in a numeric value.  */
+      flags_val = convert_flags (flags);
+      if (flags_val == -1)
+	/* Something went wrong.  */
+	continue;
+
+      /* Now run the actual test.  */
+      ++ntests;
+
+      if (setlocale (LC_COLLATE, locale) == NULL)
+	{
+	  puts ("*** Cannot set locale");
+	  ++nfailed;
+	  continue;
+	}
+
+      fnmres = fnmatch (pattern, input, flags_val);
+
+      printf ("%3d: fnmatch (\"%s\", \"%s\", %s) = %s%c",
+	      ++nr,
+	      escape (pattern, &escpatternlen, &escpattern),
+	      escape (input, &escinputlen, &escinput),
+	      flag_output (flags_val),
+	      (fnmres == 0
+	       ? "0" : (fnmres == FNM_NOMATCH
+			? "FNM_NOMATCH"
+			: (sprintf (numbuf, "%d", fnmres), numbuf))),
+	      (fnmres != 0) != (result != 0) ? ' ' : '\n');
+
+      if ((fnmres != 0) != (result != 0))
+	{
+	  printf ("(FAIL, expected %s) ***\n",
+		  result == 0
+		  ? "0" : (result == FNM_NOMATCH
+			   ? "FNM_NOMATCH"
+			   : (sprintf (numbuf, "%d", result), numbuf)));
+	  ++nfailed;
+	}
+    }
+
+  printf ("=====================\n%3d tests, %3d failed\n", ntests, nfailed);
+
+  free (escpattern);
+  free (escinput);
+  free (linebuf);
+
+  return nfailed != 0;
+}
+
+
+static char *
+next_input (char **line, int first, int last)
+{
+  char *cp = *line;
+  char *result;
+
+  while (*cp == ' ' || *cp == '\t')
+    ++cp;
+
+  /* We allow comment lines starting with '#'.  */
+  if (first && *cp == '#')
+    return NULL;
+
+  if (*cp == '"')
+    {
+      char *wp;
+
+      result = ++cp;
+      wp = cp;
+
+      while (*cp != '"' && *cp != '\0' && *cp != '\n')
+	if (*cp == '\\')
+	  {
+	    if (cp[1] == '\n' || cp[1] == '\0')
+	      return NULL;
+
+	    ++cp;
+	    if (*cp == 't')
+	      *wp++ = '\t';
+	    else if (*cp == 'n')
+	      *wp++ = '\n';
+	    else
+	      *wp++ = *cp;
+
+	    ++cp;
+	  }
+	else
+	  *wp++ = *cp++;
+
+      if (*cp != '"')
+	return NULL;
+
+      if (wp != cp)
+	*wp = '\0';
+    }
+  else
+    {
+      result = cp;
+      while (*cp != '\0' && *cp != '\n' && *cp != ' ' && *cp != '\t')
+	++cp;
+
+      if (cp == result && ! last)
+	/* Premature end of line.  */
+	return NULL;
+    }
+
+  /* Terminate and skip over the next white spaces.  */
+  *cp++ = '\0';
+
+  *line = cp;
+  return result;
+}
+
+
+static int
+convert_flags (const char *str)
+{
+  int result = 0;
+
+  while (*str != '\0')
+    {
+      int len;
+
+      if (strncasecmp (str, "PATHNAME", 8) == 0
+	  && (str[8] == '|' || str[8] == '\0'))
+	{
+	  result |= FNM_PATHNAME;
+	  len = 8;
+	}
+      else if (strncasecmp (str, "NOESCAPE", 8) == 0
+	       && (str[8] == '|' || str[8] == '\0'))
+	{
+	  result |= FNM_NOESCAPE;
+	  len = 8;
+	}
+      else if (strncasecmp (str, "PERIOD", 6) == 0
+	       && (str[6] == '|' || str[6] == '\0'))
+	{
+	  result |= FNM_PERIOD;
+	  len = 6;
+	}
+      else if (strncasecmp (str, "LEADING_DIR", 11) == 0
+	       && (str[11] == '|' || str[11] == '\0'))
+	{
+	  result |= FNM_LEADING_DIR;
+	  len = 11;
+	}
+      else if (strncasecmp (str, "CASEFOLD", 8) == 0
+	       && (str[8] == '|' || str[8] == '\0'))
+	{
+	  result |= FNM_CASEFOLD;
+	  len = 8;
+	}
+      else
+	return -1;
+
+      str += len;
+      if (*str != '\0')
+	++str;
+    }
+
+  return result;
+}
+
+
+static char *
+flag_output (int flags)
+{
+  static char buf[100];
+  int first = 1;
+  char *cp = buf;
+
+  if (flags & FNM_PATHNAME)
+    {
+      cp = stpcpy (cp, "FNM_PATHNAME");
+      first = 0;
+    }
+  if (flags & FNM_NOESCAPE)
+    {
+      if (! first)
+	*cp++ = '|';
+      cp = stpcpy (cp, "FNM_NOESCAPE");
+      first = 0;
+    }
+  if (flags & FNM_PERIOD)
+    {
+      if (! first)
+	*cp++ = '|';
+      cp = stpcpy (cp, "FNM_PERIOD");
+      first = 0;
+    }
+  if (flags & FNM_LEADING_DIR)
+    {
+      if (! first)
+	*cp++ = '|';
+      cp = stpcpy (cp, "FNM_LEADING_DIR");
+      first = 0;
+    }
+  if (flags & FNM_CASEFOLD)
+    {
+      if (! first)
+	*cp++ = '|';
+      cp = stpcpy (cp, "FNM_CASEFOLD");
+      first = 0;
+    }
+  if (cp == buf)
+    *cp++ = '0';
+  *cp = '\0';
+
+  return buf;
+}
+
+
+static char *
+escape (const char *str, size_t *reslenp, char **resbufp)
+{
+  size_t reslen = *reslenp;
+  char *resbuf = *resbufp;
+  size_t len = strlen (str);
+  char *wp;
+
+  if (2 * len + 1 > reslen)
+    {
+      resbuf = (char *) realloc (resbuf, 2 * len + 1);
+      if (resbuf == NULL)
+	error (EXIT_FAILURE, errno, "while allocating buffer for printing");
+      *reslenp = 2 * len + 1;
+      *resbufp = resbuf;
+    }
+
+  wp = resbuf;
+  while (*str != '\0')
+    if (*str == '\t')
+      {
+	*wp++ = '\\';
+	*wp++ = 't';
+	++str;
+      }
+    else if (*str == '\n')
+      {
+	*wp++ = '\\';
+	*wp++ = 'n';
+	++str;
+      }
+    else if (*str == '"')
+      {
+	*wp++ = '\\';
+	*wp++ = '"';
+	++str;
+      }
+    else if (*str == '\\')
+      {
+	*wp++ = '\\';
+	*wp++ = '\\';
+	++str;
+      }
+    else
+      *wp++ = *str++;
+
+  *wp = '\0';
+
+  return resbuf;
+}
diff --git a/posix/tst-fnmatch.input b/posix/tst-fnmatch.input
new file mode 100644
index 0000000000..bf28653cd5
--- /dev/null
+++ b/posix/tst-fnmatch.input
@@ -0,0 +1,286 @@
+# Tests for fnmatch.
+# Copyright (C) 2000 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributes by Ulrich Drepper <drepper@redhat.com>.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+# Derived from the IEEE 2003.2 text.  The standard only contains some
+# wording describing the situations to be tested.  It does not specify
+# any specific tests.  I.e., the tests below are in no case sufficient.
+# They are hopefully necessary, though.
+
+# B.6 004(C)
+C		 "!#%+,-./01234567889"	"!#%+,-./01234567889"  0
+C		 ":;=@ABCDEFGHIJKLMNO"	":;=@ABCDEFGHIJKLMNO"  0
+C		 "PQRSTUVWXYZ]abcdefg"	"PQRSTUVWXYZ]abcdefg"  0
+C		 "hijklmnopqrstuvwxyz"	"hijklmnopqrstuvwxyz"  0
+C		 "^_{}~"		"^_{}~"		       0
+
+# B.6 005(C)
+C		 "\"$&'()"		"\\\"\\$\\&\\'\\(\\)"  0
+C		 "*?[\\`|"		"\\*\\?\\[\\\\\\`\\|"  0
+C		 "<>"			"\\<\\>"	       0
+
+# B.6 006(C)
+C		 "?*["			"[?*[][?*[][?*[]"      0
+C		 "a/b"			"?/b"		       0
+
+# B.6 007(C)
+C		 "a/b"			"a?b"		       0
+C		 "a/b"			"a/?"		       0
+C		 "a/b"			"a?b"		       NOMATCH PATHNAME
+C		 "aa/b"			"?/b"		       NOMATCH
+C		 "aa/b"			"a?b"		       NOMATCH
+C		 "a/bb"			"a/?"		       NOMATCH
+
+# B.6 009(C)
+C		 "abc"			"[abc]"		       NOMATCH
+C		 "x"			"[abc]"		       NOMATCH
+C		 "a"			"[abc]"		       0
+C		 "["			"[[abc]"	       0
+C		 "a"			"[][abc]"	       0
+C		 "a]"			"[]a]]"		       0
+
+# B.6 010(C)
+C		"xyz"			"[!abc]"	       NOMATCH
+C		 "x"			"[!abc]"	       0
+C		 "a"			"[!abc]"	       NOMATCH
+
+# B.6 011(C)
+C		 "]"			"[][abc]"	       0
+C		 "abc]"			"[][abc]"	       NOMATCH
+C		 "[]abc"		"[][]abc"	       NOMATCH
+C		 "]"		        "[!]]"		       NOMATCH
+C		 "aa]"			"[!]a]"		       NOMATCH
+C		 "]"		        "[!a]"		       0
+C		 "]]"		        "[!a]]"		       0
+
+# B.6 012(C)
+# *** implement [. .]
+
+# B.6 013(C)
+# *** implement [. .]
+
+# B.6 014(C)
+# *** implement [. .]
+
+# B.6 015(C)
+# *** implement [= =]
+
+# B.6 016(C)
+# *** implement [= =]
+
+# B.6 017(C)
+C		"a"			"[[:alnum:]]"	       0
+C		"a"			"[![:alnum:]]"	       NOMATCH
+C		"-"			"[[:alnum:]]"	       NOMATCH
+C		"a]a"			"[[:alnum:]]a"	       NOMATCH
+C		"-"			"[[:alnum:]-]"	       0
+C		"aa"			"[[:alnum:]]a"	       0
+C		"-"			"[![:alnum:]]"	       0
+C		"]"			"[!][:alnum:]]"	       NOMATCH
+C		"["			"[![:alnum:][]"	       NOMATCH
+C		"a"			"[[:alnum:]]"	       0
+C		"b"			"[[:alnum:]]"	       0
+C		"c"			"[[:alnum:]]"	       0
+C		"d"			"[[:alnum:]]"	       0
+C		"e"			"[[:alnum:]]"	       0
+C		"f"			"[[:alnum:]]"	       0
+C		"g"			"[[:alnum:]]"	       0
+C		"h"			"[[:alnum:]]"	       0
+C		"i"			"[[:alnum:]]"	       0
+C		"j"			"[[:alnum:]]"	       0
+C		"k"			"[[:alnum:]]"	       0
+C		"l"			"[[:alnum:]]"	       0
+C		"m"			"[[:alnum:]]"	       0
+C		"n"			"[[:alnum:]]"	       0
+C		"o"			"[[:alnum:]]"	       0
+C		"p"			"[[:alnum:]]"	       0
+C		"q"			"[[:alnum:]]"	       0
+C		"r"			"[[:alnum:]]"	       0
+C		"s"			"[[:alnum:]]"	       0
+C		"t"			"[[:alnum:]]"	       0
+C		"u"			"[[:alnum:]]"	       0
+C		"v"			"[[:alnum:]]"	       0
+C		"w"			"[[:alnum:]]"	       0
+C		"x"			"[[:alnum:]]"	       0
+C		"y"			"[[:alnum:]]"	       0
+C		"z"			"[[:alnum:]]"	       0
+C		"A"			"[[:alnum:]]"	       0
+C		"B"			"[[:alnum:]]"	       0
+C		"C"			"[[:alnum:]]"	       0
+C		"D"			"[[:alnum:]]"	       0
+C		"E"			"[[:alnum:]]"	       0
+C		"F"			"[[:alnum:]]"	       0
+C		"G"			"[[:alnum:]]"	       0
+C		"H"			"[[:alnum:]]"	       0
+C		"I"			"[[:alnum:]]"	       0
+C		"J"			"[[:alnum:]]"	       0
+C		"K"			"[[:alnum:]]"	       0
+C		"L"			"[[:alnum:]]"	       0
+C		"M"			"[[:alnum:]]"	       0
+C		"N"			"[[:alnum:]]"	       0
+C		"O"			"[[:alnum:]]"	       0
+C		"P"			"[[:alnum:]]"	       0
+C		"Q"			"[[:alnum:]]"	       0
+C		"R"			"[[:alnum:]]"	       0
+C		"S"			"[[:alnum:]]"	       0
+C		"T"			"[[:alnum:]]"	       0
+C		"U"			"[[:alnum:]]"	       0
+C		"V"			"[[:alnum:]]"	       0
+C		"W"			"[[:alnum:]]"	       0
+C		"X"			"[[:alnum:]]"	       0
+C		"Y"			"[[:alnum:]]"	       0
+C		"Z"			"[[:alnum:]]"	       0
+C		"0"			"[[:alnum:]]"	       0
+C		"1"			"[[:alnum:]]"	       0
+C		"2"			"[[:alnum:]]"	       0
+C		"3"			"[[:alnum:]]"	       0
+C		"4"			"[[:alnum:]]"	       0
+C		"5"			"[[:alnum:]]"	       0
+C		"6"			"[[:alnum:]]"	       0
+C		"7"			"[[:alnum:]]"	       0
+C		"8"			"[[:alnum:]]"	       0
+C		"9"			"[[:alnum:]]"	       0
+C		"!"			"[[:alnum:]]"	       NOMATCH
+C		"#"			"[[:alnum:]]"	       NOMATCH
+C		"%"			"[[:alnum:]]"	       NOMATCH
+C		"+"			"[[:alnum:]]"	       NOMATCH
+C		","			"[[:alnum:]]"	       NOMATCH
+C		"-"			"[[:alnum:]]"	       NOMATCH
+C		"."			"[[:alnum:]]"	       NOMATCH
+C		"/"			"[[:alnum:]]"	       NOMATCH
+C		":"			"[[:alnum:]]"	       NOMATCH
+C		";"			"[[:alnum:]]"	       NOMATCH
+C		"="			"[[:alnum:]]"	       NOMATCH
+C		"@"			"[[:alnum:]]"	       NOMATCH
+C		"["			"[[:alnum:]]"	       NOMATCH
+C		"\\"			"[[:alnum:]]"	       NOMATCH
+C		"]"			"[[:alnum:]]"	       NOMATCH
+C		"^"			"[[:alnum:]]"	       NOMATCH
+C		"_"			"[[:alnum:]]"	       NOMATCH
+C		"{"			"[[:alnum:]]"	       NOMATCH
+C		"}"			"[[:alnum:]]"	       NOMATCH
+C		"~"			"[[:alnum:]]"	       NOMATCH
+C		"\""			"[[:alnum:]]"	       NOMATCH
+C		"$"			"[[:alnum:]]"	       NOMATCH
+C		"&"			"[[:alnum:]]"	       NOMATCH
+C		"'"			"[[:alnum:]]"	       NOMATCH
+C		"("			"[[:alnum:]]"	       NOMATCH
+C		")"			"[[:alnum:]]"	       NOMATCH
+C		"*"			"[[:alnum:]]"	       NOMATCH
+C		"?"			"[[:alnum:]]"	       NOMATCH
+C		"`"			"[[:alnum:]]"	       NOMATCH
+C		"|"			"[[:alnum:]]"	       NOMATCH
+C		"<"			"[[:alnum:]]"	       NOMATCH
+C		">"			"[[:alnum:]]"	       NOMATCH
+C		"\t"			"[[:cntrl:]]"	       0
+C		"t"			"[[:cntrl:]]"	       NOMATCH
+C		"t"			"[[:lower:]]"	       0
+C		"\t"			"[[:lower:]]"	       NOMATCH
+C		"T"			"[[:lower:]]"	       NOMATCH
+C		"\t"			"[[:space:]]"	       0
+C		"t"			"[[:space:]]"	       NOMATCH
+C		"t"			"[[:alpha:]]"	       0
+C		"\t"			"[[:alpha:]]"	       NOMATCH
+C		"0"			"[[:digit:]]"	       0
+C		"\t"			"[[:digit:]]"	       NOMATCH
+C		"t"			"[[:digit:]]"	       NOMATCH
+C		"\t"			"[[:print:]]"	       NOMATCH
+C		"t"			"[[:print:]]"	       0
+C		"T"			"[[:upper:]]"	       0
+C		"\t"			"[[:upper:]]"	       NOMATCH
+C		"t"			"[[:upper:]]"	       NOMATCH
+C		"\t"			"[[:blank:]]"	       0
+C		"t"			"[[:blank:]]"	       NOMATCH
+C		"\t"			"[[:graph:]]"	       NOMATCH
+C		"t"			"[[:graph:]]"	       0
+C		"."			"[[:punct:]]"	       0
+C		"t"			"[[:punct:]]"	       NOMATCH
+C		"\t"			"[[:punct:]]"	       NOMATCH
+C		"0"			"[[:xdigit:]]"	       0
+C		"\t"			"[[:xdigit:]]"	       NOMATCH
+C		"a"			"[[:xdigit:]]"	       0
+C		"A"			"[[:xdigit:]]"	       0
+C		"t"			"[[:xdigit:]]"	       NOMATCH
+C		"a"			"[[alpha]]"	       NOMATCH
+C		"a"			"[[alpha:]]"	       NOMATCH
+C		"a]"			"[[alpha]]"	       0
+C		"a]"			"[[alpha:]]"	       0
+
+# B.6 018(C)
+C		"a"			"[a-c]"		       0
+C		"b"			"[a-c]"		       0
+C		"c"			"[a-c]"		       0
+C		"a"			"[b-c]"		       NOMATCH
+C		"d"			"[b-c]"		       NOMATCH
+C		"B"			"[a-c]"		       NOMATCH
+C		"b"			"[A-C]"		       NOMATCH
+C		""			"[a-c]"		       NOMATCH
+C		"as"			"[a-ca-z]"	       NOMATCH
+
+# B.6 019(C)
+C		"b"			"[c-a]"		       NOMATCH
+
+# B.6 020(C)
+C		"a"			"[a-c0-9]"	       0
+C		"d"			"[a-c0-9]"	       NOMATCH
+C		"B"			"[a-c0-9]"	       NOMATCH
+
+# B.6 021(C)
+C		"-"			"[-a]"		       0
+C		"a"			"[-b]"		       NOMATCH
+C		"-"			"[!-a]"		       NOMATCH
+C		"a"			"[!-b]"		       0
+C		"-"			"[a-c-0-9]"	       0
+C		"b"			"[a-c-0-9]"	       0
+C		"a:"			"a[0-9-a]"	       NOMATCH
+C		"a:"			"a[09-a]"	       0
+
+# B.6 024(C)
+C		""			"*"		       0
+C		"asd/sdf"		"*"		       0
+
+# B.6 025(C)
+C		"as"			"[a-c][a-z]"	       0
+C		"as"			"??"		       0
+
+# B.6 026(C)
+C		"asd/sdf"		"as*df"		       0
+C		"asd/sdf"		"as*"		       0
+C		"asd/sdf"		"*df"		       0
+C		"asd/sdf"		"as*dg"		       NOMATCH
+C		"asdf"			"as*df"		       0
+C		"asdf"			"as*df?"	       NOMATCH
+C		"asdf"			"as*??"		       0
+C		"asdf"			"a*???"		       0
+C		"asdf"			"*????"		       0
+C		"asdf"			"????*"		       0
+C		"asdf"			"??*?"		       0
+
+# B.6 027(C)
+C		"/"			"/"		       0
+C		"/"			"/*"		       0
+C		"/"			"*/"		       0
+C		"/"			"/?"		       NOMATCH
+C		"/"			"?/"		       NOMATCH
+C		"/"			"?"		       0
+C		"."			"?"		       0
+C		"/."			"??"		       0
+C		"/"			"[!a-c]"	       0
+C		"."			"[!a-c]"	       0