saner recursive dir iteration ordering

master
Daniel Kolesa 2018-04-16 01:10:03 +02:00
parent ad635c8a23
commit 1a13f71390
1 changed files with 27 additions and 30 deletions

View File

@ -88,47 +88,44 @@ OSTD_EXPORT void recursive_directory_range::close() noexcept {
} }
OSTD_EXPORT void recursive_directory_range::read_next() { OSTD_EXPORT void recursive_directory_range::read_next() {
directory_entry curd;
if (p_stack->empty()) { if (p_stack->empty()) {
return; return;
} }
dir_read_next(static_cast<DIR *>(p_stack->top()), curd, p_dir);
struct stat sb; struct stat sb;
/* check if dir and recurse maybe */ if (stat(p_current.path().string().data(), &sb) < 0) {
while (!curd.path().empty()) { /* FIXME: throw */
if (stat(curd.path().string().data(), &sb) < 0) { abort();
/* FIXME: throw */ }
if (S_ISDIR(sb.st_mode)) {
/* directory, recurse into it and if it contains stuff, return */
DIR *nd = opendir(p_current.path().string().data());
if (!nd) {
abort(); abort();
} }
if (S_ISDIR(sb.st_mode)) { directory_entry based = p_current, curd;
/* directory, recurse into it */ dir_read_next(nd, curd, based);
DIR *nd = opendir(curd.path().string().data()); if (!curd.path().empty()) {
if (!nd) { p_dir = based;
abort();
}
p_dir = curd;
p_stack->push(nd); p_stack->push(nd);
dir_read_next(nd, curd, p_dir);
p_current = curd;
if (curd.path().empty()) {
break;
} else {
return;
}
} else {
/* not a dir, stick with it */
p_current = curd; p_current = curd;
return; return;
} else {
closedir(nd);
} }
} }
/* empty result - done with a dir, pop */ /* didn't recurse into a directory, go to next file */
closedir(static_cast<DIR *>(p_stack->top())); dir_read_next(static_cast<DIR *>(p_stack->top()), p_current, p_dir);
p_stack->pop(); /* end of dir, pop while at it */
if (!p_stack->empty()) { if (p_current.path().empty()) {
p_current.assign(p_dir); closedir(static_cast<DIR *>(p_stack->top()));
p_dir.remove_name(); p_stack->pop();
} else { if (!p_stack->empty()) {
p_current.clear(); /* got back to another dir, read next so it's valid */
p_dir.remove_name();
dir_read_next(static_cast<DIR *>(p_stack->top()), p_current, p_dir);
} else {
p_current.clear();
}
} }
} }