CMake Nightly Date Stamp
[kiteware-cmake.git] / Source / cmDocumentation.cxx
blobdb2a606dacbf87afff731c57cdeb6e353d93ec54
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmDocumentation.h"
5 #include <algorithm>
6 #include <cctype>
7 #include <cstring>
8 #include <utility>
10 #include "cmsys/FStream.hxx"
11 #include "cmsys/Glob.hxx"
12 #include "cmsys/RegularExpression.hxx"
14 #include "cmDocumentationEntry.h"
15 #include "cmDocumentationSection.h"
16 #include "cmRST.h"
17 #include "cmStringAlgorithms.h"
18 #include "cmSystemTools.h"
19 #include "cmVersion.h"
21 namespace {
22 const cmDocumentationEntry cmDocumentationStandardOptions[21] = {
23 { "-h,-H,--help,-help,-usage,/?", "Print usage information and exit." },
24 { "--version,-version,/V [<file>]", "Print version number and exit." },
25 { "--help <keyword> [<file>]", "Print help for one keyword and exit." },
26 { "--help-full [<file>]", "Print all help manuals and exit." },
27 { "--help-manual <man> [<file>]", "Print one help manual and exit." },
28 { "--help-manual-list [<file>]", "List help manuals available and exit." },
29 { "--help-command <cmd> [<file>]", "Print help for one command and exit." },
30 { "--help-command-list [<file>]",
31 "List commands with help available and exit." },
32 { "--help-commands [<file>]", "Print cmake-commands manual and exit." },
33 { "--help-module <mod> [<file>]", "Print help for one module and exit." },
34 { "--help-module-list [<file>]",
35 "List modules with help available and exit." },
36 { "--help-modules [<file>]", "Print cmake-modules manual and exit." },
37 { "--help-policy <cmp> [<file>]", "Print help for one policy and exit." },
38 { "--help-policy-list [<file>]",
39 "List policies with help available and exit." },
40 { "--help-policies [<file>]", "Print cmake-policies manual and exit." },
41 { "--help-property <prop> [<file>]",
42 "Print help for one property and exit." },
43 { "--help-property-list [<file>]",
44 "List properties with help available and exit." },
45 { "--help-properties [<file>]", "Print cmake-properties manual and exit." },
46 { "--help-variable var [<file>]", "Print help for one variable and exit." },
47 { "--help-variable-list [<file>]",
48 "List variables with help available and exit." },
49 { "--help-variables [<file>]", "Print cmake-variables manual and exit." }
52 const cmDocumentationEntry cmDocumentationCPackGeneratorsHeader = {
53 {},
54 "The following generators are available on this platform:"
57 const cmDocumentationEntry cmDocumentationCMakeGeneratorsHeader = {
58 {},
59 "The following generators are available on this platform (* marks "
60 "default):"
63 bool isOption(const char* arg)
65 return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
66 (strcmp(arg, "/?") == 0));
68 } // anonymous namespace
70 cmDocumentation::cmDocumentation()
72 this->addCommonStandardDocSections();
73 this->ShowGenerators = true;
76 bool cmDocumentation::PrintVersion(std::ostream& os)
78 /* clang-format off */
79 os <<
80 this->GetNameString() <<
81 " version " << cmVersion::GetCMakeVersion() << "\n"
82 "\n"
83 "CMake suite maintained and supported by Kitware (kitware.com/cmake).\n"
85 /* clang-format on */
86 return true;
89 bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
91 switch (ht) {
92 case cmDocumentation::Usage:
93 return this->PrintUsage(os);
94 case cmDocumentation::Help:
95 return this->PrintHelp(os);
96 case cmDocumentation::Full:
97 return this->PrintHelpFull(os);
98 case cmDocumentation::OneArbitrary:
99 return this->PrintHelpOneArbitrary(os);
100 case cmDocumentation::OneManual:
101 return this->PrintHelpOneManual(os);
102 case cmDocumentation::OneCommand:
103 return this->PrintHelpOneCommand(os);
104 case cmDocumentation::OneModule:
105 return this->PrintHelpOneModule(os);
106 case cmDocumentation::OnePolicy:
107 return this->PrintHelpOnePolicy(os);
108 case cmDocumentation::OneProperty:
109 return this->PrintHelpOneProperty(os);
110 case cmDocumentation::OneVariable:
111 return this->PrintHelpOneVariable(os);
112 case cmDocumentation::ListManuals:
113 return this->PrintHelpListManuals(os);
114 case cmDocumentation::ListCommands:
115 return this->PrintHelpListCommands(os);
116 case cmDocumentation::ListModules:
117 return this->PrintHelpListModules(os);
118 case cmDocumentation::ListProperties:
119 return this->PrintHelpListProperties(os);
120 case cmDocumentation::ListVariables:
121 return this->PrintHelpListVariables(os);
122 case cmDocumentation::ListPolicies:
123 return this->PrintHelpListPolicies(os);
124 case cmDocumentation::ListGenerators:
125 return this->PrintHelpListGenerators(os);
126 case cmDocumentation::Version:
127 return this->PrintVersion(os);
128 case cmDocumentation::OldCustomModules:
129 return this->PrintOldCustomModules(os);
130 default:
131 return false;
135 bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
137 int count = 0;
138 bool result = true;
140 // Loop over requested documentation types.
141 for (RequestedHelpItem const& rhi : this->RequestedHelpItems) {
142 this->CurrentArgument = rhi.Argument;
143 // If a file name was given, use it. Otherwise, default to the
144 // given stream.
145 cmsys::ofstream fout;
146 std::ostream* s = &os;
147 if (!rhi.Filename.empty()) {
148 fout.open(rhi.Filename.c_str());
149 s = &fout;
150 } else if (++count > 1) {
151 os << "\n\n";
154 // Print this documentation type to the stream.
155 if (!this->PrintDocumentation(rhi.HelpType, *s) || s->fail()) {
156 result = false;
159 return result;
162 void cmDocumentation::WarnFormFromFilename(
163 cmDocumentation::RequestedHelpItem& request, bool& result)
165 std::string ext = cmSystemTools::GetFilenameLastExtension(request.Filename);
166 ext = cmSystemTools::UpperCase(ext);
167 if ((ext == ".HTM") || (ext == ".HTML")) {
168 request.HelpType = cmDocumentation::None;
169 result = true;
170 cmSystemTools::Message("Warning: HTML help format no longer supported");
171 } else if (ext == ".DOCBOOK") {
172 request.HelpType = cmDocumentation::None;
173 result = true;
174 cmSystemTools::Message("Warning: Docbook help format no longer supported");
176 // ".1" to ".9" should be manpages
177 else if ((ext.length() == 2) && (ext[1] >= '1') && (ext[1] <= '9')) {
178 request.HelpType = cmDocumentation::None;
179 result = true;
180 cmSystemTools::Message("Warning: Man help format no longer supported");
184 std::string cmDocumentation::GeneralizeKeyword(std::string cname)
186 std::map<std::string, const std::vector<std::string>> conversions;
187 std::vector<std::string> languages = {
188 "C", "CXX", "CSharp", "CUDA", "OBJC",
189 "OBJCXX", "Fortran", "HIP", "ISPC", "Swift",
190 "ASM", "ASM_NASM", "ASM_MARMASM", "ASM_MASM", "ASM-ATT"
192 std::vector<std::string> configs = { "DEBUG", "RELEASE", "RELWITHDEBINFO",
193 "MINSIZEREL" };
194 conversions.emplace("LANG", std::move(languages));
195 conversions.emplace("CONFIG", std::move(configs));
196 for (auto const& it : conversions) {
197 for (auto const& to_replace : it.second) {
198 cmsys::RegularExpression reg(
199 cmStrCat("(^|_)(", to_replace, ")(\\.|$|_)"));
200 if (reg.find(cname)) {
201 cname.replace(reg.start(2), to_replace.length(), it.first);
205 return cname;
208 void cmDocumentation::addCommonStandardDocSections()
210 cmDocumentationSection sec{ "Options" };
211 sec.Append(cmDocumentationStandardOptions);
212 this->AllSections.emplace("Options", std::move(sec));
215 void cmDocumentation::addCMakeStandardDocSections()
217 cmDocumentationSection sec{ "Generators" };
218 sec.Append(cmDocumentationCMakeGeneratorsHeader);
219 this->AllSections.emplace("Generators", std::move(sec));
222 void cmDocumentation::addCTestStandardDocSections()
224 // This is currently done for backward compatibility reason
225 // We may suppress some of these.
226 this->addCMakeStandardDocSections();
229 void cmDocumentation::addCPackStandardDocSections()
231 cmDocumentationSection sec{ "Generators" };
232 sec.Append(cmDocumentationCPackGeneratorsHeader);
233 this->AllSections.emplace("Generators", std::move(sec));
236 bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
237 const char* exitOpt)
239 // Providing zero arguments gives usage information.
240 if (argc == 1) {
241 RequestedHelpItem help;
242 help.HelpType = cmDocumentation::Usage;
243 this->RequestedHelpItems.push_back(std::move(help));
244 return true;
247 auto get_opt_argument = [=](const int nextIdx, std::string& target) -> bool {
248 if ((nextIdx < argc) && !isOption(argv[nextIdx])) {
249 target = argv[nextIdx];
250 return true;
252 return false;
255 // Search for supported help options.
257 bool result = false;
258 for (int i = 1; i < argc; ++i) {
259 if (exitOpt && strcmp(argv[i], exitOpt) == 0) {
260 return result;
262 RequestedHelpItem help;
263 // Check if this is a supported help option.
264 if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0) ||
265 (strcmp(argv[i], "/?") == 0) || (strcmp(argv[i], "-usage") == 0) ||
266 (strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-H") == 0)) {
267 help.HelpType = cmDocumentation::Help;
268 i += int(get_opt_argument(i + 1, help.Argument));
269 // special case for arbitrary keyword help
270 if (!help.Argument.empty()) {
271 help.HelpType = cmDocumentation::OneArbitrary;
272 i += int(get_opt_argument(i + 1, help.Filename));
274 } else if (strcmp(argv[i], "--help-properties") == 0) {
275 help.HelpType = cmDocumentation::OneManual;
276 help.Argument = "cmake-properties.7";
277 i += int(get_opt_argument(i + 1, help.Filename));
278 this->WarnFormFromFilename(help, result);
279 } else if (strcmp(argv[i], "--help-policies") == 0) {
280 help.HelpType = cmDocumentation::OneManual;
281 help.Argument = "cmake-policies.7";
282 i += int(get_opt_argument(i + 1, help.Filename));
283 this->WarnFormFromFilename(help, result);
284 } else if (strcmp(argv[i], "--help-variables") == 0) {
285 help.HelpType = cmDocumentation::OneManual;
286 help.Argument = "cmake-variables.7";
287 i += int(get_opt_argument(i + 1, help.Filename));
288 this->WarnFormFromFilename(help, result);
289 } else if (strcmp(argv[i], "--help-modules") == 0) {
290 help.HelpType = cmDocumentation::OneManual;
291 help.Argument = "cmake-modules.7";
292 i += int(get_opt_argument(i + 1, help.Filename));
293 this->WarnFormFromFilename(help, result);
294 } else if (strcmp(argv[i], "--help-custom-modules") == 0) {
295 i += int(get_opt_argument(i + 1, help.Filename));
296 cmSystemTools::Message(
297 "Warning: --help-custom-modules no longer supported");
298 if (help.Filename.empty()) {
299 return true;
301 // Avoid breaking old project builds completely by at least generating
302 // the output file. Abuse help.Argument to give the file name to
303 // PrintOldCustomModules without disrupting our internal API.
304 help.HelpType = cmDocumentation::OldCustomModules;
305 help.Argument = cmSystemTools::GetFilenameName(help.Filename);
306 } else if (strcmp(argv[i], "--help-commands") == 0) {
307 help.HelpType = cmDocumentation::OneManual;
308 help.Argument = "cmake-commands.7";
309 i += int(get_opt_argument(i + 1, help.Filename));
310 this->WarnFormFromFilename(help, result);
311 } else if (strcmp(argv[i], "--help-compatcommands") == 0) {
312 cmSystemTools::Message(
313 "Warning: --help-compatcommands no longer supported");
314 return true;
315 } else if (strcmp(argv[i], "--help-full") == 0) {
316 help.HelpType = cmDocumentation::Full;
317 i += int(get_opt_argument(i + 1, help.Filename));
318 this->WarnFormFromFilename(help, result);
319 } else if (strcmp(argv[i], "--help-html") == 0) {
320 cmSystemTools::Message("Warning: --help-html no longer supported");
321 return true;
322 } else if (strcmp(argv[i], "--help-man") == 0) {
323 cmSystemTools::Message("Warning: --help-man no longer supported");
324 return true;
325 } else if (strcmp(argv[i], "--help-command") == 0) {
326 help.HelpType = cmDocumentation::OneCommand;
327 i += int(get_opt_argument(i + 1, help.Argument));
328 i += int(get_opt_argument(i + 1, help.Filename));
329 help.Argument = cmSystemTools::LowerCase(help.Argument);
330 this->WarnFormFromFilename(help, result);
331 } else if (strcmp(argv[i], "--help-module") == 0) {
332 help.HelpType = cmDocumentation::OneModule;
333 i += int(get_opt_argument(i + 1, help.Argument));
334 i += int(get_opt_argument(i + 1, help.Filename));
335 this->WarnFormFromFilename(help, result);
336 } else if (strcmp(argv[i], "--help-property") == 0) {
337 help.HelpType = cmDocumentation::OneProperty;
338 i += int(get_opt_argument(i + 1, help.Argument));
339 i += int(get_opt_argument(i + 1, help.Filename));
340 this->WarnFormFromFilename(help, result);
341 } else if (strcmp(argv[i], "--help-policy") == 0) {
342 help.HelpType = cmDocumentation::OnePolicy;
343 i += int(get_opt_argument(i + 1, help.Argument));
344 i += int(get_opt_argument(i + 1, help.Filename));
345 this->WarnFormFromFilename(help, result);
346 } else if (strcmp(argv[i], "--help-variable") == 0) {
347 help.HelpType = cmDocumentation::OneVariable;
348 i += int(get_opt_argument(i + 1, help.Argument));
349 i += int(get_opt_argument(i + 1, help.Filename));
350 this->WarnFormFromFilename(help, result);
351 } else if (strcmp(argv[i], "--help-manual") == 0) {
352 help.HelpType = cmDocumentation::OneManual;
353 i += int(get_opt_argument(i + 1, help.Argument));
354 i += int(get_opt_argument(i + 1, help.Filename));
355 this->WarnFormFromFilename(help, result);
356 } else if (strcmp(argv[i], "--help-command-list") == 0) {
357 help.HelpType = cmDocumentation::ListCommands;
358 i += int(get_opt_argument(i + 1, help.Filename));
359 } else if (strcmp(argv[i], "--help-module-list") == 0) {
360 help.HelpType = cmDocumentation::ListModules;
361 i += int(get_opt_argument(i + 1, help.Filename));
362 } else if (strcmp(argv[i], "--help-property-list") == 0) {
363 help.HelpType = cmDocumentation::ListProperties;
364 i += int(get_opt_argument(i + 1, help.Filename));
365 } else if (strcmp(argv[i], "--help-variable-list") == 0) {
366 help.HelpType = cmDocumentation::ListVariables;
367 i += int(get_opt_argument(i + 1, help.Filename));
368 } else if (strcmp(argv[i], "--help-policy-list") == 0) {
369 help.HelpType = cmDocumentation::ListPolicies;
370 i += int(get_opt_argument(i + 1, help.Filename));
371 } else if (strcmp(argv[i], "--help-manual-list") == 0) {
372 help.HelpType = cmDocumentation::ListManuals;
373 i += int(get_opt_argument(i + 1, help.Filename));
374 } else if (strcmp(argv[i], "--copyright") == 0) {
375 cmSystemTools::Message("Warning: --copyright no longer supported");
376 return true;
377 } else if ((strcmp(argv[i], "--version") == 0) ||
378 (strcmp(argv[i], "-version") == 0) ||
379 (strcmp(argv[i], "/V") == 0)) {
380 help.HelpType = cmDocumentation::Version;
381 i += int(get_opt_argument(i + 1, help.Filename));
383 if (help.HelpType != None) {
384 // This is a help option. See if there is a file name given.
385 result = true;
386 this->RequestedHelpItems.push_back(std::move(help));
389 return result;
392 void cmDocumentation::SetName(const std::string& name)
394 this->NameString = name;
397 void cmDocumentation::SetSection(const char* name,
398 cmDocumentationSection section)
400 this->SectionAtName(name) = std::move(section);
403 cmDocumentationSection& cmDocumentation::SectionAtName(const char* name)
405 return this->AllSections.emplace(name, cmDocumentationSection{ name })
406 .first->second;
409 void cmDocumentation::AppendSection(const char* name,
410 cmDocumentationEntry& docs)
413 std::vector<cmDocumentationEntry> docsVec;
414 docsVec.push_back(docs);
415 this->AppendSection(name, docsVec);
418 void cmDocumentation::PrependSection(const char* name,
419 cmDocumentationEntry& docs)
422 std::vector<cmDocumentationEntry> docsVec;
423 docsVec.push_back(docs);
424 this->PrependSection(name, docsVec);
427 void cmDocumentation::GlobHelp(std::vector<std::string>& files,
428 std::string const& pattern)
430 cmsys::Glob gl;
431 std::string findExpr =
432 cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/", pattern, ".rst");
433 if (gl.FindFiles(findExpr)) {
434 files = gl.GetFiles();
438 void cmDocumentation::PrintNames(std::ostream& os, std::string const& pattern)
440 std::vector<std::string> files;
441 this->GlobHelp(files, pattern);
442 std::vector<std::string> names;
443 for (std::string const& f : files) {
444 std::string line;
445 cmsys::ifstream fin(f.c_str());
446 while (fin && cmSystemTools::GetLineFromStream(fin, line)) {
447 if (!line.empty() && (isalnum(line[0]) || line[0] == '<')) {
448 names.push_back(line);
449 break;
453 std::sort(names.begin(), names.end());
454 for (std::string const& n : names) {
455 os << n << '\n';
459 bool cmDocumentation::PrintFiles(std::ostream& os, std::string const& pattern)
461 bool found = false;
462 std::vector<std::string> files;
463 this->GlobHelp(files, pattern);
464 std::sort(files.begin(), files.end());
465 cmRST r(os, cmSystemTools::GetCMakeRoot() + "/Help");
466 for (std::string const& f : files) {
467 found = r.ProcessFile(f) || found;
469 return found;
472 bool cmDocumentation::PrintHelpFull(std::ostream& os)
474 return this->PrintFiles(os, "index");
477 bool cmDocumentation::PrintHelpOneManual(std::ostream& os)
479 std::string mname = this->CurrentArgument;
480 std::string::size_type mlen = mname.length();
481 if (mlen > 3 && mname[mlen - 3] == '(' && mname[mlen - 1] == ')') {
482 mname = mname.substr(0, mlen - 3) + "." + mname[mlen - 2];
484 if (this->PrintFiles(os, cmStrCat("manual/", mname)) ||
485 this->PrintFiles(os, cmStrCat("manual/", mname, ".[0-9]"))) {
486 return true;
488 // Argument was not a manual. Complain.
489 os << "Argument \"" << this->CurrentArgument
490 << "\" to --help-manual is not an available manual. "
491 "Use --help-manual-list to see all available manuals.\n";
492 return false;
495 bool cmDocumentation::PrintHelpListManuals(std::ostream& os)
497 this->PrintNames(os, "manual/*");
498 return true;
501 bool cmDocumentation::PrintHelpOneArbitrary(std::ostream& os)
503 std::string word = cmSystemTools::HelpFileName(this->CurrentArgument);
504 std::string word_m = GeneralizeKeyword(word);
506 // Support legacy style uppercase commands, with LANG and CONFIG
507 // substitutions
508 bool found = this->PrintFiles(os, cmStrCat("*/", word));
509 if (found) {
510 os << "\n";
512 found = this->PrintFiles(
513 os, cmStrCat("command/", cmSystemTools::LowerCase(word))) ||
514 found;
515 if (found) {
516 return true;
518 found = this->PrintFiles(os, cmStrCat("*/", word_m));
519 if (found) {
520 os << "\n";
522 found = this->PrintFiles(
523 os, cmStrCat("command/", cmSystemTools::LowerCase(word_m))) ||
524 found;
525 if (found) {
526 return true;
528 os << "Argument \"" << this->CurrentArgument
529 << "\" to --help did not match any keywords. "
530 "Use --help without any arguments to print CMake help information.\n";
531 return false;
534 bool cmDocumentation::PrintHelpOneCommand(std::ostream& os)
536 std::string cname = cmSystemTools::LowerCase(this->CurrentArgument);
537 if (this->PrintFiles(os, cmStrCat("command/", cname))) {
538 return true;
540 // Argument was not a command. Complain.
541 os << "Argument \"" << this->CurrentArgument
542 << "\" to --help-command is not a CMake command. "
543 "Use --help-command-list to see all commands.\n";
544 return false;
547 bool cmDocumentation::PrintHelpListCommands(std::ostream& os)
549 this->PrintNames(os, "command/*");
550 return true;
553 bool cmDocumentation::PrintHelpOneModule(std::ostream& os)
555 std::string mname = this->CurrentArgument;
556 if (this->PrintFiles(os, cmStrCat("module/", mname))) {
557 return true;
559 // Argument was not a module. Complain.
560 os << "Argument \"" << this->CurrentArgument
561 << "\" to --help-module is not a CMake module.\n";
562 return false;
565 bool cmDocumentation::PrintHelpListModules(std::ostream& os)
567 std::vector<std::string> files;
568 this->GlobHelp(files, "module/*");
569 std::vector<std::string> modules;
570 for (std::string const& f : files) {
571 std::string module = cmSystemTools::GetFilenameName(f);
572 modules.push_back(module.substr(0, module.size() - 4));
574 std::sort(modules.begin(), modules.end());
575 for (std::string const& m : modules) {
576 os << m << '\n';
578 return true;
581 bool cmDocumentation::PrintHelpOneProperty(std::ostream& os)
583 std::string pname = cmSystemTools::HelpFileName(this->CurrentArgument);
584 if (this->PrintFiles(os, cmStrCat("prop_*/", pname))) {
585 return true;
587 // Argument was not a property. Complain.
588 os << "Argument \"" << this->CurrentArgument
589 << "\" to --help-property is not a CMake property. "
590 "Use --help-property-list to see all properties.\n";
591 return false;
594 bool cmDocumentation::PrintHelpListProperties(std::ostream& os)
596 this->PrintNames(os, "prop_*/*");
597 return true;
600 bool cmDocumentation::PrintHelpOnePolicy(std::ostream& os)
602 std::string pname = this->CurrentArgument;
603 std::vector<std::string> files;
604 if (this->PrintFiles(os, cmStrCat("policy/", pname))) {
605 return true;
608 // Argument was not a policy. Complain.
609 os << "Argument \"" << this->CurrentArgument
610 << "\" to --help-policy is not a CMake policy.\n";
611 return false;
614 bool cmDocumentation::PrintHelpListPolicies(std::ostream& os)
616 this->PrintNames(os, "policy/*");
617 return true;
620 bool cmDocumentation::PrintHelpListGenerators(std::ostream& os)
622 const auto si = this->AllSections.find("Generators");
623 if (si != this->AllSections.end()) {
624 this->Formatter.PrintSection(os, si->second);
626 return true;
629 bool cmDocumentation::PrintHelpOneVariable(std::ostream& os)
631 std::string vname = cmSystemTools::HelpFileName(this->CurrentArgument);
632 if (this->PrintFiles(os, cmStrCat("variable/", vname))) {
633 return true;
635 // Argument was not a variable. Complain.
636 os << "Argument \"" << this->CurrentArgument
637 << "\" to --help-variable is not a defined variable. "
638 "Use --help-variable-list to see all defined variables.\n";
639 return false;
642 bool cmDocumentation::PrintHelpListVariables(std::ostream& os)
644 this->PrintNames(os, "variable/*");
645 return true;
648 bool cmDocumentation::PrintUsage(std::ostream& os)
650 const auto si = this->AllSections.find("Usage");
651 if (si != this->AllSections.end()) {
652 this->Formatter.PrintSection(os, si->second);
654 return true;
657 bool cmDocumentation::PrintHelp(std::ostream& os)
659 auto si = this->AllSections.find("Usage");
660 if (si != this->AllSections.end()) {
661 this->Formatter.PrintSection(os, si->second);
663 si = this->AllSections.find("Options");
664 if (si != this->AllSections.end()) {
665 this->Formatter.PrintSection(os, si->second);
667 if (this->ShowGenerators) {
668 si = this->AllSections.find("Generators");
669 if (si != this->AllSections.end()) {
670 this->Formatter.PrintSection(os, si->second);
673 return true;
676 const char* cmDocumentation::GetNameString() const
678 if (!this->NameString.empty()) {
679 return this->NameString.c_str();
681 return "CMake";
684 bool cmDocumentation::PrintOldCustomModules(std::ostream& os)
686 // CheckOptions abuses the Argument field to give us the file name.
687 std::string filename = this->CurrentArgument;
688 std::string ext = cmSystemTools::UpperCase(
689 cmSystemTools::GetFilenameLastExtension(filename));
690 std::string name = cmSystemTools::GetFilenameWithoutLastExtension(filename);
692 const char* summary = "cmake --help-custom-modules no longer supported\n";
693 const char* detail =
694 "CMake versions prior to 3.0 exposed their internal module help page\n"
695 "generation functionality through the --help-custom-modules option.\n"
696 "CMake versions 3.0 and above use other means to generate their module\n"
697 "help pages so this functionality is no longer available to be exposed.\n"
698 "\n"
699 "This file was generated as a placeholder to provide this information.\n";
700 if ((ext == ".HTM") || (ext == ".HTML")) {
701 os << "<html><title>" << name << "</title><body>\n"
702 << summary << "<p/>\n"
703 << detail << "</body></html>\n";
704 } else if ((ext.length() == 2) && (ext[1] >= '1') && (ext[1] <= '9')) {
705 /* clang-format off */
706 os <<
707 ".TH " << name << ' ' << ext[1] << " \"" <<
708 cmSystemTools::GetCurrentDateTime("%B %d, %Y") <<
709 "\" \"cmake " << cmVersion::GetCMakeVersion() << "\"\n"
710 ".SH NAME\n"
711 ".PP\n" <<
712 name << " \\- " << summary <<
713 "\n"
714 ".SH DESCRIPTION\n"
715 ".PP\n" <<
716 detail
718 /* clang-format on */
719 } else {
720 os << name << "\n\n" << summary << '\n' << detail;
722 return true;