diff --git a/CMakeLists.txt b/CMakeLists.txt index 620b5d806..25cd576c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -582,7 +582,7 @@ install(FILES Copyright.txt DESTINATION ${CMAKE_DOC_DIR}) # Install script directories. install( - DIRECTORY Modules Templates + DIRECTORY Help Modules Templates DESTINATION ${CMAKE_DATA_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ DIRECTORY_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index f8f215fae..3c51e7ab5 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -13,9 +13,13 @@ #include "cmSystemTools.h" #include "cmVersion.h" +#include "cmRST.h" + #include #include +#include + #include //---------------------------------------------------------------------------- @@ -101,22 +105,30 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) { case cmDocumentation::Usage: return this->PrintDocumentationUsage(os); - case cmDocumentation::Single: - case cmDocumentation::SingleModule: - case cmDocumentation::SinglePolicy: - case cmDocumentation::SingleProperty: - case cmDocumentation::SingleVariable: - case cmDocumentation::List: - case cmDocumentation::ModuleList: - case cmDocumentation::PropertyList: - case cmDocumentation::VariableList: - case cmDocumentation::PolicyList: - case cmDocumentation::Modules: - case cmDocumentation::Policies: - case cmDocumentation::Properties: - case cmDocumentation::Variables: - case cmDocumentation::Commands: - return false; + case cmDocumentation::OneManual: + return this->PrintHelpOneManual(os); + case cmDocumentation::OneCommand: + return this->PrintHelpOneCommand(os); + case cmDocumentation::OneModule: + return this->PrintHelpOneModule(os); + case cmDocumentation::OnePolicy: + return this->PrintHelpOnePolicy(os); + case cmDocumentation::OneProperty: + return this->PrintHelpOneProperty(os); + case cmDocumentation::OneVariable: + return this->PrintHelpOneVariable(os); + case cmDocumentation::ListManuals: + return this->PrintHelpListManuals(os); + case cmDocumentation::ListCommands: + return this->PrintHelpListCommands(os); + case cmDocumentation::ListModules: + return this->PrintHelpListModules(os); + case cmDocumentation::ListProperties: + return this->PrintHelpListProperties(os); + case cmDocumentation::ListVariables: + return this->PrintHelpListVariables(os); + case cmDocumentation::ListPolicies: + return this->PrintHelpListPolicies(os); case cmDocumentation::Version: return this->PrintVersion(os); default: return false; @@ -126,6 +138,7 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) //---------------------------------------------------------------------------- bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) { + int count = 0; bool result = true; // Loop over requested documentation types. @@ -152,6 +165,10 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) result = false; } } + else if(++count > 1) + { + os << "\n\n"; + } // Print this documentation type to the stream. if(!this->PrintDocumentation(i->HelpType, *s) || !*s) @@ -287,33 +304,37 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, // special case for single command if (!help.Argument.empty()) { - help.HelpType = cmDocumentation::Single; + help.HelpType = cmDocumentation::OneCommand; } } else if(strcmp(argv[i], "--help-properties") == 0) { - help.HelpType = cmDocumentation::Properties; + help.HelpType = cmDocumentation::OneManual; + help.Argument = "cmake-properties.7"; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); } else if(strcmp(argv[i], "--help-policies") == 0) { - help.HelpType = cmDocumentation::Policies; + help.HelpType = cmDocumentation::OneManual; + help.Argument = "cmake-policies.7"; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); } else if(strcmp(argv[i], "--help-variables") == 0) { - help.HelpType = cmDocumentation::Variables; + help.HelpType = cmDocumentation::OneManual; + help.Argument = "cmake-variables.7"; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); } else if(strcmp(argv[i], "--help-modules") == 0) { - help.HelpType = cmDocumentation::Modules; + help.HelpType = cmDocumentation::OneManual; + help.Argument = "cmake-modules.7"; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); @@ -327,7 +348,8 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-commands") == 0) { - help.HelpType = cmDocumentation::Commands; + help.HelpType = cmDocumentation::OneManual; + help.Argument = "cmake-commands.7"; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); @@ -359,7 +381,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-command") == 0) { - help.HelpType = cmDocumentation::Single; + help.HelpType = cmDocumentation::OneCommand; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.Argument = cmSystemTools::LowerCase(help.Argument); @@ -368,7 +390,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-module") == 0) { - help.HelpType = cmDocumentation::SingleModule; + help.HelpType = cmDocumentation::OneModule; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, @@ -376,7 +398,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-property") == 0) { - help.HelpType = cmDocumentation::SingleProperty; + help.HelpType = cmDocumentation::OneProperty; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, @@ -384,7 +406,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-policy") == 0) { - help.HelpType = cmDocumentation::SinglePolicy; + help.HelpType = cmDocumentation::OnePolicy; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, @@ -392,42 +414,54 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } else if(strcmp(argv[i], "--help-variable") == 0) { - help.HelpType = cmDocumentation::SingleVariable; + help.HelpType = cmDocumentation::OneVariable; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename, &help.ManSection); } + else if(strcmp(argv[i], "--help-manual") == 0) + { + help.HelpType = cmDocumentation::OneManual; + GET_OPT_ARGUMENT(help.Argument); + GET_OPT_ARGUMENT(help.Filename); + this->WarnFormFromFilename(help); + } else if(strcmp(argv[i], "--help-command-list") == 0) { - help.HelpType = cmDocumentation::List; + help.HelpType = cmDocumentation::ListCommands; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::TextForm; } else if(strcmp(argv[i], "--help-module-list") == 0) { - help.HelpType = cmDocumentation::ModuleList; + help.HelpType = cmDocumentation::ListModules; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::TextForm; } else if(strcmp(argv[i], "--help-property-list") == 0) { - help.HelpType = cmDocumentation::PropertyList; + help.HelpType = cmDocumentation::ListProperties; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::TextForm; } else if(strcmp(argv[i], "--help-variable-list") == 0) { - help.HelpType = cmDocumentation::VariableList; + help.HelpType = cmDocumentation::ListVariables; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::TextForm; } else if(strcmp(argv[i], "--help-policy-list") == 0) { - help.HelpType = cmDocumentation::PolicyList; + help.HelpType = cmDocumentation::ListPolicies; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::TextForm; } + else if(strcmp(argv[i], "--help-manual-list") == 0) + { + help.HelpType = cmDocumentation::ListManuals; + GET_OPT_ARGUMENT(help.Filename); + } else if(strcmp(argv[i], "--copyright") == 0) { GET_OPT_ARGUMENT(help.Filename); @@ -616,6 +650,217 @@ void cmDocumentation::PrependSection(const char *name, this->PrependSection(name,docsVec); } +//---------------------------------------------------------------------------- +void cmDocumentation::GlobHelp(std::vector& files, + std::string const& pattern) +{ + cmsys::Glob gl; + std::string findExpr = this->CMakeRoot + "/Help/" + pattern + ".rst"; + if(gl.FindFiles(findExpr)) + { + files = gl.GetFiles(); + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintNames(std::ostream& os, + std::string const& pattern) +{ + std::vector files; + this->GlobHelp(files, pattern); + std::vector names; + for (std::vector::const_iterator i = files.begin(); + i != files.end(); ++i) + { + std::string line; + std::ifstream fin(i->c_str()); + while(fin && cmSystemTools::GetLineFromStream(fin, line)) + { + if(!line.empty() && (isalnum(line[0]) || line[0] == '<')) + { + names.push_back(line); + break; + } + } + } + std::sort(names.begin(), names.end()); + for (std::vector::iterator i = names.begin(); + i != names.end(); ++i) + { + os << *i << "\n"; + } +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintFiles(std::ostream& os, + std::string const& pattern) +{ + bool found = false; + std::vector files; + this->GlobHelp(files, pattern); + std::sort(files.begin(), files.end()); + cmRST r(os, this->CMakeRoot + "/Help"); + for (std::vector::const_iterator i = files.begin(); + i != files.end(); ++i) + { + found = r.ProcessFile(i->c_str()) || found; + } + return found; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOneManual(std::ostream& os) +{ + std::string mname = this->CurrentArgument; + std::string::size_type mlen = mname.length(); + if(mlen > 3 && mname[mlen-3] == '(' && + mname[mlen-1] == ')') + { + mname = mname.substr(0, mlen-3) + "." + mname[mlen-2]; + } + if(this->PrintFiles(os, "manual/" + mname) || + this->PrintFiles(os, "manual/" + mname + ".[0-9]")) + { + return true; + } + // Argument was not a manual. Complain. + os << "Argument \"" << this->CurrentArgument.c_str() + << "\" to --help-manual is not an available manual. " + << "Use --help-manual-list to see all available manuals.\n"; + return false; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpListManuals(std::ostream& os) +{ + this->PrintNames(os, "manual/*"); + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOneCommand(std::ostream& os) +{ + std::string cname = cmSystemTools::LowerCase(this->CurrentArgument); + if(this->PrintFiles(os, "command/" + cname)) + { + 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::PrintHelpListCommands(std::ostream& os) +{ + this->PrintNames(os, "command/*"); + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOneModule(std::ostream& os) +{ + std::string mname = this->CurrentArgument; + if(this->PrintFiles(os, "module/" + mname)) + { + 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::PrintHelpListModules(std::ostream& os) +{ + std::vector files; + this->GlobHelp(files, "module/*"); + std::vector modules; + for (std::vector::iterator fi = files.begin(); + fi != files.end(); ++fi) + { + std::string module = cmSystemTools::GetFilenameName(*fi); + modules.push_back(module.substr(0, module.size()-4)); + } + std::sort(modules.begin(), modules.end()); + for (std::vector::iterator i = modules.begin(); + i != modules.end(); ++i) + { + os << *i << "\n"; + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOneProperty(std::ostream& os) +{ + std::string pname = cmSystemTools::HelpFileName(this->CurrentArgument); + if(this->PrintFiles(os, "prop_*/" + pname)) + { + return true; + } + // Argument was not a property. 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::PrintHelpListProperties(std::ostream& os) +{ + this->PrintNames(os, "prop_*/*"); + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOnePolicy(std::ostream& os) +{ + std::string pname = this->CurrentArgument; + std::vector files; + if(this->PrintFiles(os, "policy/" + pname)) + { + return true; + } + + // Argument was not a policy. Complain. + os << "Argument \"" << this->CurrentArgument.c_str() + << "\" to --help-policy is not a CMake policy.\n"; + return false; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpListPolicies(std::ostream& os) +{ + this->PrintNames(os, "policy/*"); + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpOneVariable(std::ostream& os) +{ + std::string vname = cmSystemTools::HelpFileName(this->CurrentArgument); + if(this->PrintFiles(os, "variable/" + vname)) + { + return true; + } + // Argument was not a variable. 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::PrintHelpListVariables(std::ostream& os) +{ + this->PrintNames(os, "variable/*"); + return true; +} + //---------------------------------------------------------------------------- bool cmDocumentation::PrintDocumentationUsage(std::ostream& os) { diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index fac37480d..31c7602b3 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -131,7 +131,23 @@ public: private: void SetForm(Form f, int manSection); + void GlobHelp(std::vector& files, std::string const& pattern); + void PrintNames(std::ostream& os, std::string const& pattern); + bool PrintFiles(std::ostream& os, std::string const& pattern); + bool PrintVersion(std::ostream& os); + bool PrintHelpOneManual(std::ostream& os); + bool PrintHelpOneCommand(std::ostream& os); + bool PrintHelpOneModule(std::ostream& os); + bool PrintHelpOnePolicy(std::ostream& os); + bool PrintHelpOneProperty(std::ostream& os); + bool PrintHelpOneVariable(std::ostream& os); + bool PrintHelpListManuals(std::ostream& os); + bool PrintHelpListCommands(std::ostream& os); + bool PrintHelpListModules(std::ostream& os); + bool PrintHelpListProperties(std::ostream& os); + bool PrintHelpListVariables(std::ostream& os); + bool PrintHelpListPolicies(std::ostream& os); bool PrintDocumentationUsage(std::ostream& os); const char* GetNameString() const; diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h index 534a4dede..0bce50cc8 100644 --- a/Source/cmDocumentationFormatter.h +++ b/Source/cmDocumentationFormatter.h @@ -25,10 +25,11 @@ class cmDocumentationEnums public: /** Types of help provided. */ enum Type - { None, Usage, Single, SingleModule, SingleProperty, SingleVariable, - List, ModuleList, PropertyList, VariableList, PolicyList, - Properties, Variables, Modules, Commands, - Copyright, Version, Policies, SinglePolicy }; + { + None, Version, Usage, ListManuals, + ListCommands, ListModules, ListProperties, ListVariables, ListPolicies, + OneManual, OneCommand, OneModule, OneProperty, OneVariable, OnePolicy + }; /** Forms of documentation output. */ enum Form { TextForm, HTMLForm, RSTForm, ManForm, UsageForm, DocbookForm }; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 9ec49382a..cbd4632e3 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -200,6 +200,13 @@ std::string cmSystemTools::EscapeQuotes(const char* str) return result; } +std::string cmSystemTools::HelpFileName(std::string name) +{ + cmSystemTools::ReplaceString(name, "<", ""); + cmSystemTools::ReplaceString(name, ">", ""); + return name; +} + std::string cmSystemTools::TrimWhitespace(const std::string& s) { std::string::const_iterator start = s.begin(); diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 9d7dae9ef..cbc1140ff 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -49,6 +49,9 @@ public: ///! Escape quotes in a string. static std::string EscapeQuotes(const char* str); + /** Map help document name to file name. */ + static std::string HelpFileName(std::string); + /** * Returns a string that has whitespace removed from the start and the end. */