diff options
Diffstat (limited to 'Source/cmDocumentation.cxx')
-rw-r--r-- | Source/cmDocumentation.cxx | 1978 |
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 *> §ions) +{ + 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)); +} |