Calls proc with user_data for each entry of the directory dir_name, and returns true if every entry could be examined.
With recursive the walk goes into sub-directories too.
visit_files :: (
dir_name: string,
recursive: bool,
user_data: $T,
proc: (info: *File_Visit_Info, user_data: T),
visit_files := true,
visit_directories := false,
visit_symlinks := true,
follow_directory_symlinks := true
) -> bool
- The order is the file system's and is not sorted.
.and..are skipped. visit_files,visit_directoriesandvisit_symlinkspick whatprochears about. A link counts as a link whatever it points at, so withvisit_symlinksoff it is never reported as a file or a directory.- A directory is entered whether or not it is reported.
proccan stop that by settinginfo.descend_into_directorytofalse, which needsvisit_directoriesso thatprocsees the directory. follow_directory_symlinksdecides whether links to directories are entered. A directory that is already being walked further up is not entered again, so link cycles end. Two different paths to one directory are both walked.infoand its strings are valid only during the call. A link whose target is missing is reported as a link, with the details of the link itself.
A missing or unreadable dir_name returns false without calling proc. An entry whose details cannot be read is reported
with had_error set and makes the result false, but the walk goes on.
Parameters
- dir_name: string
- recursive: bool
- user_data: $T
- proc: (info: *File_Visit_Info, user_data: T)
- visit_files := true
- visit_directories := false
- visit_symlinks := true
- follow_directory_symlinks := true
Returns
- bool
#import "Extensions/Environment";
#import "File";
base := environment_variable("TMPDIR");
if base == "" base = environment_variable("TEMP");
if base == "" base = "/tmp";
root := tprint("%/jai-doc-visit-files", base);
defer {
file_delete(tprint("%/top", root));
file_delete(tprint("%/sub/leaf", root));
delete_directory(tprint("%/sub", root));
delete_directory(root);
}
assert(make_directory_if_it_does_not_exist(tprint("%/sub", root), recursive = true));
assert(write_entire_file(tprint("%/top", root), "top"));
assert(write_entire_file(tprint("%/sub/leaf", root), "leaf"));
Count :: struct {
files: int;
directories: int;
bytes: s64;
}
count: Count;
tally :: (info: *File_Visit_Info, count: *Count) {
if info.is_directory count.directories += 1;
else {
count.files += 1;
count.bytes += info.size;
}
}
assert(visit_files(root, true, *count, tally, visit_directories = true));
assert(count.files == 2 && count.directories == 1 && count.bytes == 7);
count = .{};
assert(visit_files(root, false, *count, tally)); // top level only
assert(count.files == 1);
assert(!visit_files(tprint("%/missing", root), false, *count, tally));