Skip to content

Commit 43c2120

Browse files
PeterChou1AlexisPerry
authored andcommitted
[clang-doc] Add --asset option to clang-doc (llvm#94717)
Adds a new option --asset which allows users to specify the asset folder for the html output of clang-doc.
1 parent b78e24e commit 43c2120

File tree

2 files changed

+83
-19
lines changed

2 files changed

+83
-19
lines changed

clang-tools-extra/clang-doc/tool/ClangDocMain.cpp

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ static llvm::cl::list<std::string> UserStylesheets(
8181
llvm::cl::desc("CSS stylesheets to extend the default styles."),
8282
llvm::cl::cat(ClangDocCategory));
8383

84+
static llvm::cl::opt<std::string> UserAssetPath(
85+
"asset",
86+
llvm::cl::desc("User supplied asset path to "
87+
"override the default css and js files for html output"),
88+
llvm::cl::cat(ClangDocCategory));
89+
8490
static llvm::cl::opt<std::string> SourceRoot("source-root", llvm::cl::desc(R"(
8591
Directory where processed files are stored.
8692
Links to definition locations will only be
@@ -127,16 +133,86 @@ std::string getFormatString() {
127133
// GetMainExecutable (since some platforms don't support taking the
128134
// address of main, and some platforms can't implement GetMainExecutable
129135
// without being given the address of a function in the main executable).
130-
std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
136+
std::string getExecutablePath(const char *Argv0, void *MainAddr) {
131137
return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
132138
}
133139

140+
llvm::Error getAssetFiles(clang::doc::ClangDocContext &CDCtx) {
141+
using DirIt = llvm::sys::fs::directory_iterator;
142+
std::error_code FileErr;
143+
llvm::SmallString<128> FilePath(UserAssetPath);
144+
for (DirIt DirStart = DirIt(UserAssetPath, FileErr),
145+
DirEnd;
146+
!FileErr && DirStart != DirEnd; DirStart.increment(FileErr)) {
147+
FilePath = DirStart->path();
148+
if (llvm::sys::fs::is_regular_file(FilePath)) {
149+
if (llvm::sys::path::extension(FilePath) == ".css")
150+
CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
151+
std::string(FilePath));
152+
else if (llvm::sys::path::extension(FilePath) == ".js")
153+
CDCtx.FilesToCopy.emplace_back(FilePath.str());
154+
}
155+
}
156+
if (FileErr)
157+
return llvm::createFileError(FilePath, FileErr);
158+
return llvm::Error::success();
159+
}
160+
161+
llvm::Error getDefaultAssetFiles(const char *Argv0,
162+
clang::doc::ClangDocContext &CDCtx) {
163+
void *MainAddr = (void *)(intptr_t)getExecutablePath;
164+
std::string ClangDocPath = getExecutablePath(Argv0, MainAddr);
165+
llvm::SmallString<128> NativeClangDocPath;
166+
llvm::sys::path::native(ClangDocPath, NativeClangDocPath);
167+
168+
llvm::SmallString<128> AssetsPath;
169+
AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath);
170+
llvm::sys::path::append(AssetsPath, "..", "share", "clang");
171+
llvm::SmallString<128> DefaultStylesheet;
172+
llvm::sys::path::native(AssetsPath, DefaultStylesheet);
173+
llvm::sys::path::append(DefaultStylesheet,
174+
"clang-doc-default-stylesheet.css");
175+
llvm::SmallString<128> IndexJS;
176+
llvm::sys::path::native(AssetsPath, IndexJS);
177+
llvm::sys::path::append(IndexJS, "index.js");
178+
179+
llvm::outs() << "Using default asset: " << AssetsPath << "\n";
180+
181+
if (!llvm::sys::fs::is_regular_file(IndexJS))
182+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
183+
"default index.js file missing at " +
184+
IndexJS + "\n");
185+
186+
if (!llvm::sys::fs::is_regular_file(DefaultStylesheet))
187+
return llvm::createStringError(
188+
llvm::inconvertibleErrorCode(),
189+
"default clang-doc-default-stylesheet.css file missing at " +
190+
DefaultStylesheet + "\n");
191+
192+
CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
193+
std::string(DefaultStylesheet));
194+
CDCtx.FilesToCopy.emplace_back(IndexJS.str());
195+
196+
return llvm::Error::success();
197+
}
198+
199+
llvm::Error getHtmlAssetFiles(const char *Argv0,
200+
clang::doc::ClangDocContext &CDCtx) {
201+
if (!UserAssetPath.empty() &&
202+
!llvm::sys::fs::is_directory(std::string(UserAssetPath)))
203+
llvm::outs() << "Asset path supply is not a directory: " << UserAssetPath
204+
<< " falling back to default\n";
205+
if (llvm::sys::fs::is_directory(std::string(UserAssetPath)))
206+
return getAssetFiles(CDCtx);
207+
return getDefaultAssetFiles(Argv0, CDCtx);
208+
}
209+
134210
int main(int argc, const char **argv) {
135211
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
136212
std::error_code OK;
137213

138214
const char *Overview =
139-
R"(Generates documentation from source code and comments.
215+
R"(Generates documentation from source code and comments.
140216
141217
Example usage for files without flags (default):
142218
@@ -182,23 +258,9 @@ Example usage for a project using a compile commands database:
182258
{"index.js", "index_json.js"}};
183259

184260
if (Format == "html") {
185-
void *MainAddr = (void *)(intptr_t)GetExecutablePath;
186-
std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
187-
llvm::SmallString<128> NativeClangDocPath;
188-
llvm::sys::path::native(ClangDocPath, NativeClangDocPath);
189-
llvm::SmallString<128> AssetsPath;
190-
AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath);
191-
llvm::sys::path::append(AssetsPath, "..", "share", "clang");
192-
llvm::SmallString<128> DefaultStylesheet;
193-
llvm::sys::path::native(AssetsPath, DefaultStylesheet);
194-
llvm::sys::path::append(DefaultStylesheet,
195-
"clang-doc-default-stylesheet.css");
196-
llvm::SmallString<128> IndexJS;
197-
llvm::sys::path::native(AssetsPath, IndexJS);
198-
llvm::sys::path::append(IndexJS, "index.js");
199-
CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
200-
std::string(DefaultStylesheet));
201-
CDCtx.FilesToCopy.emplace_back(IndexJS.str());
261+
if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) {
262+
llvm::outs() << "warning: " << toString(std::move(Err)) << "\n";
263+
}
202264
}
203265

204266
// Mapping phase
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// RUN: clang-doc --format=html --executor=standalone %s -output=%t/docs | FileCheck %s
2+
// CHECK: Using default asset: {{.*}}{{[\/]}}share{{[\/]}}clang

0 commit comments

Comments
 (0)