| 2696 | */ |
| 2697 | |
| 2698 | static enum path_treatment read_directory_recursive(struct dir_struct *dir, |
| 2699 | struct index_state *istate, const char *base, int baselen, |
| 2700 | struct untracked_cache_dir *untracked, int check_only, |
| 2701 | int stop_at_first_file, const struct pathspec *pathspec) |
| 2702 | { |
| 2703 | /* |
| 2704 | * WARNING: Do NOT recurse unless path_recurse is returned from |
| 2705 | * treat_path(). Recursing on any other return value |
| 2706 | * can result in exponential slowdown. |
| 2707 | */ |
| 2708 | struct cached_dir cdir; |
| 2709 | enum path_treatment state, subdir_state, dir_state = path_none; |
| 2710 | struct strbuf path = STRBUF_INIT; |
| 2711 | |
| 2712 | strbuf_add(&path, base, baselen); |
| 2713 | |
| 2714 | if (open_cached_dir(&cdir, dir, untracked, istate, &path, check_only)) |
| 2715 | goto out; |
| 2716 | dir->internal.visited_directories++; |
| 2717 | |
| 2718 | if (untracked) |
| 2719 | untracked->check_only = !!check_only; |
| 2720 | |
| 2721 | while (!read_cached_dir(&cdir)) { |
| 2722 | /* check how the file or directory should be treated */ |
| 2723 | state = treat_path(dir, untracked, &cdir, istate, &path, |
| 2724 | baselen, pathspec); |
| 2725 | dir->internal.visited_paths++; |
| 2726 | |
| 2727 | if (state > dir_state) |
| 2728 | dir_state = state; |
| 2729 | |
| 2730 | /* recurse into subdir if instructed by treat_path */ |
| 2731 | if (state == path_recurse) { |
| 2732 | struct untracked_cache_dir *ud; |
| 2733 | ud = lookup_untracked(dir->untracked, |
| 2734 | untracked, |
| 2735 | path.buf + baselen, |
| 2736 | path.len - baselen); |
| 2737 | subdir_state = |
| 2738 | read_directory_recursive(dir, istate, path.buf, |
| 2739 | path.len, ud, |
| 2740 | check_only, stop_at_first_file, pathspec); |
| 2741 | if (subdir_state > dir_state) |
| 2742 | dir_state = subdir_state; |
| 2743 | |
| 2744 | if (pathspec && |
| 2745 | !match_pathspec(istate, pathspec, path.buf, path.len, |
| 2746 | 0 /* prefix */, NULL, |
| 2747 | 0 /* do NOT special case dirs */)) |
| 2748 | state = path_none; |
| 2749 | } |
| 2750 | |
| 2751 | if (check_only) { |
| 2752 | if (stop_at_first_file) { |
| 2753 | /* |
| 2754 | * If stopping at first file, then |
| 2755 | * signal that a file was found by |
no test coverage detected