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>
Brandon Williams committed
Jan 4, 2017 at 10:03 UTC
e1b8c7bdc0ceba64e4d9fa91b951af3d1de18870
1 file changed
+76
-103
dir.c
+76
-103
@@ -16,11 +16,6 @@
16
#include "varint.h"
17
#include "ewah/ewok.h"
18
19
-struct path_simplify {
20
- int len;
21
- const char *path;
22
-};
23
-
19
/*
20
* Tells read_directory_recursive how a file or directory should be treated.
21
* Values are ordered by significance, e.g. if a directory contains both
@@ -50,7 +45,7 @@ struct cached_dir {
45
46
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
47
const char *path, int len, struct untracked_cache_dir *untracked,
53
- int check_only, const struct path_simplify *simplify);
48
+ int check_only, const struct pathspec *pathspec);
49
static int get_dtype(struct dirent *de, const char *path, int len);
50
51
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)
1307
static enum path_treatment treat_directory(struct dir_struct *dir,
1308
struct untracked_cache_dir *untracked,
1309
const char *dirname, int len, int baselen, int exclude,
1315
- const struct path_simplify *simplify)
1310
+ const struct pathspec *pathspec)
1311
{
1312
/* The "len-1" is to strip the final '/' */
1313
switch (directory_exists_in_index(dirname, len-1)) {
@@ -1341,7 +1336,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1336
untracked = lookup_untracked(dir->untracked, untracked,
1337
dirname + baselen, len - baselen);
1338
return read_directory_recursive(dir, dirname, len,
1344
- untracked, 1, simplify);
1339
+ untracked, 1, pathspec);
1340
}
1341
1342
/*
@@ -1349,24 +1344,33 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1344
* reading - if the path cannot possibly be in the pathspec,
1345
* return true, and we'll skip it early.
1346
*/
1352
-static int simplify_away(const char *path, int pathlen, const struct path_simplify *simplify)
1347
+static int simplify_away(const char *path, int pathlen,
1348
+ const struct pathspec *pathspec)
1349
{
1354
- if (simplify) {
1355
- for (;;) {
1356
- const char *match = simplify->path;
1357
- int len = simplify->len;
1350
+ int i;
1351
1359
- if (!match)
1360
- break;
1361
- if (len > pathlen)
1362
- len = pathlen;
1363
- if (!memcmp(path, match, len))
1364
- return 0;
1365
- simplify++;
1366
- }
1367
- return 1;
1352
+ if (!pathspec || !pathspec->nr)
1353
+ return 0;
1354
+
1355
+ GUARD_PATHSPEC(pathspec,
1356
+ PATHSPEC_FROMTOP |
1357
+ PATHSPEC_MAXDEPTH |
1358
+ PATHSPEC_LITERAL |
1359
+ PATHSPEC_GLOB |
1360
+ PATHSPEC_ICASE |
1361
+ PATHSPEC_EXCLUDE);
1362
+
1363
+ for (i = 0; i < pathspec->nr; i++) {
1364
+ const struct pathspec_item *item = &pathspec->items[i];
1365
+ int len = item->nowildcard_len;
1366
+
1367
+ if (len > pathlen)
1368
+ len = pathlen;
1369
+ if (!ps_strncmp(item, item->match, path, len))
1370
+ return 0;
1371
}
1369
- return 0;
1372
+
1373
+ return 1;
1374
}
1375
1376
/*
@@ -1380,19 +1384,33 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
1384
* 2. the path is a directory prefix of some element in the
1385
* pathspec
1386
*/
1383
-static int exclude_matches_pathspec(const char *path, int len,
1384
- const struct path_simplify *simplify)
1385
-{
1386
- if (simplify) {
1387
- for (; simplify->path; simplify++) {
1388
- if (len == simplify->len
1389
- && !memcmp(path, simplify->path, len))
1390
- return 1;
1391
- if (len < simplify->len
1392
- && simplify->path[len] == '/'
1393
- && !memcmp(path, simplify->path, len))
1394
- return 1;
1395
- }
1387
+static int exclude_matches_pathspec(const char *path, int pathlen,
1388
+ const struct pathspec *pathspec)
1389
+{
1390
+ int i;
1391
+
1392
+ if (!pathspec || !pathspec->nr)
1393
+ return 0;
1394
+
1395
+ GUARD_PATHSPEC(pathspec,
1396
+ PATHSPEC_FROMTOP |
1397
+ PATHSPEC_MAXDEPTH |
1398
+ PATHSPEC_LITERAL |
1399
+ PATHSPEC_GLOB |
1400
+ PATHSPEC_ICASE |
1401
+ PATHSPEC_EXCLUDE);
1402
+
1403
+ for (i = 0; i < pathspec->nr; i++) {
1404
+ const struct pathspec_item *item = &pathspec->items[i];
1405
+ int len = item->nowildcard_len;
1406
+
1407
+ if (len == pathlen &&
1408
+ !ps_strncmp(item, item->match, path, pathlen))
1409
+ return 1;
1410
+ if (len > pathlen &&
1411
+ item->match[pathlen] == '/' &&
1412
+ !ps_strncmp(item, item->match, path, pathlen))
1413
+ return 1;
1414
}
1415
return 0;
1416
}
@@ -1460,7 +1478,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1478
struct untracked_cache_dir *untracked,
1479
struct strbuf *path,
1480
int baselen,
1463
- const struct path_simplify *simplify,
1481
+ const struct pathspec *pathspec,
1482
int dtype, struct dirent *de)
1483
{
1484
int exclude;
@@ -1512,7 +1530,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1530
case DT_DIR:
1531
strbuf_addch(path, '/');
1532
return treat_directory(dir, untracked, path->buf, path->len,
1515
- baselen, exclude, simplify);
1533
+ baselen, exclude, pathspec);
1534
case DT_REG:
1535
case DT_LNK:
1536
return exclude ? path_excluded : path_untracked;
@@ -1524,7 +1542,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,
1542
struct cached_dir *cdir,
1543
struct strbuf *path,
1544
int baselen,
1527
- const struct path_simplify *simplify)
1545
+ const struct pathspec *pathspec)
1546
{
1547
strbuf_setlen(path, baselen);
1548
if (!cdir->ucd) {
@@ -1541,7 +1559,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,
1559
* with check_only set.
1560
*/
1561
return read_directory_recursive(dir, path->buf, path->len,
1544
- cdir->ucd, 1, simplify);
1562
+ cdir->ucd, 1, pathspec);
1563
/*
1564
* We get path_recurse in the first run when
1565
* directory_exists_in_index() returns index_nonexistent. We
@@ -1556,23 +1574,23 @@ static enum path_treatment treat_path(struct dir_struct *dir,
1574
struct cached_dir *cdir,
1575
struct strbuf *path,
1576
int baselen,
1559
- const struct path_simplify *simplify)
1577
+ const struct pathspec *pathspec)
1578
{
1579
int dtype;
1580
struct dirent *de = cdir->de;
1581
1582
if (!de)
1583
return treat_path_fast(dir, untracked, cdir, path,
1566
- baselen, simplify);
1584
+ baselen, pathspec);
1585
if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
1586
return path_none;
1587
strbuf_setlen(path, baselen);
1588
strbuf_addstr(path, de->d_name);
1571
- if (simplify_away(path->buf, path->len, simplify))
1589
+ if (simplify_away(path->buf, path->len, pathspec))
1590
return path_none;
1591
1592
dtype = DTYPE(de);
1575
- return treat_one_path(dir, untracked, path, baselen, simplify, dtype, de);
1593
+ return treat_one_path(dir, untracked, path, baselen, pathspec, dtype, de);
1594
}
1595
1596
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)
1721
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1722
const char *base, int baselen,
1723
struct untracked_cache_dir *untracked, int check_only,
1706
- const struct path_simplify *simplify)
1724
+ const struct pathspec *pathspec)
1725
{
1726
struct cached_dir cdir;
1727
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,
1737
1738
while (!read_cached_dir(&cdir)) {
1739
/* check how the file or directory should be treated */
1722
- state = treat_path(dir, untracked, &cdir, &path, baselen, simplify);
1740
+ state = treat_path(dir, untracked, &cdir, &path,
1741
+ baselen, pathspec);
1742
1743
if (state > dir_state)
1744
dir_state = state;
@@ -1731,8 +1750,9 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1750
path.buf + baselen,
1751
path.len - baselen);
1752
subdir_state =
1734
- read_directory_recursive(dir, path.buf, path.len,
1735
- ud, check_only, simplify);
1753
+ read_directory_recursive(dir, path.buf,
1754
+ path.len, ud,
1755
+ check_only, pathspec);
1756
if (subdir_state > dir_state)
1757
dir_state = subdir_state;
1758
}
@@ -1756,7 +1776,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1776
else if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||
1777
((dir->flags & DIR_COLLECT_IGNORED) &&
1778
exclude_matches_pathspec(path.buf, path.len,
1759
- simplify)))
1779
+ pathspec)))
1780
dir_add_ignored(dir, path.buf, path.len);
1781
break;
1782
@@ -1787,36 +1807,9 @@ static int cmp_name(const void *p1, const void *p2)
1807
return name_compare(e1->name, e1->len, e2->name, e2->len);
1808
}
1809
1790
-static struct path_simplify *create_simplify(const char **pathspec)
1791
-{
1792
- int nr, alloc = 0;
1793
- struct path_simplify *simplify = NULL;
1794
-
1795
- if (!pathspec)
1796
- return NULL;
1797
-
1798
- for (nr = 0 ; ; nr++) {
1799
- const char *match;
1800
- ALLOC_GROW(simplify, nr + 1, alloc);
1801
- match = *pathspec++;
1802
- if (!match)
1803
- break;
1804
- simplify[nr].path = match;
1805
- simplify[nr].len = simple_length(match);
1806
- }
1807
- simplify[nr].path = NULL;
1808
- simplify[nr].len = 0;
1809
- return simplify;
1810
-}
1811
-
1812
-static void free_simplify(struct path_simplify *simplify)
1813
-{
1814
- free(simplify);
1815
-}
1816
-
1810
static int treat_leading_path(struct dir_struct *dir,
1811
const char *path, int len,
1819
- const struct path_simplify *simplify)
1812
+ const struct pathspec *pathspec)
1813
{
1814
struct strbuf sb = STRBUF_INIT;
1815
int baselen, rc = 0;
@@ -1840,9 +1833,9 @@ static int treat_leading_path(struct dir_struct *dir,
1833
strbuf_add(&sb, path, baselen);
1834
if (!is_directory(sb.buf))
1835
break;
1843
- if (simplify_away(sb.buf, sb.len, simplify))
1836
+ if (simplify_away(sb.buf, sb.len, pathspec))
1837
break;
1845
- if (treat_one_path(dir, NULL, &sb, baselen, simplify,
1838
+ if (treat_one_path(dir, NULL, &sb, baselen, pathspec,
1839
DT_DIR, NULL) == path_none)
1840
break; /* do not recurse into it */
1841
if (len <= baselen) {
@@ -2010,33 +2003,14 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
2003
return root;
2004
}
2005
2013
-int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec)
2006
+int read_directory(struct dir_struct *dir, const char *path,
2007
+ int len, const struct pathspec *pathspec)
2008
{
2015
- struct path_simplify *simplify;
2009
struct untracked_cache_dir *untracked;
2010
2018
- /*
2019
- * Check out create_simplify()
2020
- */
2021
- if (pathspec)
2022
- GUARD_PATHSPEC(pathspec,
2023
- PATHSPEC_FROMTOP |
2024
- PATHSPEC_MAXDEPTH |
2025
- PATHSPEC_LITERAL |
2026
- PATHSPEC_GLOB |
2027
- PATHSPEC_ICASE |
2028
- PATHSPEC_EXCLUDE);
2029
-
2011
if (has_symlink_leading_path(path, len))
2012
return dir->nr;
2013
2033
- /*
2034
- * exclude patterns are treated like positive ones in
2035
- * create_simplify. Usually exclude patterns should be a
2036
- * subset of positive ones, which has no impacts on
2037
- * create_simplify().
2038
- */
2039
- simplify = create_simplify(pathspec ? pathspec->_raw : NULL);
2014
untracked = validate_untracked_cache(dir, len, pathspec);
2015
if (!untracked)
2016
/*
@@ -2044,9 +2018,8 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
2018
* e.g. prep_exclude()
2019
*/
2020
dir->untracked = NULL;
2047
- if (!len || treat_leading_path(dir, path, len, simplify))
2048
- read_directory_recursive(dir, path, len, untracked, 0, simplify);
2049
- free_simplify(simplify);
2021
+ if (!len || treat_leading_path(dir, path, len, pathspec))
2022
+ read_directory_recursive(dir, path, len, untracked, 0, pathspec);
2023
QSORT(dir->entries, dir->nr, cmp_name);
2024
QSORT(dir->ignored, dir->ignored_nr, cmp_name);
2025
if (dir->untracked) {