|  | @@ -14,7 +14,9 @@
 | 
	
		
			
				|  |  |  #include "cmSystemTools.h"
 | 
	
		
			
				|  |  |  #include "cmVersion.h"
 | 
	
		
			
				|  |  |  #include <cmsys/Directory.hxx>
 | 
	
		
			
				|  |  | +#include <cmsys/Glob.hxx>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#include <algorithm>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  static const char *cmDocumentationStandardOptions[][3] =
 | 
	
	
		
			
				|  | @@ -220,55 +222,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 +513,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)
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -709,6 +665,423 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename(
 | 
	
		
			
				|  |  |    return cmDocumentation::TextForm;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +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");
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void cmDocumentation::addAutomaticVariableSections(const std::string& section)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  std::vector<std::string>::iterator it;
 | 
	
		
			
				|  |  | +  it = std::find(this->VariableSections.begin(),
 | 
	
		
			
				|  |  | +                 this->VariableSections.end(),
 | 
	
		
			
				|  |  | +                 section);
 | 
	
		
			
				|  |  | +  /* if the section does not exist then add it */
 | 
	
		
			
				|  |  | +  if (it==this->VariableSections.end())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    this->VariableSections.push_back(section);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +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)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    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 section;
 | 
	
		
			
				|  |  | +    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;
 | 
	
		
			
				|  |  | +               // 10 is the size of '##section' + 1
 | 
	
		
			
				|  |  | +               section = line.substr(10,std::string::npos);
 | 
	
		
			
				|  |  | +               /* 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:
 | 
	
		
			
				|  |  | +                   this->addAutomaticVariableSections(section);
 | 
	
		
			
				|  |  | +                   cm->DefineProperty
 | 
	
		
			
				|  |  | +                       (name.c_str(), cmProperty::VARIABLE,
 | 
	
		
			
				|  |  | +                        brief.c_str(),
 | 
	
		
			
				|  |  | +                        full.c_str(),false,
 | 
	
		
			
				|  |  | +                        section.c_str());
 | 
	
		
			
				|  |  | +                   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)
 |