exclude: handle wildcards with FNM_EXTMATCH
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 29 Apr 2012 22:53:53 +0000 (15:53 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 29 Apr 2012 22:53:53 +0000 (15:53 -0700)
* lib/exclude.c (fnmatch_pattern_has_wildcards): Also treat '+(',
'+@', '!(' as wildcards, if FNM_EXTMATCH.  Make it clear in a
comment that "has wildcards" really means "has or may have
wildcards".  Simplify by avoiding the need to call strcspn.

ChangeLog
lib/exclude.c

index e1f0798..9d5195f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-04-29  Paul Eggert  <eggert@cs.ucla.edu>
+
+       exclude: handle wildcards with FNM_EXTMATCH
+       * lib/exclude.c (fnmatch_pattern_has_wildcards): Also treat '+(',
+       '+@', '!(' as wildcards, if FNM_EXTMATCH.  Make it clear in a
+       comment that "has wildcards" really means "has or may have
+       wildcards".  Simplify by avoiding the need to call strcspn.
+
 2012-04-29  Bruno Haible  <bruno@clisp.org>
 
        gnulib-tool: Fix list of authors.
index bc3e6e6..d135b09 100644 (file)
@@ -110,28 +110,31 @@ struct exclude
     struct exclude_segment *head, *tail;
   };
 
-/* Return true if str has wildcard characters */
+/* Return true if STR has or may have wildcards, when matched with OPTIONS.
+   Return false if STR definitely does not have wildcards.  */
 bool
 fnmatch_pattern_has_wildcards (const char *str, int options)
 {
-  const char *cset = "\\?*[]";
-  if (options & FNM_NOESCAPE)
-    cset++;
-  while (*str)
+  while (1)
     {
-      size_t n = strcspn (str, cset);
-      if (str[n] == 0)
-        break;
-      else if (str[n] == '\\')
+      switch (*str++)
         {
-          str += n + 1;
-          if (*str)
-            str++;
+        case '\\':
+          str += ! (options & FNM_NOESCAPE) && *str;
+          break;
+
+        case '+': case '@': case '!':
+          if (options & FNM_EXTMATCH && *str == '(')
+            return true;
+          break;
+
+        case '?': case '*': case '[':
+          return true;
+
+        case '\0':
+          return false;
         }
-      else
-        return true;
     }
-  return false;
 }
 
 static void