treewide: rename 'struct exclude' to 'struct path_pattern'

The first consumer of pattern-matching filenames was the
.gitignore feature. In that context, storing a list of patterns
as a list of 'struct exclude' items makes sense. However, the
sparse-checkout feature then adopted these structures and methods,
but with the opposite meaning: these patterns match the files
that should be included!

It would be clearer to rename this entire library as a "pattern
matching" library, and the callers apply exclusion/inclusion
logic accordingly based on their needs.

This commit renames 'struct exclude' to 'struct path_pattern'
and renames several variable names to match. 'struct pattern'
was already taken by attr.c, and this more completely describes
that the patterns are specific to file paths.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Derrick Stolee 2019-09-03 11:04:55 -07:00 committed by Junio C Hamano
parent 90d21f9ebf
commit ab8db61390
3 changed files with 80 additions and 77 deletions

View file

@ -32,19 +32,19 @@ static const struct option check_ignore_options[] = {
OPT_END() OPT_END()
}; };
static void output_exclude(const char *path, struct exclude *exclude) static void output_pattern(const char *path, struct path_pattern *pattern)
{ {
char *bang = (exclude && exclude->flags & EXC_FLAG_NEGATIVE) ? "!" : ""; char *bang = (pattern && pattern->flags & EXC_FLAG_NEGATIVE) ? "!" : "";
char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : ""; char *slash = (pattern && pattern->flags & EXC_FLAG_MUSTBEDIR) ? "/" : "";
if (!nul_term_line) { if (!nul_term_line) {
if (!verbose) { if (!verbose) {
write_name_quoted(path, stdout, '\n'); write_name_quoted(path, stdout, '\n');
} else { } else {
if (exclude) { if (pattern) {
quote_c_style(exclude->el->src, NULL, stdout, 0); quote_c_style(pattern->el->src, NULL, stdout, 0);
printf(":%d:%s%s%s\t", printf(":%d:%s%s%s\t",
exclude->srcpos, pattern->srcpos,
bang, exclude->pattern, slash); bang, pattern->pattern, slash);
} }
else { else {
printf("::\t"); printf("::\t");
@ -56,11 +56,11 @@ static void output_exclude(const char *path, struct exclude *exclude)
if (!verbose) { if (!verbose) {
printf("%s%c", path, '\0'); printf("%s%c", path, '\0');
} else { } else {
if (exclude) if (pattern)
printf("%s%c%d%c%s%s%s%c%s%c", printf("%s%c%d%c%s%s%s%c%s%c",
exclude->el->src, '\0', pattern->el->src, '\0',
exclude->srcpos, '\0', pattern->srcpos, '\0',
bang, exclude->pattern, slash, '\0', bang, pattern->pattern, slash, '\0',
path, '\0'); path, '\0');
else else
printf("%c%c%c%s%c", '\0', '\0', '\0', path, '\0'); printf("%c%c%c%s%c", '\0', '\0', '\0', path, '\0');
@ -74,7 +74,7 @@ static int check_ignore(struct dir_struct *dir,
const char *full_path; const char *full_path;
char *seen; char *seen;
int num_ignored = 0, i; int num_ignored = 0, i;
struct exclude *exclude; struct path_pattern *pattern;
struct pathspec pathspec; struct pathspec pathspec;
if (!argc) { if (!argc) {
@ -103,15 +103,15 @@ static int check_ignore(struct dir_struct *dir,
seen = find_pathspecs_matching_against_index(&pathspec, &the_index); seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
for (i = 0; i < pathspec.nr; i++) { for (i = 0; i < pathspec.nr; i++) {
full_path = pathspec.items[i].match; full_path = pathspec.items[i].match;
exclude = NULL; pattern = NULL;
if (!seen[i]) { if (!seen[i]) {
int dtype = DT_UNKNOWN; int dtype = DT_UNKNOWN;
exclude = last_exclude_matching(dir, &the_index, pattern = last_exclude_matching(dir, &the_index,
full_path, &dtype); full_path, &dtype);
} }
if (!quiet && (exclude || show_non_matching)) if (!quiet && (pattern || show_non_matching))
output_exclude(pathspec.items[i].original, exclude); output_pattern(pathspec.items[i].original, pattern);
if (exclude) if (pattern)
num_ignored++; num_ignored++;
} }
free(seen); free(seen);

115
dir.c
View file

@ -602,27 +602,27 @@ void parse_exclude_pattern(const char **pattern,
void add_exclude(const char *string, const char *base, void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *el, int srcpos) int baselen, struct exclude_list *el, int srcpos)
{ {
struct exclude *x; struct path_pattern *pattern;
int patternlen; int patternlen;
unsigned flags; unsigned flags;
int nowildcardlen; int nowildcardlen;
parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
if (flags & EXC_FLAG_MUSTBEDIR) { if (flags & EXC_FLAG_MUSTBEDIR) {
FLEXPTR_ALLOC_MEM(x, pattern, string, patternlen); FLEXPTR_ALLOC_MEM(pattern, pattern, string, patternlen);
} else { } else {
x = xmalloc(sizeof(*x)); pattern = xmalloc(sizeof(*pattern));
x->pattern = string; pattern->pattern = string;
} }
x->patternlen = patternlen; pattern->patternlen = patternlen;
x->nowildcardlen = nowildcardlen; pattern->nowildcardlen = nowildcardlen;
x->base = base; pattern->base = base;
x->baselen = baselen; pattern->baselen = baselen;
x->flags = flags; pattern->flags = flags;
x->srcpos = srcpos; pattern->srcpos = srcpos;
ALLOC_GROW(el->excludes, el->nr + 1, el->alloc); ALLOC_GROW(el->patterns, el->nr + 1, el->alloc);
el->excludes[el->nr++] = x; el->patterns[el->nr++] = pattern;
x->el = el; pattern->el = el;
} }
static int read_skip_worktree_file_from_index(const struct index_state *istate, static int read_skip_worktree_file_from_index(const struct index_state *istate,
@ -651,8 +651,8 @@ void clear_exclude_list(struct exclude_list *el)
int i; int i;
for (i = 0; i < el->nr; i++) for (i = 0; i < el->nr; i++)
free(el->excludes[i]); free(el->patterns[i]);
free(el->excludes); free(el->patterns);
free(el->filebuf); free(el->filebuf);
memset(el, 0, sizeof(*el)); memset(el, 0, sizeof(*el));
@ -1021,51 +1021,54 @@ int match_pathname(const char *pathname, int pathlen,
* any, determines the fate. Returns the exclude_list element which * any, determines the fate. Returns the exclude_list element which
* matched, or NULL for undecided. * matched, or NULL for undecided.
*/ */
static struct exclude *last_exclude_matching_from_list(const char *pathname, static struct path_pattern *last_exclude_matching_from_list(const char *pathname,
int pathlen, int pathlen,
const char *basename, const char *basename,
int *dtype, int *dtype,
struct exclude_list *el, struct exclude_list *el,
struct index_state *istate) struct index_state *istate)
{ {
struct exclude *exc = NULL; /* undecided */ struct path_pattern *res = NULL; /* undecided */
int i; int i;
if (!el->nr) if (!el->nr)
return NULL; /* undefined */ return NULL; /* undefined */
for (i = el->nr - 1; 0 <= i; i--) { for (i = el->nr - 1; 0 <= i; i--) {
struct exclude *x = el->excludes[i]; struct path_pattern *pattern = el->patterns[i];
const char *exclude = x->pattern; const char *exclude = pattern->pattern;
int prefix = x->nowildcardlen; int prefix = pattern->nowildcardlen;
if (x->flags & EXC_FLAG_MUSTBEDIR) { if (pattern->flags & EXC_FLAG_MUSTBEDIR) {
if (*dtype == DT_UNKNOWN) if (*dtype == DT_UNKNOWN)
*dtype = get_dtype(NULL, istate, pathname, pathlen); *dtype = get_dtype(NULL, istate, pathname, pathlen);
if (*dtype != DT_DIR) if (*dtype != DT_DIR)
continue; continue;
} }
if (x->flags & EXC_FLAG_NODIR) { if (pattern->flags & EXC_FLAG_NODIR) {
if (match_basename(basename, if (match_basename(basename,
pathlen - (basename - pathname), pathlen - (basename - pathname),
exclude, prefix, x->patternlen, exclude, prefix, pattern->patternlen,
x->flags)) { pattern->flags)) {
exc = x; res = pattern;
break; break;
} }
continue; continue;
} }
assert(x->baselen == 0 || x->base[x->baselen - 1] == '/'); assert(pattern->baselen == 0 ||
pattern->base[pattern->baselen - 1] == '/');
if (match_pathname(pathname, pathlen, if (match_pathname(pathname, pathlen,
x->base, x->baselen ? x->baselen - 1 : 0, pattern->base,
exclude, prefix, x->patternlen, x->flags)) { pattern->baselen ? pattern->baselen - 1 : 0,
exc = x; exclude, prefix, pattern->patternlen,
pattern->flags)) {
res = pattern;
break; break;
} }
} }
return exc; return res;
} }
/* /*
@ -1076,30 +1079,30 @@ int is_excluded_from_list(const char *pathname,
int pathlen, const char *basename, int *dtype, int pathlen, const char *basename, int *dtype,
struct exclude_list *el, struct index_state *istate) struct exclude_list *el, struct index_state *istate)
{ {
struct exclude *exclude; struct path_pattern *pattern;
exclude = last_exclude_matching_from_list(pathname, pathlen, basename, pattern = last_exclude_matching_from_list(pathname, pathlen, basename,
dtype, el, istate); dtype, el, istate);
if (exclude) if (pattern)
return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1; return pattern->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
return -1; /* undecided */ return -1; /* undecided */
} }
static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir, static struct path_pattern *last_exclude_matching_from_lists(
struct index_state *istate, struct dir_struct *dir, struct index_state *istate,
const char *pathname, int pathlen, const char *basename, const char *pathname, int pathlen,
int *dtype_p) const char *basename, int *dtype_p)
{ {
int i, j; int i, j;
struct exclude_list_group *group; struct exclude_list_group *group;
struct exclude *exclude; struct path_pattern *pattern;
for (i = EXC_CMDL; i <= EXC_FILE; i++) { for (i = EXC_CMDL; i <= EXC_FILE; i++) {
group = &dir->exclude_list_group[i]; group = &dir->exclude_list_group[i];
for (j = group->nr - 1; j >= 0; j--) { for (j = group->nr - 1; j >= 0; j--) {
exclude = last_exclude_matching_from_list( pattern = last_exclude_matching_from_list(
pathname, pathlen, basename, dtype_p, pathname, pathlen, basename, dtype_p,
&group->el[j], istate); &group->el[j], istate);
if (exclude) if (pattern)
return exclude; return pattern;
} }
} }
return NULL; return NULL;
@ -1132,7 +1135,7 @@ static void prep_exclude(struct dir_struct *dir,
break; break;
el = &group->el[dir->exclude_stack->exclude_ix]; el = &group->el[dir->exclude_stack->exclude_ix];
dir->exclude_stack = stk->prev; dir->exclude_stack = stk->prev;
dir->exclude = NULL; dir->pattern = NULL;
free((char *)el->src); /* see strbuf_detach() below */ free((char *)el->src); /* see strbuf_detach() below */
clear_exclude_list(el); clear_exclude_list(el);
free(stk); free(stk);
@ -1140,7 +1143,7 @@ static void prep_exclude(struct dir_struct *dir,
} }
/* Skip traversing into sub directories if the parent is excluded */ /* Skip traversing into sub directories if the parent is excluded */
if (dir->exclude) if (dir->pattern)
return; return;
/* /*
@ -1189,15 +1192,15 @@ static void prep_exclude(struct dir_struct *dir,
if (stk->baselen) { if (stk->baselen) {
int dt = DT_DIR; int dt = DT_DIR;
dir->basebuf.buf[stk->baselen - 1] = 0; dir->basebuf.buf[stk->baselen - 1] = 0;
dir->exclude = last_exclude_matching_from_lists(dir, dir->pattern = last_exclude_matching_from_lists(dir,
istate, istate,
dir->basebuf.buf, stk->baselen - 1, dir->basebuf.buf, stk->baselen - 1,
dir->basebuf.buf + current, &dt); dir->basebuf.buf + current, &dt);
dir->basebuf.buf[stk->baselen - 1] = '/'; dir->basebuf.buf[stk->baselen - 1] = '/';
if (dir->exclude && if (dir->pattern &&
dir->exclude->flags & EXC_FLAG_NEGATIVE) dir->pattern->flags & EXC_FLAG_NEGATIVE)
dir->exclude = NULL; dir->pattern = NULL;
if (dir->exclude) { if (dir->pattern) {
dir->exclude_stack = stk; dir->exclude_stack = stk;
return; return;
} }
@ -1223,7 +1226,7 @@ static void prep_exclude(struct dir_struct *dir,
/* /*
* dir->basebuf gets reused by the traversal, but we * dir->basebuf gets reused by the traversal, but we
* need fname to remain unchanged to ensure the src * need fname to remain unchanged to ensure the src
* member of each struct exclude correctly * member of each struct path_pattern correctly
* back-references its source file. Other invocations * back-references its source file. Other invocations
* of add_exclude_list provide stable strings, so we * of add_exclude_list provide stable strings, so we
* strbuf_detach() and free() here in the caller. * strbuf_detach() and free() here in the caller.
@ -1266,7 +1269,7 @@ static void prep_exclude(struct dir_struct *dir,
* Returns the exclude_list element which matched, or NULL for * Returns the exclude_list element which matched, or NULL for
* undecided. * undecided.
*/ */
struct exclude *last_exclude_matching(struct dir_struct *dir, struct path_pattern *last_exclude_matching(struct dir_struct *dir,
struct index_state *istate, struct index_state *istate,
const char *pathname, const char *pathname,
int *dtype_p) int *dtype_p)
@ -1277,8 +1280,8 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,
prep_exclude(dir, istate, pathname, basename-pathname); prep_exclude(dir, istate, pathname, basename-pathname);
if (dir->exclude) if (dir->pattern)
return dir->exclude; return dir->pattern;
return last_exclude_matching_from_lists(dir, istate, pathname, pathlen, return last_exclude_matching_from_lists(dir, istate, pathname, pathlen,
basename, dtype_p); basename, dtype_p);
@ -1292,10 +1295,10 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,
int is_excluded(struct dir_struct *dir, struct index_state *istate, int is_excluded(struct dir_struct *dir, struct index_state *istate,
const char *pathname, int *dtype_p) const char *pathname, int *dtype_p)
{ {
struct exclude *exclude = struct path_pattern *pattern =
last_exclude_matching(dir, istate, pathname, dtype_p); last_exclude_matching(dir, istate, pathname, dtype_p);
if (exclude) if (pattern)
return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1; return pattern->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
return 0; return 0;
} }

8
dir.h
View file

@ -16,7 +16,7 @@ struct dir_entry {
#define EXC_FLAG_MUSTBEDIR 8 #define EXC_FLAG_MUSTBEDIR 8
#define EXC_FLAG_NEGATIVE 16 #define EXC_FLAG_NEGATIVE 16
struct exclude { struct path_pattern {
/* /*
* This allows callers of last_exclude_matching() etc. * This allows callers of last_exclude_matching() etc.
* to determine the origin of the matching pattern. * to determine the origin of the matching pattern.
@ -54,7 +54,7 @@ struct exclude_list {
/* origin of list, e.g. path to filename, or descriptive string */ /* origin of list, e.g. path to filename, or descriptive string */
const char *src; const char *src;
struct exclude **excludes; struct path_pattern **patterns;
}; };
/* /*
@ -191,7 +191,7 @@ struct dir_struct {
* matching exclude struct if the directory is excluded. * matching exclude struct if the directory is excluded.
*/ */
struct exclude_stack *exclude_stack; struct exclude_stack *exclude_stack;
struct exclude *exclude; struct path_pattern *pattern;
struct strbuf basebuf; struct strbuf basebuf;
/* Enable untracked file cache if set */ /* Enable untracked file cache if set */
@ -248,7 +248,7 @@ int match_pathname(const char *, int,
const char *, int, const char *, int,
const char *, int, int, unsigned); const char *, int, int, unsigned);
struct exclude *last_exclude_matching(struct dir_struct *dir, struct path_pattern *last_exclude_matching(struct dir_struct *dir,
struct index_state *istate, struct index_state *istate,
const char *name, int *dtype); const char *name, int *dtype);