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#pragma once
18
19#include <errno.h>
20#include <libgen.h>
21#include <sys/stat.h>
22#include <unistd.h>
23
24#include <string>
25#include <unordered_set>
26#include <vector>
27
28#include <llvm/ADT/StringRef.h>
29
30std::string getWorkingDir();
31std::vector<std::string> collectHeaders(const std::string& directory,
32                                        const std::unordered_set<std::string>& ignored_directories);
33
34static inline std::string dirname(const std::string& path) {
35  std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
36  return dirname(path_copy.get());
37}
38
39static inline bool is_directory(const std::string& path) {
40  struct stat st;
41  if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
42    return true;
43  }
44  return false;
45}
46
47static inline bool mkdirs(const std::string& path) {
48  if (is_directory(path)) {
49    return true;
50  }
51
52  std::string parent = dirname(path);
53  if (parent == path) {
54    return false;
55  }
56
57  if (!mkdirs(parent)) {
58    return false;
59  }
60
61  if (mkdir(path.c_str(), 0700) != 0) {
62    if (errno != EEXIST) {
63      return false;
64    }
65    return is_directory(path);
66  }
67
68  return true;
69}
70
71static inline std::string to_string(const char* c) {
72  return c;
73}
74
75static inline const std::string& to_string(const std::string& str) {
76  return str;
77}
78
79template <typename Collection>
80static inline std::string Join(Collection c, const std::string& delimiter = ", ") {
81  std::string result;
82  for (const auto& item : c) {
83    using namespace std;
84    result.append(to_string(item));
85    result.append(delimiter);
86  }
87  if (!result.empty()) {
88    result.resize(result.length() - delimiter.length());
89  }
90  return result;
91}
92
93llvm::StringRef StripPrefix(llvm::StringRef string, llvm::StringRef prefix);
94