* io/Versions (__dup2, __pipe): Added to GLIBC_2.0 for
[kopensolaris-gnu/glibc.git] / posix / fnmatch.c
index 4f5c667..dc389ef 100644 (file)
@@ -35,7 +35,7 @@
 # include <strings.h>
 #endif
 
-#ifdef STDC_HEADERS
+#if defined STDC_HEADERS || defined _LIBC
 # include <stdlib.h>
 #endif
 
@@ -136,7 +136,7 @@ fnmatch (pattern, string, flags)
      int flags;
 {
   register const char *p = pattern, *n = string;
-  register char c;
+  register unsigned char c;
 
 /* Note that this evaluates C many times.  */
 # ifdef _LIBC
@@ -170,7 +170,7 @@ fnmatch (pattern, string, flags)
                return FNM_NOMATCH;
              c = FOLD (c);
            }
-         if (FOLD (*n) != c)
+         if (FOLD ((unsigned char) *n) != c)
            return FNM_NOMATCH;
          break;
 
@@ -202,10 +202,10 @@ fnmatch (pattern, string, flags)
            return 0;
 
          {
-           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+           unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
            c1 = FOLD (c1);
            for (--p; *n != '\0'; ++n)
-             if ((c == '[' || FOLD (*n) == c1) &&
+             if ((c == '[' || FOLD ((unsigned char) *n) == c1) &&
                  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
                return 0;
            return FNM_NOMATCH;
@@ -216,6 +216,7 @@ fnmatch (pattern, string, flags)
            /* Nonzero if the sense of the character class is inverted.  */
            static int posixly_correct;
            register int not;
+           char cold;
 
            if (posixly_correct == 0)
              posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
@@ -227,6 +228,10 @@ fnmatch (pattern, string, flags)
                (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
              return FNM_NOMATCH;
 
+           if (*n == '/' && (flags & FNM_FILE_NAME))
+             /* `/' cannot be matched.  */
+             return FNM_NOMATCH;
+
            not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
            if (not)
              ++p;
@@ -234,13 +239,14 @@ fnmatch (pattern, string, flags)
            c = *p++;
            for (;;)
              {
-               int fn = FOLD (*n);
+               unsigned char fn = FOLD ((unsigned char) *n);
 
                if (!(flags & FNM_NOESCAPE) && c == '\\')
                  {
                    if (*p == '\0')
                      return FNM_NOMATCH;
-                   c = FOLD (*p++);
+                   c = FOLD ((unsigned char) *p);
+                   ++p;
 
                    if (c == fn)
                      goto matched;
@@ -277,21 +283,21 @@ fnmatch (pattern, string, flags)
                      /* Invalid character class name.  */
                      return FNM_NOMATCH;
 
-                   if (__iswctype (__btowc (*n), wt))
+                   if (__iswctype (__btowc ((unsigned char) *n), wt))
                      goto matched;
 # else
-                   if ((STREQ (str, "alnum") && ISALNUM (*n))
-                       || (STREQ (str, "alpha") && ISALPHA (*n))
-                       || (STREQ (str, "blank") && ISBLANK (*n))
-                       || (STREQ (str, "cntrl") && ISCNTRL (*n))
-                       || (STREQ (str, "digit") && ISDIGIT (*n))
-                       || (STREQ (str, "graph") && ISGRAPH (*n))
-                       || (STREQ (str, "lower") && ISLOWER (*n))
-                       || (STREQ (str, "print") && ISPRINT (*n))
-                       || (STREQ (str, "punct") && ISPUNCT (*n))
-                       || (STREQ (str, "space") && ISSPACE (*n))
-                       || (STREQ (str, "upper") && ISUPPER (*n))
-                       || (STREQ (str, "xdigit") && ISXDIGIT (*n)))
+                   if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
+                       || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
+                       || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
+                       || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
+                       || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
+                       || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
+                       || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
+                       || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
+                       || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
+                       || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
+                       || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
+                       || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
                      goto matched;
 # endif
                  }
@@ -301,8 +307,23 @@ fnmatch (pattern, string, flags)
                else if (FOLD (c) == fn)
                  goto matched;
 
+               cold = c;
                c = *p++;
 
+               if (c == '-' && *p != ']')
+                 {
+                   /* It is a range.  */
+                   unsigned char cend = *p++;
+                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
+                     cend = *p++;
+                   if (cend == '\0')
+                     return FNM_NOMATCH;
+
+                   if (cold <= fn && fn <= FOLD (cend))
+                     goto matched;
+
+                   c = *p++;
+                 }
                if (c == ']')
                  break;
              }
@@ -343,7 +364,7 @@ fnmatch (pattern, string, flags)
          break;
 
        default:
-         if (c != FOLD (*n))
+         if (c != FOLD ((unsigned char) *n))
            return FNM_NOMATCH;
        }