dir: add generic "walk all files" helper
There is sometimes a need to visit every file within a directory, recursively. The main example is remove_dir_recursively(), though it has some extra flags that make it want to iterate over paths in a custom way. There is also the fill_directory() approach but that involves an index and a pathspec. This change adds a new for_each_file_in_dir() method that will be helpful in the next change. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>next
parent
a8077c1913
commit
1588e836bb
28
dir.c
28
dir.c
|
@ -30,6 +30,7 @@
|
|||
#include "read-cache-ll.h"
|
||||
#include "setup.h"
|
||||
#include "sparse-index.h"
|
||||
#include "strbuf.h"
|
||||
#include "submodule-config.h"
|
||||
#include "symlinks.h"
|
||||
#include "trace2.h"
|
||||
|
@ -87,6 +88,33 @@ struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp)
|
|||
return e;
|
||||
}
|
||||
|
||||
int for_each_file_in_dir(struct strbuf *path, file_iterator fn, const void *data)
|
||||
{
|
||||
struct dirent *e;
|
||||
int res = 0;
|
||||
size_t baselen = path->len;
|
||||
DIR *dir = opendir(path->buf);
|
||||
|
||||
if (!dir)
|
||||
return 0;
|
||||
|
||||
while (!res && (e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
|
||||
unsigned char dtype = get_dtype(e, path, 0);
|
||||
strbuf_setlen(path, baselen);
|
||||
strbuf_addstr(path, e->d_name);
|
||||
|
||||
if (dtype == DT_REG) {
|
||||
res = fn(path->buf, data);
|
||||
} else if (dtype == DT_DIR) {
|
||||
strbuf_addch(path, '/');
|
||||
res = for_each_file_in_dir(path, fn, data);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return res;
|
||||
}
|
||||
|
||||
int count_slashes(const char *s)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
|
14
dir.h
14
dir.h
|
@ -536,6 +536,20 @@ int get_sparse_checkout_patterns(struct pattern_list *pl);
|
|||
*/
|
||||
int remove_dir_recursively(struct strbuf *path, int flag);
|
||||
|
||||
/*
|
||||
* This function pointer type is called on each file discovered in
|
||||
* for_each_file_in_dir. The iteration stops if this method returns
|
||||
* non-zero.
|
||||
*/
|
||||
typedef int (*file_iterator)(const char *path, const void *data);
|
||||
|
||||
struct strbuf;
|
||||
/*
|
||||
* Given a directory path, recursively visit each file within, including
|
||||
* within subdirectories.
|
||||
*/
|
||||
int for_each_file_in_dir(struct strbuf *path, file_iterator fn, const void *data);
|
||||
|
||||
/*
|
||||
* Tries to remove the path, along with leading empty directories so long as
|
||||
* those empty directories are not startup_info->original_cwd. Ignores
|
||||
|
|
Loading…
Reference in New Issue