From 83e34dd9e688b4721c70c56e66629bdc2768fa77 Mon Sep 17 00:00:00 2001 From: Eric NOULARD Date: Tue, 15 Nov 2011 20:24:38 +0100 Subject: Implement simple CMake script comment markup language. The language is very simple. It use ## special comment which opens a structured documentation block and ##end closes it. This may be used to extract documentation for macro as 'command' and 'variables' such that cpack --help-command and --help-variable does parse builtin modules files (CPack.cmake, CPackComponent.cmake, ...) in order to extract the corresponding doc. --- Modules/CPack.cmake | 12 +++ Modules/CPackComponent.cmake | 8 ++ Source/CPack/cmCPackDocumentMacros.cxx | 2 +- Source/CPack/cmCPackDocumentVariables.cxx | 6 -- Source/CPack/cpack.cxx | 34 +++++- Source/cmDocumentation.cxx | 171 ++++++++++++++++++++++++++++++ Source/cmDocumentation.h | 23 ++++ 7 files changed, 247 insertions(+), 9 deletions(-) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 2cc27cf..ce59693 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -49,21 +49,33 @@ # there are a variety of variables that can be set to customize # the resulting installers. The most commonly-used variables are: # +##variable # CPACK_PACKAGE_NAME - The name of the package (or application). If # not specified, defaults to the project name. +##end # +##variable # CPACK_PACKAGE_VENDOR - The name of the package vendor (e.g., # "Kitware"). +##end # +##variable # CPACK_PACKAGE_VERSION_MAJOR - Package major Version +##end # +##variable # CPACK_PACKAGE_VERSION_MINOR - Package minor Version +##end # +##variable # CPACK_PACKAGE_VERSION_PATCH - Package patch Version +##end # +##variable # CPACK_PACKAGE_DESCRIPTION_FILE - A text file used to describe the # project. Used, for example, the introduction screen of a # CPack-generated Windows installer to describe the project. +##end # # CPACK_PACKAGE_DESCRIPTION_SUMMARY - Short description of the # project (only a few words). diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 1c10372..a0e0667 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -21,6 +21,7 @@ # INSTALL commands, and should be further described by the following # CPack commands: # +##macro # cpack_add_component - Describes a CPack installation component # named by the COMPONENT argument to a CMake INSTALL command. # @@ -90,7 +91,9 @@ # create a file with some name based on CPACK_PACKAGE_FILE_NAME and # the name of the component. See cpack_configure_downloads for more # information. +##end # +##macro # cpack_add_component_group - Describes a group of related CPack # installation components. # @@ -134,7 +137,9 @@ # # BOLD_TITLE indicates that the group title should appear in bold, # to call the user's attention to the group. +##end # +##macro # cpack_add_install_type - Add a new installation type containing a # set of predefined component selections to the graphical installer. # @@ -153,7 +158,9 @@ # DISPLAY_NAME is the displayed name of the install type, which will # typically show up in a drop-down box within a graphical # installer. This value can be any string. +##end # +##macro # cpack_configure_downloads - Configure CPack to download selected # components on-the-fly as part of the installation process. # @@ -203,6 +210,7 @@ # that can be called from Windows' Add/Remove Programs dialog (via the # "Modify" button) to change the set of installed components. NO_ADD_REMOVE # turns off this behavior. This option is ignored on Mac OS X. +##endmacro #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx index 0dd51a9..1ff0351 100644 --- a/Source/CPack/cmCPackDocumentMacros.cxx +++ b/Source/CPack/cmCPackDocumentMacros.cxx @@ -74,5 +74,5 @@ void cmCPackDocumentMacros::GetMacrosDocumentation( "information." ); - v.push_back(e); + //v.push_back(e); } diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx index 1c98e7c..ab806d2 100644 --- a/Source/CPack/cmCPackDocumentVariables.cxx +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -5,12 +5,6 @@ void cmCPackDocumentVariables::DefineVariables(cmake* cm) { // Subsection: variables defined/used by cpack, // which are common to all CPack generators - cm->DefineProperty - ("CPACK_PACKAGE_NAME", cmProperty::VARIABLE, - "The name of the package (or application).", - "If not specified, defaults to the project name." - "", false, - "Variables common to all CPack generators"); cm->DefineProperty ("CPACK_PACKAGE_VENDOR", cmProperty::VARIABLE, diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 2cfbf12..8e59fa0 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -520,11 +520,41 @@ int main (int argc, char *argv[]) doc.PrependSection("Options",cmDocumentationOptions); cmCPackDocumentVariables::DefineVariables(&cminst); + + std::vector commands; + + cminst.AddCMakePaths(); + std::string systemFile = + globalMF->GetModulesFile("CMakeDetermineSystem.cmake"); + if (!globalMF->ReadListFile(0, systemFile.c_str())) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Error reading CMakeDetermineSystem.cmake" << std::endl); + return 1; + } + + systemFile = + globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake"); + if (!globalMF->ReadListFile(0, systemFile.c_str())) + { + cmCPack_Log(&log, cmCPackLog::LOG_ERROR, + "Error reading CMakeSystemSpecificInformation.cmake" + << std::endl); + return 1; + } + std::string cpFile = globalMF->GetModulesFile("CPack.cmake"); + doc.getStructuredDocFromFile(cpFile.c_str(), + commands,&cminst,"Variables common to all CPack generators"); + cpFile = globalMF->GetModulesFile("CPackComponent.cmake"); + doc.getStructuredDocFromFile(cpFile.c_str(), + commands,&cminst,"Variables common to all CPack generators"); + cpFile = globalMF->GetModulesFile("CPackRPM.cmake"); + doc.getStructuredDocFromFile(cpFile.c_str(), + commands,&cminst,"Variables specific to a CPack generator"); + std::map propDocs; cminst.GetPropertiesDocumentation(propDocs); doc.SetSections(propDocs); - - std::vector commands; cminst.GetCommandDocumentation(commands); cmCPackDocumentMacros::GetMacrosDocumentation(commands); doc.SetSection("Commands",commands); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 8f603f2..b7b8e37 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -511,6 +511,8 @@ bool cmDocumentation::CreateSingleModule(const char* fname, { if(line.size() && line[0] == '#') { + /* line beginnings with ## are mark-up ignore them */ + if (line[1] == '#') continue; // blank line if(line.size() <= 2) { @@ -744,6 +746,175 @@ void cmDocumentation::addCPackStandardDocSections() } //---------------------------------------------------------------------------- +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& commands, + cmake* cm, + const char *docSection) +{ + typedef enum sdoce { + SDOC_NONE, SDOC_MACRO, + SDOC_PARAM, SDOC_VARIABLE, + SDOC_UNKNOWN} sdoc_t; + int nbDocItemFound = 0; + int docCtxIdx = 0; + std::vector docContextStack(60); + docContextStack[docCtxIdx]=SDOC_NONE; + cmDocumentationEntry e; + std::ifstream fin(fname); + if(!fin) + { + //std::cerr << "Internal error: can not open script file: <" << fname <<">."<< std::endl; + return nbDocItemFound; + } + std::string name; + std::string full; + std::string brief; + std::string line; + bool newCtx = false; + bool inBrief = false; + brief = ""; + full = ""; + bool newParagraph = true; + while ( fin && cmSystemTools::GetLineFromStream(fin, line) ) + { + if(line.size() && line[0] == '#') + { + /* handle structured doc context */ + if (line[1]=='#') { + std::string mkword = line.substr(2,std::string::npos); + if (mkword=="macro") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_MACRO; + newCtx = true; + } + else if (mkword=="variable") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_VARIABLE; + newCtx = true; + } + else if (mkword.substr(0,3)=="end") + { + ; + switch (docContextStack[docCtxIdx]) { + case SDOC_MACRO: + 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; + } + docCtxIdx--; + newCtx = false; + } + else + { + // error out unhandled context + std::cerr << "Internal error: unknown markup context <" + << mkword <<"> found in:" << fname << std::endl; + 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) + { + name = line.substr(1,line.find("-")-1); + trim(name); + brief = ""; + line = line.substr(line.find("- ")+1,std::string::npos); + inBrief = true; + full = ""; + } + // blank line + if(line.size() <= 2) + { + inBrief = false; + full += "\n"; + newParagraph = true; + } + // brief terminated by . + else if (inBrief && line[line.length()-1]=='.') + { + inBrief = false; + brief += line.c_str()+1; + } + // 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] == ' ') + { + 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; + } + } + } + /* 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 a7a7a1f..2f6e09e 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 { @@ -131,6 +132,28 @@ public: /** Add the CPack standard documentation section(s) */ void addCPackStandardDocSections(); + /** + * Get the documentation of macros and variable documented + * with CMake structured documentation in a CMake script. + * 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 ##macro, ##param, ##variable and ##end + * which 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) + * @return the number of documented items (command and variable) + * found in the file. + */ + int getStructuredDocFromFile(const char* fname, + std::vector& commands, + cmake* cm, + const char *docSection); + ; private: void SetForm(Form f); void SetDocName(const char* docname); -- cgit v0.12