dir: remove struct path_simplify
Teach simplify_away() and exclude_matches_pathspec() to handle struct pathspec directly, eliminating the need for the struct path_simplify. Also renamed the len parameter to pathlen in exclude_matches_pathspec() to match the parameter names used in simplify_away(). Signed-off-by: Brandon Williams <bmwill@google.com> Reviewed-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
2ec87741b2
commit
e1b8c7bdc0
165
dir.c
165
dir.c
@ -16,11 +16,6 @@
|
||||
#include "varint.h"
|
||||
#include "ewah/ewok.h"
|
||||
|
||||
struct path_simplify {
|
||||
int len;
|
||||
const char *path;
|
||||
};
|
||||
|
||||
/*
|
||||
* Tells read_directory_recursive how a file or directory should be treated.
|
||||
* Values are ordered by significance, e.g. if a directory contains both
|
||||
@ -50,7 +45,7 @@ struct cached_dir {
|
||||
|
||||
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
|
||||
const char *path, int len, struct untracked_cache_dir *untracked,
|
||||
int check_only, const struct path_simplify *simplify);
|
||||
int check_only, const struct pathspec *pathspec);
|
||||
static int get_dtype(struct dirent *de, const char *path, int len);
|
||||
|
||||
int fspathcmp(const char *a, const char *b)
|
||||
@ -1312,7 +1307,7 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
|
||||
static enum path_treatment treat_directory(struct dir_struct *dir,
|
||||
struct untracked_cache_dir *untracked,
|
||||
const char *dirname, int len, int baselen, int exclude,
|
||||
const struct path_simplify *simplify)
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
/* The "len-1" is to strip the final '/' */
|
||||
switch (directory_exists_in_index(dirname, len-1)) {
|
||||
@ -1341,7 +1336,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
|
||||
untracked = lookup_untracked(dir->untracked, untracked,
|
||||
dirname + baselen, len - baselen);
|
||||
return read_directory_recursive(dir, dirname, len,
|
||||
untracked, 1, simplify);
|
||||
untracked, 1, pathspec);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1349,24 +1344,33 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
|
||||
* reading - if the path cannot possibly be in the pathspec,
|
||||
* return true, and we'll skip it early.
|
||||
*/
|
||||
static int simplify_away(const char *path, int pathlen, const struct path_simplify *simplify)
|
||||
static int simplify_away(const char *path, int pathlen,
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
if (simplify) {
|
||||
for (;;) {
|
||||
const char *match = simplify->path;
|
||||
int len = simplify->len;
|
||||
int i;
|
||||
|
||||
if (!pathspec || !pathspec->nr)
|
||||
return 0;
|
||||
|
||||
GUARD_PATHSPEC(pathspec,
|
||||
PATHSPEC_FROMTOP |
|
||||
PATHSPEC_MAXDEPTH |
|
||||
PATHSPEC_LITERAL |
|
||||
PATHSPEC_GLOB |
|
||||
PATHSPEC_ICASE |
|
||||
PATHSPEC_EXCLUDE);
|
||||
|
||||
for (i = 0; i < pathspec->nr; i++) {
|
||||
const struct pathspec_item *item = &pathspec->items[i];
|
||||
int len = item->nowildcard_len;
|
||||
|
||||
if (!match)
|
||||
break;
|
||||
if (len > pathlen)
|
||||
len = pathlen;
|
||||
if (!memcmp(path, match, len))
|
||||
if (!ps_strncmp(item, item->match, path, len))
|
||||
return 0;
|
||||
simplify++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1380,20 +1384,34 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
|
||||
* 2. the path is a directory prefix of some element in the
|
||||
* pathspec
|
||||
*/
|
||||
static int exclude_matches_pathspec(const char *path, int len,
|
||||
const struct path_simplify *simplify)
|
||||
static int exclude_matches_pathspec(const char *path, int pathlen,
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
if (simplify) {
|
||||
for (; simplify->path; simplify++) {
|
||||
if (len == simplify->len
|
||||
&& !memcmp(path, simplify->path, len))
|
||||
int i;
|
||||
|
||||
if (!pathspec || !pathspec->nr)
|
||||
return 0;
|
||||
|
||||
GUARD_PATHSPEC(pathspec,
|
||||
PATHSPEC_FROMTOP |
|
||||
PATHSPEC_MAXDEPTH |
|
||||
PATHSPEC_LITERAL |
|
||||
PATHSPEC_GLOB |
|
||||
PATHSPEC_ICASE |
|
||||
PATHSPEC_EXCLUDE);
|
||||
|
||||
for (i = 0; i < pathspec->nr; i++) {
|
||||
const struct pathspec_item *item = &pathspec->items[i];
|
||||
int len = item->nowildcard_len;
|
||||
|
||||
if (len == pathlen &&
|
||||
!ps_strncmp(item, item->match, path, pathlen))
|
||||
return 1;
|
||||
if (len < simplify->len
|
||||
&& simplify->path[len] == '/'
|
||||
&& !memcmp(path, simplify->path, len))
|
||||
if (len > pathlen &&
|
||||
item->match[pathlen] == '/' &&
|
||||
!ps_strncmp(item, item->match, path, pathlen))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1460,7 +1478,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
|
||||
struct untracked_cache_dir *untracked,
|
||||
struct strbuf *path,
|
||||
int baselen,
|
||||
const struct path_simplify *simplify,
|
||||
const struct pathspec *pathspec,
|
||||
int dtype, struct dirent *de)
|
||||
{
|
||||
int exclude;
|
||||
@ -1512,7 +1530,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
|
||||
case DT_DIR:
|
||||
strbuf_addch(path, '/');
|
||||
return treat_directory(dir, untracked, path->buf, path->len,
|
||||
baselen, exclude, simplify);
|
||||
baselen, exclude, pathspec);
|
||||
case DT_REG:
|
||||
case DT_LNK:
|
||||
return exclude ? path_excluded : path_untracked;
|
||||
@ -1524,7 +1542,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,
|
||||
struct cached_dir *cdir,
|
||||
struct strbuf *path,
|
||||
int baselen,
|
||||
const struct path_simplify *simplify)
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
strbuf_setlen(path, baselen);
|
||||
if (!cdir->ucd) {
|
||||
@ -1541,7 +1559,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,
|
||||
* with check_only set.
|
||||
*/
|
||||
return read_directory_recursive(dir, path->buf, path->len,
|
||||
cdir->ucd, 1, simplify);
|
||||
cdir->ucd, 1, pathspec);
|
||||
/*
|
||||
* We get path_recurse in the first run when
|
||||
* directory_exists_in_index() returns index_nonexistent. We
|
||||
@ -1556,23 +1574,23 @@ static enum path_treatment treat_path(struct dir_struct *dir,
|
||||
struct cached_dir *cdir,
|
||||
struct strbuf *path,
|
||||
int baselen,
|
||||
const struct path_simplify *simplify)
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
int dtype;
|
||||
struct dirent *de = cdir->de;
|
||||
|
||||
if (!de)
|
||||
return treat_path_fast(dir, untracked, cdir, path,
|
||||
baselen, simplify);
|
||||
baselen, pathspec);
|
||||
if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
|
||||
return path_none;
|
||||
strbuf_setlen(path, baselen);
|
||||
strbuf_addstr(path, de->d_name);
|
||||
if (simplify_away(path->buf, path->len, simplify))
|
||||
if (simplify_away(path->buf, path->len, pathspec))
|
||||
return path_none;
|
||||
|
||||
dtype = DTYPE(de);
|
||||
return treat_one_path(dir, untracked, path, baselen, simplify, dtype, de);
|
||||
return treat_one_path(dir, untracked, path, baselen, pathspec, dtype, de);
|
||||
}
|
||||
|
||||
static void add_untracked(struct untracked_cache_dir *dir, const char *name)
|
||||
@ -1703,7 +1721,7 @@ static void close_cached_dir(struct cached_dir *cdir)
|
||||
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
|
||||
const char *base, int baselen,
|
||||
struct untracked_cache_dir *untracked, int check_only,
|
||||
const struct path_simplify *simplify)
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
struct cached_dir cdir;
|
||||
enum path_treatment state, subdir_state, dir_state = path_none;
|
||||
@ -1719,7 +1737,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
|
||||
|
||||
while (!read_cached_dir(&cdir)) {
|
||||
/* check how the file or directory should be treated */
|
||||
state = treat_path(dir, untracked, &cdir, &path, baselen, simplify);
|
||||
state = treat_path(dir, untracked, &cdir, &path,
|
||||
baselen, pathspec);
|
||||
|
||||
if (state > dir_state)
|
||||
dir_state = state;
|
||||
@ -1731,8 +1750,9 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
|
||||
path.buf + baselen,
|
||||
path.len - baselen);
|
||||
subdir_state =
|
||||
read_directory_recursive(dir, path.buf, path.len,
|
||||
ud, check_only, simplify);
|
||||
read_directory_recursive(dir, path.buf,
|
||||
path.len, ud,
|
||||
check_only, pathspec);
|
||||
if (subdir_state > dir_state)
|
||||
dir_state = subdir_state;
|
||||
}
|
||||
@ -1756,7 +1776,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
|
||||
else if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||
|
||||
((dir->flags & DIR_COLLECT_IGNORED) &&
|
||||
exclude_matches_pathspec(path.buf, path.len,
|
||||
simplify)))
|
||||
pathspec)))
|
||||
dir_add_ignored(dir, path.buf, path.len);
|
||||
break;
|
||||
|
||||
@ -1787,36 +1807,9 @@ static int cmp_name(const void *p1, const void *p2)
|
||||
return name_compare(e1->name, e1->len, e2->name, e2->len);
|
||||
}
|
||||
|
||||
static struct path_simplify *create_simplify(const char **pathspec)
|
||||
{
|
||||
int nr, alloc = 0;
|
||||
struct path_simplify *simplify = NULL;
|
||||
|
||||
if (!pathspec)
|
||||
return NULL;
|
||||
|
||||
for (nr = 0 ; ; nr++) {
|
||||
const char *match;
|
||||
ALLOC_GROW(simplify, nr + 1, alloc);
|
||||
match = *pathspec++;
|
||||
if (!match)
|
||||
break;
|
||||
simplify[nr].path = match;
|
||||
simplify[nr].len = simple_length(match);
|
||||
}
|
||||
simplify[nr].path = NULL;
|
||||
simplify[nr].len = 0;
|
||||
return simplify;
|
||||
}
|
||||
|
||||
static void free_simplify(struct path_simplify *simplify)
|
||||
{
|
||||
free(simplify);
|
||||
}
|
||||
|
||||
static int treat_leading_path(struct dir_struct *dir,
|
||||
const char *path, int len,
|
||||
const struct path_simplify *simplify)
|
||||
const struct pathspec *pathspec)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int baselen, rc = 0;
|
||||
@ -1840,9 +1833,9 @@ static int treat_leading_path(struct dir_struct *dir,
|
||||
strbuf_add(&sb, path, baselen);
|
||||
if (!is_directory(sb.buf))
|
||||
break;
|
||||
if (simplify_away(sb.buf, sb.len, simplify))
|
||||
if (simplify_away(sb.buf, sb.len, pathspec))
|
||||
break;
|
||||
if (treat_one_path(dir, NULL, &sb, baselen, simplify,
|
||||
if (treat_one_path(dir, NULL, &sb, baselen, pathspec,
|
||||
DT_DIR, NULL) == path_none)
|
||||
break; /* do not recurse into it */
|
||||
if (len <= baselen) {
|
||||
@ -2010,33 +2003,14 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
|
||||
return root;
|
||||
}
|
||||
|
||||
int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec)
|
||||
int read_directory(struct dir_struct *dir, const char *path,
|
||||
int len, const struct pathspec *pathspec)
|
||||
{
|
||||
struct path_simplify *simplify;
|
||||
struct untracked_cache_dir *untracked;
|
||||
|
||||
/*
|
||||
* Check out create_simplify()
|
||||
*/
|
||||
if (pathspec)
|
||||
GUARD_PATHSPEC(pathspec,
|
||||
PATHSPEC_FROMTOP |
|
||||
PATHSPEC_MAXDEPTH |
|
||||
PATHSPEC_LITERAL |
|
||||
PATHSPEC_GLOB |
|
||||
PATHSPEC_ICASE |
|
||||
PATHSPEC_EXCLUDE);
|
||||
|
||||
if (has_symlink_leading_path(path, len))
|
||||
return dir->nr;
|
||||
|
||||
/*
|
||||
* exclude patterns are treated like positive ones in
|
||||
* create_simplify. Usually exclude patterns should be a
|
||||
* subset of positive ones, which has no impacts on
|
||||
* create_simplify().
|
||||
*/
|
||||
simplify = create_simplify(pathspec ? pathspec->_raw : NULL);
|
||||
untracked = validate_untracked_cache(dir, len, pathspec);
|
||||
if (!untracked)
|
||||
/*
|
||||
@ -2044,9 +2018,8 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
|
||||
* e.g. prep_exclude()
|
||||
*/
|
||||
dir->untracked = NULL;
|
||||
if (!len || treat_leading_path(dir, path, len, simplify))
|
||||
read_directory_recursive(dir, path, len, untracked, 0, simplify);
|
||||
free_simplify(simplify);
|
||||
if (!len || treat_leading_path(dir, path, len, pathspec))
|
||||
read_directory_recursive(dir, path, len, untracked, 0, pathspec);
|
||||
QSORT(dir->entries, dir->nr, cmp_name);
|
||||
QSORT(dir->ignored, dir->ignored_nr, cmp_name);
|
||||
if (dir->untracked) {
|
||||
|
Loading…
Reference in New Issue
Block a user