Commit de70bb46ae4ea91c26f6afdc210f37b8980b7a76

Patrick Steinhardt 2019-06-13T15:27:22

global: convert trivial `fnmatch` users to use `wildcard` Upstream git.git has converted its codebase to use wildcard in favor of fnmatch in commit 70a8fc999d (stop using fnmatch (either native or compat), 2014-02-15). To keep our own regex-matching in line with what git does, convert all trivial instances of `fnmatch` usage to use `wildcard`, instead. Trivial usage is defined to be use of `fnmatch` with either no flags or flags that have a 1:1 equivalent in wildmatch (PATHNAME, IGNORECASE).

diff --git a/src/describe.c b/src/describe.c
index 1354290..42e5848 100644
--- a/src/describe.c
+++ b/src/describe.c
@@ -14,13 +14,13 @@
 
 #include "commit.h"
 #include "commit_list.h"
-#include "fnmatch.h"
 #include "oidmap.h"
 #include "refs.h"
 #include "repository.h"
 #include "revwalk.h"
 #include "tag.h"
 #include "vector.h"
+#include "wildmatch.h"
 
 /* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */
 
@@ -215,7 +215,7 @@ static int get_name(const char *refname, void *payload)
 		return 0;
 
 	/* Accept only tags that match the pattern, if given */
-	if (data->opts->pattern && (!is_tag || p_fnmatch(data->opts->pattern,
+	if (data->opts->pattern && (!is_tag || wildmatch(data->opts->pattern,
 		refname + strlen(GIT_REFS_TAGS_DIR), 0)))
 				return 0;
 
diff --git a/src/ignore.c b/src/ignore.c
index 5427efa..1d256c9 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -12,7 +12,7 @@
 #include "attrcache.h"
 #include "path.h"
 #include "config.h"
-#include "fnmatch.h"
+#include "wildmatch.h"
 
 #define GIT_IGNORE_INTERNAL		"[internal]exclude"
 
@@ -101,7 +101,7 @@ static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
  */
 static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match)
 {
-	int error = 0, fnflags;
+	int error = 0, wildmatch_flags;
 	size_t i;
 	git_attr_fnmatch *rule;
 	char *path;
@@ -109,9 +109,9 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
 
 	*out = 0;
 
-	fnflags = FNM_PATHNAME;
+	wildmatch_flags = WM_PATHNAME;
 	if (match->flags & GIT_ATTR_FNMATCH_ICASE)
-		fnflags |= FNM_IGNORECASE;
+		wildmatch_flags |= WM_CASEFOLD;
 
 	/* path of the file relative to the workdir, so we match the rules in subdirs */
 	if (match->containing_dir) {
@@ -141,13 +141,13 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
 		if (git_buf_oom(&buf))
 			goto out;
 
-		if ((error = p_fnmatch(git_buf_cstr(&buf), path, fnflags)) < 0) {
+		if ((error = wildmatch(git_buf_cstr(&buf), path, wildmatch_flags)) < 0) {
 			git_error_set(GIT_ERROR_INVALID, "error matching pattern");
 			goto out;
 		}
 
 		/* if we found a match, we want to keep this rule */
-		if (error != FNM_NOMATCH) {
+		if (error != WM_NOMATCH) {
 			*out = 1;
 			error = 0;
 			goto out;
diff --git a/src/pathspec.c b/src/pathspec.c
index 80144c7..0cd3fc4 100644
--- a/src/pathspec.c
+++ b/src/pathspec.c
@@ -16,7 +16,7 @@
 #include "index.h"
 #include "bitvec.h"
 #include "diff.h"
-#include "fnmatch.h"
+#include "wildmatch.h"
 
 /* what is the common non-wildcard prefix for all items in the pathspec */
 char *git_pathspec_prefix(const git_strarray *pathspec)
@@ -111,7 +111,7 @@ void git_pathspec__vfree(git_vector *vspec)
 }
 
 struct pathspec_match_context {
-	int fnmatch_flags;
+	int wildmatch_flags;
 	int (*strcomp)(const char *, const char *);
 	int (*strncomp)(const char *, const char *, size_t);
 };
@@ -122,11 +122,11 @@ static void pathspec_match_context_init(
 	bool casefold)
 {
 	if (disable_fnmatch)
-		ctxt->fnmatch_flags = -1;
+		ctxt->wildmatch_flags = -1;
 	else if (casefold)
-		ctxt->fnmatch_flags = FNM_CASEFOLD;
+		ctxt->wildmatch_flags = WM_CASEFOLD;
 	else
-		ctxt->fnmatch_flags = 0;
+		ctxt->wildmatch_flags = 0;
 
 	if (casefold) {
 		ctxt->strcomp  = git__strcasecmp;
@@ -142,16 +142,16 @@ static int pathspec_match_one(
 	struct pathspec_match_context *ctxt,
 	const char *path)
 {
-	int result = (match->flags & GIT_ATTR_FNMATCH_MATCH_ALL) ? 0 : FNM_NOMATCH;
+	int result = (match->flags & GIT_ATTR_FNMATCH_MATCH_ALL) ? 0 : WM_NOMATCH;
 
-	if (result == FNM_NOMATCH)
-		result = ctxt->strcomp(match->pattern, path) ? FNM_NOMATCH : 0;
+	if (result == WM_NOMATCH)
+		result = ctxt->strcomp(match->pattern, path) ? WM_NOMATCH : 0;
 
-	if (ctxt->fnmatch_flags >= 0 && result == FNM_NOMATCH)
-		result = p_fnmatch(match->pattern, path, ctxt->fnmatch_flags);
+	if (ctxt->wildmatch_flags >= 0 && result == WM_NOMATCH)
+		result = wildmatch(match->pattern, path, ctxt->wildmatch_flags);
 
 	/* if we didn't match, look for exact dirname prefix match */
-	if (result == FNM_NOMATCH &&
+	if (result == WM_NOMATCH &&
 		(match->flags & GIT_ATTR_FNMATCH_HASWILD) == 0 &&
 		ctxt->strncomp(path, match->pattern, match->length) == 0 &&
 		path[match->length] == '/')
@@ -160,7 +160,7 @@ static int pathspec_match_one(
 	/* if we didn't match and this is a negative match, check for exact
 	 * match of filename with leading '!'
 	 */
-	if (result == FNM_NOMATCH &&
+	if (result == WM_NOMATCH &&
 		(match->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0 &&
 		*path == '!' &&
 		ctxt->strncomp(path + 1, match->pattern, match->length) == 0 &&
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 22b08a1..e5ee392 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -18,7 +18,7 @@
 #include "iterator.h"
 #include "sortedcache.h"
 #include "signature.h"
-#include "fnmatch.h"
+#include "wildmatch.h"
 
 #include <git2/tag.h>
 #include <git2/object.h>
@@ -572,7 +572,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
 		ref_name = git_buf_cstr(&path);
 
 		if (git__suffixcmp(ref_name, ".lock") == 0 ||
-			(iter->glob && p_fnmatch(iter->glob, ref_name, 0) != 0))
+			(iter->glob && wildmatch(iter->glob, ref_name, 0) != 0))
 			continue;
 
 		ref_dup = git_pool_strdup(&iter->pool, ref_name);
@@ -618,7 +618,7 @@ static int refdb_fs_backend__iterator_next(
 
 		if (ref->flags & PACKREF_SHADOWED)
 			continue;
-		if (iter->glob && p_fnmatch(iter->glob, ref->name, 0) != 0)
+		if (iter->glob && wildmatch(iter->glob, ref->name, 0) != 0)
 			continue;
 
 		*out = git_reference__alloc(ref->name, &ref->oid, &ref->peel);
@@ -661,7 +661,7 @@ static int refdb_fs_backend__iterator_next_name(
 
 		if (ref->flags & PACKREF_SHADOWED)
 			continue;
-		if (iter->glob && p_fnmatch(iter->glob, ref->name, 0) != 0)
+		if (iter->glob && wildmatch(iter->glob, ref->name, 0) != 0)
 			continue;
 
 		*out = ref->name;
diff --git a/src/refspec.c b/src/refspec.c
index 30e618f..854240a 100644
--- a/src/refspec.c
+++ b/src/refspec.c
@@ -9,10 +9,10 @@
 
 #include "git2/errors.h"
 
-#include "util.h"
-#include "fnmatch.h"
 #include "refs.h"
+#include "util.h"
 #include "vector.h"
+#include "wildmatch.h"
 
 int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
 {
@@ -213,7 +213,7 @@ int git_refspec_src_matches(const git_refspec *refspec, const char *refname)
 	if (refspec == NULL || refspec->src == NULL)
 		return false;
 
-	return (p_fnmatch(refspec->src, refname, 0) == 0);
+	return (wildmatch(refspec->src, refname, 0) == 0);
 }
 
 int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
@@ -221,7 +221,7 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
 	if (refspec == NULL || refspec->dst == NULL)
 		return false;
 
-	return (p_fnmatch(refspec->dst, refname, 0) == 0);
+	return (wildmatch(refspec->dst, refname, 0) == 0);
 }
 
 static int refspec_transform(
diff --git a/src/status.c b/src/status.c
index 84c4b66..a01736d 100644
--- a/src/status.c
+++ b/src/status.c
@@ -16,7 +16,7 @@
 #include "repository.h"
 #include "ignore.h"
 #include "index.h"
-#include "fnmatch.h"
+#include "wildmatch.h"
 
 #include "git2/diff.h"
 #include "diff.h"
@@ -457,7 +457,7 @@ struct status_file_info {
 	char *expected;
 	unsigned int count;
 	unsigned int status;
-	int fnm_flags;
+	int wildmatch_flags;
 	int ambiguous;
 };
 
@@ -469,11 +469,11 @@ static int get_one_status(const char *path, unsigned int status, void *data)
 	sfi->count++;
 	sfi->status = status;
 
-	strcomp = (sfi->fnm_flags & FNM_CASEFOLD) ? git__strcasecmp : git__strcmp;
+	strcomp = (sfi->wildmatch_flags & WM_CASEFOLD) ? git__strcasecmp : git__strcmp;
 
 	if (sfi->count > 1 ||
 		(strcomp(sfi->expected, path) != 0 &&
-		 p_fnmatch(sfi->expected, path, sfi->fnm_flags) != 0))
+		 wildmatch(sfi->expected, path, sfi->wildmatch_flags) != 0))
 	{
 		sfi->ambiguous = true;
 		return GIT_EAMBIGUOUS; /* git_error_set will be done by caller */
@@ -500,7 +500,7 @@ int git_status_file(
 	if ((sfi.expected = git__strdup(path)) == NULL)
 		return -1;
 	if (index->ignore_case)
-		sfi.fnm_flags = FNM_CASEFOLD;
+		sfi.wildmatch_flags = WM_CASEFOLD;
 
 	opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
 	opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
diff --git a/src/tag.c b/src/tag.c
index e39a79c..42c4e99 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -8,9 +8,9 @@
 #include "tag.h"
 
 #include "commit.h"
-#include "fnmatch.h"
 #include "signature.h"
 #include "message.h"
+#include "wildmatch.h"
 #include "git2/object.h"
 #include "git2/repository.h"
 #include "git2/signature.h"
@@ -476,7 +476,7 @@ static int tag_list_cb(const char *tag_name, git_oid *oid, void *data)
 	GIT_UNUSED(oid);
 
 	if (!*filter->pattern ||
-		p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
+	    wildmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
 	{
 		char *matched = git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN);
 		GIT_ERROR_CHECK_ALLOC(matched);
diff --git a/tests/describe/describe_helpers.c b/tests/describe/describe_helpers.c
index e8e887c..80217dc 100644
--- a/tests/describe/describe_helpers.c
+++ b/tests/describe/describe_helpers.c
@@ -1,6 +1,6 @@
 #include "describe_helpers.h"
 
-#include "fnmatch.h"
+#include "wildmatch.h"
 
 void assert_describe(
 	const char *expected_output,
@@ -18,7 +18,7 @@ void assert_describe(
 	cl_git_pass(git_describe_commit(&result, object, opts));
 	cl_git_pass(git_describe_format(&label, result, fmt_opts));
 
-	cl_must_pass(p_fnmatch(expected_output, git_buf_cstr(&label), 0));
+	cl_must_pass(wildmatch(expected_output, git_buf_cstr(&label), 0));
 
 	git_describe_result_free(result);
 	git_object_free(object);
@@ -37,7 +37,7 @@ void assert_describe_workdir(
 	cl_git_pass(git_describe_workdir(&result, repo, opts));
 	cl_git_pass(git_describe_format(&label, result, fmt_opts));
 
-	cl_must_pass(p_fnmatch(expected_output, git_buf_cstr(&label), 0));
+	cl_must_pass(wildmatch(expected_output, git_buf_cstr(&label), 0));
 
 	git_describe_result_free(result);
 	git_buf_dispose(&label);