[VFS] Add support for "no_push" to VFS recursive iterators.

The "regular" file system has a useful feature that makes it possible to
stop recursing when using the recursive directory iterators. This
functionality was missing for the VFS recursive iterator and this patch
adds that.

Differential revision: https://reviews.llvm.org/D53465

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345793 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jonas Devlieghere
2018-10-31 23:36:10 +00:00
parent 585b6667b4
commit d886fa4497
3 changed files with 115 additions and 20 deletions

View File

@@ -2157,28 +2157,33 @@ vfs::recursive_directory_iterator::recursive_directory_iterator(
: FS(&FS_) {
directory_iterator I = FS->dir_begin(Path, EC);
if (I != directory_iterator()) {
State = std::make_shared<IterState>();
State->push(I);
State = std::make_shared<detail::RecDirIterState>();
State->Stack.push(I);
}
}
vfs::recursive_directory_iterator &
recursive_directory_iterator::increment(std::error_code &EC) {
assert(FS && State && !State->empty() && "incrementing past end");
assert(!State->top()->path().empty() && "non-canonical end iterator");
assert(FS && State && !State->Stack.empty() && "incrementing past end");
assert(!State->Stack.top()->path().empty() && "non-canonical end iterator");
vfs::directory_iterator End;
if (State->top()->type() == sys::fs::file_type::directory_file) {
vfs::directory_iterator I = FS->dir_begin(State->top()->path(), EC);
if (I != End) {
State->push(I);
return *this;
if (State->HasNoPushRequest)
State->HasNoPushRequest = false;
else {
if (State->Stack.top()->type() == sys::fs::file_type::directory_file) {
vfs::directory_iterator I = FS->dir_begin(State->Stack.top()->path(), EC);
if (I != End) {
State->Stack.push(I);
return *this;
}
}
}
while (!State->empty() && State->top().increment(EC) == End)
State->pop();
while (!State->Stack.empty() && State->Stack.top().increment(EC) == End)
State->Stack.pop();
if (State->empty())
if (State->Stack.empty())
State.reset(); // end iterator
return *this;