changeset 16803:50f45dd3bacf

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.
author Paul Eggert <eggert@cs.ucla.edu>
date Sun, 29 Apr 2012 15:53:53 -0700
parents b21cba808f11
children b994b31c2a5d
files ChangeLog lib/exclude.c
diffstat 2 files changed, 26 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- a/lib/exclude.c
+++ b/lib/exclude.c
@@ -110,28 +110,31 @@
     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