summaryrefslogtreecommitdiffstats
path: root/Source/cmDocumentation.cxx
diff options
context:
space:
mode:
authorEric NOULARD <eric.noulard@gmail.com>2011-11-15 19:24:38 (GMT)
committerEric NOULARD <eric.noulard@gmail.com>2012-01-22 10:44:05 (GMT)
commit83e34dd9e688b4721c70c56e66629bdc2768fa77 (patch)
treebae87f4bb777b7c9e73d77628f52da25add82b4c /Source/cmDocumentation.cxx
parentc6a016944211b737c45385423fc7df10462e34ab (diff)
downloadCMake-83e34dd9e688b4721c70c56e66629bdc2768fa77.zip
CMake-83e34dd9e688b4721c70c56e66629bdc2768fa77.tar.gz
CMake-83e34dd9e688b4721c70c56e66629bdc2768fa77.tar.bz2
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.
Diffstat (limited to 'Source/cmDocumentation.cxx')
-rw-r--r--Source/cmDocumentation.cxx171
1 files changed, 171 insertions, 0 deletions
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<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)
{