|
@@ -1153,6 +1153,13 @@ name_next (int change_dirs)
|
|
|
return nelt ? nelt->v.name : NULL;
|
|
|
}
|
|
|
|
|
|
+static bool
|
|
|
+name_is_wildcard (struct name const *name)
|
|
|
+{
|
|
|
+ return (name->matching_flags & EXCLUDE_WILDCARDS) &&
|
|
|
+ fnmatch_pattern_has_wildcards (name->name, name->matching_flags);
|
|
|
+}
|
|
|
+
|
|
|
/* Gather names in a list for scanning. Could hash them later if we
|
|
|
really care.
|
|
|
|
|
@@ -1189,6 +1196,7 @@ name_gather (void)
|
|
|
buffer->directory = NULL;
|
|
|
buffer->parent = NULL;
|
|
|
buffer->cmdline = true;
|
|
|
+ buffer->is_wildcard = name_is_wildcard (buffer);
|
|
|
|
|
|
namelist = nametail = buffer;
|
|
|
}
|
|
@@ -1232,6 +1240,7 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
|
|
|
name->directory = NULL;
|
|
|
name->parent = parent;
|
|
|
name->cmdline = cmdline;
|
|
|
+ name->is_wildcard = name_is_wildcard (name);
|
|
|
|
|
|
if (nametail)
|
|
|
nametail->next = name;
|
|
@@ -1265,19 +1274,22 @@ add_starting_file (char const *file_name)
|
|
|
name->directory = NULL;
|
|
|
name->parent = NULL;
|
|
|
name->cmdline = true;
|
|
|
+ name->is_wildcard = name_is_wildcard (name);
|
|
|
|
|
|
starting_file_option = true;
|
|
|
}
|
|
|
|
|
|
-/* Find a match for FILE_NAME in the name list. */
|
|
|
+/* Find a match for FILE_NAME in the name list. If EXPECT is true,
|
|
|
+ look for exact match (no wildcards). */
|
|
|
static struct name *
|
|
|
-namelist_match (char const *file_name)
|
|
|
+namelist_match (char const *file_name, bool exact)
|
|
|
{
|
|
|
struct name *p;
|
|
|
|
|
|
for (p = namelist; p; p = p->next)
|
|
|
{
|
|
|
if (p->name[0]
|
|
|
+ && (exact ? !p->is_wildcard : true)
|
|
|
&& exclude_fnmatch (p->name, file_name, p->matching_flags))
|
|
|
return p;
|
|
|
}
|
|
@@ -1321,7 +1333,7 @@ name_match (const char *file_name)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- cursor = namelist_match (file_name);
|
|
|
+ cursor = namelist_match (file_name, false);
|
|
|
if (starting_file_option)
|
|
|
{
|
|
|
/* If starting_file_option is set, the head of the list is the name
|
|
@@ -1870,13 +1882,14 @@ collect_and_sort_names (void)
|
|
|
1. It returns a pointer to the name it matched, and doesn't set FOUND
|
|
|
in structure. The caller will have to do that if it wants to.
|
|
|
2. If the namelist is empty, it returns null, unlike name_match, which
|
|
|
- returns TRUE. */
|
|
|
+ returns TRUE.
|
|
|
+ 3. If EXPECT is true, it looks for exact matches only (no wildcards). */
|
|
|
struct name *
|
|
|
-name_scan (const char *file_name)
|
|
|
+name_scan (const char *file_name, bool exact)
|
|
|
{
|
|
|
while (1)
|
|
|
{
|
|
|
- struct name *cursor = namelist_match (file_name);
|
|
|
+ struct name *cursor = namelist_match (file_name, exact);
|
|
|
if (cursor)
|
|
|
return cursor;
|
|
|
|
|
@@ -1896,9 +1909,10 @@ name_scan (const char *file_name)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* This returns a name from the namelist which doesn't have ->found
|
|
|
- set. It sets ->found before returning, so successive calls will
|
|
|
- find and return all the non-found names in the namelist. */
|
|
|
+/* This returns a name from the namelist which is an exact match (i.e.
|
|
|
+ not a pattern) and doesn't have ->found set. It sets ->found before
|
|
|
+ returning, so successive calls will find and return all the non-found
|
|
|
+ names in the namelist. */
|
|
|
struct name *gnu_list_name;
|
|
|
|
|
|
struct name const *
|
|
@@ -1907,11 +1921,13 @@ name_from_list (void)
|
|
|
if (!gnu_list_name)
|
|
|
gnu_list_name = namelist;
|
|
|
while (gnu_list_name
|
|
|
- && (gnu_list_name->found_count || gnu_list_name->name[0] == 0))
|
|
|
+ && (gnu_list_name->is_wildcard ||
|
|
|
+ gnu_list_name->found_count || gnu_list_name->name[0] == 0))
|
|
|
gnu_list_name = gnu_list_name->next;
|
|
|
if (gnu_list_name)
|
|
|
{
|
|
|
- gnu_list_name->found_count++;
|
|
|
+ if (!gnu_list_name->is_wildcard)
|
|
|
+ gnu_list_name->found_count++;
|
|
|
chdir_do (gnu_list_name->change_dir);
|
|
|
return gnu_list_name;
|
|
|
}
|