Skip to content

Commit 53cc535

Browse files
committed
read_directory_recursive(): refactor handling of a single path into a separate function
Primarily because I want to reuse it in a separate function later, but this de-dents a huge function by one tabstop which by itself is an improvement as well. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 472e746 commit 53cc535

File tree

1 file changed

+90
-63
lines changed

1 file changed

+90
-63
lines changed

dir.c

Lines changed: 90 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,84 @@ static int get_dtype(struct dirent *de, const char *path, int len)
625625
return dtype;
626626
}
627627

628+
enum path_treatment {
629+
path_ignored,
630+
path_handled,
631+
path_recurse,
632+
};
633+
634+
static enum path_treatment treat_path(struct dir_struct *dir,
635+
struct dirent *de,
636+
char *path, int path_max,
637+
int baselen,
638+
const struct path_simplify *simplify,
639+
int *len)
640+
{
641+
int dtype, exclude;
642+
643+
if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
644+
return path_ignored;
645+
*len = strlen(de->d_name);
646+
/* Ignore overly long pathnames! */
647+
if (*len + baselen + 8 > path_max)
648+
return path_ignored;
649+
memcpy(path + baselen, de->d_name, *len + 1);
650+
*len += baselen;
651+
if (simplify_away(path, *len, simplify))
652+
return path_ignored;
653+
654+
dtype = DTYPE(de);
655+
exclude = excluded(dir, path, &dtype);
656+
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
657+
&& in_pathspec(path, *len, simplify))
658+
dir_add_ignored(dir, path, *len);
659+
660+
/*
661+
* Excluded? If we don't explicitly want to show
662+
* ignored files, ignore it
663+
*/
664+
if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
665+
return path_ignored;
666+
667+
if (dtype == DT_UNKNOWN)
668+
dtype = get_dtype(de, path, *len);
669+
670+
/*
671+
* Do we want to see just the ignored files?
672+
* We still need to recurse into directories,
673+
* even if we don't ignore them, since the
674+
* directory may contain files that we do..
675+
*/
676+
if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
677+
if (dtype != DT_DIR)
678+
return path_ignored;
679+
}
680+
681+
switch (dtype) {
682+
default:
683+
return path_ignored;
684+
case DT_DIR:
685+
memcpy(path + *len, "/", 2);
686+
(*len)++;
687+
switch (treat_directory(dir, path, *len, simplify)) {
688+
case show_directory:
689+
if (exclude != !!(dir->flags
690+
& DIR_SHOW_IGNORED))
691+
return path_ignored;
692+
break;
693+
case recurse_into_directory:
694+
return path_recurse;
695+
case ignore_directory:
696+
return path_ignored;
697+
}
698+
break;
699+
case DT_REG:
700+
case DT_LNK:
701+
break;
702+
}
703+
return path_handled;
704+
}
705+
628706
/*
629707
* Read a directory tree. We currently ignore anything but
630708
* directories, regular files and symlinks. That's because git
@@ -634,7 +712,10 @@ static int get_dtype(struct dirent *de, const char *path, int len)
634712
* Also, we ignore the name ".git" (even if it is not a directory).
635713
* That likely will not change.
636714
*/
637-
static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
715+
static int read_directory_recursive(struct dir_struct *dir,
716+
const char *base, int baselen,
717+
int check_only,
718+
const struct path_simplify *simplify)
638719
{
639720
DIR *fdir = opendir(*base ? base : ".");
640721
int contents = 0;
@@ -645,70 +726,16 @@ static int read_directory_recursive(struct dir_struct *dir, const char *base, in
645726
memcpy(path, base, baselen);
646727

647728
while ((de = readdir(fdir)) != NULL) {
648-
int len, dtype;
649-
int exclude;
650-
651-
if (is_dot_or_dotdot(de->d_name) ||
652-
!strcmp(de->d_name, ".git"))
653-
continue;
654-
len = strlen(de->d_name);
655-
/* Ignore overly long pathnames! */
656-
if (len + baselen + 8 > sizeof(path))
729+
int len;
730+
switch (treat_path(dir, de, path, sizeof(path),
731+
baselen, simplify, &len)) {
732+
case path_recurse:
733+
contents += read_directory_recursive
734+
(dir, path, len, 0, simplify);
657735
continue;
658-
memcpy(path + baselen, de->d_name, len+1);
659-
len = baselen + len;
660-
if (simplify_away(path, len, simplify))
736+
case path_ignored:
661737
continue;
662-
663-
dtype = DTYPE(de);
664-
exclude = excluded(dir, path, &dtype);
665-
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
666-
&& in_pathspec(path, len, simplify))
667-
dir_add_ignored(dir, path,len);
668-
669-
/*
670-
* Excluded? If we don't explicitly want to show
671-
* ignored files, ignore it
672-
*/
673-
if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
674-
continue;
675-
676-
if (dtype == DT_UNKNOWN)
677-
dtype = get_dtype(de, path, len);
678-
679-
/*
680-
* Do we want to see just the ignored files?
681-
* We still need to recurse into directories,
682-
* even if we don't ignore them, since the
683-
* directory may contain files that we do..
684-
*/
685-
if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
686-
if (dtype != DT_DIR)
687-
continue;
688-
}
689-
690-
switch (dtype) {
691-
default:
692-
continue;
693-
case DT_DIR:
694-
memcpy(path + len, "/", 2);
695-
len++;
696-
switch (treat_directory(dir, path, len, simplify)) {
697-
case show_directory:
698-
if (exclude != !!(dir->flags
699-
& DIR_SHOW_IGNORED))
700-
continue;
701-
break;
702-
case recurse_into_directory:
703-
contents += read_directory_recursive(dir,
704-
path, len, 0, simplify);
705-
continue;
706-
case ignore_directory:
707-
continue;
708-
}
709-
break;
710-
case DT_REG:
711-
case DT_LNK:
738+
case path_handled:
712739
break;
713740
}
714741
contents++;

0 commit comments

Comments
 (0)