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