diff options
author | David Cole <david.cole@kitware.com> | 2012-02-14 21:14:56 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2012-02-14 21:14:56 (GMT) |
commit | 4f9c114dfabac98dc1b1e55bac3a6be8e9dd23cf (patch) | |
tree | 7dd181e8295ed801132256eb9b91a2aa7e5ad3c2 /Source | |
parent | 4f81c709d1c5f9d2ea9bea0b7d2a1cdee9a33f7e (diff) | |
parent | d4b77eba17e01badc836777dbb0c9ec287f098aa (diff) | |
download | CMake-4f9c114dfabac98dc1b1e55bac3a6be8e9dd23cf.zip CMake-4f9c114dfabac98dc1b1e55bac3a6be8e9dd23cf.tar.gz CMake-4f9c114dfabac98dc1b1e55bac3a6be8e9dd23cf.tar.bz2 |
Merge topic 'ImproveCPackDoc-reloaded'
d4b77eb Avoid discovering system infos for documentation. Adding some path is enough.
9002f73 Fix non existent std::string::clear on VS6
02ccb32 Create getDocumentedModulesListInDir which may be used in other context.
24fbc28 Add missing section markup for CPackComponent
bafd8a9 Example of builtin variable documentation (i.e. only used in C++ source code).
543f1ad Make the load of script documentation more efficient and dynamic.
cdbd1a9 Fix another compiler warning due to a typo
52c53de Really avoid compiler warning about unused vars
37f90ed Calm down compiler warning about unused var
7c82b7f Fix potential bad memory access, thanks to Eike
62b589b Suppress unused var, beautify code, avoid 1 extra newline.
751713f Update bash completion file in order to handle new CPack doc options.
1629615 CPack Documentation extraction from CMake script begins to work
83e34dd Implement simple CMake script comment markup language.
c6a0169 CPack begin the implementation of --help-command* and --help-variables*
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentMacros.cxx | 16 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentMacros.h | 21 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentVariables.cxx | 32 | ||||
-rw-r--r-- | Source/CPack/cmCPackDocumentVariables.h | 21 | ||||
-rw-r--r-- | Source/CPack/cpack.cxx | 95 | ||||
-rw-r--r-- | Source/CursesDialog/ccmake.cxx | 1 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetup.cxx | 1 | ||||
-rw-r--r-- | Source/cmCommand.h | 11 | ||||
-rw-r--r-- | Source/cmDocumentation.cxx | 457 | ||||
-rw-r--r-- | Source/cmDocumentation.h | 68 | ||||
-rw-r--r-- | Source/cmFunctionCommand.cxx | 11 | ||||
-rw-r--r-- | Source/cmMacroCommand.cxx | 11 | ||||
-rw-r--r-- | Source/cmake.cxx | 4 | ||||
-rw-r--r-- | Source/cmakemain.cxx | 1 | ||||
-rw-r--r-- | Source/ctest.cxx | 1 |
16 files changed, 697 insertions, 56 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index b5115b7..0c420b9 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -449,6 +449,8 @@ SET(CPACK_SRCS CPack/cmCPackTarBZip2Generator.cxx CPack/cmCPackTarCompressGenerator.cxx CPack/cmCPackZIPGenerator.cxx + CPack/cmCPackDocumentVariables.cxx + CPack/cmCPackDocumentMacros.cxx ) IF(CYGWIN) diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx new file mode 100644 index 0000000..ddc75a4 --- /dev/null +++ b/Source/CPack/cmCPackDocumentMacros.cxx @@ -0,0 +1,16 @@ +#include "cmCPackDocumentMacros.h" + +void cmCPackDocumentMacros::GetMacrosDocumentation( + std::vector<cmDocumentationEntry>& ) +{ + // Commented-out example of use + // + // cmDocumentationEntry e("cpack_<macro>", + // "Brief Description" + // "which may be on several lines.", + // "Long description in pre-formatted format" + // " blah\n" + // " blah\n" + //); + //v.push_back(e); +} diff --git a/Source/CPack/cmCPackDocumentMacros.h b/Source/CPack/cmCPackDocumentMacros.h new file mode 100644 index 0000000..544f74f --- /dev/null +++ b/Source/CPack/cmCPackDocumentMacros.h @@ -0,0 +1,21 @@ +/*============================================================================ + 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. +============================================================================*/ +#ifndef cmCPackDocumentMacros_h +#define cmCPackDocumentMacros_h +#include "cmStandardIncludes.h" +class cmCPackDocumentMacros +{ +public: + static void GetMacrosDocumentation(std::vector<cmDocumentationEntry>& v); +}; + +#endif diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx new file mode 100644 index 0000000..68cde78 --- /dev/null +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -0,0 +1,32 @@ +#include "cmCPackDocumentVariables.h" +#include "cmake.h" + +void cmCPackDocumentVariables::DefineVariables(cmake* cm) +{ + // Subsection: variables defined/used by cpack, + // which are common to all CPack generators + + cm->DefineProperty + ("CPACK_PACKAGING_INSTALL_PREFIX", cmProperty::VARIABLE, + "The prefix used in the built package.", + "Each CPack generator has a default value (like /usr)." + " This default value may" + " be overwritten from the CMakeLists.txt or the cpack command line" + " by setting an alternative value.\n" + "e.g. " + " set(CPACK_PACKAGING_INSTALL_PREFIX \"/opt\")\n" + "This is not the same purpose as CMAKE_INSTALL_PREFIX which" + " is used when installing from the build tree without building" + " a package." + "", false, + "Variables common to all CPack generators"); + + // Subsection: variables defined/used by cpack, + // which are specific to one CPack generator +// cm->DefineProperty +// ("CPACK_RPM_PACKAGE_NAME", cmProperty::VARIABLE, +// "RPM specific package name.", +// "If not specified, defaults to CPACK_PACKAGE_NAME." +// "", false, +// "Variables specific to a CPack generator"); +} diff --git a/Source/CPack/cmCPackDocumentVariables.h b/Source/CPack/cmCPackDocumentVariables.h new file mode 100644 index 0000000..e7971be --- /dev/null +++ b/Source/CPack/cmCPackDocumentVariables.h @@ -0,0 +1,21 @@ +/*============================================================================ + 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. +============================================================================*/ +#ifndef cmCPackDocumentVariables_h +#define cmCPackDocumentVariables_h +class cmake; +class cmCPackDocumentVariables +{ +public: + static void DefineVariables(cmake* cm); +}; + +#endif diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 163f744..c541610 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -14,6 +14,8 @@ // Need these for documentation support. #include "cmake.h" #include "cmDocumentation.h" +#include "cmCPackDocumentVariables.h" +#include "cmCPackDocumentMacros.h" #include "cmCPackGeneratorFactory.h" #include "cmCPackGenerator.h" #include "cmake.h" @@ -24,6 +26,7 @@ #include "cmCPackLog.h" #include <cmsys/CommandLineArguments.hxx> +#include <cmsys/SystemTools.hxx> #include <memory> // auto_ptr //---------------------------------------------------------------------------- @@ -90,6 +93,40 @@ static const char * cmDocumentationOptions[][3] = "If vendor is not specified on cpack command line " "(or inside CMakeLists.txt) then" "CPack.cmake defines it with a default value"}, + {"--help-command cmd [file]", "Print help for a single command and exit.", + "Full documentation specific to the given command is displayed. " + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-command-list [file]", "List available commands and exit.", + "The list contains all commands for which help may be obtained by using " + "the --help-command argument followed by a command name. " + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-commands [file]", "Print help for all commands and exit.", + "Full documentation specific for all current command is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variable var [file]", + "Print help for a single variable and exit.", + "Full documentation specific to the given variable is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variable-list [file]", "List documented variables and exit.", + "The list contains all variables for which help may be obtained by using " + "the --help-variable argument followed by a variable name. If a file is " + "specified, the help is written into it." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variables [file]", "Print help for all variables and exit.", + "Full documentation for all variables is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, {0,0,0} }; @@ -137,12 +174,15 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, return 1; } + //---------------------------------------------------------------------------- // this is CPack. int main (int argc, char *argv[]) { cmSystemTools::FindExecutableDirectory(argv[0]); cmCPackLog log; + int nocwd = 0; + log.SetErrorPrefix("CPack Error: "); log.SetWarningPrefix("CPack Warning: "); log.SetOutputPrefix("CPack: "); @@ -154,6 +194,7 @@ int main (int argc, char *argv[]) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Current working directory cannot be established." << std::endl); + nocwd = 1; } std::string generator; @@ -179,7 +220,6 @@ int main (int argc, char *argv[]) cpackConfigFile = ""; - cmDocumentation doc; cmsys::CommandLineArguments arg; arg.Initialize(argc, argv); typedef cmsys::CommandLineArguments argT; @@ -252,17 +292,25 @@ int main (int argc, char *argv[]) generators.SetLogger(&log); cmCPackGenerator* cpackGenerator = 0; - if ( !helpFull.empty() || !helpMAN.empty() || - !helpHTML.empty() || helpVersion ) + cmDocumentation doc; + doc.addCPackStandardDocSections(); + /* Were we invoked to display doc or to do some work ? */ + if(doc.CheckOptions(argc, argv,"-G") || nocwd) { - help = true; + help = true; } + else + { + help = false; + } + + // This part is used for cpack documentation lookup as well. + cminst.AddCMakePaths(); if ( parsed && !help ) { // find out which system cpack is running on, so it can setup the search // paths, so FIND_XXX() commands can be used in scripts - cminst.AddCMakePaths(); std::string systemFile = globalMF->GetModulesFile("CMakeDetermineSystem.cmake"); if (!globalMF->ReadListFile(0, systemFile.c_str())) @@ -465,14 +513,49 @@ int main (int argc, char *argv[]) */ if ( help ) { - doc.CheckOptions(argc, argv); // Construct and print requested documentation. + std::vector<cmDocumentationEntry> variables; + doc.SetName("cpack"); doc.SetSection("Name",cmDocumentationName); doc.SetSection("Usage",cmDocumentationUsage); doc.SetSection("Description",cmDocumentationDescription); doc.PrependSection("Options",cmDocumentationOptions); + // statically (in C++ code) defined variables + cmCPackDocumentVariables::DefineVariables(&cminst); + + std::vector<cmDocumentationEntry> commands; + + std::string docedFile; + std::string docPath; + cmDocumentation::documentedModulesList_t docedModList; + + docedFile = globalMF->GetModulesFile("CPack.cmake"); + if (docedFile.length()!=0) + { + docPath = cmSystemTools::GetFilenamePath(docedFile.c_str()); + doc.getDocumentedModulesListInDir(docPath,"CPack*.cmake",docedModList); + } + + // parse the files for documentation. + cmDocumentation::documentedModulesList_t::iterator docedIt; + for (docedIt = docedModList.begin(); + docedIt!= docedModList.end(); ++docedIt) + { + doc.GetStructuredDocFromFile( + (docedIt->first).c_str(), + commands,&cminst,(docedIt->second).c_str()); + } + + std::map<std::string,cmDocumentationSection *> propDocs; + cminst.GetPropertiesDocumentation(propDocs); + doc.SetSections(propDocs); + cminst.GetCommandDocumentation(commands,true,false); + // statically (in C++ code) defined macros/commands + cmCPackDocumentMacros::GetMacrosDocumentation(commands); + doc.SetSection("Commands",commands); + std::vector<cmDocumentationEntry> v; cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt; for( generatorIt = generators.GetGeneratorsList().begin(); diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index b1a72af..623d7d3 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -102,6 +102,7 @@ int main(int argc, char** argv) { cmSystemTools::FindExecutableDirectory(argv[0]); cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(doc.CheckOptions(argc, argv)) { cmake hcm; diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 7ba7f51..b4f3d72 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -64,6 +64,7 @@ int main(int argc, char** argv) // check docs first so that X is not need to get docs // do docs, if args were given cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(argc >1 && doc.CheckOptions(argc, argv)) { // Construct and print requested documentation. diff --git a/Source/cmCommand.h b/Source/cmCommand.h index 7817eb3..e046096 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -111,6 +111,17 @@ public: } /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() + { + return true; + } + + /** * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() = 0; diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 07683d0..02f69f1 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -14,6 +14,7 @@ #include "cmSystemTools.h" #include "cmVersion.h" #include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> //---------------------------------------------------------------------------- @@ -220,55 +221,7 @@ cmDocumentation::cmDocumentation() :CurrentFormatter(0) { this->SetForm(TextForm); - - 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("Properties","PROPERTIES"); - sec->Append(cmPropertiesDocumentationDescription); - this->AllSections["Properties Description"] = sec; - - sec = new cmDocumentationSection("Generators","GENERATORS"); - sec->Append(cmDocumentationGeneratorsHeader); - this->AllSections["Generators"] = sec; - - sec = new cmDocumentationSection("Compatibility Commands", - "COMPATIBILITY COMMANDS"); - sec->Append(cmCompatCommandsDocumentationDescription); - this->AllSections["Compatibility Commands"] = 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"); - + this->addCommonStandardDocSections(); this->ShowGenerators = true; } @@ -559,6 +512,8 @@ bool cmDocumentation::CreateSingleModule(const char* fname, { 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) { @@ -710,6 +665,410 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename( } //---------------------------------------------------------------------------- +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"); + this->VariableSections.push_back( + "Variables specific to a CPack generator"); +} + +//---------------------------------------------------------------------------- +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, + const char *docSection) +{ + 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 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; + /* 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: + cm->DefineProperty + (name.c_str(), cmProperty::VARIABLE, + brief.c_str(), + full.c_str(),false, + docSection); + 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) { diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 34b83b1..00dba1a 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -21,6 +21,7 @@ #include "cmDocumentationFormatterText.h" #include "cmDocumentationFormatterUsage.h" #include "cmDocumentationSection.h" +#include "cmake.h" namespace cmsys { @@ -34,6 +35,21 @@ public: cmDocumentation(); ~cmDocumentation(); + + /** + * An helper type pair for [structured] documented modules. + * The comment of those module contains structure markup + * which makes it possible to retrieve the documentation + * of variables, macros and functions defined in the module. + * - first is the filename of the module + * - second is the section of the doc the module belongs too + */ + typedef std::pair<std::string,std::string> documentedModuleSectionPair_t; + /** + * A list of documented module(s). + */ + typedef std::list<documentedModuleSectionPair_t> documentedModulesList_t; + // High-level interface for standard documents: /** @@ -119,6 +135,58 @@ public: static Form GetFormFromFilename(const std::string& filename); + /** Add common (to all tools) documentation section(s) */ + void addCommonStandardDocSections(); + + /** Add the CMake standard documentation section(s) */ + void addCMakeStandardDocSections(); + + /** Add the CTest standard documentation section(s) */ + void addCTestStandardDocSections(); + + /** Add the CPack standard documentation section(s) */ + void addCPackStandardDocSections(); + + /** + * Retrieve the list of documented module located in + * path which match the globing expression globExpr. + * @param[in] path, directory where to start the search + * we will recurse into it. + * @param[in] globExpr, the globing expression used to + * match the file in path. + * @param[out] the list of obtained pairs (may be empty) + * @return 0 on success 1 on error or empty list + */ + int getDocumentedModulesListInDir( + std::string path, + std::string globExpr, + documentedModulesList_t& docModuleList); + + /** + * Get the documentation of macros, functions and variable documented + * with CMake structured documentation in a CMake script. + * (in fact it may be in any file which follow the structured doc format) + * Structured documentation begin with + * ## (double sharp) in column 1 & 2 immediately followed + * by a markup. Those ## are ignored by the legacy module + * documentation parser @see CreateSingleModule. + * Current markup are ##section, ##module, + * ##macro, ##function, ##variable and ##end. + * ##end is closing either of the previous ones. + * @param[in] fname the script file name to be parsed for documentation + * @param[in,out] commands the vector of command/macros documentation + * entry found in the script file. + * @param[in,out] the cmake object instance to which variable documentation + * will be attached (using @see cmake::DefineProperty) + * @param[in] the documentation section in which the property will be + * inserted. + * @return the number of documented items (command and variable) + * found in the file. + */ + int GetStructuredDocFromFile(const char* fname, + std::vector<cmDocumentationEntry>& commands, + cmake* cm, + const char *docSection); private: void SetForm(Form f); void SetDocName(const char* docname); diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index ec4fd16..7a80a1c 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -23,6 +23,17 @@ public: ~cmFunctionHelperCommand() {}; /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() + { + return false; + } + + /** * This is a virtual constructor for the command. */ virtual cmCommand* Clone() diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 774f32b..f81a63d 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -23,6 +23,17 @@ public: ~cmMacroHelperCommand() {}; /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() + { + return false; + } + + /** * This is a virtual constructor for the command. */ virtual cmCommand* Clone() diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 71dca3a..cce5080 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2660,7 +2660,9 @@ void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v, j != this->Commands.end(); ++j) { if ((( withCompatCommands == false) && ( (*j).second->IsDiscouraged())) - || ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged()))) + || ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged())) + || (!((*j).second->ShouldAppearInDocumentation())) + ) { continue; } diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 436236d..c3de8ca 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -355,6 +355,7 @@ int do_cmake(int ac, char** av) #ifdef CMAKE_BUILD_WITH_CMAKE cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(doc.CheckOptions(ac, av, "-E") || nocwd) { // Construct and print requested documentation. diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 85cecea..d41627e 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -291,6 +291,7 @@ int main (int argc, char *argv[]) << "*********************************" << std::endl); } cmDocumentation doc; + doc.addCTestStandardDocSections(); if(doc.CheckOptions(argc, argv) || nocwd) { // Construct and print requested documentation. |