|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include "Utils.h" | 
|  |  | 
|  | #include <err.h> | 
|  | #include <fts.h> | 
|  | #include <string.h> | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include <sstream> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include <android-base/strings.h> | 
|  |  | 
|  | #include "DeclarationDatabase.h" | 
|  |  | 
|  | std::string getWorkingDir() { | 
|  | char buf[PATH_MAX]; | 
|  | if (!getcwd(buf, sizeof(buf))) { | 
|  | err(1, "getcwd failed"); | 
|  | } | 
|  | return buf; | 
|  | } | 
|  |  | 
|  | std::vector<std::string> collectHeaders(const std::string& directory, | 
|  | const std::unordered_set<std::string>& ignored_directories) { | 
|  | std::vector<std::string> headers; | 
|  |  | 
|  | char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr }; | 
|  | std::unique_ptr<FTS, decltype(&fts_close)> fts( | 
|  | fts_open(dir_argv, FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close); | 
|  |  | 
|  | if (!fts) { | 
|  | err(1, "failed to open directory '%s'", directory.c_str()); | 
|  | } | 
|  |  | 
|  | FTSENT* skipping = nullptr; | 
|  | while (FTSENT* ent = fts_read(fts.get())) { | 
|  | if (ent->fts_info & FTS_DP) { | 
|  | if (ent == skipping) { | 
|  | skipping = nullptr; | 
|  | } | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (skipping != nullptr) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (ent->fts_info & FTS_D) { | 
|  | if (ignored_directories.count(ent->fts_path) != 0) { | 
|  | // fts_read guarantees that `ent` is valid and sane to hold on to until | 
|  | // after it's returned with FTS_DP set. | 
|  | skipping = ent; | 
|  | } | 
|  | continue; | 
|  | } | 
|  |  | 
|  | std::string path = ent->fts_path; | 
|  | if (!android::base::EndsWith(path, ".h")) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | headers.push_back(std::move(path)); | 
|  | } | 
|  |  | 
|  | return headers; | 
|  | } | 
|  |  | 
|  | llvm::StringRef StripPrefix(llvm::StringRef string, llvm::StringRef prefix) { | 
|  | if (string.startswith(prefix)) { | 
|  | return string.drop_front(prefix.size()); | 
|  | } | 
|  | return string; | 
|  | } |