untracked cache: make a wrapper around {open,read,close}dir()
This allows us to feed different info to read_directory_recursive() based on untracked cache in the next patch. Helped-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Mar 8, 2015 at 17:12 UTC
cf7c61484f77f6212b52c7e9fdce7bfbbb4eb854
1 file changed
+47
-8
dir.c
+47
-8
@@ -31,6 +31,15 @@ enum path_treatment {
31
path_untracked
32
};
33
34
+/*
35
+ * Support data structure for our opendir/readdir/closedir wrappers
36
+ */
37
+struct cached_dir {
38
+ DIR *fdir;
39
+ struct untracked_cache_dir *untracked;
40
+ struct dirent *de;
41
+};
42
+
43
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
44
const char *path, int len, struct untracked_cache_dir *untracked,
45
int check_only, const struct path_simplify *simplify);
@@ -1418,12 +1427,13 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1427
1428
static enum path_treatment treat_path(struct dir_struct *dir,
1429
struct untracked_cache_dir *untracked,
1421
- struct dirent *de,
1430
+ struct cached_dir *cdir,
1431
struct strbuf *path,
1432
int baselen,
1433
const struct path_simplify *simplify)
1434
{
1435
int dtype;
1436
+ struct dirent *de = cdir->de;
1437
1438
if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
1439
return path_none;
@@ -1445,6 +1455,37 @@ static void add_untracked(struct untracked_cache_dir *dir, const char *name)
1455
dir->untracked[dir->untracked_nr++] = xstrdup(name);
1456
}
1457
1458
+static int open_cached_dir(struct cached_dir *cdir,
1459
+ struct dir_struct *dir,
1460
+ struct untracked_cache_dir *untracked,
1461
+ struct strbuf *path,
1462
+ int check_only)
1463
+{
1464
+ memset(cdir, 0, sizeof(*cdir));
1465
+ cdir->untracked = untracked;
1466
+ cdir->fdir = opendir(path->len ? path->buf : ".");
1467
+ if (!cdir->fdir)
1468
+ return -1;
1469
+ return 0;
1470
+}
1471
+
1472
+static int read_cached_dir(struct cached_dir *cdir)
1473
+{
1474
+ if (cdir->fdir) {
1475
+ cdir->de = readdir(cdir->fdir);
1476
+ if (!cdir->de)
1477
+ return -1;
1478
+ return 0;
1479
+ }
1480
+ return -1;
1481
+}
1482
+
1483
+static void close_cached_dir(struct cached_dir *cdir)
1484
+{
1485
+ if (cdir->fdir)
1486
+ closedir(cdir->fdir);
1487
+}
1488
+
1489
/*
1490
* Read a directory tree. We currently ignore anything but
1491
* directories, regular files and symlinks. That's because git
@@ -1461,23 +1502,21 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1502
struct untracked_cache_dir *untracked, int check_only,
1503
const struct path_simplify *simplify)
1504
{
1464
- DIR *fdir;
1505
+ struct cached_dir cdir;
1506
enum path_treatment state, subdir_state, dir_state = path_none;
1466
- struct dirent *de;
1507
struct strbuf path = STRBUF_INIT;
1508
1509
strbuf_add(&path, base, baselen);
1510
1471
- fdir = opendir(path.len ? path.buf : ".");
1472
- if (!fdir)
1511
+ if (open_cached_dir(&cdir, dir, untracked, &path, check_only))
1512
goto out;
1513
1514
if (untracked)
1515
untracked->check_only = !!check_only;
1516
1478
- while ((de = readdir(fdir)) != NULL) {
1517
+ while (!read_cached_dir(&cdir)) {
1518
/* check how the file or directory should be treated */
1480
- state = treat_path(dir, untracked, de, &path, baselen, simplify);
1519
+ state = treat_path(dir, untracked, &cdir, &path, baselen, simplify);
1520
1521
if (state > dir_state)
1522
dir_state = state;
@@ -1530,7 +1569,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1569
break;
1570
}
1571
}
1533
- closedir(fdir);
1572
+ close_cached_dir(&cdir);
1573
out:
1574
strbuf_release(&path);
1575