changeset 42:a2a5c078f12b

updated from FSF
author Jim Meyering <jim@meyering.net>
date Wed, 31 Mar 1993 01:23:35 +0000
parents 1840d8d6c895
children 85c86308e0ef
files lib/fnmatch.c
diffstat 1 files changed, 33 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -16,16 +16,13 @@
 Cambridge, MA 02139, USA.  */
 
 #include <errno.h>
-#include "fnmatch.h"
+#include <fnmatch.h>
+#include <ctype.h>
 
 #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
 extern int errno;
 #endif
 
-#if !__STDC__
-#define const
-#endif
-
 /* Match STRING against the filename pattern PATTERN, returning zero if
    it matches, nonzero if not.  */
 int
@@ -37,40 +34,42 @@
   register const char *p = pattern, *n = string;
   register char c;
 
-  if ((flags & ~__FNM_FLAGS) != 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
+/* Note that this evalutes C many times.  */
+#define FOLD(c)	((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
 
   while ((c = *p++) != '\0')
     {
+      c = FOLD (c);
+
       switch (c)
 	{
 	case '?':
 	  if (*n == '\0')
 	    return FNM_NOMATCH;
-	  else if ((flags & FNM_PATHNAME) && *n == '/')
+	  else if ((flags & FNM_FILE_NAME) && *n == '/')
 	    return FNM_NOMATCH;
 	  else if ((flags & FNM_PERIOD) && *n == '.' &&
-		   (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+		   (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
 	    return FNM_NOMATCH;
 	  break;
 
 	case '\\':
 	  if (!(flags & FNM_NOESCAPE))
-	    c = *p++;
-	  if (*n != c)
+	    {
+	      c = *p++;
+	      c = FOLD (c);
+	    }
+	  if (FOLD (*n) != c)
 	    return FNM_NOMATCH;
 	  break;
 
 	case '*':
 	  if ((flags & FNM_PERIOD) && *n == '.' &&
-	      (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+	      (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
 	    return FNM_NOMATCH;
 
 	  for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
-	    if (((flags & FNM_PATHNAME) && *n == '/') ||
+	    if (((flags & FNM_FILE_NAME) && *n == '/') ||
 		(c == '?' && *n == '\0'))
 	      return FNM_NOMATCH;
 
@@ -79,8 +78,9 @@
 
 	  {
 	    char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+	    c1 = FOLD (c1);
 	    for (--p; *n != '\0'; ++n)
-	      if ((c == '[' || *n == c1) &&
+	      if ((c == '[' || FOLD (*n) == c1) &&
 		  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
 		return 0;
 	    return FNM_NOMATCH;
@@ -95,7 +95,7 @@
 	      return FNM_NOMATCH;
 
 	    if ((flags & FNM_PERIOD) && *n == '.' &&
-		(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+		(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
 	      return FNM_NOMATCH;
 
 	    not = (*p == '!' || *p == '^');
@@ -110,13 +110,16 @@
 		if (!(flags & FNM_NOESCAPE) && c == '\\')
 		  cstart = cend = *p++;
 
+		cstart = cend = FOLD (cstart);
+
 		if (c == '\0')
 		  /* [ (unterminated) loses.  */
 		  return FNM_NOMATCH;
 
 		c = *p++;
+		c = FOLD (c);
 
-		if ((flags & FNM_PATHNAME) && c == '/')
+		if ((flags & FNM_FILE_NAME) && c == '/')
 		  /* [/] can never match.  */
 		  return FNM_NOMATCH;
 
@@ -127,10 +130,12 @@
 		      cend = *p++;
 		    if (cend == '\0')
 		      return FNM_NOMATCH;
+		    cend = FOLD (cend);
+
 		    c = *p++;
 		  }
 
-		if (*n >= cstart && *n <= cend)
+		if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
 		  goto matched;
 
 		if (c == ']')
@@ -150,7 +155,7 @@
 
 		c = *p++;
 		if (!(flags & FNM_NOESCAPE) && c == '\\')
-		  /* 1003.2d11 is unclear if this is right.  %%% */
+		  /* XXX 1003.2d11 is unclear if this is right.  */
 		  ++p;
 	      }
 	    if (not)
@@ -159,14 +164,18 @@
 	  break;
 
 	default:
-	  if (c != *n)
+	  if (c != FOLD (*n))
 	    return FNM_NOMATCH;
 	}
 
       ++n;
     }
 
-  if (*n == '\0' || ((flags & FNM_TARPATH) && *n == '/'))
+  if (*n == '\0')
+    return 0;
+
+  if ((flags & FNM_LEADING_DIR) && *n == '/')
+    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
     return 0;
 
   return FNM_NOMATCH;