/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmDocumentation.h"

#include "cmSystemTools.h"
#include "cmVersion.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>

#include <algorithm>

//----------------------------------------------------------------------------
static const char *cmDocumentationStandardOptions[][3] =
{
  {"--copyright [file]", "Print the CMake copyright and exit.",
   "If a file is specified, the copyright is written into it."},
  {"--help,-help,-usage,-h,-H,/?", "Print usage information and exit.",
   "Usage describes the basic command line interface and its options."},
  {"--help-full [file]", "Print full help and exit.",
   "Full help displays most of the documentation provided by the UNIX "
   "man page.  It is provided for use on non-UNIX platforms, but is "
   "also convenient if the man page is not installed.  If a file is "
   "specified, the help is written into it."},
  {"--help-html [file]", "Print full help in HTML format.",
   "This option is used by CMake authors to help produce web pages.  "
   "If a file is specified, the help is written into it."},
  {"--help-man [file]", "Print full help as a UNIX man page and exit.",
   "This option is used by the cmake build to generate the UNIX man page.  "
   "If a file is specified, the help is written into it."},
  {"--version,-version,/V [file]",
   "Show program name/version banner and exit.",
   "If a file is specified, the version is written into it."},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmModulesDocumentationDescription[][3] =
{
  {0,
  "  CMake Modules - Modules coming with CMake, the Cross-Platform Makefile "
  "Generator.", 0},
//  CMAKE_DOCUMENTATION_OVERVIEW,
  {0,
  "This is the documentation for the modules and scripts coming with CMake. "
  "Using these modules you can check the computer system for "
  "installed software packages, features of the compiler and the "
  "existence of headers to name just a few.", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmCustomModulesDocumentationDescription[][3] =
{
  {0,
  "  Custom CMake Modules - Additional Modules for CMake.", 0},
//  CMAKE_DOCUMENTATION_OVERVIEW,
  {0,
  "This is the documentation for additional modules and scripts for CMake. "
  "Using these modules you can check the computer system for "
  "installed software packages, features of the compiler and the "
  "existence of headers to name just a few.", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmPropertiesDocumentationDescription[][3] =
{
  {0,
   "  CMake Properties - Properties supported by CMake, "
   "the Cross-Platform Makefile Generator.", 0},
//  CMAKE_DOCUMENTATION_OVERVIEW,
  {0,
   "This is the documentation for the properties supported by CMake. "
   "Properties can have different scopes. They can either be assigned to a "
   "source file, a directory, a target or globally to CMake. By modifying the "
   "values of properties the behaviour of the build system can be customized.",
   0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmCompatCommandsDocumentationDescription[][3] =
{
  {0,
   "  CMake Compatibility Listfile Commands - "
   "Obsolete commands supported by CMake for compatibility.", 0},
//  CMAKE_DOCUMENTATION_OVERVIEW,
  {0,
  "This is the documentation for now obsolete listfile commands from previous "
  "CMake versions, which are still supported for compatibility reasons. You "
  "should instead use the newer, faster and shinier new commands. ;-)", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationModulesHeader[][3] =
{
  {0,
   "The following modules are provided with CMake. "
   "They can be used with INCLUDE(ModuleName).", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationCustomModulesHeader[][3] =
{
  {0,
   "The following modules are also available for CMake. "
   "They can be used with INCLUDE(ModuleName).", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationGeneratorsHeader[][3] =
{
  {0,
   "The following generators are available on this platform:", 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationStandardSeeAlso[][3] =
{
  {0,
   "The following resources are available to get help using CMake:", 0},
  {"Home Page",
   "http://www.cmake.org",
   "The primary starting point for learning about CMake."},
  {"Frequently Asked Questions",
   "http://www.cmake.org/Wiki/CMake_FAQ",
   "A Wiki is provided containing answers to frequently asked questions. "},
  {"Online Documentation",
   "http://www.cmake.org/HTML/Documentation.html",
   "Links to available documentation may be found on this web page."},
  {"Mailing List",
   "http://www.cmake.org/HTML/MailingLists.html",
   "For help and discussion about using cmake, a mailing list is provided at "
   "cmake@cmake.org. "
   "The list is member-post-only but one may sign up on the CMake web page. "
   "Please first read the full documentation at "
   "http://www.cmake.org before posting questions to the list."},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationCopyright[][3] =
{
  {0,
   "Copyright 2000-2012 Kitware, Inc., Insight Software Consortium.  "
   "All rights reserved.", 0},
  {0,
   "Redistribution and use in source and binary forms, with or without "
   "modification, are permitted provided that the following conditions are "
   "met:", 0},
  {"",
   "Redistributions of source code must retain the above copyright notice, "
   "this list of conditions and the following disclaimer.", 0},
  {"",
   "Redistributions in binary form must reproduce the above copyright "
   "notice, this list of conditions and the following disclaimer in the "
   "documentation and/or other materials provided with the distribution.",
   0},
  {"",
   "Neither the names of Kitware, Inc., the Insight Software Consortium, "
   "nor the names of their contributors may be used to endorse or promote "
   "products derived from this software without specific prior written "
   "permission.", 0},
  {0,
   "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "
   "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
   "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR "
   "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT "
   "HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, "
   "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT "
   "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, "
   "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY "
   "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT "
   "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "
   "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
   0},
  {0, 0, 0}
};

//----------------------------------------------------------------------------
#define DOCUMENT_INTRO(type, default_name, desc) \
  static char const *cmDocumentation##type##Intro[2] = { default_name, desc };
#define GET_DOCUMENT_INTRO(type) cmDocumentation##type##Intro

DOCUMENT_INTRO(Modules, "cmakemodules",
  "Reference of available CMake modules.");
DOCUMENT_INTRO(CustomModules, "cmakecustommodules",
  "Reference of available CMake custom modules.");
DOCUMENT_INTRO(Policies, "cmakepolicies",
  "Reference of CMake policies.");
DOCUMENT_INTRO(Properties, "cmakeprops",
  "Reference of CMake properties.");
DOCUMENT_INTRO(Variables, "cmakevars",
  "Reference of CMake variables.");
DOCUMENT_INTRO(Commands, "cmakecommands",
  "Reference of available CMake commands.");
DOCUMENT_INTRO(CompatCommands, "cmakecompat",
  "Reference of CMake compatibility commands.");

//----------------------------------------------------------------------------
cmDocumentation::cmDocumentation()
:CurrentFormatter(0)
{
  this->SetForm(TextForm, 0);
  this->addCommonStandardDocSections();
  this->ShowGenerators = true;
}

//----------------------------------------------------------------------------
cmDocumentation::~cmDocumentation()
{
  for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
      i != this->ModuleStrings.end(); ++i)
    {
    delete [] *i;
    }
  for(std::map<std::string,cmDocumentationSection *>::iterator i =
        this->AllSections.begin();
      i != this->AllSections.end(); ++i)
    {
    delete i->second;
    }
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintCopyright(std::ostream& os)
{
  cmDocumentationSection *sec = this->AllSections["Copyright"];
  const std::vector<cmDocumentationEntry> &entries = sec->GetEntries();
  for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
      op != entries.end(); ++op)
    {
    if(op->Name.size())
      {
      os << " * ";
      this->TextFormatter.SetIndent("    ");
      this->TextFormatter.PrintColumn(os, op->Brief.c_str());
      }
    else
      {
      this->TextFormatter.SetIndent("");
      this->TextFormatter.PrintColumn(os, op->Brief.c_str());
      }
    os << "\n";
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintVersion(std::ostream& os)
{
  os << this->GetNameString() << " version "
     << cmVersion::GetCMakeVersion() << "\n";
  return true;
}

//----------------------------------------------------------------------------
void cmDocumentation::AddSectionToPrint(const char *section)
{
  if (this->AllSections.find(section) != this->AllSections.end())
    {
    this->PrintSections.push_back(this->AllSections[section]);
    }
}

//----------------------------------------------------------------------------
void cmDocumentation::ClearSections()
{
  this->PrintSections.erase(this->PrintSections.begin(),
                            this->PrintSections.end());
  this->ModulesFound.clear();
}

//----------------------------------------------------------------------------
void cmDocumentation::AddDocumentIntroToPrint(const char* intro[2])
{
  const char* docname = this->GetDocName(false);
  if(intro && docname)
    {
    cmDocumentationSection* section;
    std::string desc("");

    desc += docname;
    desc += " - ";
    desc += intro[1];

    section = new cmDocumentationSection("Introduction", "NAME");
    section->Append(0, desc.c_str(), 0);
    this->PrintSections.push_back(section);
    }
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os,
                                         const char* docname)
{
  if ((this->CurrentFormatter->GetForm() != HTMLForm)
       && (this->CurrentFormatter->GetForm() != DocbookForm)
       && (this->CurrentFormatter->GetForm() != ManForm))
    {
    this->PrintVersion(os);
    }

  // Handle Document Name. docname==0 disables intro.
  this->SetDocName("");
  if (docname)
    {
    if (*docname)
      this->SetDocName(docname);
    else // empty string was given. select default if possible
      this->SetDocName(this->GetDefaultDocName(ht));
    }

  switch (ht)
    {
    case cmDocumentation::Usage:
      return this->PrintDocumentationUsage(os);
    case cmDocumentation::Single:
      return this->PrintDocumentationSingle(os);
    case cmDocumentation::SingleModule:
      return this->PrintDocumentationSingleModule(os);
    case cmDocumentation::SinglePolicy:
      return this->PrintDocumentationSinglePolicy(os);
    case cmDocumentation::SingleProperty:
      return this->PrintDocumentationSingleProperty(os);
    case cmDocumentation::SingleVariable:
      return this->PrintDocumentationSingleVariable(os);
    case cmDocumentation::List:
      this->PrintDocumentationList(os,"Commands");
      this->PrintDocumentationList(os,"Compatibility Commands");
      return true;
    case cmDocumentation::ModuleList:
      // find the modules first, print the custom module docs only if
      // any custom modules have been found actually, Alex
      this->CreateCustomModulesSection();
      this->CreateModulesSection();
      if (this->AllSections.find("Custom CMake Modules")
         != this->AllSections.end())
        {
        this->PrintDocumentationList(os,"Custom CMake Modules");
        }
      this->PrintDocumentationList(os,"Modules");
      return true;
    case cmDocumentation::PropertyList:
      this->PrintDocumentationList(os,"Properties Description");
      for (std::vector<std::string>::iterator i =
             this->PropertySections.begin();
           i != this->PropertySections.end(); ++i)
        {
        this->PrintDocumentationList(os,i->c_str());
        }
      return true;
    case cmDocumentation::VariableList:
      for (std::vector<std::string>::iterator i =
             this->VariableSections.begin();
           i != this->VariableSections.end(); ++i)
        {
        this->PrintDocumentationList(os,i->c_str());
        }
      return true;
    case cmDocumentation::Full:
      return this->PrintDocumentationFull(os);
    case cmDocumentation::Modules:
      return this->PrintDocumentationModules(os);
    case cmDocumentation::CustomModules:
      return this->PrintDocumentationCustomModules(os);
    case cmDocumentation::Policies:
      return this->PrintDocumentationPolicies(os);
    case cmDocumentation::Properties:
      return this->PrintDocumentationProperties(os);
    case cmDocumentation::Variables:
      return this->PrintDocumentationVariables(os);
    case cmDocumentation::Commands:
      return this->PrintDocumentationCurrentCommands(os);
    case cmDocumentation::CompatCommands:
      return this->PrintDocumentationCompatCommands(os);

    case cmDocumentation::Copyright:
      return this->PrintCopyright(os);
    case cmDocumentation::Version:
      return true;
    default: return false;
    }
}

//----------------------------------------------------------------------------
bool cmDocumentation::CreateModulesSection()
{
  cmDocumentationSection *sec =
    new cmDocumentationSection("Standard CMake Modules", "MODULES");
  this->AllSections["Modules"] = sec;
  std::string cmakeModules = this->CMakeRoot;
  cmakeModules += "/Modules";
  cmsys::Directory dir;
  dir.Load(cmakeModules.c_str());
  if (dir.GetNumberOfFiles() > 0)
    {
    sec->Append(cmDocumentationModulesHeader[0]);
    sec->Append(cmModulesDocumentationDescription);
    this->CreateModuleDocsForDir(dir, *this->AllSections["Modules"]);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::CreateCustomModulesSection()
{
  bool sectionHasHeader = false;

  std::vector<std::string> dirs;
  cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);

  for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
      dirIt != dirs.end();
      ++dirIt)
    {
    cmsys::Directory dir;
    dir.Load(dirIt->c_str());
    if (dir.GetNumberOfFiles() > 0)
      {
      if (!sectionHasHeader)
        {
        cmDocumentationSection *sec =
          new cmDocumentationSection("Custom CMake Modules","CUSTOM MODULES");
        this->AllSections["Custom CMake Modules"] = sec;
        sec->Append(cmDocumentationCustomModulesHeader[0]);
        sec->Append(cmCustomModulesDocumentationDescription);
        sectionHasHeader = true;
        }
      this->CreateModuleDocsForDir
        (dir, *this->AllSections["Custom CMake Modules"]);
      }
    }

  return true;
}

//----------------------------------------------------------------------------
void cmDocumentation
::CreateModuleDocsForDir(cmsys::Directory& dir,
                         cmDocumentationSection &moduleSection)
{
  // sort the files alphabetically, so the docs for one module are easier
  // to find than if they are in random order
  std::vector<std::string> sortedFiles;
  for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
  {
    sortedFiles.push_back(dir.GetFile(i));
  }
  std::sort(sortedFiles.begin(), sortedFiles.end());

  for(std::vector<std::string>::const_iterator fname = sortedFiles.begin();
      fname!=sortedFiles.end(); ++fname)
    {
    if(fname->length() > 6)
      {
      if(fname->substr(fname->length()-6, 6) == ".cmake")
        {
        std::string moduleName = fname->substr(0, fname->length()-6);
        // this check is to avoid creating documentation for the modules with
        // the same name in multiple directories of CMAKE_MODULE_PATH
        if (this->ModulesFound.find(moduleName) == this->ModulesFound.end())
          {
          this->ModulesFound.insert(moduleName);
          std::string path = dir.GetPath();
          path += "/";
          path += (*fname);
          this->CreateSingleModule(path.c_str(), moduleName.c_str(),
                                   moduleSection);
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
bool cmDocumentation::CreateSingleModule(const char* fname,
                                         const char* moduleName,
                                         cmDocumentationSection &moduleSection)
{
  std::ifstream fin(fname);
  if(!fin)
    {
    std::cerr << "Internal error: can not open module." << fname << std::endl;
    return false;
    }
  std::string line;
  std::string text;
  std::string brief;
  brief = " ";
  bool newParagraph = true;
  while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
    {
    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)
        {
        text += "\n";
        newParagraph = true;
        }
      else if(line[2] == '-')
        {
        brief = line.c_str()+4;
        }
      else
        {
        // 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;
          }
        }
      }
    else
      {
      break;
      }
    }

  if(text.length() < 2 && brief.length() == 1)
    {
    return false;
    }

  char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
  char* ptext = strcpy(new char[text.length()+1], text.c_str());
  this->ModuleStrings.push_back(pname);
  this->ModuleStrings.push_back(ptext);
  char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
  this->ModuleStrings.push_back(pbrief);
  moduleSection.Append(pname, pbrief, ptext);
  return true;
}


//----------------------------------------------------------------------------
bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
{
  bool result = true;

  // Loop over requested documentation types.
  for(std::vector<RequestedHelpItem>::const_iterator
      i = this->RequestedHelpItems.begin();
      i != this->RequestedHelpItems.end();
      ++i)
    {
    this->SetForm(i->HelpForm, i->ManSection);
    this->CurrentArgument = i->Argument;
    // If a file name was given, use it.  Otherwise, default to the
    // given stream.
    std::ofstream* fout = 0;
    std::ostream* s = &os;
    std::string docname("");
    if(i->Filename.length() > 0)
      {
      fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
      if(fout)
        {
        s = fout;
        }
      else
        {
        result = false;
        }
      if(i->Filename != "-")
        {
        docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
        }
      }

    // Print this documentation type to the stream.
    if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
      {
      result = false;
      }

    // Close the file if we wrote one.
    if(fout)
      {
      delete fout;
      }
    }
  return result;
}

#define GET_OPT_ARGUMENT(target)                      \
     if((i+1 < argc) && !this->IsOption(argv[i+1]))   \
        {                                             \
        target = argv[i+1];                           \
        i = i+1;                                      \
        };


cmDocumentation::Form cmDocumentation::GetFormFromFilename(
                                                   const std::string& filename,
                                                   int* manSection)
{
  std::string ext = cmSystemTools::GetFilenameLastExtension(filename);
  ext = cmSystemTools::UpperCase(ext);
  if ((ext == ".HTM") || (ext == ".HTML"))
    {
    return cmDocumentation::HTMLForm;
    }

  if (ext == ".DOCBOOK")
    {
    return cmDocumentation::DocbookForm;
    }

  // ".1" to ".9" should be manpages
  if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
    {
    if (manSection)
      {
      *manSection = ext[1] - '0';
      }
    return cmDocumentation::ManForm;
    }

  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)
{
  // Providing zero arguments gives usage information.
  if(argc == 1)
    {
    RequestedHelpItem help;
    help.HelpType = cmDocumentation::Usage;
    help.HelpForm = cmDocumentation::UsageForm;
    this->RequestedHelpItems.push_back(help);
    return true;
    }

  // Search for supported help options.

  bool result = false;
  for(int i=1; i < argc; ++i)
    {
    if(exitOpt && strcmp(argv[i], exitOpt) == 0)
      {
      return result;
      }
    RequestedHelpItem help;
    // Check if this is a supported help option.
    if((strcmp(argv[i], "-help") == 0) ||
       (strcmp(argv[i], "--help") == 0) ||
       (strcmp(argv[i], "/?") == 0) ||
       (strcmp(argv[i], "-usage") == 0) ||
       (strcmp(argv[i], "-h") == 0) ||
       (strcmp(argv[i], "-H") == 0))
      {
      help.HelpType = cmDocumentation::Usage;
      help.HelpForm = cmDocumentation::UsageForm;
      GET_OPT_ARGUMENT(help.Argument);
      help.Argument = cmSystemTools::LowerCase(help.Argument);
      // special case for single command
      if (!help.Argument.empty())
        {
        help.HelpType = cmDocumentation::Single;
        }
      }
    else if(strcmp(argv[i], "--help-properties") == 0)
      {
      help.HelpType = cmDocumentation::Properties;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-policies") == 0)
      {
      help.HelpType = cmDocumentation::Policies;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-variables") == 0)
      {
      help.HelpType = cmDocumentation::Variables;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-modules") == 0)
      {
      help.HelpType = cmDocumentation::Modules;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-custom-modules") == 0)
      {
      help.HelpType = cmDocumentation::CustomModules;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-commands") == 0)
      {
      help.HelpType = cmDocumentation::Commands;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-compatcommands") == 0)
      {
      help.HelpType = cmDocumentation::CompatCommands;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-full") == 0)
      {
      help.HelpType = cmDocumentation::Full;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-html") == 0)
      {
      help.HelpType = cmDocumentation::Full;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::HTMLForm;
      }
    else if(strcmp(argv[i], "--help-man") == 0)
      {
      help.HelpType = cmDocumentation::Full;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::ManForm;
      help.ManSection = 1;
      }
    else if(strcmp(argv[i], "--help-command") == 0)
      {
      help.HelpType = cmDocumentation::Single;
      GET_OPT_ARGUMENT(help.Argument);
      GET_OPT_ARGUMENT(help.Filename);
      help.Argument = cmSystemTools::LowerCase(help.Argument);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-module") == 0)
      {
      help.HelpType = cmDocumentation::SingleModule;
      GET_OPT_ARGUMENT(help.Argument);
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-property") == 0)
      {
      help.HelpType = cmDocumentation::SingleProperty;
      GET_OPT_ARGUMENT(help.Argument);
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-policy") == 0)
      {
      help.HelpType = cmDocumentation::SinglePolicy;
      GET_OPT_ARGUMENT(help.Argument);
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-variable") == 0)
      {
      help.HelpType = cmDocumentation::SingleVariable;
      GET_OPT_ARGUMENT(help.Argument);
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename,
                                                &help.ManSection);
      }
    else if(strcmp(argv[i], "--help-command-list") == 0)
      {
      help.HelpType = cmDocumentation::List;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::TextForm;
      }
    else if(strcmp(argv[i], "--help-module-list") == 0)
      {
      help.HelpType = cmDocumentation::ModuleList;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::TextForm;
      }
    else if(strcmp(argv[i], "--help-property-list") == 0)
      {
      help.HelpType = cmDocumentation::PropertyList;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::TextForm;
      }
    else if(strcmp(argv[i], "--help-variable-list") == 0)
      {
      help.HelpType = cmDocumentation::VariableList;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::TextForm;
      }
    else if(strcmp(argv[i], "--copyright") == 0)
      {
      help.HelpType = cmDocumentation::Copyright;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::UsageForm;
      }
    else if((strcmp(argv[i], "--version") == 0) ||
            (strcmp(argv[i], "-version") == 0) ||
            (strcmp(argv[i], "/V") == 0))
      {
      help.HelpType = cmDocumentation::Version;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = cmDocumentation::UsageForm;
      }
    if(help.HelpType != None)
      {
      // This is a help option.  See if there is a file name given.
      result = true;
      this->RequestedHelpItems.push_back(help);
      }
    }
  return result;
}

//----------------------------------------------------------------------------
void cmDocumentation::Print(Form f, int manSection, std::ostream& os)
{
  this->SetForm(f, manSection);
  this->Print(os);
}

//----------------------------------------------------------------------------
void cmDocumentation::Print(std::ostream& os)
{
  // if the formatter supports it, print a master index for
  // all sections
  this->CurrentFormatter->PrintIndex(os, this->PrintSections);
  for(unsigned int i=0; i < this->PrintSections.size(); ++i)
    {
    std::string name = this->PrintSections[i]->
      GetName((this->CurrentFormatter->GetForm()));
    this->CurrentFormatter->PrintSection(os,*this->PrintSections[i],
                                         name.c_str());
    }
}

//----------------------------------------------------------------------------
void cmDocumentation::SetName(const char* name)
{
  this->NameString = name?name:"";
}

//----------------------------------------------------------------------------
void cmDocumentation::SetDocName(const char *docname)
{
  this->DocName = docname?docname:"";
}

//----------------------------------------------------------------------------
void cmDocumentation::SetSection(const char *name,
                                 cmDocumentationSection *section)
{
  if (this->AllSections.find(name) != this->AllSections.end())
    {
    delete this->AllSections[name];
    }
  this->AllSections[name] = section;
}

//----------------------------------------------------------------------------
void cmDocumentation::SetSection(const char *name,
                                 std::vector<cmDocumentationEntry> &docs)
{
  cmDocumentationSection *sec =
    new cmDocumentationSection(name,
                               cmSystemTools::UpperCase(name).c_str());
  sec->Append(docs);
  this->SetSection(name,sec);
}

//----------------------------------------------------------------------------
void cmDocumentation::SetSection(const char *name,
                                 const char *docs[][3])
{
  cmDocumentationSection *sec =
    new cmDocumentationSection(name,
                               cmSystemTools::UpperCase(name).c_str());
  sec->Append(docs);
  this->SetSection(name,sec);
}

//----------------------------------------------------------------------------
void cmDocumentation
::SetSections(std::map<std::string,cmDocumentationSection *> &sections)
{
  for (std::map<std::string,cmDocumentationSection *>::const_iterator
         it = sections.begin(); it != sections.end(); ++it)
    {
    this->SetSection(it->first.c_str(),it->second);
    }
}

//----------------------------------------------------------------------------
void cmDocumentation::PrependSection(const char *name,
                                     const char *docs[][3])
{
  cmDocumentationSection *sec = 0;
  if (this->AllSections.find(name) == this->AllSections.end())
    {
    sec = new cmDocumentationSection
      (name, cmSystemTools::UpperCase(name).c_str());
    this->SetSection(name,sec);
    }
  else
    {
    sec = this->AllSections[name];
    }
  sec->Prepend(docs);
}

//----------------------------------------------------------------------------
void cmDocumentation::PrependSection(const char *name,
                                     std::vector<cmDocumentationEntry> &docs)
{
  cmDocumentationSection *sec = 0;
  if (this->AllSections.find(name) == this->AllSections.end())
    {
    sec = new cmDocumentationSection
      (name, cmSystemTools::UpperCase(name).c_str());
    this->SetSection(name,sec);
    }
  else
    {
    sec = this->AllSections[name];
    }
  sec->Prepend(docs);
}

//----------------------------------------------------------------------------
void cmDocumentation::AppendSection(const char *name,
                                    const char *docs[][3])
{
  cmDocumentationSection *sec = 0;
  if (this->AllSections.find(name) == this->AllSections.end())
    {
    sec = new cmDocumentationSection
      (name, cmSystemTools::UpperCase(name).c_str());
    this->SetSection(name,sec);
    }
  else
    {
    sec = this->AllSections[name];
    }
  sec->Append(docs);
}

//----------------------------------------------------------------------------
void cmDocumentation::AppendSection(const char *name,
                                    std::vector<cmDocumentationEntry> &docs)
{
  cmDocumentationSection *sec = 0;
  if (this->AllSections.find(name) == this->AllSections.end())
    {
    sec = new cmDocumentationSection
      (name, cmSystemTools::UpperCase(name).c_str());
    this->SetSection(name,sec);
    }
  else
    {
    sec = this->AllSections[name];
    }
  sec->Append(docs);
}

//----------------------------------------------------------------------------
void cmDocumentation::AppendSection(const char *name,
                                    cmDocumentationEntry &docs)
{

  std::vector<cmDocumentationEntry> docsVec;
  docsVec.push_back(docs);
  this->AppendSection(name,docsVec);
}

//----------------------------------------------------------------------------
void cmDocumentation::PrependSection(const char *name,
                                     cmDocumentationEntry &docs)
{

  std::vector<cmDocumentationEntry> docsVec;
  docsVec.push_back(docs);
  this->PrependSection(name,docsVec);
}

//----------------------------------------------------------------------------
void cmDocumentation::SetSeeAlsoList(const char *data[][3])
{
  cmDocumentationSection *sec =
    new cmDocumentationSection("See Also", "SEE ALSO");
  this->AllSections["See Also"] = sec;
  this->SeeAlsoString = ".B ";
  int i = 0;
  while(data[i][1])
    {
    this->SeeAlsoString += data[i][1];
    this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
    ++i;
    }
  sec->Append(0,this->SeeAlsoString.c_str(),0);
  sec->Append(cmDocumentationStandardSeeAlso);
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
                                                const char *section)
{
  if(this->AllSections.find(section) == this->AllSections.end())
    {
    os << "Internal error: " << section << " list is empty." << std::endl;
    return false;
    }
  if(this->CurrentArgument.length() == 0)
    {
    os << "Required argument missing.\n";
    return false;
    }
  const std::vector<cmDocumentationEntry> &entries =
    this->AllSections[section]->GetEntries();
  for(std::vector<cmDocumentationEntry>::const_iterator ei =
        entries.begin();
      ei != entries.end(); ++ei)
    {
    if(this->CurrentArgument == ei->Name)
      {
      this->PrintDocumentationCommand(os, *ei);
      return true;
      }
    }
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
{
  if (this->PrintDocumentationGeneric(os,"Commands"))
    {
    return true;
    }
  if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
    {
    return true;
    }

  // Argument was not a command.  Complain.
  os << "Argument \"" << this->CurrentArgument.c_str()
     << "\" to --help-command is not a CMake command.  "
     << "Use --help-command-list to see all commands.\n";
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
{
  if(this->CurrentArgument.length() == 0)
    {
    os << "Argument --help-module needs a module name.\n";
    return false;
    }

  std::string moduleName;
  // find the module
  std::vector<std::string> dirs;
  cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
  for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
      dirIt != dirs.end();
      ++dirIt)
    {
    moduleName = *dirIt;
    moduleName += "/";
    moduleName += this->CurrentArgument;
    moduleName += ".cmake";
    if(cmSystemTools::FileExists(moduleName.c_str()))
      {
      break;
      }
    moduleName = "";
    }

  if (moduleName.empty())
    {
    moduleName = this->CMakeRoot;
    moduleName += "/Modules/";
    moduleName += this->CurrentArgument;
    moduleName += ".cmake";
    if(!cmSystemTools::FileExists(moduleName.c_str()))
      {
      moduleName = "";
      }
    }

  if(!moduleName.empty())
    {
    cmDocumentationSection *sec =
      new cmDocumentationSection("Standard CMake Modules", "MODULES");
    this->AllSections["Modules"] = sec;
    if (this->CreateSingleModule(moduleName.c_str(),
                                 this->CurrentArgument.c_str(),
                                 *this->AllSections["Modules"]))
      {
      if(this->AllSections["Modules"]->GetEntries().size())
        {
        this->PrintDocumentationCommand
          (os,  this->AllSections["Modules"]->GetEntries()[0]);
        os <<  "\n       Defined in: ";
        os << moduleName << "\n";
        return true;
        }
      else
        {
        return false;
        }
      }
    }

  // Argument was not a module.  Complain.
  os << "Argument \"" << this->CurrentArgument.c_str()
     << "\" to --help-module is not a CMake module.\n";
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
{
  bool done = false;
  for (std::vector<std::string>::iterator i =
         this->PropertySections.begin();
       !done && i != this->PropertySections.end(); ++i)
    {
    done = this->PrintDocumentationGeneric(os,i->c_str());
    }

  if (done)
    {
    return true;
    }

  // Argument was not a command.  Complain.
  os << "Argument \"" << this->CurrentArgument.c_str()
     << "\" to --help-property is not a CMake property.  "
     << "Use --help-property-list to see all properties.\n";
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
{
  if (this->PrintDocumentationGeneric(os,"Policies"))
    {
    return true;
    }

  // Argument was not a command.  Complain.
  os << "Argument \"" << this->CurrentArgument.c_str()
     << "\" to --help-policy is not a CMake policy.\n";
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSingleVariable(std::ostream& os)
{
  bool done = false;
  for (std::vector<std::string>::iterator i =
         this->VariableSections.begin();
       !done && i != this->VariableSections.end(); ++i)
    {
    done = this->PrintDocumentationGeneric(os,i->c_str());
    }

  if (done)
    {
    return true;
    }

  // Argument was not a command.  Complain.
  os << "Argument \"" << this->CurrentArgument.c_str()
     << "\" to --help-variable is not a defined variable.  "
     << "Use --help-variable-list to see all defined variables.\n";
  return false;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationList(std::ostream& os,
                                             const char *section)
{
  if(this->AllSections.find(section) == this->AllSections.end())
    {
    os << "Internal error: " << section << " list is empty." << std::endl;
    return false;
    }

  const std::vector<cmDocumentationEntry> &entries =
    this->AllSections[section]->GetEntries();
  for(std::vector<cmDocumentationEntry>::const_iterator ei =
        entries.begin();
      ei != entries.end(); ++ei)
    {
    if(ei->Name.size())
      {
      os << ei->Name << std::endl;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
{
  this->ClearSections();
  this->AddSectionToPrint("Usage");
  this->AddSectionToPrint("Options");
  if(this->ShowGenerators)
    {
    this->AddSectionToPrint("Generators");
    }
  this->Print(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
{
  this->CreateFullDocumentation();
  this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
{
  this->ClearSections();
  this->CreateModulesSection();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Modules));
  this->AddSectionToPrint("Description");
  this->AddSectionToPrint("Modules");
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("See Also");
  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
{
  this->ClearSections();
  this->CreateCustomModulesSection();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CustomModules));
  this->AddSectionToPrint("Description");
  this->AddSectionToPrint("Custom CMake Modules");
// the custom modules are most probably not under Kitware's copyright, Alex
//  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("See Also");

  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
{
  this->ClearSections();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Policies));
  this->AddSectionToPrint("Description");
  this->AddSectionToPrint("Policies");
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("See Also");

  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
{
  this->ClearSections();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Properties));
  this->AddSectionToPrint("Properties Description");
  for (std::vector<std::string>::iterator i =
         this->PropertySections.begin();
       i != this->PropertySections.end(); ++i)
    {
    this->AddSectionToPrint(i->c_str());
    }
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("Standard See Also");
  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
{
  this->ClearSections();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
  for (std::vector<std::string>::iterator i =
         this->VariableSections.begin();
       i != this->VariableSections.end(); ++i)
    {
    this->AddSectionToPrint(i->c_str());
    }
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("Standard See Also");
  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
{
  this->ClearSections();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Commands));
  this->AddSectionToPrint("Commands");
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("Standard See Also");
  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
{
  this->ClearSections();
  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CompatCommands));
  this->AddSectionToPrint("Compatibility Commands Description");
  this->AddSectionToPrint("Compatibility Commands");
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("Standard See Also");
  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
void cmDocumentation
::PrintDocumentationCommand(std::ostream& os,
                            const cmDocumentationEntry &entry)
{
  // the string "SingleItem" will be used in a few places to detect the case
  // that only the documentation for a single item is printed
  cmDocumentationSection *sec = new cmDocumentationSection("SingleItem","");
  sec->Append(entry);
  this->AllSections["temp"] = sec;
  this->ClearSections();
  this->AddSectionToPrint("temp");
  this->Print(os);
  this->AllSections.erase("temp");
  delete sec;
}

//----------------------------------------------------------------------------
void cmDocumentation::CreateFullDocumentation()
{
  this->ClearSections();
  this->CreateCustomModulesSection();
  this->CreateModulesSection();

  std::set<std::string> emitted;
  this->AddSectionToPrint("Name");
  emitted.insert("Name");
  this->AddSectionToPrint("Usage");
  emitted.insert("Usage");
  this->AddSectionToPrint("Description");
  emitted.insert("Description");
  this->AddSectionToPrint("Options");
  emitted.insert("Options");
  this->AddSectionToPrint("Generators");
  emitted.insert("Generators");
  this->AddSectionToPrint("Commands");
  emitted.insert("Commands");


  this->AddSectionToPrint("Properties Description");
  emitted.insert("Properties Description");
  for (std::vector<std::string>::iterator i =
         this->PropertySections.begin();
       i != this->PropertySections.end(); ++i)
    {
    this->AddSectionToPrint(i->c_str());
    emitted.insert(i->c_str());
    }

  emitted.insert("Copyright");
  emitted.insert("See Also");
  emitted.insert("Standard See Also");
  emitted.insert("Author");

  // add any sections not yet written out, or to be written out
  for (std::map<std::string, cmDocumentationSection*>::iterator i =
         this->AllSections.begin();
       i != this->AllSections.end(); ++i)
    {
    if (emitted.find(i->first) == emitted.end())
      {
      this->AddSectionToPrint(i->first.c_str());
      }
    }

  this->AddSectionToPrint("Copyright");

  if(this->CurrentFormatter->GetForm() == ManForm)
    {
    this->AddSectionToPrint("See Also");
    this->AddSectionToPrint("Author");
    }
  else
    {
    this->AddSectionToPrint("Standard See Also");
    }
}

//----------------------------------------------------------------------------
void cmDocumentation::SetForm(Form f, int manSection)
{
  switch(f)
  {
    case HTMLForm:
      this->CurrentFormatter = &this->HTMLFormatter;
      break;
    case DocbookForm:
      this->CurrentFormatter = &this->DocbookFormatter;
      break;
    case ManForm:
      this->ManFormatter.SetManSection(manSection);
      this->CurrentFormatter = &this->ManFormatter;
      break;
    case TextForm:
      this->CurrentFormatter = &this->TextFormatter;
      break;
    case UsageForm:
      this->CurrentFormatter = & this->UsageFormatter;
      break;
  }
}


//----------------------------------------------------------------------------
const char* cmDocumentation::GetNameString() const
{
  if(this->NameString.length() > 0)
    {
    return this->NameString.c_str();
    }
  else
    {
    return "CMake";
    }
}

//----------------------------------------------------------------------------
const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
{
  if (this->DocName.length() > 0)
    {
    return this->DocName.c_str();
    }
  else if (fallbackToNameString)
    {
    return this->GetNameString();
    }
  else
    return 0;
}

//----------------------------------------------------------------------------
#define CASE_DEFAULT_DOCNAME(doctype) \
  case cmDocumentation::doctype : \
    return GET_DOCUMENT_INTRO(doctype)[0];
const char* cmDocumentation::GetDefaultDocName(Type ht) const
{
  switch (ht)
    {
    CASE_DEFAULT_DOCNAME(Modules)
    CASE_DEFAULT_DOCNAME(CustomModules)
    CASE_DEFAULT_DOCNAME(Policies)
    CASE_DEFAULT_DOCNAME(Properties)
    CASE_DEFAULT_DOCNAME(Variables)
    CASE_DEFAULT_DOCNAME(Commands)
    CASE_DEFAULT_DOCNAME(CompatCommands)
    default: break;
    }
  return 0;
}

//----------------------------------------------------------------------------
bool cmDocumentation::IsOption(const char* arg) const
{
  return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
          (strcmp(arg, "/?") == 0));
}
