/*============================================================================
  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>


//----------------------------------------------------------------------------
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", "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 [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 "
  "existance 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 "
  "existance 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,
   "Summary of helpful links:\n"
   "  Home: http://www.cmake.org\n"
   "  Docs: http://www.cmake.org/HTML/Documentation.html\n"
   "  Mail: http://www.cmake.org/HTML/MailingLists.html\n"
   "  FAQ:  http://www.cmake.org/Wiki/CMake_FAQ\n"
   , 0},
  {0,0,0}
};

//----------------------------------------------------------------------------
static const char *cmDocumentationCopyright[][3] =
{
  {0,
   "Copyright 2000-2009 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);

  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->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] == '#')
      {
      // 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
      {
      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;
      }
    }
  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);
    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)
{
  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'))
    {
    return cmDocumentation::ManForm;
    }

  return cmDocumentation::TextForm;
}

//----------------------------------------------------------------------------
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);
      }
    else if(strcmp(argv[i], "--help-policies") == 0)
      {
      help.HelpType = cmDocumentation::Policies;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-variables") == 0)
      {
      help.HelpType = cmDocumentation::Variables;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-modules") == 0)
      {
      help.HelpType = cmDocumentation::Modules;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-custom-modules") == 0)
      {
      help.HelpType = cmDocumentation::CustomModules;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-commands") == 0)
      {
      help.HelpType = cmDocumentation::Commands;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-compatcommands") == 0)
      {
      help.HelpType = cmDocumentation::CompatCommands;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    else if(strcmp(argv[i], "--help-full") == 0)
      {
      help.HelpType = cmDocumentation::Full;
      GET_OPT_ARGUMENT(help.Filename);
      help.HelpForm = this->GetFormFromFilename(help.Filename);
      }
    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;
      }
    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);
      }
    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);
      }
    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);
      }
    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);
      }
    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);
      }
    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, std::ostream& os)
{
  this->SetForm(f);
  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"]))
      {
      this->PrintDocumentationCommand
        (os,  this->AllSections["Modules"]->GetEntries()[0]);
      os <<  "\n       Defined in: ";
      os << moduleName << "\n";
      return true;
      }
    }

  // 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)
{
  switch(f)
  {
    case HTMLForm:
      this->CurrentFormatter = &this->HTMLFormatter;
      break;
    case DocbookForm:
      this->CurrentFormatter = &this->DocbookFormatter;
      break;
    case ManForm:
      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));
}
