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) {