File: filesystem.cc

package info (click to toggle)
ccls 0.20210330-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,340 kB
  • sloc: cpp: 13,398; python: 152; makefile: 15; objc: 15; ansic: 1
file content (60 lines) | stat: -rw-r--r-- 1,969 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0

#include "filesystem.hh"
using namespace llvm;

#include "utils.hh"

#include <set>
#include <vector>

void getFilesInFolder(std::string folder, bool recursive, bool dir_prefix,
                      const std::function<void(const std::string &)> &handler) {
  ccls::ensureEndsInSlash(folder);
  sys::fs::file_status status;
  if (sys::fs::status(folder, status, true))
    return;
  sys::fs::UniqueID id;
  std::vector<std::string> curr{folder};
  std::vector<std::pair<std::string, sys::fs::file_status>> succ;
  std::set<sys::fs::UniqueID> seen{status.getUniqueID()};
  while (curr.size() || succ.size()) {
    if (curr.empty()) {
      for (auto &it : succ)
        if (!seen.count(it.second.getUniqueID()))
          curr.push_back(std::move(it.first));
      succ.clear();
    } else {
      std::error_code ec;
      std::string folder1 = curr.back();
      curr.pop_back();
      for (sys::fs::directory_iterator i(folder1, ec, false), e; i != e && !ec;
           i.increment(ec)) {
        std::string path = i->path();
        std::string filename(sys::path::filename(path));
        if ((filename[0] == '.' && filename != ".ccls") ||
            sys::fs::status(path, status, false))
          continue;
        if (sys::fs::is_symlink_file(status)) {
          if (sys::fs::status(path, status, true))
            continue;
          if (sys::fs::is_directory(status)) {
            if (recursive)
              succ.emplace_back(path, status);
            continue;
          }
        }
        if (sys::fs::is_regular_file(status)) {
          if (!dir_prefix)
            path = path.substr(folder.size());
          handler(sys::path::convert_to_slash(path));
        } else if (recursive && sys::fs::is_directory(status) &&
                   !seen.count(id = status.getUniqueID())) {
          curr.push_back(path);
          seen.insert(id);
        }
      }
    }
  }
}