aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp')
-rw-r--r--clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp47
1 files changed, 31 insertions, 16 deletions
diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index b4b9322..3650f66 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -29,7 +29,8 @@ namespace clang {
namespace doc {
static Error generateDocForJSON(json::Value &JSON, StringRef Filename,
StringRef Path, raw_fd_ostream &OS,
- const ClangDocContext &CDCtx);
+ const ClangDocContext &CDCtx,
+ StringRef HTMLRootPath);
static Error createFileOpenError(StringRef FileName, std::error_code EC) {
return createFileError("cannot open file " + FileName, EC);
@@ -159,16 +160,24 @@ Error MustacheHTMLGenerator::generateDocs(
{
llvm::TimeTraceScope TS("Iterate JSON files");
std::error_code EC;
- sys::fs::directory_iterator JSONIter(JSONPath, EC);
+ sys::fs::recursive_directory_iterator JSONIter(JSONPath, EC);
std::vector<json::Value> JSONFiles;
JSONFiles.reserve(Infos.size());
if (EC)
return createStringError("Failed to create directory iterator.");
- SmallString<128> HTMLDirPath(RootDir.str() + "/html/");
+ SmallString<128> HTMLDirPath(RootDir.str() + "/html");
if (auto EC = sys::fs::create_directories(HTMLDirPath))
return createFileError(HTMLDirPath, EC);
- while (JSONIter != sys::fs::directory_iterator()) {
+ while (JSONIter != sys::fs::recursive_directory_iterator()) {
+ // create the same directory structure in the HTML dir
+ if (JSONIter->type() == sys::fs::file_type::directory_file) {
+ SmallString<128> HTMLClonedPath(JSONIter->path());
+ sys::path::replace_path_prefix(HTMLClonedPath, JSONPath, HTMLDirPath);
+ if (auto EC = sys::fs::create_directories(HTMLClonedPath))
+ return createFileError(HTMLClonedPath, EC);
+ }
+
if (EC)
return createFileError("Failed to iterate: " + JSONIter->path(), EC);
@@ -190,15 +199,16 @@ Error MustacheHTMLGenerator::generateDocs(
return Parsed.takeError();
std::error_code FileErr;
- SmallString<128> HTMLFilePath(HTMLDirPath);
- sys::path::append(HTMLFilePath, sys::path::filename(Path));
+ SmallString<128> HTMLFilePath(JSONIter->path());
+ sys::path::replace_path_prefix(HTMLFilePath, JSONPath, HTMLDirPath);
sys::path::replace_extension(HTMLFilePath, "html");
raw_fd_ostream InfoOS(HTMLFilePath, FileErr, sys::fs::OF_None);
if (FileErr)
return createFileOpenError(Path, FileErr);
- if (Error Err = generateDocForJSON(*Parsed, sys::path::stem(HTMLFilePath),
- HTMLFilePath, InfoOS, CDCtx))
+ if (Error Err =
+ generateDocForJSON(*Parsed, sys::path::stem(HTMLFilePath),
+ HTMLFilePath, InfoOS, CDCtx, HTMLDirPath))
return Err;
JSONIter.increment(EC);
}
@@ -207,16 +217,16 @@ Error MustacheHTMLGenerator::generateDocs(
return Error::success();
}
-static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V) {
+static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
+ SmallString<128> RelativeHTMLPath) {
V.getAsObject()->insert({"ProjectName", CDCtx.ProjectName});
json::Value StylesheetArr = Array();
- SmallString<128> RelativePath("./");
- sys::path::native(RelativePath, sys::path::Style::posix);
+ sys::path::native(RelativeHTMLPath, sys::path::Style::posix);
auto *SSA = StylesheetArr.getAsArray();
SSA->reserve(CDCtx.UserStylesheets.size());
for (const auto &FilePath : CDCtx.UserStylesheets) {
- SmallString<128> StylesheetPath = RelativePath;
+ SmallString<128> StylesheetPath = RelativeHTMLPath;
sys::path::append(StylesheetPath, sys::path::Style::posix,
sys::path::filename(FilePath));
SSA->emplace_back(StylesheetPath);
@@ -227,7 +237,7 @@ static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V) {
auto *SCA = ScriptArr.getAsArray();
SCA->reserve(CDCtx.JsScripts.size());
for (auto Script : CDCtx.JsScripts) {
- SmallString<128> JsPath = RelativePath;
+ SmallString<128> JsPath = RelativeHTMLPath;
sys::path::append(JsPath, sys::path::Style::posix,
sys::path::filename(Script));
SCA->emplace_back(JsPath);
@@ -238,7 +248,8 @@ static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V) {
static Error generateDocForJSON(json::Value &JSON, StringRef Filename,
StringRef Path, raw_fd_ostream &OS,
- const ClangDocContext &CDCtx) {
+ const ClangDocContext &CDCtx,
+ StringRef HTMLRootPath) {
auto StrValue = (*JSON.getAsObject())["InfoType"];
if (StrValue.kind() != json::Value::Kind::String)
return createStringError("JSON file '%s' does not contain key: 'InfoType'.",
@@ -249,13 +260,17 @@ static Error generateDocForJSON(json::Value &JSON, StringRef Filename,
"JSON file '%s' does not contain 'InfoType' field as a string.",
Filename.str().c_str());
+ SmallString<128> PathVec(Path);
+ // Remove filename, or else the relative path will have an extra "../"
+ sys::path::remove_filename(PathVec);
+ auto RelativeHTMLPath = computeRelativePath(HTMLRootPath, PathVec);
if (ObjTypeStr.value() == "namespace") {
- if (auto Err = setupTemplateValue(CDCtx, JSON))
+ if (auto Err = setupTemplateValue(CDCtx, JSON, RelativeHTMLPath))
return Err;
assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
NamespaceTemplate->render(JSON, OS);
} else if (ObjTypeStr.value() == "record") {
- if (auto Err = setupTemplateValue(CDCtx, JSON))
+ if (auto Err = setupTemplateValue(CDCtx, JSON, RelativeHTMLPath))
return Err;
assert(RecordTemplate && "RecordTemplate is nullptr.");
RecordTemplate->render(JSON, OS);