summaryrefslogtreecommitdiff
path: root/Source/cmDocumentation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmDocumentation.cxx')
-rw-r--r--Source/cmDocumentation.cxx1978
1 files changed, 1978 insertions, 0 deletions
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
new file mode 100644
index 000000000..1b042ae6f
--- /dev/null
+++ b/Source/cmDocumentation.cxx
@@ -0,0 +1,1978 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmDocumentation.h"
+
+#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+
+#include <algorithm>
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationStandardOptions[][3] =
+{
+ {"--copyright [file]", "Print the CMake copyright and exit.",
+ "If a file is specified, the copyright is written into it."},
+ {"--help,-help,-usage,-h,-H,/?", "Print usage information and exit.",
+ "Usage describes the basic command line interface and its options."},
+ {"--help-full [file]", "Print full help and exit.",
+ "Full help displays most of the documentation provided by the UNIX "
+ "man page. It is provided for use on non-UNIX platforms, but is "
+ "also convenient if the man page is not installed. If a file is "
+ "specified, the help is written into it."},
+ {"--help-html [file]", "Print full help in HTML format.",
+ "This option is used by CMake authors to help produce web pages. "
+ "If a file is specified, the help is written into it."},
+ {"--help-man [file]", "Print full help as a UNIX man page and exit.",
+ "This option is used by the cmake build to generate the UNIX man page. "
+ "If a file is specified, the help is written into it."},
+ {"--version,-version,/V [file]",
+ "Show program name/version banner and exit.",
+ "If a file is specified, the version is written into it."},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmModulesDocumentationDescription[][3] =
+{
+ {0,
+ " CMake Modules - Modules coming with CMake, the Cross-Platform Makefile "
+ "Generator.", 0},
+// CMAKE_DOCUMENTATION_OVERVIEW,
+ {0,
+ "This is the documentation for the modules and scripts coming with CMake. "
+ "Using these modules you can check the computer system for "
+ "installed software packages, features of the compiler and the "
+ "existance of headers to name just a few.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmCustomModulesDocumentationDescription[][3] =
+{
+ {0,
+ " Custom CMake Modules - Additional Modules for CMake.", 0},
+// CMAKE_DOCUMENTATION_OVERVIEW,
+ {0,
+ "This is the documentation for additional modules and scripts for CMake. "
+ "Using these modules you can check the computer system for "
+ "installed software packages, features of the compiler and the "
+ "existance of headers to name just a few.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmPropertiesDocumentationDescription[][3] =
+{
+ {0,
+ " CMake Properties - Properties supported by CMake, "
+ "the Cross-Platform Makefile Generator.", 0},
+// CMAKE_DOCUMENTATION_OVERVIEW,
+ {0,
+ "This is the documentation for the properties supported by CMake. "
+ "Properties can have different scopes. They can either be assigned to a "
+ "source file, a directory, a target or globally to CMake. By modifying the "
+ "values of properties the behaviour of the build system can be customized.",
+ 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmCompatCommandsDocumentationDescription[][3] =
+{
+ {0,
+ " CMake Compatibility Listfile Commands - "
+ "Obsolete commands supported by CMake for compatibility.", 0},
+// CMAKE_DOCUMENTATION_OVERVIEW,
+ {0,
+ "This is the documentation for now obsolete listfile commands from previous "
+ "CMake versions, which are still supported for compatibility reasons. You "
+ "should instead use the newer, faster and shinier new commands. ;-)", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationModulesHeader[][3] =
+{
+ {0,
+ "The following modules are provided with CMake. "
+ "They can be used with INCLUDE(ModuleName).", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationCustomModulesHeader[][3] =
+{
+ {0,
+ "The following modules are also available for CMake. "
+ "They can be used with INCLUDE(ModuleName).", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationGeneratorsHeader[][3] =
+{
+ {0,
+ "The following generators are available on this platform:", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationStandardSeeAlso[][3] =
+{
+ {0,
+ "The following resources are available to get help using CMake:", 0},
+ {"Home Page",
+ "http://www.cmake.org",
+ "The primary starting point for learning about CMake."},
+ {"Frequently Asked Questions",
+ "http://www.cmake.org/Wiki/CMake_FAQ",
+ "A Wiki is provided containing answers to frequently asked questions. "},
+ {"Online Documentation",
+ "http://www.cmake.org/HTML/Documentation.html",
+ "Links to available documentation may be found on this web page."},
+ {"Mailing List",
+ "http://www.cmake.org/HTML/MailingLists.html",
+ "For help and discussion about using cmake, a mailing list is provided at "
+ "cmake@cmake.org. "
+ "The list is member-post-only but one may sign up on the CMake web page. "
+ "Please first read the full documentation at "
+ "http://www.cmake.org before posting questions to the list."},
+ {0,
+ "Summary of helpful links:\n"
+ " Home: http://www.cmake.org\n"
+ " Docs: http://www.cmake.org/HTML/Documentation.html\n"
+ " Mail: http://www.cmake.org/HTML/MailingLists.html\n"
+ " FAQ: http://www.cmake.org/Wiki/CMake_FAQ\n"
+ , 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationCopyright[][3] =
+{
+ {0,
+ "Copyright 2000-2009 Kitware, Inc., Insight Software Consortium. "
+ "All rights reserved.", 0},
+ {0,
+ "Redistribution and use in source and binary forms, with or without "
+ "modification, are permitted provided that the following conditions are "
+ "met:", 0},
+ {"",
+ "Redistributions of source code must retain the above copyright notice, "
+ "this list of conditions and the following disclaimer.", 0},
+ {"",
+ "Redistributions in binary form must reproduce the above copyright "
+ "notice, this list of conditions and the following disclaimer in the "
+ "documentation and/or other materials provided with the distribution.",
+ 0},
+ {"",
+ "Neither the names of Kitware, Inc., the Insight Software Consortium, "
+ "nor the names of their contributors may be used to endorse or promote "
+ "products derived from this software without specific prior written "
+ "permission.", 0},
+ {0,
+ "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "
+ "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
+ "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR "
+ "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT "
+ "HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, "
+ "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT "
+ "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, "
+ "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY "
+ "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT "
+ "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "
+ "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ 0},
+ {0, 0, 0}
+};
+
+//----------------------------------------------------------------------------
+#define DOCUMENT_INTRO(type, default_name, desc) \
+ static char const *cmDocumentation##type##Intro[2] = { default_name, desc };
+#define GET_DOCUMENT_INTRO(type) cmDocumentation##type##Intro
+
+DOCUMENT_INTRO(Modules, "cmakemodules",
+ "Reference of available CMake modules.");
+DOCUMENT_INTRO(CustomModules, "cmakecustommodules",
+ "Reference of available CMake custom modules.");
+DOCUMENT_INTRO(Policies, "cmakepolicies",
+ "Reference of CMake policies.");
+DOCUMENT_INTRO(Properties, "cmakeprops",
+ "Reference of CMake properties.");
+DOCUMENT_INTRO(Variables, "cmakevars",
+ "Reference of CMake variables.");
+DOCUMENT_INTRO(Commands, "cmakecommands",
+ "Reference of available CMake commands.");
+DOCUMENT_INTRO(CompatCommands, "cmakecompat",
+ "Reference of CMake compatibility commands.");
+
+//----------------------------------------------------------------------------
+cmDocumentation::cmDocumentation()
+:CurrentFormatter(0)
+{
+ this->SetForm(TextForm, 0);
+ this->addCommonStandardDocSections();
+ this->ShowGenerators = true;
+}
+
+//----------------------------------------------------------------------------
+cmDocumentation::~cmDocumentation()
+{
+ for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
+ i != this->ModuleStrings.end(); ++i)
+ {
+ delete [] *i;
+ }
+ for(std::map<std::string,cmDocumentationSection *>::iterator i =
+ this->AllSections.begin();
+ i != this->AllSections.end(); ++i)
+ {
+ delete i->second;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintCopyright(std::ostream& os)
+{
+ cmDocumentationSection *sec = this->AllSections["Copyright"];
+ const std::vector<cmDocumentationEntry> &entries = sec->GetEntries();
+ for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
+ op != entries.end(); ++op)
+ {
+ if(op->Name.size())
+ {
+ os << " * ";
+ this->TextFormatter.SetIndent(" ");
+ this->TextFormatter.PrintColumn(os, op->Brief.c_str());
+ }
+ else
+ {
+ this->TextFormatter.SetIndent("");
+ this->TextFormatter.PrintColumn(os, op->Brief.c_str());
+ }
+ os << "\n";
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintVersion(std::ostream& os)
+{
+ os << this->GetNameString() << " version "
+ << cmVersion::GetCMakeVersion() << "\n";
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AddSectionToPrint(const char *section)
+{
+ if (this->AllSections.find(section) != this->AllSections.end())
+ {
+ this->PrintSections.push_back(this->AllSections[section]);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::ClearSections()
+{
+ this->PrintSections.erase(this->PrintSections.begin(),
+ this->PrintSections.end());
+ this->ModulesFound.clear();
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AddDocumentIntroToPrint(const char* intro[2])
+{
+ const char* docname = this->GetDocName(false);
+ if(intro && docname)
+ {
+ cmDocumentationSection* section;
+ std::string desc("");
+
+ desc += docname;
+ desc += " - ";
+ desc += intro[1];
+
+ section = new cmDocumentationSection("Introduction", "NAME");
+ section->Append(0, desc.c_str(), 0);
+ this->PrintSections.push_back(section);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os,
+ const char* docname)
+{
+ if ((this->CurrentFormatter->GetForm() != HTMLForm)
+ && (this->CurrentFormatter->GetForm() != DocbookForm)
+ && (this->CurrentFormatter->GetForm() != ManForm))
+ {
+ this->PrintVersion(os);
+ }
+
+ // Handle Document Name. docname==0 disables intro.
+ this->SetDocName("");
+ if (docname)
+ {
+ if (*docname)
+ this->SetDocName(docname);
+ else // empty string was given. select default if possible
+ this->SetDocName(this->GetDefaultDocName(ht));
+ }
+
+ switch (ht)
+ {
+ case cmDocumentation::Usage:
+ return this->PrintDocumentationUsage(os);
+ case cmDocumentation::Single:
+ return this->PrintDocumentationSingle(os);
+ case cmDocumentation::SingleModule:
+ return this->PrintDocumentationSingleModule(os);
+ case cmDocumentation::SinglePolicy:
+ return this->PrintDocumentationSinglePolicy(os);
+ case cmDocumentation::SingleProperty:
+ return this->PrintDocumentationSingleProperty(os);
+ case cmDocumentation::SingleVariable:
+ return this->PrintDocumentationSingleVariable(os);
+ case cmDocumentation::List:
+ this->PrintDocumentationList(os,"Commands");
+ this->PrintDocumentationList(os,"Compatibility Commands");
+ return true;
+ case cmDocumentation::ModuleList:
+ // find the modules first, print the custom module docs only if
+ // any custom modules have been found actually, Alex
+ this->CreateCustomModulesSection();
+ this->CreateModulesSection();
+ if (this->AllSections.find("Custom CMake Modules")
+ != this->AllSections.end())
+ {
+ this->PrintDocumentationList(os,"Custom CMake Modules");
+ }
+ this->PrintDocumentationList(os,"Modules");
+ return true;
+ case cmDocumentation::PropertyList:
+ this->PrintDocumentationList(os,"Properties Description");
+ for (std::vector<std::string>::iterator i =
+ this->PropertySections.begin();
+ i != this->PropertySections.end(); ++i)
+ {
+ this->PrintDocumentationList(os,i->c_str());
+ }
+ return true;
+ case cmDocumentation::VariableList:
+ for (std::vector<std::string>::iterator i =
+ this->VariableSections.begin();
+ i != this->VariableSections.end(); ++i)
+ {
+ this->PrintDocumentationList(os,i->c_str());
+ }
+ return true;
+ case cmDocumentation::Full:
+ return this->PrintDocumentationFull(os);
+ case cmDocumentation::Modules:
+ return this->PrintDocumentationModules(os);
+ case cmDocumentation::CustomModules:
+ return this->PrintDocumentationCustomModules(os);
+ case cmDocumentation::Policies:
+ return this->PrintDocumentationPolicies(os);
+ case cmDocumentation::Properties:
+ return this->PrintDocumentationProperties(os);
+ case cmDocumentation::Variables:
+ return this->PrintDocumentationVariables(os);
+ case cmDocumentation::Commands:
+ return this->PrintDocumentationCurrentCommands(os);
+ case cmDocumentation::CompatCommands:
+ return this->PrintDocumentationCompatCommands(os);
+
+ case cmDocumentation::Copyright:
+ return this->PrintCopyright(os);
+ case cmDocumentation::Version:
+ return true;
+ default: return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::CreateModulesSection()
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection("Standard CMake Modules", "MODULES");
+ this->AllSections["Modules"] = sec;
+ std::string cmakeModules = this->CMakeRoot;
+ cmakeModules += "/Modules";
+ cmsys::Directory dir;
+ dir.Load(cmakeModules.c_str());
+ if (dir.GetNumberOfFiles() > 0)
+ {
+ sec->Append(cmDocumentationModulesHeader[0]);
+ sec->Append(cmModulesDocumentationDescription);
+ this->CreateModuleDocsForDir(dir, *this->AllSections["Modules"]);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::CreateCustomModulesSection()
+{
+ bool sectionHasHeader = false;
+
+ std::vector<std::string> dirs;
+ cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
+
+ for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
+ dirIt != dirs.end();
+ ++dirIt)
+ {
+ cmsys::Directory dir;
+ dir.Load(dirIt->c_str());
+ if (dir.GetNumberOfFiles() > 0)
+ {
+ if (!sectionHasHeader)
+ {
+ cmDocumentationSection *sec =
+ new cmDocumentationSection("Custom CMake Modules","CUSTOM MODULES");
+ this->AllSections["Custom CMake Modules"] = sec;
+ sec->Append(cmDocumentationCustomModulesHeader[0]);
+ sec->Append(cmCustomModulesDocumentationDescription);
+ sectionHasHeader = true;
+ }
+ this->CreateModuleDocsForDir
+ (dir, *this->AllSections["Custom CMake Modules"]);
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation
+::CreateModuleDocsForDir(cmsys::Directory& dir,
+ cmDocumentationSection &moduleSection)
+{
+ // sort the files alphabetically, so the docs for one module are easier
+ // to find than if they are in random order
+ std::vector<std::string> sortedFiles;
+ for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
+ {
+ sortedFiles.push_back(dir.GetFile(i));
+ }
+ std::sort(sortedFiles.begin(), sortedFiles.end());
+
+ for(std::vector<std::string>::const_iterator fname = sortedFiles.begin();
+ fname!=sortedFiles.end(); ++fname)
+ {
+ if(fname->length() > 6)
+ {
+ if(fname->substr(fname->length()-6, 6) == ".cmake")
+ {
+ std::string moduleName = fname->substr(0, fname->length()-6);
+ // this check is to avoid creating documentation for the modules with
+ // the same name in multiple directories of CMAKE_MODULE_PATH
+ if (this->ModulesFound.find(moduleName) == this->ModulesFound.end())
+ {
+ this->ModulesFound.insert(moduleName);
+ std::string path = dir.GetPath();
+ path += "/";
+ path += (*fname);
+ this->CreateSingleModule(path.c_str(), moduleName.c_str(),
+ moduleSection);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::CreateSingleModule(const char* fname,
+ const char* moduleName,
+ cmDocumentationSection &moduleSection)
+{
+ std::ifstream fin(fname);
+ if(!fin)
+ {
+ std::cerr << "Internal error: can not open module." << fname << std::endl;
+ return false;
+ }
+ std::string line;
+ std::string text;
+ std::string brief;
+ brief = " ";
+ bool newParagraph = true;
+ while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
+ {
+ if(line.size() && line[0] == '#')
+ {
+ /* line beginnings with ## are mark-up ignore them */
+ if (line.size()>=2 && line[1] == '#') continue;
+ // blank line
+ if(line.size() <= 2)
+ {
+ text += "\n";
+ newParagraph = true;
+ }
+ else if(line[2] == '-')
+ {
+ brief = line.c_str()+4;
+ }
+ else
+ {
+ // two spaces
+ if(line[1] == ' ' && line[2] == ' ')
+ {
+ if(!newParagraph)
+ {
+ text += "\n";
+ newParagraph = true;
+ }
+ // Skip #, and leave space for preformatted
+ text += line.c_str()+1;
+ text += "\n";
+ }
+ else if(line[1] == ' ')
+ {
+ if(!newParagraph)
+ {
+ text += " ";
+ }
+ newParagraph = false;
+ // skip # and space
+ text += line.c_str()+2;
+ }
+ else
+ {
+ if(!newParagraph)
+ {
+ text += " ";
+ }
+ newParagraph = false;
+ // skip #
+ text += line.c_str()+1;
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(text.length() < 2 && brief.length() == 1)
+ {
+ return false;
+ }
+
+ char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
+ char* ptext = strcpy(new char[text.length()+1], text.c_str());
+ this->ModuleStrings.push_back(pname);
+ this->ModuleStrings.push_back(ptext);
+ char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
+ this->ModuleStrings.push_back(pbrief);
+ moduleSection.Append(pname, pbrief, ptext);
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
+{
+ bool result = true;
+
+ // Loop over requested documentation types.
+ for(std::vector<RequestedHelpItem>::const_iterator
+ i = this->RequestedHelpItems.begin();
+ i != this->RequestedHelpItems.end();
+ ++i)
+ {
+ this->SetForm(i->HelpForm, i->ManSection);
+ this->CurrentArgument = i->Argument;
+ // If a file name was given, use it. Otherwise, default to the
+ // given stream.
+ std::ofstream* fout = 0;
+ std::ostream* s = &os;
+ std::string docname("");
+ if(i->Filename.length() > 0)
+ {
+ fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
+ if(fout)
+ {
+ s = fout;
+ }
+ else
+ {
+ result = false;
+ }
+ if(i->Filename != "-")
+ {
+ docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
+ }
+ }
+
+ // Print this documentation type to the stream.
+ if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
+ {
+ result = false;
+ }
+
+ // Close the file if we wrote one.
+ if(fout)
+ {
+ delete fout;
+ }
+ }
+ return result;
+}
+
+#define GET_OPT_ARGUMENT(target) \
+ if((i+1 < argc) && !this->IsOption(argv[i+1])) \
+ { \
+ target = argv[i+1]; \
+ i = i+1; \
+ };
+
+
+cmDocumentation::Form cmDocumentation::GetFormFromFilename(
+ const std::string& filename,
+ int* manSection)
+{
+ std::string ext = cmSystemTools::GetFilenameLastExtension(filename);
+ ext = cmSystemTools::UpperCase(ext);
+ if ((ext == ".HTM") || (ext == ".HTML"))
+ {
+ return cmDocumentation::HTMLForm;
+ }
+
+ if (ext == ".DOCBOOK")
+ {
+ return cmDocumentation::DocbookForm;
+ }
+
+ // ".1" to ".9" should be manpages
+ if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
+ {
+ if (manSection)
+ {
+ *manSection = ext[1] - '0';
+ }
+ return cmDocumentation::ManForm;
+ }
+
+ return cmDocumentation::TextForm;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCommonStandardDocSections()
+{
+ cmDocumentationSection *sec;
+
+ sec = new cmDocumentationSection("Author","AUTHOR");
+ sec->Append(cmDocumentationEntry
+ (0,
+ "This manual page was generated by the \"--help-man\" option.",
+ 0));
+ this->AllSections["Author"] = sec;
+
+ sec = new cmDocumentationSection("Copyright","COPYRIGHT");
+ sec->Append(cmDocumentationCopyright);
+ this->AllSections["Copyright"] = sec;
+
+ sec = new cmDocumentationSection("See Also","SEE ALSO");
+ sec->Append(cmDocumentationStandardSeeAlso);
+ this->AllSections["Standard See Also"] = sec;
+
+ sec = new cmDocumentationSection("Options","OPTIONS");
+ sec->Append(cmDocumentationStandardOptions);
+ this->AllSections["Options"] = sec;
+
+ sec = new cmDocumentationSection("Compatibility Commands",
+ "COMPATIBILITY COMMANDS");
+ sec->Append(cmCompatCommandsDocumentationDescription);
+ this->AllSections["Compatibility Commands"] = sec;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCMakeStandardDocSections()
+{
+ cmDocumentationSection *sec;
+
+ sec = new cmDocumentationSection("Properties","PROPERTIES");
+ sec->Append(cmPropertiesDocumentationDescription);
+ this->AllSections["Properties Description"] = sec;
+
+ sec = new cmDocumentationSection("Generators","GENERATORS");
+ sec->Append(cmDocumentationGeneratorsHeader);
+ this->AllSections["Generators"] = sec;
+
+ this->PropertySections.push_back("Properties of Global Scope");
+ this->PropertySections.push_back("Properties on Directories");
+ this->PropertySections.push_back("Properties on Targets");
+ this->PropertySections.push_back("Properties on Tests");
+ this->PropertySections.push_back("Properties on Source Files");
+ this->PropertySections.push_back("Properties on Cache Entries");
+
+ this->VariableSections.push_back("Variables that Provide Information");
+ this->VariableSections.push_back("Variables That Change Behavior");
+ this->VariableSections.push_back("Variables That Describe the System");
+ this->VariableSections.push_back("Variables that Control the Build");
+ this->VariableSections.push_back("Variables for Languages");
+
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCTestStandardDocSections()
+{
+ // This is currently done for backward compatibility reason
+ // We may suppress some of these.
+ addCMakeStandardDocSections();
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCPackStandardDocSections()
+{
+ cmDocumentationSection *sec;
+
+ sec = new cmDocumentationSection("Generators","GENERATORS");
+ sec->Append(cmDocumentationGeneratorsHeader);
+ this->AllSections["Generators"] = sec;
+
+ this->VariableSections.push_back(
+ "Variables common to all CPack generators");
+}
+
+void cmDocumentation::addAutomaticVariableSections(const std::string& section)
+{
+ std::vector<std::string>::iterator it;
+ it = std::find(this->VariableSections.begin(),
+ this->VariableSections.end(),
+ section);
+ /* if the section does not exist then add it */
+ if (it==this->VariableSections.end())
+ {
+ this->VariableSections.push_back(section);
+ }
+}
+//----------------------------------------------------------------------------
+int cmDocumentation::getDocumentedModulesListInDir(
+ std::string path,
+ std::string globExpr,
+ documentedModulesList_t& docedModuleList)
+{
+ cmsys::Glob gl;
+ std::string findExpr;
+ std::vector<std::string> files;
+ std::string line;
+ documentedModuleSectionPair_t docPair;
+ int nbDocumentedModules = 0;
+
+ findExpr = path + "/" + globExpr;
+ if (gl.FindFiles(findExpr))
+ {
+ files = gl.GetFiles();
+ for (std::vector<std::string>::iterator itf=files.begin();
+ itf!=files.end();++itf)
+ {
+ std::ifstream fin((*itf).c_str());
+ // file access trouble ignore it (ignore this kind of error)
+ if (!fin) continue;
+ /* read first line in order to get doc section */
+ if (cmSystemTools::GetLineFromStream(fin, line))
+ {
+ /* Doc section indicates that
+ * this file has structured doc in it.
+ */
+ if (line.find("##section")!=std::string::npos)
+ {
+ // ok found one more documented module
+ ++nbDocumentedModules;
+ docPair.first = *itf;
+ // 10 is the size of '##section' + 1
+ docPair.second = line.substr(10,std::string::npos);
+ docedModuleList.push_back(docPair);
+ }
+ // No else if no section is found (undocumented module)
+ }
+ // No else cannot read first line (ignore this kind of error)
+ line = "";
+ }
+ }
+ if (nbDocumentedModules>0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+static void trim(std::string& s)
+{
+ std::string::size_type pos = s.find_last_not_of(' ');
+ if(pos != std::string::npos)
+ {
+ s.erase(pos + 1);
+ pos = s.find_first_not_of(' ');
+ if(pos != std::string::npos) s.erase(0, pos);
+ }
+ else
+ {
+ s.erase(s.begin(), s.end());
+ }
+}
+
+int cmDocumentation::GetStructuredDocFromFile(
+ const char* fname,
+ std::vector<cmDocumentationEntry>& commands,
+ cmake* cm)
+{
+ typedef enum sdoce {
+ SDOC_NONE, SDOC_MODULE, SDOC_MACRO, SDOC_FUNCTION, SDOC_VARIABLE,
+ SDOC_SECTION,
+ SDOC_UNKNOWN} sdoc_t;
+ int nbDocItemFound = 0;
+ int docCtxIdx = 0;
+ std::vector<int> docContextStack(60);
+ docContextStack[docCtxIdx]=SDOC_NONE;
+ cmDocumentationEntry e;
+ std::ifstream fin(fname);
+ if(!fin)
+ {
+ return nbDocItemFound;
+ }
+ std::string section;
+ std::string name;
+ std::string full;
+ std::string brief;
+ std::string line;
+ bool newCtx = false; /* we've just entered ##<beginkey> context */
+ bool inBrief = false; /* we are currently parsing brief desc. */
+ bool inFullFirstParagraph = false; /* we are currently parsing full
+ desc. first paragraph */
+ brief = "";
+ full = "";
+ bool newParagraph = true;
+ while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
+ {
+ if(line.size() && line[0] == '#')
+ {
+ /* handle structured doc context */
+ if ((line.size()>=2) && line[1]=='#')
+ {
+ /* markup word is following '##' stopping at first space
+ * Some markup word like 'section' may have more characters
+ * following but we don't handle those here.
+ */
+ std::string mkword = line.substr(2,line.find(' ',2)-2);
+ if (mkword=="macro")
+ {
+ docCtxIdx++;
+ docContextStack[docCtxIdx]=SDOC_MACRO;
+ newCtx = true;
+ }
+ else if (mkword=="variable")
+ {
+ docCtxIdx++;
+ docContextStack[docCtxIdx]=SDOC_VARIABLE;
+ newCtx = true;
+ }
+ else if (mkword=="function")
+ {
+ docCtxIdx++;
+ docContextStack[docCtxIdx]=SDOC_FUNCTION;
+ newCtx = true;
+ }
+ else if (mkword=="module")
+ {
+ docCtxIdx++;
+ docContextStack[docCtxIdx]=SDOC_MODULE;
+ newCtx = true;
+ }
+ else if (mkword=="section")
+ {
+ docCtxIdx++;
+ docContextStack[docCtxIdx]=SDOC_SECTION;
+ // 10 is the size of '##section' + 1
+ section = line.substr(10,std::string::npos);
+ /* drop the rest of the line */
+ line = "";
+ newCtx = true;
+ }
+ else if (mkword.substr(0,3)=="end")
+ {
+ switch (docContextStack[docCtxIdx]) {
+ case SDOC_MACRO:
+ /* for now MACRO and FUNCTION are handled in the same way */
+ case SDOC_FUNCTION:
+ commands.push_back(cmDocumentationEntry(name.c_str(),
+ brief.c_str(),full.c_str()));
+ break;
+ case SDOC_VARIABLE:
+ this->addAutomaticVariableSections(section);
+ cm->DefineProperty
+ (name.c_str(), cmProperty::VARIABLE,
+ brief.c_str(),
+ full.c_str(),false,
+ section.c_str());
+ break;
+ case SDOC_MODULE:
+ /* not implemented */
+ break;
+ case SDOC_SECTION:
+ /* not implemented */
+ break;
+ default:
+ /* ignore other cases */
+ break;
+ }
+ docCtxIdx--;
+ newCtx = false;
+ ++nbDocItemFound;
+ }
+ else
+ {
+ // error out unhandled context
+ return nbDocItemFound;
+ }
+ /* context is set go to next doc line */
+ continue;
+ }
+
+ // Now parse the text attached to the context
+
+ // The first line after the context mark-up contains::
+ // name - brief until. (brief is dot terminated or
+ // followed by a blank line)
+ if (newCtx)
+ {
+ // no brief (for easy variable definition)
+ if (line.find("-")==std::string::npos)
+ {
+ name = line.substr(1,std::string::npos);
+ trim(name);
+ brief = "";
+ inBrief = false;
+ full = "";
+ }
+ // here we have a name and brief beginning
+ else
+ {
+ name = line.substr(1,line.find("-")-1);
+ trim(name);
+ // we are parsing the brief context
+ brief = line.substr(line.find("-")+1,std::string::npos);
+ trim(brief);
+ // Brief may already be terminated on the first line
+ if (brief.find('.')!=std::string::npos)
+ {
+ inBrief = false;
+ full = brief.substr(brief.find('.')+1,std::string::npos);
+ trim(full);
+ inFullFirstParagraph = true;
+ brief = brief.substr(0,brief.find('.'));
+ }
+ // brief is continued on following lines
+ else
+ {
+ inBrief = true;
+ full = "";
+ }
+ }
+ newCtx = false;
+ continue;
+ }
+ // blank line
+ if(line.size() <= 2)
+ {
+ if (inBrief) {
+ inBrief = false;
+ full = "";
+ } else {
+ if (full.length()>0)
+ {
+ full += "\n";
+ }
+ // the first paragraph of full has ended
+ inFullFirstParagraph = false;
+ }
+ newParagraph = true;
+ }
+ // brief is terminated by '.'
+ else if (inBrief && (line.find('.')!=std::string::npos))
+ {
+ /* the brief just ended */
+ inBrief = false;
+ std::string endBrief = line.substr(1,line.find('.'));
+ trim(endBrief);
+ trim(brief);
+ brief += " " + endBrief;
+ full += line.substr(line.find('.')+1,std::string::npos);
+ trim(full);
+ inFullFirstParagraph = true;
+ }
+ // we handle full text or multi-line brief.
+ else
+ {
+ std::string* text;
+ if (inBrief)
+ {
+ text = &brief;
+ }
+ else
+ {
+ text = &full;
+ }
+ // two spaces
+ if(line[1] == ' ' && line[2] == ' ')
+ {
+ // there is no "full first paragraph at all."
+ if (line[3] == ' ')
+ {
+ inFullFirstParagraph = false;
+ }
+
+ if(!newParagraph && !inFullFirstParagraph)
+ {
+ *text += "\n";
+ newParagraph = true;
+ }
+ // Skip #, and leave space for pre-formatted
+ if (inFullFirstParagraph)
+ {
+ std::string temp = line.c_str()+1;
+ trim(temp);
+ *text += " " + temp;
+ }
+ else
+ {
+ *text += line.c_str()+1;
+ *text += "\n";
+ }
+ }
+ else if(line[1] == ' ')
+ {
+ if(!newParagraph)
+ {
+ *text += " ";
+ }
+ newParagraph = false;
+ // skip # and space
+ *text += line.c_str()+2;
+ }
+ else
+ {
+ if(!newParagraph)
+ {
+ *text += " ";
+ }
+ newParagraph = false;
+ // skip #
+ *text += line.c_str()+1;
+ }
+ }
+ }
+ /* next line is not the first context line */
+ newCtx = false;
+ }
+ return nbDocItemFound;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
+ const char* exitOpt)
+{
+ // Providing zero arguments gives usage information.
+ if(argc == 1)
+ {
+ RequestedHelpItem help;
+ help.HelpType = cmDocumentation::Usage;
+ help.HelpForm = cmDocumentation::UsageForm;
+ this->RequestedHelpItems.push_back(help);
+ return true;
+ }
+
+ // Search for supported help options.
+
+ bool result = false;
+ for(int i=1; i < argc; ++i)
+ {
+ if(exitOpt && strcmp(argv[i], exitOpt) == 0)
+ {
+ return result;
+ }
+ RequestedHelpItem help;
+ // Check if this is a supported help option.
+ if((strcmp(argv[i], "-help") == 0) ||
+ (strcmp(argv[i], "--help") == 0) ||
+ (strcmp(argv[i], "/?") == 0) ||
+ (strcmp(argv[i], "-usage") == 0) ||
+ (strcmp(argv[i], "-h") == 0) ||
+ (strcmp(argv[i], "-H") == 0))
+ {
+ help.HelpType = cmDocumentation::Usage;
+ help.HelpForm = cmDocumentation::UsageForm;
+ GET_OPT_ARGUMENT(help.Argument);
+ help.Argument = cmSystemTools::LowerCase(help.Argument);
+ // special case for single command
+ if (!help.Argument.empty())
+ {
+ help.HelpType = cmDocumentation::Single;
+ }
+ }
+ else if(strcmp(argv[i], "--help-properties") == 0)
+ {
+ help.HelpType = cmDocumentation::Properties;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-policies") == 0)
+ {
+ help.HelpType = cmDocumentation::Policies;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-variables") == 0)
+ {
+ help.HelpType = cmDocumentation::Variables;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-modules") == 0)
+ {
+ help.HelpType = cmDocumentation::Modules;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-custom-modules") == 0)
+ {
+ help.HelpType = cmDocumentation::CustomModules;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-commands") == 0)
+ {
+ help.HelpType = cmDocumentation::Commands;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-compatcommands") == 0)
+ {
+ help.HelpType = cmDocumentation::CompatCommands;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-full") == 0)
+ {
+ help.HelpType = cmDocumentation::Full;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-html") == 0)
+ {
+ help.HelpType = cmDocumentation::Full;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::HTMLForm;
+ }
+ else if(strcmp(argv[i], "--help-man") == 0)
+ {
+ help.HelpType = cmDocumentation::Full;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::ManForm;
+ help.ManSection = 1;
+ }
+ else if(strcmp(argv[i], "--help-command") == 0)
+ {
+ help.HelpType = cmDocumentation::Single;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.Argument = cmSystemTools::LowerCase(help.Argument);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-module") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleModule;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-property") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleProperty;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-policy") == 0)
+ {
+ help.HelpType = cmDocumentation::SinglePolicy;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-variable") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleVariable;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-command-list") == 0)
+ {
+ help.HelpType = cmDocumentation::List;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-module-list") == 0)
+ {
+ help.HelpType = cmDocumentation::ModuleList;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-property-list") == 0)
+ {
+ help.HelpType = cmDocumentation::PropertyList;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-variable-list") == 0)
+ {
+ help.HelpType = cmDocumentation::VariableList;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--copyright") == 0)
+ {
+ help.HelpType = cmDocumentation::Copyright;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::UsageForm;
+ }
+ else if((strcmp(argv[i], "--version") == 0) ||
+ (strcmp(argv[i], "-version") == 0) ||
+ (strcmp(argv[i], "/V") == 0))
+ {
+ help.HelpType = cmDocumentation::Version;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::UsageForm;
+ }
+ if(help.HelpType != None)
+ {
+ // This is a help option. See if there is a file name given.
+ result = true;
+ this->RequestedHelpItems.push_back(help);
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::Print(Form f, int manSection, std::ostream& os)
+{
+ this->SetForm(f, manSection);
+ this->Print(os);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::Print(std::ostream& os)
+{
+ // if the formatter supports it, print a master index for
+ // all sections
+ this->CurrentFormatter->PrintIndex(os, this->PrintSections);
+ for(unsigned int i=0; i < this->PrintSections.size(); ++i)
+ {
+ std::string name = this->PrintSections[i]->
+ GetName((this->CurrentFormatter->GetForm()));
+ this->CurrentFormatter->PrintSection(os,*this->PrintSections[i],
+ name.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetName(const char* name)
+{
+ this->NameString = name?name:"";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetDocName(const char *docname)
+{
+ this->DocName = docname?docname:"";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ cmDocumentationSection *section)
+{
+ if (this->AllSections.find(name) != this->AllSections.end())
+ {
+ delete this->AllSections[name];
+ }
+ this->AllSections[name] = section;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection(name,
+ cmSystemTools::UpperCase(name).c_str());
+ sec->Append(docs);
+ this->SetSection(name,sec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection(name,
+ cmSystemTools::UpperCase(name).c_str());
+ sec->Append(docs);
+ this->SetSection(name,sec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation
+::SetSections(std::map<std::string,cmDocumentationSection *> &sections)
+{
+ for (std::map<std::string,cmDocumentationSection *>::const_iterator
+ it = sections.begin(); it != sections.end(); ++it)
+ {
+ this->SetSection(it->first.c_str(),it->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Prepend(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Prepend(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Append(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Append(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ cmDocumentationEntry &docs)
+{
+
+ std::vector<cmDocumentationEntry> docsVec;
+ docsVec.push_back(docs);
+ this->AppendSection(name,docsVec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ cmDocumentationEntry &docs)
+{
+
+ std::vector<cmDocumentationEntry> docsVec;
+ docsVec.push_back(docs);
+ this->PrependSection(name,docsVec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSeeAlsoList(const char *data[][3])
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection("See Also", "SEE ALSO");
+ this->AllSections["See Also"] = sec;
+ this->SeeAlsoString = ".B ";
+ int i = 0;
+ while(data[i][1])
+ {
+ this->SeeAlsoString += data[i][1];
+ this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
+ ++i;
+ }
+ sec->Append(0,this->SeeAlsoString.c_str(),0);
+ sec->Append(cmDocumentationStandardSeeAlso);
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
+ const char *section)
+{
+ if(this->AllSections.find(section) == this->AllSections.end())
+ {
+ os << "Internal error: " << section << " list is empty." << std::endl;
+ return false;
+ }
+ if(this->CurrentArgument.length() == 0)
+ {
+ os << "Required argument missing.\n";
+ return false;
+ }
+ const std::vector<cmDocumentationEntry> &entries =
+ this->AllSections[section]->GetEntries();
+ for(std::vector<cmDocumentationEntry>::const_iterator ei =
+ entries.begin();
+ ei != entries.end(); ++ei)
+ {
+ if(this->CurrentArgument == ei->Name)
+ {
+ this->PrintDocumentationCommand(os, *ei);
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
+{
+ if (this->PrintDocumentationGeneric(os,"Commands"))
+ {
+ return true;
+ }
+ if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
+ {
+ return true;
+ }
+
+ // Argument was not a command. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-command is not a CMake command. "
+ << "Use --help-command-list to see all commands.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
+{
+ if(this->CurrentArgument.length() == 0)
+ {
+ os << "Argument --help-module needs a module name.\n";
+ return false;
+ }
+
+ std::string moduleName;
+ // find the module
+ std::vector<std::string> dirs;
+ cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
+ for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
+ dirIt != dirs.end();
+ ++dirIt)
+ {
+ moduleName = *dirIt;
+ moduleName += "/";
+ moduleName += this->CurrentArgument;
+ moduleName += ".cmake";
+ if(cmSystemTools::FileExists(moduleName.c_str()))
+ {
+ break;
+ }
+ moduleName = "";
+ }
+
+ if (moduleName.empty())
+ {
+ moduleName = this->CMakeRoot;
+ moduleName += "/Modules/";
+ moduleName += this->CurrentArgument;
+ moduleName += ".cmake";
+ if(!cmSystemTools::FileExists(moduleName.c_str()))
+ {
+ moduleName = "";
+ }
+ }
+
+ if(!moduleName.empty())
+ {
+ cmDocumentationSection *sec =
+ new cmDocumentationSection("Standard CMake Modules", "MODULES");
+ this->AllSections["Modules"] = sec;
+ if (this->CreateSingleModule(moduleName.c_str(),
+ this->CurrentArgument.c_str(),
+ *this->AllSections["Modules"]))
+ {
+ if(this->AllSections["Modules"]->GetEntries().size())
+ {
+ this->PrintDocumentationCommand
+ (os, this->AllSections["Modules"]->GetEntries()[0]);
+ os << "\n Defined in: ";
+ os << moduleName << "\n";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ // Argument was not a module. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-module is not a CMake module.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
+{
+ bool done = false;
+ for (std::vector<std::string>::iterator i =
+ this->PropertySections.begin();
+ !done && i != this->PropertySections.end(); ++i)
+ {
+ done = this->PrintDocumentationGeneric(os,i->c_str());
+ }
+
+ if (done)
+ {
+ return true;
+ }
+
+ // Argument was not a command. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-property is not a CMake property. "
+ << "Use --help-property-list to see all properties.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
+{
+ if (this->PrintDocumentationGeneric(os,"Policies"))
+ {
+ return true;
+ }
+
+ // Argument was not a command. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-policy is not a CMake policy.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleVariable(std::ostream& os)
+{
+ bool done = false;
+ for (std::vector<std::string>::iterator i =
+ this->VariableSections.begin();
+ !done && i != this->VariableSections.end(); ++i)
+ {
+ done = this->PrintDocumentationGeneric(os,i->c_str());
+ }
+
+ if (done)
+ {
+ return true;
+ }
+
+ // Argument was not a command. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-variable is not a defined variable. "
+ << "Use --help-variable-list to see all defined variables.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationList(std::ostream& os,
+ const char *section)
+{
+ if(this->AllSections.find(section) == this->AllSections.end())
+ {
+ os << "Internal error: " << section << " list is empty." << std::endl;
+ return false;
+ }
+
+ const std::vector<cmDocumentationEntry> &entries =
+ this->AllSections[section]->GetEntries();
+ for(std::vector<cmDocumentationEntry>::const_iterator ei =
+ entries.begin();
+ ei != entries.end(); ++ei)
+ {
+ if(ei->Name.size())
+ {
+ os << ei->Name << std::endl;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddSectionToPrint("Usage");
+ this->AddSectionToPrint("Options");
+ if(this->ShowGenerators)
+ {
+ this->AddSectionToPrint("Generators");
+ }
+ this->Print(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
+{
+ this->CreateFullDocumentation();
+ this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
+{
+ this->ClearSections();
+ this->CreateModulesSection();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Modules));
+ this->AddSectionToPrint("Description");
+ this->AddSectionToPrint("Modules");
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("See Also");
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
+{
+ this->ClearSections();
+ this->CreateCustomModulesSection();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CustomModules));
+ this->AddSectionToPrint("Description");
+ this->AddSectionToPrint("Custom CMake Modules");
+// the custom modules are most probably not under Kitware's copyright, Alex
+// this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("See Also");
+
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Policies));
+ this->AddSectionToPrint("Description");
+ this->AddSectionToPrint("Policies");
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("See Also");
+
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Properties));
+ this->AddSectionToPrint("Properties Description");
+ for (std::vector<std::string>::iterator i =
+ this->PropertySections.begin();
+ i != this->PropertySections.end(); ++i)
+ {
+ this->AddSectionToPrint(i->c_str());
+ }
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("Standard See Also");
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
+ for (std::vector<std::string>::iterator i =
+ this->VariableSections.begin();
+ i != this->VariableSections.end(); ++i)
+ {
+ this->AddSectionToPrint(i->c_str());
+ }
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("Standard See Also");
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Commands));
+ this->AddSectionToPrint("Commands");
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("Standard See Also");
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CompatCommands));
+ this->AddSectionToPrint("Compatibility Commands Description");
+ this->AddSectionToPrint("Compatibility Commands");
+ this->AddSectionToPrint("Copyright");
+ this->AddSectionToPrint("Standard See Also");
+ this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation
+::PrintDocumentationCommand(std::ostream& os,
+ const cmDocumentationEntry &entry)
+{
+ // the string "SingleItem" will be used in a few places to detect the case
+ // that only the documentation for a single item is printed
+ cmDocumentationSection *sec = new cmDocumentationSection("SingleItem","");
+ sec->Append(entry);
+ this->AllSections["temp"] = sec;
+ this->ClearSections();
+ this->AddSectionToPrint("temp");
+ this->Print(os);
+ this->AllSections.erase("temp");
+ delete sec;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::CreateFullDocumentation()
+{
+ this->ClearSections();
+ this->CreateCustomModulesSection();
+ this->CreateModulesSection();
+
+ std::set<std::string> emitted;
+ this->AddSectionToPrint("Name");
+ emitted.insert("Name");
+ this->AddSectionToPrint("Usage");
+ emitted.insert("Usage");
+ this->AddSectionToPrint("Description");
+ emitted.insert("Description");
+ this->AddSectionToPrint("Options");
+ emitted.insert("Options");
+ this->AddSectionToPrint("Generators");
+ emitted.insert("Generators");
+ this->AddSectionToPrint("Commands");
+ emitted.insert("Commands");
+
+
+ this->AddSectionToPrint("Properties Description");
+ emitted.insert("Properties Description");
+ for (std::vector<std::string>::iterator i =
+ this->PropertySections.begin();
+ i != this->PropertySections.end(); ++i)
+ {
+ this->AddSectionToPrint(i->c_str());
+ emitted.insert(i->c_str());
+ }
+
+ emitted.insert("Copyright");
+ emitted.insert("See Also");
+ emitted.insert("Standard See Also");
+ emitted.insert("Author");
+
+ // add any sections not yet written out, or to be written out
+ for (std::map<std::string, cmDocumentationSection*>::iterator i =
+ this->AllSections.begin();
+ i != this->AllSections.end(); ++i)
+ {
+ if (emitted.find(i->first) == emitted.end())
+ {
+ this->AddSectionToPrint(i->first.c_str());
+ }
+ }
+
+ this->AddSectionToPrint("Copyright");
+
+ if(this->CurrentFormatter->GetForm() == ManForm)
+ {
+ this->AddSectionToPrint("See Also");
+ this->AddSectionToPrint("Author");
+ }
+ else
+ {
+ this->AddSectionToPrint("Standard See Also");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetForm(Form f, int manSection)
+{
+ switch(f)
+ {
+ case HTMLForm:
+ this->CurrentFormatter = &this->HTMLFormatter;
+ break;
+ case DocbookForm:
+ this->CurrentFormatter = &this->DocbookFormatter;
+ break;
+ case ManForm:
+ this->ManFormatter.SetManSection(manSection);
+ this->CurrentFormatter = &this->ManFormatter;
+ break;
+ case TextForm:
+ this->CurrentFormatter = &this->TextFormatter;
+ break;
+ case UsageForm:
+ this->CurrentFormatter = & this->UsageFormatter;
+ break;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+const char* cmDocumentation::GetNameString() const
+{
+ if(this->NameString.length() > 0)
+ {
+ return this->NameString.c_str();
+ }
+ else
+ {
+ return "CMake";
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
+{
+ if (this->DocName.length() > 0)
+ {
+ return this->DocName.c_str();
+ }
+ else if (fallbackToNameString)
+ {
+ return this->GetNameString();
+ }
+ else
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+#define CASE_DEFAULT_DOCNAME(doctype) \
+ case cmDocumentation::doctype : \
+ return GET_DOCUMENT_INTRO(doctype)[0];
+const char* cmDocumentation::GetDefaultDocName(Type ht) const
+{
+ switch (ht)
+ {
+ CASE_DEFAULT_DOCNAME(Modules)
+ CASE_DEFAULT_DOCNAME(CustomModules)
+ CASE_DEFAULT_DOCNAME(Policies)
+ CASE_DEFAULT_DOCNAME(Properties)
+ CASE_DEFAULT_DOCNAME(Variables)
+ CASE_DEFAULT_DOCNAME(Commands)
+ CASE_DEFAULT_DOCNAME(CompatCommands)
+ default: break;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::IsOption(const char* arg) const
+{
+ return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
+ (strcmp(arg, "/?") == 0));
+}