diff options
author | Colin Watson <cjwatson@debian.org> | 2022-10-11 17:18:39 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2022-10-11 17:18:39 +0100 |
commit | b06b3d373acd1a3883edab5860448b774e330c7b (patch) | |
tree | 47128b8498ae5629ae6191fea128f87575ec9838 | |
parent | 737e0215d9455222112ae73711fb87df828ae648 (diff) |
match_in_directory: Split into multiple functions
`match_in_directory` had two almost entirely disjoint code paths, one
for regex patterns and one for wildcard patterns; but its structure made
it difficult for `gcc -fanalyzer` to understand that, and it was a bit
unclear for humans too. Split it up for clarity.
* src/globbing.c (match_in_directory): Split out the
regex/wildcard-handling parts to ...
(match_regex_in_directory, match_wildcard_in_directory): ... here,
respectively.
-rw-r--r-- | src/globbing.c | 113 |
1 files changed, 68 insertions, 45 deletions
diff --git a/src/globbing.c b/src/globbing.c index 9a65b534..b9338981 100644 --- a/src/globbing.c +++ b/src/globbing.c @@ -208,62 +208,70 @@ static int pattern_compare (const void *a, const void *b) return strncasecmp (key->pattern, memb, key->len); } -static void match_in_directory (const char *path, const char *pattern, - int opts, gl_list_t matched) +static void match_regex_in_directory (const char *path, const char *pattern, + int opts, gl_list_t matched, + struct dirent_names *cache) { - struct dirent_names *cache; int flags; regex_t preg; - struct pattern_bsearch pattern_start = { NULL, -1 }; - char **bsearched; size_t i; - cache = update_directory_cache (path); - if (!cache) { - debug ("directory cache update failed\n"); - return; + debug ("matching regex in %s: %s\n", path, pattern); + + flags = REG_EXTENDED | REG_NOSUB | + ((opts & LFF_MATCHCASE) ? 0 : REG_ICASE); + + xregcomp (&preg, pattern, flags); + + for (i = 0; i < cache->names_len; ++i) { + if (regexec (&preg, cache->names[i], 0, NULL, 0) != 0) + continue; + + debug ("matched: %s/%s\n", path, cache->names[i]); + + gl_list_add_last (matched, + xasprintf ("%s/%s", path, cache->names[i])); } - debug ("globbing pattern in %s: %s\n", path, pattern); + regfree (&preg); +} - if (opts & LFF_REGEX) - flags = REG_EXTENDED | REG_NOSUB | - ((opts & LFF_MATCHCASE) ? 0 : REG_ICASE); - else - flags = (opts & LFF_MATCHCASE) ? 0 : FNM_CASEFOLD; +static void match_wildcard_in_directory (const char *path, const char *pattern, + int opts, gl_list_t matched, + struct dirent_names *cache) +{ + int flags; + struct pattern_bsearch pattern_start = { NULL, -1 }; + char **bsearched; + size_t i; - if (opts & LFF_REGEX) { - xregcomp (&preg, pattern, flags); - bsearched = cache->names; - } else { - pattern_start.pattern = xstrndup (pattern, - strcspn (pattern, "?*{}\\")); - pattern_start.len = strlen (pattern_start.pattern); - bsearched = bsearch (&pattern_start, cache->names, - cache->names_len, sizeof *cache->names, - &pattern_compare); - if (!bsearched) { - free (pattern_start.pattern); - return; - } - while (bsearched > cache->names && - !strncasecmp (pattern_start.pattern, *(bsearched - 1), - pattern_start.len)) - --bsearched; + debug ("matching wildcard in %s: %s\n", path, pattern); + + flags = (opts & LFF_MATCHCASE) ? 0 : FNM_CASEFOLD; + + pattern_start.pattern = xstrndup (pattern, + strcspn (pattern, "?*{}\\")); + pattern_start.len = strlen (pattern_start.pattern); + bsearched = bsearch (&pattern_start, cache->names, + cache->names_len, sizeof *cache->names, + &pattern_compare); + if (!bsearched) { + free (pattern_start.pattern); + return; } + while (bsearched > cache->names && + !strncasecmp (pattern_start.pattern, *(bsearched - 1), + pattern_start.len)) + --bsearched; for (i = bsearched - cache->names; i < cache->names_len; ++i) { - if (opts & LFF_REGEX) { - if (regexec (&preg, cache->names[i], 0, NULL, 0) != 0) - continue; - } else { - if (strncasecmp (pattern_start.pattern, - cache->names[i], pattern_start.len)) - break; + assert (pattern_start.pattern); + if (strncasecmp (pattern_start.pattern, + cache->names[i], pattern_start.len)) + break; - if (fnmatch (pattern, cache->names[i], flags) != 0) - continue; - } + if (fnmatch (pattern, cache->names[i], flags) != 0) + continue; debug ("matched: %s/%s\n", path, cache->names[i]); @@ -271,10 +279,25 @@ static void match_in_directory (const char *path, const char *pattern, xasprintf ("%s/%s", path, cache->names[i])); } + free (pattern_start.pattern); +} + +static void match_in_directory (const char *path, const char *pattern, + int opts, gl_list_t matched) +{ + struct dirent_names *cache; + + cache = update_directory_cache (path); + if (!cache) { + debug ("directory cache update failed\n"); + return; + } + if (opts & LFF_REGEX) - regfree (&preg); + match_regex_in_directory (path, pattern, opts, matched, cache); else - free (pattern_start.pattern); + match_wildcard_in_directory (path, pattern, opts, matched, + cache); } gl_list_t look_for_file (const char *hier, const char *sec, |