1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Utils.h" 18 19 #include <err.h> 20 #include <fts.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #include <sstream> 25 #include <string> 26 #include <vector> 27 28 #include <android-base/strings.h> 29 30 #include "DeclarationDatabase.h" 31 32 std::string getWorkingDir() { 33 char buf[PATH_MAX]; 34 if (!getcwd(buf, sizeof(buf))) { 35 err(1, "getcwd failed"); 36 } 37 return buf; 38 } 39 40 std::vector<std::string> collectHeaders(const std::string& directory, 41 const std::unordered_set<std::string>& ignored_directories) { 42 std::vector<std::string> headers; 43 44 char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr }; 45 std::unique_ptr<FTS, decltype(&fts_close)> fts( 46 fts_open(dir_argv, FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close); 47 48 if (!fts) { 49 err(1, "failed to open directory '%s'", directory.c_str()); 50 } 51 52 FTSENT* skipping = nullptr; 53 while (FTSENT* ent = fts_read(fts.get())) { 54 if (ent->fts_info & FTS_DP) { 55 if (ent == skipping) { 56 skipping = nullptr; 57 } 58 continue; 59 } 60 61 if (skipping != nullptr) { 62 continue; 63 } 64 65 if (ent->fts_info & FTS_D) { 66 if (ignored_directories.count(ent->fts_path) != 0) { 67 // fts_read guarantees that `ent` is valid and sane to hold on to until 68 // after it's returned with FTS_DP set. 69 skipping = ent; 70 } 71 continue; 72 } 73 74 std::string path = ent->fts_path; 75 if (!android::base::EndsWith(path, ".h")) { 76 continue; 77 } 78 79 headers.push_back(std::move(path)); 80 } 81 82 return headers; 83 } 84 85 llvm::StringRef StripPrefix(llvm::StringRef string, llvm::StringRef prefix) { 86 if (string.startswith(prefix)) { 87 return string.drop_front(prefix.size()); 88 } 89 return string; 90 } 91