1 //===- HeaderFile.cpp ------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/InstallAPI/HeaderFile.h"
10 #include "llvm/TextAPI/Utils.h"
13 namespace clang::installapi
{
15 llvm::Regex
HeaderFile::getFrameworkIncludeRule() {
16 return llvm::Regex("/(.+)\\.framework/(.+)?Headers/(.+)");
19 std::optional
<std::string
> createIncludeHeaderName(const StringRef FullPath
) {
20 // Headers in usr(/local)*/include.
21 std::string Pattern
= "/include/";
22 auto PathPrefix
= FullPath
.find(Pattern
);
23 if (PathPrefix
!= StringRef::npos
) {
24 PathPrefix
+= Pattern
.size();
25 return FullPath
.drop_front(PathPrefix
).str();
29 SmallVector
<StringRef
, 4> Matches
;
30 HeaderFile::getFrameworkIncludeRule().match(FullPath
, &Matches
);
31 // Returned matches are always in stable order.
32 if (Matches
.size() != 4)
35 return Matches
[1].drop_front(Matches
[1].rfind('/') + 1).str() + "/" +
39 bool isHeaderFile(StringRef Path
) {
40 return StringSwitch
<bool>(sys::path::extension(Path
))
41 .Cases(".h", ".H", ".hh", ".hpp", ".hxx", true)
45 llvm::Expected
<PathSeq
> enumerateFiles(FileManager
&FM
, StringRef Directory
) {
48 auto &FS
= FM
.getVirtualFileSystem();
49 for (llvm::vfs::recursive_directory_iterator
i(FS
, Directory
, EC
), ie
;
50 i
!= ie
; i
.increment(EC
)) {
52 return errorCodeToError(EC
);
54 // Skip files that do not exist. This usually happens for broken symlinks.
55 if (FS
.status(i
->path()) == std::errc::no_such_file_or_directory
)
58 StringRef Path
= i
->path();
59 if (isHeaderFile(Path
))
60 Files
.emplace_back(Path
);
66 HeaderGlob::HeaderGlob(StringRef GlobString
, Regex
&&Rule
, HeaderType Type
)
67 : GlobString(GlobString
), Rule(std::move(Rule
)), Type(Type
) {}
69 bool HeaderGlob::match(const HeaderFile
&Header
) {
70 if (Header
.getType() != Type
)
73 bool Match
= Rule
.match(Header
.getPath());
79 Expected
<std::unique_ptr
<HeaderGlob
>> HeaderGlob::create(StringRef GlobString
,
81 auto Rule
= MachO::createRegexFromGlob(GlobString
);
83 return Rule
.takeError();
85 return std::make_unique
<HeaderGlob
>(GlobString
, std::move(*Rule
), Type
);
88 } // namespace clang::installapi