/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmDocumentation.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:08 $
  Version:   $Revision: 1.1.1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices 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 (c) 2002 Kitware, Inc., Insight 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},
  {"",
   "The names of Kitware, Inc., the Insight Consortium, or the names of "
   "any consortium members, or of any contributors, may not be used to "
   "endorse or promote products derived from this software without "
   "specific prior written permission.", 0},
  {"",
   "Modified source versions must be plainly marked as such, and must "
   "not be misrepresented as being the original software.", 0},
  {0,
   "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 AUTHORS 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}
};

//----------------------------------------------------------------------------
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->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");
}

//----------------------------------------------------------------------------
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();
}

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

  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;
    if(i->Filename.length() > 0)
      {
      fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
      if(fout)
        {
        s = fout;
        }
      else
        {
        result = false;
        }
      }
    
    // Print this documentation type to the stream.
    if(!this->PrintDocumentation(i->HelpType, *s) || !*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::GetFilenameExtension(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)
{
  // 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)
    {
    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::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");
  this->AddSectionToPrint("Generators");
  this->Print(os);
  return true;
}

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

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

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
{
  this->ClearSections();
  this->CreateCustomModulesSection();
  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(this->GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

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

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

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
{
  this->ClearSections();
  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(this->GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
{
  this->ClearSections();
  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(this->GetNameString(), os);
  this->Print(os);
  this->CurrentFormatter->PrintFooter(os);
  return true;
}

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

//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
{
  this->ClearSections();
  this->AddSectionToPrint("Compatibility Commands Description");
  this->AddSectionToPrint("Compatibility Commands");
  this->AddSectionToPrint("Copyright");
  this->AddSectionToPrint("Standard See Also");
  this->CurrentFormatter->PrintHeader(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";
    }
}

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