Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmDocumentation.cxx
blob937260bd972ad1ad0198ae88bfe4e8e1338358ef
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmDocumentation.cxx,v $
5 Language: C++
6 Date: $Date: 2008-03-05 16:05:20 $
7 Version: $Revision: 1.69 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmDocumentation.h"
19 #include "cmSystemTools.h"
20 #include "cmVersion.h"
21 #include <cmsys/Directory.hxx>
24 //----------------------------------------------------------------------------
25 static const char *cmDocumentationStandardOptions[][3] =
27 {"--copyright [file]", "Print the CMake copyright and exit.",
28 "If a file is specified, the copyright is written into it."},
29 {"--help", "Print usage information and exit.",
30 "Usage describes the basic command line interface and its options."},
31 {"--help-full [file]", "Print full help and exit.",
32 "Full help displays most of the documentation provided by the UNIX "
33 "man page. It is provided for use on non-UNIX platforms, but is "
34 "also convenient if the man page is not installed. If a file is "
35 "specified, the help is written into it."},
36 {"--help-html [file]", "Print full help in HTML format.",
37 "This option is used by CMake authors to help produce web pages. "
38 "If a file is specified, the help is written into it."},
39 {"--help-man [file]", "Print full help as a UNIX man page and exit.",
40 "This option is used by the cmake build to generate the UNIX man page. "
41 "If a file is specified, the help is written into it."},
42 {"--version [file]", "Show program name/version banner and exit.",
43 "If a file is specified, the version is written into it."},
44 {0,0,0}
47 //----------------------------------------------------------------------------
48 static const char *cmModulesDocumentationDescription[][3] =
50 {0,
51 " CMake Modules - Modules coming with CMake, the Cross-Platform Makefile "
52 "Generator.", 0},
53 // CMAKE_DOCUMENTATION_OVERVIEW,
54 {0,
55 "This is the documentation for the modules and scripts coming with CMake. "
56 "Using these modules you can check the computer system for "
57 "installed software packages, features of the compiler and the "
58 "existance of headers to name just a few.", 0},
59 {0,0,0}
62 //----------------------------------------------------------------------------
63 static const char *cmCustomModulesDocumentationDescription[][3] =
65 {0,
66 " Custom CMake Modules - Additional Modules for CMake.", 0},
67 // CMAKE_DOCUMENTATION_OVERVIEW,
68 {0,
69 "This is the documentation for additional modules and scripts for CMake. "
70 "Using these modules you can check the computer system for "
71 "installed software packages, features of the compiler and the "
72 "existance of headers to name just a few.", 0},
73 {0,0,0}
76 //----------------------------------------------------------------------------
77 static const char *cmPropertiesDocumentationDescription[][3] =
79 {0,
80 " CMake Properties - Properties supported by CMake, "
81 "the Cross-Platform Makefile Generator.", 0},
82 // CMAKE_DOCUMENTATION_OVERVIEW,
83 {0,
84 "This is the documentation for the properties supported by CMake. "
85 "Properties can have different scopes. They can either be assigned to a "
86 "source file, a directory, a target or globally to CMake. By modifying the "
87 "values of properties the behaviour of the build system can be customized.",
88 0},
89 {0,0,0}
92 //----------------------------------------------------------------------------
93 static const char *cmCompatCommandsDocumentationDescription[][3] =
95 {0,
96 " CMake Compatibility Listfile Commands - "
97 "Obsolete commands supported by CMake for compatibility.", 0},
98 // CMAKE_DOCUMENTATION_OVERVIEW,
99 {0,
100 "This is the documentation for now obsolete listfile commands from previous "
101 "CMake versions, which are still supported for compatibility reasons. You "
102 "should instead use the newer, faster and shinier new commands. ;-)", 0},
103 {0,0,0}
106 //----------------------------------------------------------------------------
107 static const char *cmDocumentationModulesHeader[][3] =
110 "The following modules are provided with CMake. "
111 "They can be used with INCLUDE(ModuleName).", 0},
112 {0,0,0}
115 //----------------------------------------------------------------------------
116 static const char *cmDocumentationCustomModulesHeader[][3] =
119 "The following modules are also available for CMake. "
120 "They can be used with INCLUDE(ModuleName).", 0},
121 {0,0,0}
124 //----------------------------------------------------------------------------
125 static const char *cmDocumentationGeneratorsHeader[][3] =
128 "The following generators are available on this platform:", 0},
129 {0,0,0}
132 //----------------------------------------------------------------------------
133 static const char *cmDocumentationStandardSeeAlso[][3] =
136 "The following resources are available to get help using CMake:", 0},
137 {"Home Page",
138 "http://www.cmake.org",
139 "The primary starting point for learning about CMake."},
140 {"Frequently Asked Questions",
141 "http://www.cmake.org/Wiki/CMake_FAQ",
142 "A Wiki is provided containing answers to frequently asked questions. "},
143 {"Online Documentation",
144 "http://www.cmake.org/HTML/Documentation.html",
145 "Links to available documentation may be found on this web page."},
146 {"Mailing List",
147 "http://www.cmake.org/HTML/MailingLists.html",
148 "For help and discussion about using cmake, a mailing list is provided at "
149 "cmake@cmake.org. "
150 "The list is member-post-only but one may sign up on the CMake web page. "
151 "Please first read the full documentation at "
152 "http://www.cmake.org before posting questions to the list."},
154 "Summary of helpful links:\n"
155 " Home: http://www.cmake.org\n"
156 " Docs: http://www.cmake.org/HTML/Documentation.html\n"
157 " Mail: http://www.cmake.org/HTML/MailingLists.html\n"
158 " FAQ: http://www.cmake.org/Wiki/CMake_FAQ\n"
159 , 0},
160 {0,0,0}
163 //----------------------------------------------------------------------------
164 static const char *cmDocumentationCopyright[][3] =
167 "Copyright (c) 2002 Kitware, Inc., Insight Consortium. "
168 "All rights reserved.", 0},
170 "Redistribution and use in source and binary forms, with or without "
171 "modification, are permitted provided that the following conditions are "
172 "met:", 0},
173 {"",
174 "Redistributions of source code must retain the above copyright notice, "
175 "this list of conditions and the following disclaimer.", 0},
176 {"",
177 "Redistributions in binary form must reproduce the above copyright "
178 "notice, this list of conditions and the following disclaimer in the "
179 "documentation and/or other materials provided with the distribution.",
181 {"",
182 "The names of Kitware, Inc., the Insight Consortium, or the names of "
183 "any consortium members, or of any contributors, may not be used to "
184 "endorse or promote products derived from this software without "
185 "specific prior written permission.", 0},
186 {"",
187 "Modified source versions must be plainly marked as such, and must "
188 "not be misrepresented as being the original software.", 0},
190 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "
191 "``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
192 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR "
193 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR "
194 "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, "
195 "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, "
196 "PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR "
197 "PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF "
198 "LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING "
199 "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS "
200 "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", 0},
201 {0, 0, 0}
204 //----------------------------------------------------------------------------
205 cmDocumentation::cmDocumentation()
206 :CurrentFormatter(0)
208 this->SetForm(TextForm);
210 cmDocumentationSection *sec;
212 sec = new cmDocumentationSection("Author","AUTHOR");
213 sec->Append(cmDocumentationEntry
215 "This manual page was generated by the \"--help-man\" option.",
216 0));
217 this->AllSections["Author"] = sec;
219 sec = new cmDocumentationSection("Copyright","COPYRIGHT");
220 sec->Append(cmDocumentationCopyright);
221 this->AllSections["Copyright"] = sec;
223 sec = new cmDocumentationSection("See Also","SEE ALSO");
224 sec->Append(cmDocumentationStandardSeeAlso);
225 this->AllSections["Standard See Also"] = sec;
227 sec = new cmDocumentationSection("Options","OPTIONS");
228 sec->Append(cmDocumentationStandardOptions);
229 this->AllSections["Options"] = sec;
231 sec = new cmDocumentationSection("Properties","PROPERTIES");
232 sec->Append(cmPropertiesDocumentationDescription);
233 this->AllSections["Properties Description"] = sec;
235 sec = new cmDocumentationSection("Generators","GENERATORS");
236 sec->Append(cmDocumentationGeneratorsHeader);
237 this->AllSections["Generators"] = sec;
239 sec = new cmDocumentationSection("Compatibility Commands",
240 "COMPATIBILITY COMMANDS");
241 sec->Append(cmCompatCommandsDocumentationDescription);
242 this->AllSections["Compatibility Commands"] = sec;
245 this->PropertySections.push_back("Properties of Global Scope");
246 this->PropertySections.push_back("Properties on Directories");
247 this->PropertySections.push_back("Properties on Targets");
248 this->PropertySections.push_back("Properties on Tests");
249 this->PropertySections.push_back("Properties on Source Files");
251 this->VariableSections.push_back("Variables that Provide Information");
252 this->VariableSections.push_back("Variables That Change Behavior");
253 this->VariableSections.push_back("Variables That Describe the System");
254 this->VariableSections.push_back("Variables that Control the Build");
255 this->VariableSections.push_back("Variables for Languages");
258 //----------------------------------------------------------------------------
259 cmDocumentation::~cmDocumentation()
261 for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
262 i != this->ModuleStrings.end(); ++i)
264 delete [] *i;
266 for(std::map<std::string,cmDocumentationSection *>::iterator i =
267 this->AllSections.begin();
268 i != this->AllSections.end(); ++i)
270 delete i->second;
274 //----------------------------------------------------------------------------
275 bool cmDocumentation::PrintCopyright(std::ostream& os)
277 cmDocumentationSection *sec = this->AllSections["Copyright"];
278 const std::vector<cmDocumentationEntry> &entries = sec->GetEntries();
279 for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
280 op != entries.end(); ++op)
282 if(op->Name.size())
284 os << " * ";
285 this->TextFormatter.SetIndent(" ");
286 this->TextFormatter.PrintColumn(os, op->Brief.c_str());
288 else
290 this->TextFormatter.SetIndent("");
291 this->TextFormatter.PrintColumn(os, op->Brief.c_str());
293 os << "\n";
295 return true;
298 //----------------------------------------------------------------------------
299 bool cmDocumentation::PrintVersion(std::ostream& os)
301 os << this->GetNameString() << " version "
302 << cmVersion::GetCMakeVersion() << "\n";
303 return true;
306 //----------------------------------------------------------------------------
307 void cmDocumentation::AddSectionToPrint(const char *section)
309 if (this->AllSections.find(section) != this->AllSections.end())
311 this->PrintSections.push_back(this->AllSections[section]);
315 //----------------------------------------------------------------------------
316 void cmDocumentation::ClearSections()
318 this->PrintSections.erase(this->PrintSections.begin(),
319 this->PrintSections.end());
320 this->ModulesFound.clear();
323 //----------------------------------------------------------------------------
324 bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
326 if ((this->CurrentFormatter->GetForm() != HTMLForm)
327 && (this->CurrentFormatter->GetForm() != DocbookForm)
328 && (this->CurrentFormatter->GetForm() != ManForm))
330 this->PrintVersion(os);
333 switch (ht)
335 case cmDocumentation::Usage:
336 return this->PrintDocumentationUsage(os);
337 case cmDocumentation::Single:
338 return this->PrintDocumentationSingle(os);
339 case cmDocumentation::SingleModule:
340 return this->PrintDocumentationSingleModule(os);
341 case cmDocumentation::SinglePolicy:
342 return this->PrintDocumentationSinglePolicy(os);
343 case cmDocumentation::SingleProperty:
344 return this->PrintDocumentationSingleProperty(os);
345 case cmDocumentation::SingleVariable:
346 return this->PrintDocumentationSingleVariable(os);
347 case cmDocumentation::List:
348 this->PrintDocumentationList(os,"Commands");
349 this->PrintDocumentationList(os,"Compatibility Commands");
350 return true;
351 case cmDocumentation::ModuleList:
352 // find the modules first, print the custom module docs only if
353 // any custom modules have been found actually, Alex
354 this->CreateCustomModulesSection();
355 this->CreateModulesSection();
356 if (this->AllSections.find("Custom CMake Modules")
357 != this->AllSections.end())
359 this->PrintDocumentationList(os,"Custom CMake Modules");
361 this->PrintDocumentationList(os,"Modules");
362 return true;
363 case cmDocumentation::PropertyList:
364 this->PrintDocumentationList(os,"Properties Description");
365 for (std::vector<std::string>::iterator i =
366 this->PropertySections.begin();
367 i != this->PropertySections.end(); ++i)
369 this->PrintDocumentationList(os,i->c_str());
371 return true;
372 case cmDocumentation::VariableList:
373 for (std::vector<std::string>::iterator i =
374 this->VariableSections.begin();
375 i != this->VariableSections.end(); ++i)
377 this->PrintDocumentationList(os,i->c_str());
379 return true;
380 case cmDocumentation::Full:
381 return this->PrintDocumentationFull(os);
382 case cmDocumentation::Modules:
383 return this->PrintDocumentationModules(os);
384 case cmDocumentation::CustomModules:
385 return this->PrintDocumentationCustomModules(os);
386 case cmDocumentation::Policies:
387 return this->PrintDocumentationPolicies(os);
388 case cmDocumentation::Properties:
389 return this->PrintDocumentationProperties(os);
390 case cmDocumentation::Variables:
391 return this->PrintDocumentationVariables(os);
392 case cmDocumentation::Commands:
393 return this->PrintDocumentationCurrentCommands(os);
394 case cmDocumentation::CompatCommands:
395 return this->PrintDocumentationCompatCommands(os);
397 case cmDocumentation::Copyright:
398 return this->PrintCopyright(os);
399 case cmDocumentation::Version:
400 return true;
401 default: return false;
405 //----------------------------------------------------------------------------
406 bool cmDocumentation::CreateModulesSection()
408 cmDocumentationSection *sec =
409 new cmDocumentationSection("Standard CMake Modules", "MODULES");
410 this->AllSections["Modules"] = sec;
411 std::string cmakeModules = this->CMakeRoot;
412 cmakeModules += "/Modules";
413 cmsys::Directory dir;
414 dir.Load(cmakeModules.c_str());
415 if (dir.GetNumberOfFiles() > 0)
417 sec->Append(cmDocumentationModulesHeader[0]);
418 sec->Append(cmModulesDocumentationDescription);
419 this->CreateModuleDocsForDir(dir, *this->AllSections["Modules"]);
421 return true;
424 //----------------------------------------------------------------------------
425 bool cmDocumentation::CreateCustomModulesSection()
427 bool sectionHasHeader = false;
429 std::vector<std::string> dirs;
430 cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
432 for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
433 dirIt != dirs.end();
434 ++dirIt)
436 cmsys::Directory dir;
437 dir.Load(dirIt->c_str());
438 if (dir.GetNumberOfFiles() > 0)
440 if (!sectionHasHeader)
442 cmDocumentationSection *sec =
443 new cmDocumentationSection("Custom CMake Modules","CUSTOM MODULES");
444 this->AllSections["Custom CMake Modules"] = sec;
445 sec->Append(cmDocumentationCustomModulesHeader[0]);
446 sec->Append(cmCustomModulesDocumentationDescription);
447 sectionHasHeader = true;
449 this->CreateModuleDocsForDir
450 (dir, *this->AllSections["Custom CMake Modules"]);
454 return true;
457 //----------------------------------------------------------------------------
458 void cmDocumentation
459 ::CreateModuleDocsForDir(cmsys::Directory& dir,
460 cmDocumentationSection &moduleSection)
462 // sort the files alphabetically, so the docs for one module are easier
463 // to find than if they are in random order
464 std::vector<std::string> sortedFiles;
465 for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
467 sortedFiles.push_back(dir.GetFile(i));
469 std::sort(sortedFiles.begin(), sortedFiles.end());
471 for(std::vector<std::string>::const_iterator fname = sortedFiles.begin();
472 fname!=sortedFiles.end(); ++fname)
474 if(fname->length() > 6)
476 if(fname->substr(fname->length()-6, 6) == ".cmake")
478 std::string moduleName = fname->substr(0, fname->length()-6);
479 // this check is to avoid creating documentation for the modules with
480 // the same name in multiple directories of CMAKE_MODULE_PATH
481 if (this->ModulesFound.find(moduleName) == this->ModulesFound.end())
483 this->ModulesFound.insert(moduleName);
484 std::string path = dir.GetPath();
485 path += "/";
486 path += (*fname);
487 this->CreateSingleModule(path.c_str(), moduleName.c_str(),
488 moduleSection);
495 //----------------------------------------------------------------------------
496 bool cmDocumentation::CreateSingleModule(const char* fname,
497 const char* moduleName,
498 cmDocumentationSection &moduleSection)
500 std::ifstream fin(fname);
501 if(!fin)
503 std::cerr << "Internal error: can not open module." << fname << std::endl;
504 return false;
506 std::string line;
507 std::string text;
508 std::string brief;
509 brief = " ";
510 bool newParagraph = true;
511 while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
513 if(line.size() && line[0] == '#')
515 // blank line
516 if(line.size() <= 2)
518 text += "\n";
519 newParagraph = true;
521 else if(line[2] == '-')
523 brief = line.c_str()+4;
525 else
527 // two spaces
528 if(line[1] == ' ' && line[2] == ' ')
530 if(!newParagraph)
532 text += "\n";
533 newParagraph = true;
535 // Skip #, and leave space for preformatted
536 text += line.c_str()+1;
537 text += "\n";
539 else if(line[1] == ' ')
541 if(!newParagraph)
543 text += " ";
545 newParagraph = false;
546 // skip # and space
547 text += line.c_str()+2;
549 else
551 if(!newParagraph)
553 text += " ";
555 newParagraph = false;
556 // skip #
557 text += line.c_str()+1;
561 else
563 if(text.length() < 2 && brief.length() == 1)
565 return false;
567 char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
568 char* ptext = strcpy(new char[text.length()+1], text.c_str());
569 this->ModuleStrings.push_back(pname);
570 this->ModuleStrings.push_back(ptext);
571 char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
572 this->ModuleStrings.push_back(pbrief);
573 moduleSection.Append(pname, pbrief, ptext);
574 return true;
577 return true;
581 //----------------------------------------------------------------------------
582 bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
584 bool result = true;
586 // Loop over requested documentation types.
587 for(std::vector<RequestedHelpItem>::const_iterator
588 i = this->RequestedHelpItems.begin();
589 i != this->RequestedHelpItems.end();
590 ++i)
592 this->SetForm(i->HelpForm);
593 this->CurrentArgument = i->Argument;
594 // If a file name was given, use it. Otherwise, default to the
595 // given stream.
596 std::ofstream* fout = 0;
597 std::ostream* s = &os;
598 if(i->Filename.length() > 0)
600 fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
601 if(fout)
603 s = fout;
605 else
607 result = false;
611 // Print this documentation type to the stream.
612 if(!this->PrintDocumentation(i->HelpType, *s) || !*s)
614 result = false;
617 // Close the file if we wrote one.
618 if(fout)
620 delete fout;
623 return result;
626 #define GET_OPT_ARGUMENT(target) \
627 if((i+1 < argc) && !this->IsOption(argv[i+1])) \
629 target = argv[i+1]; \
630 i = i+1; \
634 cmDocumentation::Form cmDocumentation::GetFormFromFilename(
635 const std::string& filename)
637 std::string ext = cmSystemTools::GetFilenameExtension(filename);
638 ext = cmSystemTools::UpperCase(ext);
639 if ((ext == ".HTM") || (ext == ".HTML"))
641 return cmDocumentation::HTMLForm;
644 if (ext == ".DOCBOOK")
646 return cmDocumentation::DocbookForm;
649 // ".1" to ".9" should be manpages
650 if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
652 return cmDocumentation::ManForm;
655 return cmDocumentation::TextForm;
658 //----------------------------------------------------------------------------
659 bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
661 // Providing zero arguments gives usage information.
662 if(argc == 1)
664 RequestedHelpItem help;
665 help.HelpType = cmDocumentation::Usage;
666 help.HelpForm = cmDocumentation::UsageForm;
667 this->RequestedHelpItems.push_back(help);
668 return true;
671 // Search for supported help options.
673 bool result = false;
674 for(int i=1; i < argc; ++i)
676 RequestedHelpItem help;
677 // Check if this is a supported help option.
678 if((strcmp(argv[i], "-help") == 0) ||
679 (strcmp(argv[i], "--help") == 0) ||
680 (strcmp(argv[i], "/?") == 0) ||
681 (strcmp(argv[i], "-usage") == 0) ||
682 (strcmp(argv[i], "-h") == 0) ||
683 (strcmp(argv[i], "-H") == 0))
685 help.HelpType = cmDocumentation::Usage;
686 help.HelpForm = cmDocumentation::UsageForm;
687 GET_OPT_ARGUMENT(help.Argument);
688 help.Argument = cmSystemTools::LowerCase(help.Argument);
689 // special case for single command
690 if (!help.Argument.empty())
692 help.HelpType = cmDocumentation::Single;
695 else if(strcmp(argv[i], "--help-properties") == 0)
697 help.HelpType = cmDocumentation::Properties;
698 GET_OPT_ARGUMENT(help.Filename);
699 help.HelpForm = this->GetFormFromFilename(help.Filename);
701 else if(strcmp(argv[i], "--help-policies") == 0)
703 help.HelpType = cmDocumentation::Policies;
704 GET_OPT_ARGUMENT(help.Filename);
705 help.HelpForm = this->GetFormFromFilename(help.Filename);
707 else if(strcmp(argv[i], "--help-variables") == 0)
709 help.HelpType = cmDocumentation::Variables;
710 GET_OPT_ARGUMENT(help.Filename);
711 help.HelpForm = this->GetFormFromFilename(help.Filename);
713 else if(strcmp(argv[i], "--help-modules") == 0)
715 help.HelpType = cmDocumentation::Modules;
716 GET_OPT_ARGUMENT(help.Filename);
717 help.HelpForm = this->GetFormFromFilename(help.Filename);
719 else if(strcmp(argv[i], "--help-custom-modules") == 0)
721 help.HelpType = cmDocumentation::CustomModules;
722 GET_OPT_ARGUMENT(help.Filename);
723 help.HelpForm = this->GetFormFromFilename(help.Filename);
725 else if(strcmp(argv[i], "--help-commands") == 0)
727 help.HelpType = cmDocumentation::Commands;
728 GET_OPT_ARGUMENT(help.Filename);
729 help.HelpForm = this->GetFormFromFilename(help.Filename);
731 else if(strcmp(argv[i], "--help-compatcommands") == 0)
733 help.HelpType = cmDocumentation::CompatCommands;
734 GET_OPT_ARGUMENT(help.Filename);
735 help.HelpForm = this->GetFormFromFilename(help.Filename);
737 else if(strcmp(argv[i], "--help-full") == 0)
739 help.HelpType = cmDocumentation::Full;
740 GET_OPT_ARGUMENT(help.Filename);
741 help.HelpForm = this->GetFormFromFilename(help.Filename);
743 else if(strcmp(argv[i], "--help-html") == 0)
745 help.HelpType = cmDocumentation::Full;
746 GET_OPT_ARGUMENT(help.Filename);
747 help.HelpForm = cmDocumentation::HTMLForm;
749 else if(strcmp(argv[i], "--help-man") == 0)
751 help.HelpType = cmDocumentation::Full;
752 GET_OPT_ARGUMENT(help.Filename);
753 help.HelpForm = cmDocumentation::ManForm;
755 else if(strcmp(argv[i], "--help-command") == 0)
757 help.HelpType = cmDocumentation::Single;
758 GET_OPT_ARGUMENT(help.Argument);
759 GET_OPT_ARGUMENT(help.Filename);
760 help.Argument = cmSystemTools::LowerCase(help.Argument);
761 help.HelpForm = this->GetFormFromFilename(help.Filename);
763 else if(strcmp(argv[i], "--help-module") == 0)
765 help.HelpType = cmDocumentation::SingleModule;
766 GET_OPT_ARGUMENT(help.Argument);
767 GET_OPT_ARGUMENT(help.Filename);
768 help.HelpForm = this->GetFormFromFilename(help.Filename);
770 else if(strcmp(argv[i], "--help-property") == 0)
772 help.HelpType = cmDocumentation::SingleProperty;
773 GET_OPT_ARGUMENT(help.Argument);
774 GET_OPT_ARGUMENT(help.Filename);
775 help.HelpForm = this->GetFormFromFilename(help.Filename);
777 else if(strcmp(argv[i], "--help-policy") == 0)
779 help.HelpType = cmDocumentation::SinglePolicy;
780 GET_OPT_ARGUMENT(help.Argument);
781 GET_OPT_ARGUMENT(help.Filename);
782 help.HelpForm = this->GetFormFromFilename(help.Filename);
784 else if(strcmp(argv[i], "--help-variable") == 0)
786 help.HelpType = cmDocumentation::SingleVariable;
787 GET_OPT_ARGUMENT(help.Argument);
788 GET_OPT_ARGUMENT(help.Filename);
789 help.HelpForm = this->GetFormFromFilename(help.Filename);
791 else if(strcmp(argv[i], "--help-command-list") == 0)
793 help.HelpType = cmDocumentation::List;
794 GET_OPT_ARGUMENT(help.Filename);
795 help.HelpForm = cmDocumentation::TextForm;
797 else if(strcmp(argv[i], "--help-module-list") == 0)
799 help.HelpType = cmDocumentation::ModuleList;
800 GET_OPT_ARGUMENT(help.Filename);
801 help.HelpForm = cmDocumentation::TextForm;
803 else if(strcmp(argv[i], "--help-property-list") == 0)
805 help.HelpType = cmDocumentation::PropertyList;
806 GET_OPT_ARGUMENT(help.Filename);
807 help.HelpForm = cmDocumentation::TextForm;
809 else if(strcmp(argv[i], "--help-variable-list") == 0)
811 help.HelpType = cmDocumentation::VariableList;
812 GET_OPT_ARGUMENT(help.Filename);
813 help.HelpForm = cmDocumentation::TextForm;
815 else if(strcmp(argv[i], "--copyright") == 0)
817 help.HelpType = cmDocumentation::Copyright;
818 GET_OPT_ARGUMENT(help.Filename);
819 help.HelpForm = cmDocumentation::UsageForm;
821 else if((strcmp(argv[i], "--version") == 0) ||
822 (strcmp(argv[i], "-version") == 0) ||
823 (strcmp(argv[i], "/V") == 0))
825 help.HelpType = cmDocumentation::Version;
826 GET_OPT_ARGUMENT(help.Filename);
827 help.HelpForm = cmDocumentation::UsageForm;
829 if(help.HelpType != None)
831 // This is a help option. See if there is a file name given.
832 result = true;
833 this->RequestedHelpItems.push_back(help);
836 return result;
839 //----------------------------------------------------------------------------
840 void cmDocumentation::Print(Form f, std::ostream& os)
842 this->SetForm(f);
843 this->Print(os);
846 //----------------------------------------------------------------------------
847 void cmDocumentation::Print(std::ostream& os)
849 // if the formatter supports it, print a master index for
850 // all sections
851 this->CurrentFormatter->PrintIndex(os, this->PrintSections);
852 for(unsigned int i=0; i < this->PrintSections.size(); ++i)
854 std::string name = this->PrintSections[i]->
855 GetName((this->CurrentFormatter->GetForm()));
856 this->CurrentFormatter->PrintSection(os,*this->PrintSections[i],
857 name.c_str());
861 //----------------------------------------------------------------------------
862 void cmDocumentation::SetName(const char* name)
864 this->NameString = name?name:"";
867 //----------------------------------------------------------------------------
868 void cmDocumentation::SetSection(const char *name,
869 cmDocumentationSection *section)
871 if (this->AllSections.find(name) != this->AllSections.end())
873 delete this->AllSections[name];
875 this->AllSections[name] = section;
878 //----------------------------------------------------------------------------
879 void cmDocumentation::SetSection(const char *name,
880 std::vector<cmDocumentationEntry> &docs)
882 cmDocumentationSection *sec =
883 new cmDocumentationSection(name,
884 cmSystemTools::UpperCase(name).c_str());
885 sec->Append(docs);
886 this->SetSection(name,sec);
889 //----------------------------------------------------------------------------
890 void cmDocumentation::SetSection(const char *name,
891 const char *docs[][3])
893 cmDocumentationSection *sec =
894 new cmDocumentationSection(name,
895 cmSystemTools::UpperCase(name).c_str());
896 sec->Append(docs);
897 this->SetSection(name,sec);
900 //----------------------------------------------------------------------------
901 void cmDocumentation
902 ::SetSections(std::map<std::string,cmDocumentationSection *> &sections)
904 for (std::map<std::string,cmDocumentationSection *>::const_iterator
905 it = sections.begin(); it != sections.end(); ++it)
907 this->SetSection(it->first.c_str(),it->second);
911 //----------------------------------------------------------------------------
912 void cmDocumentation::PrependSection(const char *name,
913 const char *docs[][3])
915 cmDocumentationSection *sec = 0;
916 if (this->AllSections.find(name) == this->AllSections.end())
918 sec = new cmDocumentationSection
919 (name, cmSystemTools::UpperCase(name).c_str());
920 this->SetSection(name,sec);
922 else
924 sec = this->AllSections[name];
926 sec->Prepend(docs);
929 //----------------------------------------------------------------------------
930 void cmDocumentation::PrependSection(const char *name,
931 std::vector<cmDocumentationEntry> &docs)
933 cmDocumentationSection *sec = 0;
934 if (this->AllSections.find(name) == this->AllSections.end())
936 sec = new cmDocumentationSection
937 (name, cmSystemTools::UpperCase(name).c_str());
938 this->SetSection(name,sec);
940 else
942 sec = this->AllSections[name];
944 sec->Prepend(docs);
947 //----------------------------------------------------------------------------
948 void cmDocumentation::AppendSection(const char *name,
949 const char *docs[][3])
951 cmDocumentationSection *sec = 0;
952 if (this->AllSections.find(name) == this->AllSections.end())
954 sec = new cmDocumentationSection
955 (name, cmSystemTools::UpperCase(name).c_str());
956 this->SetSection(name,sec);
958 else
960 sec = this->AllSections[name];
962 sec->Append(docs);
965 //----------------------------------------------------------------------------
966 void cmDocumentation::AppendSection(const char *name,
967 std::vector<cmDocumentationEntry> &docs)
969 cmDocumentationSection *sec = 0;
970 if (this->AllSections.find(name) == this->AllSections.end())
972 sec = new cmDocumentationSection
973 (name, cmSystemTools::UpperCase(name).c_str());
974 this->SetSection(name,sec);
976 else
978 sec = this->AllSections[name];
980 sec->Append(docs);
983 //----------------------------------------------------------------------------
984 void cmDocumentation::AppendSection(const char *name,
985 cmDocumentationEntry &docs)
988 std::vector<cmDocumentationEntry> docsVec;
989 docsVec.push_back(docs);
990 this->AppendSection(name,docsVec);
993 //----------------------------------------------------------------------------
994 void cmDocumentation::PrependSection(const char *name,
995 cmDocumentationEntry &docs)
998 std::vector<cmDocumentationEntry> docsVec;
999 docsVec.push_back(docs);
1000 this->PrependSection(name,docsVec);
1003 //----------------------------------------------------------------------------
1004 void cmDocumentation::SetSeeAlsoList(const char *data[][3])
1006 cmDocumentationSection *sec =
1007 new cmDocumentationSection("See Also", "SEE ALSO");
1008 this->AllSections["See Also"] = sec;
1009 this->SeeAlsoString = ".B ";
1010 int i = 0;
1011 while(data[i][1])
1013 this->SeeAlsoString += data[i][1];
1014 this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
1015 ++i;
1017 sec->Append(0,this->SeeAlsoString.c_str(),0);
1018 sec->Append(cmDocumentationStandardSeeAlso);
1021 //----------------------------------------------------------------------------
1022 bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
1023 const char *section)
1025 if(this->AllSections.find(section) == this->AllSections.end())
1027 os << "Internal error: " << section << " list is empty." << std::endl;
1028 return false;
1030 if(this->CurrentArgument.length() == 0)
1032 os << "Required argument missing.\n";
1033 return false;
1035 const std::vector<cmDocumentationEntry> &entries =
1036 this->AllSections[section]->GetEntries();
1037 for(std::vector<cmDocumentationEntry>::const_iterator ei =
1038 entries.begin();
1039 ei != entries.end(); ++ei)
1041 if(this->CurrentArgument == ei->Name)
1043 this->PrintDocumentationCommand(os, *ei);
1044 return true;
1047 return false;
1050 //----------------------------------------------------------------------------
1051 bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
1053 if (this->PrintDocumentationGeneric(os,"Commands"))
1055 return true;
1057 if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
1059 return true;
1062 // Argument was not a command. Complain.
1063 os << "Argument \"" << this->CurrentArgument.c_str()
1064 << "\" to --help-command is not a CMake command. "
1065 << "Use --help-command-list to see all commands.\n";
1066 return false;
1069 //----------------------------------------------------------------------------
1070 bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
1072 if(this->CurrentArgument.length() == 0)
1074 os << "Argument --help-module needs a module name.\n";
1075 return false;
1078 std::string moduleName;
1079 // find the module
1080 std::vector<std::string> dirs;
1081 cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
1082 for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
1083 dirIt != dirs.end();
1084 ++dirIt)
1086 moduleName = *dirIt;
1087 moduleName += "/";
1088 moduleName += this->CurrentArgument;
1089 moduleName += ".cmake";
1090 if(cmSystemTools::FileExists(moduleName.c_str()))
1092 break;
1094 moduleName = "";
1097 if (moduleName.empty())
1099 moduleName = this->CMakeRoot;
1100 moduleName += "/Modules/";
1101 moduleName += this->CurrentArgument;
1102 moduleName += ".cmake";
1103 if(!cmSystemTools::FileExists(moduleName.c_str()))
1105 moduleName = "";
1109 if(!moduleName.empty())
1111 cmDocumentationSection *sec =
1112 new cmDocumentationSection("Standard CMake Modules", "MODULES");
1113 this->AllSections["Modules"] = sec;
1114 if (this->CreateSingleModule(moduleName.c_str(),
1115 this->CurrentArgument.c_str(),
1116 *this->AllSections["Modules"]))
1118 this->PrintDocumentationCommand
1119 (os, this->AllSections["Modules"]->GetEntries()[0]);
1120 os << "\n Defined in: ";
1121 os << moduleName << "\n";
1122 return true;
1126 // Argument was not a module. Complain.
1127 os << "Argument \"" << this->CurrentArgument.c_str()
1128 << "\" to --help-module is not a CMake module.\n";
1129 return false;
1132 //----------------------------------------------------------------------------
1133 bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
1135 bool done = false;
1136 for (std::vector<std::string>::iterator i =
1137 this->PropertySections.begin();
1138 !done && i != this->PropertySections.end(); ++i)
1140 done = this->PrintDocumentationGeneric(os,i->c_str());
1143 if (done)
1145 return true;
1148 // Argument was not a command. Complain.
1149 os << "Argument \"" << this->CurrentArgument.c_str()
1150 << "\" to --help-property is not a CMake property. "
1151 << "Use --help-property-list to see all properties.\n";
1152 return false;
1155 //----------------------------------------------------------------------------
1156 bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
1158 if (this->PrintDocumentationGeneric(os,"Policies"))
1160 return true;
1163 // Argument was not a command. Complain.
1164 os << "Argument \"" << this->CurrentArgument.c_str()
1165 << "\" to --help-policy is not a CMake policy.\n";
1166 return false;
1169 //----------------------------------------------------------------------------
1170 bool cmDocumentation::PrintDocumentationSingleVariable(std::ostream& os)
1172 bool done = false;
1173 for (std::vector<std::string>::iterator i =
1174 this->VariableSections.begin();
1175 !done && i != this->VariableSections.end(); ++i)
1177 done = this->PrintDocumentationGeneric(os,i->c_str());
1180 if (done)
1182 return true;
1185 // Argument was not a command. Complain.
1186 os << "Argument \"" << this->CurrentArgument.c_str()
1187 << "\" to --help-variable is not a defined variable. "
1188 << "Use --help-variable-list to see all defined variables.\n";
1189 return false;
1192 //----------------------------------------------------------------------------
1193 bool cmDocumentation::PrintDocumentationList(std::ostream& os,
1194 const char *section)
1196 if(this->AllSections.find(section) == this->AllSections.end())
1198 os << "Internal error: " << section << " list is empty." << std::endl;
1199 return false;
1202 const std::vector<cmDocumentationEntry> &entries =
1203 this->AllSections[section]->GetEntries();
1204 for(std::vector<cmDocumentationEntry>::const_iterator ei =
1205 entries.begin();
1206 ei != entries.end(); ++ei)
1208 if(ei->Name.size())
1210 os << ei->Name << std::endl;
1213 return true;
1216 //----------------------------------------------------------------------------
1217 bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
1219 this->ClearSections();
1220 this->AddSectionToPrint("Usage");
1221 this->AddSectionToPrint("Options");
1222 this->AddSectionToPrint("Generators");
1223 this->Print(os);
1224 return true;
1227 //----------------------------------------------------------------------------
1228 bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
1230 this->CreateFullDocumentation();
1231 this->CurrentFormatter->PrintHeader(GetNameString(), os);
1232 this->Print(os);
1233 this->CurrentFormatter->PrintFooter(os);
1234 return true;
1237 //----------------------------------------------------------------------------
1238 bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
1240 this->ClearSections();
1241 this->CreateModulesSection();
1242 this->AddSectionToPrint("Description");
1243 this->AddSectionToPrint("Modules");
1244 this->AddSectionToPrint("Copyright");
1245 this->AddSectionToPrint("See Also");
1246 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1247 this->Print(os);
1248 this->CurrentFormatter->PrintFooter(os);
1249 return true;
1252 //----------------------------------------------------------------------------
1253 bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
1255 this->ClearSections();
1256 this->CreateCustomModulesSection();
1257 this->AddSectionToPrint("Description");
1258 this->AddSectionToPrint("Custom CMake Modules");
1259 // the custom modules are most probably not under Kitware's copyright, Alex
1260 // this->AddSectionToPrint("Copyright");
1261 this->AddSectionToPrint("See Also");
1263 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1264 this->Print(os);
1265 this->CurrentFormatter->PrintFooter(os);
1266 return true;
1269 //----------------------------------------------------------------------------
1270 bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
1272 this->ClearSections();
1273 this->AddSectionToPrint("Description");
1274 this->AddSectionToPrint("Policies");
1275 this->AddSectionToPrint("Copyright");
1276 this->AddSectionToPrint("See Also");
1278 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1279 this->Print(os);
1280 this->CurrentFormatter->PrintFooter(os);
1281 return true;
1284 //----------------------------------------------------------------------------
1285 bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
1287 this->ClearSections();
1288 this->AddSectionToPrint("Properties Description");
1289 for (std::vector<std::string>::iterator i =
1290 this->PropertySections.begin();
1291 i != this->PropertySections.end(); ++i)
1293 this->AddSectionToPrint(i->c_str());
1295 this->AddSectionToPrint("Copyright");
1296 this->AddSectionToPrint("Standard See Also");
1297 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1298 this->Print(os);
1299 this->CurrentFormatter->PrintFooter(os);
1300 return true;
1303 //----------------------------------------------------------------------------
1304 bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
1306 this->ClearSections();
1307 for (std::vector<std::string>::iterator i =
1308 this->VariableSections.begin();
1309 i != this->VariableSections.end(); ++i)
1311 this->AddSectionToPrint(i->c_str());
1313 this->AddSectionToPrint("Copyright");
1314 this->AddSectionToPrint("Standard See Also");
1315 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1316 this->Print(os);
1317 this->CurrentFormatter->PrintFooter(os);
1318 return true;
1321 //----------------------------------------------------------------------------
1322 bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
1324 this->ClearSections();
1325 this->AddSectionToPrint("Commands");
1326 this->AddSectionToPrint("Copyright");
1327 this->AddSectionToPrint("Standard See Also");
1328 this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
1329 this->Print(os);
1330 this->CurrentFormatter->PrintFooter(os);
1331 return true;
1334 //----------------------------------------------------------------------------
1335 bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
1337 this->ClearSections();
1338 this->AddSectionToPrint("Compatibility Commands Description");
1339 this->AddSectionToPrint("Compatibility Commands");
1340 this->AddSectionToPrint("Copyright");
1341 this->AddSectionToPrint("Standard See Also");
1342 this->CurrentFormatter->PrintHeader(GetNameString(), os);
1343 this->Print(os);
1344 this->CurrentFormatter->PrintFooter(os);
1345 return true;
1348 //----------------------------------------------------------------------------
1349 void cmDocumentation
1350 ::PrintDocumentationCommand(std::ostream& os,
1351 const cmDocumentationEntry &entry)
1353 cmDocumentationSection *sec = new cmDocumentationSection("","");
1354 sec->Append(entry);
1355 this->AllSections["temp"] = sec;
1356 this->ClearSections();
1357 this->AddSectionToPrint("temp");
1358 this->Print(os);
1359 this->AllSections.erase("temp");
1360 delete sec;
1363 //----------------------------------------------------------------------------
1364 void cmDocumentation::CreateFullDocumentation()
1366 this->ClearSections();
1367 this->CreateCustomModulesSection();
1368 this->CreateModulesSection();
1370 std::set<std::string> emitted;
1371 this->AddSectionToPrint("Name");
1372 emitted.insert("Name");
1373 this->AddSectionToPrint("Usage");
1374 emitted.insert("Usage");
1375 this->AddSectionToPrint("Description");
1376 emitted.insert("Description");
1377 this->AddSectionToPrint("Options");
1378 emitted.insert("Options");
1379 this->AddSectionToPrint("Generators");
1380 emitted.insert("Generators");
1381 this->AddSectionToPrint("Commands");
1382 emitted.insert("Commands");
1385 this->AddSectionToPrint("Properties Description");
1386 emitted.insert("Properties Description");
1387 for (std::vector<std::string>::iterator i =
1388 this->PropertySections.begin();
1389 i != this->PropertySections.end(); ++i)
1391 this->AddSectionToPrint(i->c_str());
1392 emitted.insert(i->c_str());
1395 emitted.insert("Copyright");
1396 emitted.insert("See Also");
1397 emitted.insert("Standard See Also");
1398 emitted.insert("Author");
1400 // add any sections not yet written out, or to be written out
1401 for (std::map<std::string, cmDocumentationSection*>::iterator i =
1402 this->AllSections.begin();
1403 i != this->AllSections.end(); ++i)
1405 if (emitted.find(i->first) == emitted.end())
1407 this->AddSectionToPrint(i->first.c_str());
1411 this->AddSectionToPrint("Copyright");
1413 if(this->CurrentFormatter->GetForm() == ManForm)
1415 this->AddSectionToPrint("See Also");
1416 this->AddSectionToPrint("Author");
1418 else
1420 this->AddSectionToPrint("Standard See Also");
1424 //----------------------------------------------------------------------------
1425 void cmDocumentation::SetForm(Form f)
1427 switch(f)
1429 case HTMLForm:
1430 this->CurrentFormatter = &this->HTMLFormatter;
1431 break;
1432 case DocbookForm:
1433 this->CurrentFormatter = &this->DocbookFormatter;
1434 break;
1435 case ManForm:
1436 this->CurrentFormatter = &this->ManFormatter;
1437 break;
1438 case TextForm:
1439 this->CurrentFormatter = &this->TextFormatter;
1440 break;
1441 case UsageForm:
1442 this->CurrentFormatter = & this->UsageFormatter;
1443 break;
1448 //----------------------------------------------------------------------------
1449 const char* cmDocumentation::GetNameString() const
1451 if(this->NameString.length() > 0)
1453 return this->NameString.c_str();
1455 else
1457 return "CMake";
1461 //----------------------------------------------------------------------------
1462 bool cmDocumentation::IsOption(const char* arg) const
1464 return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
1465 (strcmp(arg, "/?") == 0));