@@ -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+
8490static llvm::cl::opt<std::string> SourceRoot (" source-root" , llvm::cl::desc(R"(
8591Directory where processed files are stored.
8692Links 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+
134210int 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
141217Example 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
0 commit comments