diff options
author | Eric NOULARD <eric.noulard@gmail.com> | 2011-11-15 19:24:38 (GMT) |
---|---|---|
committer | Eric NOULARD <eric.noulard@gmail.com> | 2012-01-22 10:44:05 (GMT) |
commit | 83e34dd9e688b4721c70c56e66629bdc2768fa77 (patch) | |
tree | bae87f4bb777b7c9e73d77628f52da25add82b4c /Source/cmDocumentation.cxx | |
parent | c6a016944211b737c45385423fc7df10462e34ab (diff) | |
download | CMake-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.cxx | 171 |
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) { |