@@ -3,30 +3,55 @@ using namespace llvm;
33
44#include " utils.h"
55
6+ #include < set>
67#include < vector>
78
89void GetFilesInFolder (std::string folder,
910 bool recursive,
1011 bool dir_prefix,
1112 const std::function<void (const std::string&)>& handler) {
1213 EnsureEndsInSlash (folder);
13- std::vector<std::string> st{folder};
14- while (st.size ()) {
15- std::error_code ec;
16- folder = st.back ();
17- st.pop_back ();
18- for (sys::fs::directory_iterator I (folder, ec), E; I != E && !ec;
19- I.increment (ec)) {
20- auto Status = I->status ();
21- if (!Status) continue ;
22- std::string path = I->path (), filename = sys::path::filename (path);
23- if (filename[0 ] != ' .' || filename == " .ccls" ) {
24- if (sys::fs::is_regular_file (*Status)) {
14+ sys::fs::file_status Status;
15+ if (sys::fs::status (folder, Status, true ))
16+ return ;
17+ sys::fs::UniqueID ID ;
18+ std::vector<std::string> curr{folder};
19+ std::vector<std::pair<std::string, sys::fs::file_status>> succ;
20+ std::set<sys::fs::UniqueID> seen{Status.getUniqueID ()};
21+ while (curr.size () || succ.size ()) {
22+ if (curr.empty ()) {
23+ for (auto & it : succ)
24+ if (!seen.count (it.second .getUniqueID ()))
25+ curr.push_back (std::move (it.first ));
26+ succ.clear ();
27+ } else {
28+ std::error_code ec;
29+ std::string folder1 = curr.back ();
30+ curr.pop_back ();
31+ for (sys::fs::directory_iterator I (folder1, ec, false ), E; I != E && !ec;
32+ I.increment (ec)) {
33+ std::string path = I->path (), filename = sys::path::filename (path);
34+ if ((filename[0 ] == ' .' && filename != " .ccls" ) ||
35+ sys::fs::status (path, Status, false ))
36+ continue ;
37+ if (sys::fs::is_symlink_file (Status)) {
38+ if (sys::fs::status (path, Status, true ))
39+ continue ;
40+ if (sys::fs::is_directory (Status)) {
41+ if (recursive)
42+ succ.emplace_back (path, Status);
43+ continue ;
44+ }
45+ }
46+ if (sys::fs::is_regular_file (Status)) {
2547 if (!dir_prefix)
2648 path = path.substr (folder.size ());
2749 handler (path);
28- } else if (recursive && sys::fs::is_directory (*Status))
29- st.push_back (path);
50+ } else if (recursive && sys::fs::is_directory (Status) &&
51+ !seen.count (ID = Status.getUniqueID ())) {
52+ curr.push_back (path);
53+ seen.insert (ID );
54+ }
3055 }
3156 }
3257 }
0 commit comments