Implement simple CMake script comment markup language.

The language is very simple. It use ##<keyword> 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.
This commit is contained in:
Eric NOULARD 2011-11-15 20:24:38 +01:00
parent c6a0169442
commit 83e34dd9e6
7 changed files with 247 additions and 9 deletions

View File

@ -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).

View File

@ -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.

View File

@ -74,5 +74,5 @@ void cmCPackDocumentMacros::GetMacrosDocumentation(
"information."
);
v.push_back(e);
//v.push_back(e);
}

View File

@ -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,

View File

@ -520,11 +520,41 @@ int main (int argc, char *argv[])
doc.PrependSection("Options",cmDocumentationOptions);
cmCPackDocumentVariables::DefineVariables(&cminst);
std::vector<cmDocumentationEntry> 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<std::string,cmDocumentationSection *> propDocs;
cminst.GetPropertiesDocumentation(propDocs);
doc.SetSections(propDocs);
std::vector<cmDocumentationEntry> commands;
cminst.GetCommandDocumentation(commands);
cmCPackDocumentMacros::GetMacrosDocumentation(commands);
doc.SetSection("Commands",commands);

View File

@ -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)
{
@ -743,6 +745,175 @@ void cmDocumentation::addCPackStandardDocSections()
"Variables specific to a CPack generator");
}
//----------------------------------------------------------------------------
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_MACRO,
SDOC_PARAM, SDOC_VARIABLE,
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)
{
//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)

View File

@ -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<cmDocumentationEntry>& commands,
cmake* cm,
const char *docSection);
;
private:
void SetForm(Form f);
void SetDocName(const char* docname);