mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 10:50:16 -06:00
Help: Allow help for arbitrary keywords
Changes `cmake --help [arg]` to search `Help/*/` instead of `Help/command/` Allows editors to easily display manual for `<cword>`
This commit is contained in:
@@ -11,6 +11,21 @@
|
||||
|
||||
Usage describes the basic command line interface and its options.
|
||||
|
||||
.. option:: --help <keyword> [<file>]
|
||||
|
||||
Print help for one CMake keyword.
|
||||
|
||||
``<keyword>`` can be a property, variable, command, policy, generator
|
||||
or module.
|
||||
|
||||
The relevant manual entry for ``<keyword>`` is
|
||||
printed in a human-readable text format.
|
||||
|file|
|
||||
|
||||
.. versionchanged:: 3.28
|
||||
|
||||
Prior to CMake 3.28, this option supported command names only.
|
||||
|
||||
.. option:: --help-full [<file>]
|
||||
|
||||
Print all help manuals and exit.
|
||||
|
||||
@@ -9,17 +9,20 @@
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/Glob.hxx"
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmDocumentationEntry.h"
|
||||
#include "cmDocumentationSection.h"
|
||||
#include "cmRST.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmVersion.h"
|
||||
|
||||
namespace {
|
||||
const cmDocumentationEntry cmDocumentationStandardOptions[20] = {
|
||||
const cmDocumentationEntry cmDocumentationStandardOptions[21] = {
|
||||
{ "-h,-H,--help,-help,-usage,/?", "Print usage information and exit." },
|
||||
{ "--version,-version,/V [<file>]", "Print version number and exit." },
|
||||
{ "--help <keyword> [<file>]", "Print help for one keyword and exit." },
|
||||
{ "--help-full [<file>]", "Print all help manuals and exit." },
|
||||
{ "--help-manual <man> [<file>]", "Print one help manual and exit." },
|
||||
{ "--help-manual-list [<file>]", "List help manuals available and exit." },
|
||||
@@ -92,6 +95,8 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
|
||||
return this->PrintHelp(os);
|
||||
case cmDocumentation::Full:
|
||||
return this->PrintHelpFull(os);
|
||||
case cmDocumentation::OneArbitrary:
|
||||
return this->PrintHelpOneArbitrary(os);
|
||||
case cmDocumentation::OneManual:
|
||||
return this->PrintHelpOneManual(os);
|
||||
case cmDocumentation::OneCommand:
|
||||
@@ -176,6 +181,30 @@ void cmDocumentation::WarnFormFromFilename(
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmDocumentation::GeneralizeKeyword(std::string cname)
|
||||
{
|
||||
std::map<std::string, const std::vector<std::string>> conversions;
|
||||
std::vector<std::string> languages = {
|
||||
"C", "CXX", "CSharp", "CUDA", "OBJC",
|
||||
"OBJCXX", "Fortran", "HIP", "ISPC", "Swift",
|
||||
"ASM", "ASM_NASM", "ASM_MARMASM", "ASM_MASM", "ASM-ATT"
|
||||
};
|
||||
std::vector<std::string> configs = { "DEBUG", "RELEASE", "RELWITHDEBINFO",
|
||||
"MINSIZEREL" };
|
||||
conversions.emplace("LANG", std::move(languages));
|
||||
conversions.emplace("CONFIG", std::move(configs));
|
||||
for (auto const& it : conversions) {
|
||||
for (auto const& to_replace : it.second) {
|
||||
cmsys::RegularExpression reg(
|
||||
cmStrCat("(^|_)(", to_replace, ")(\\.|$|_)"));
|
||||
if (reg.find(cname)) {
|
||||
cname.replace(reg.start(2), to_replace.length(), it.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cname;
|
||||
}
|
||||
|
||||
void cmDocumentation::addCommonStandardDocSections()
|
||||
{
|
||||
cmDocumentationSection sec{ "Options" };
|
||||
@@ -237,10 +266,10 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
|
||||
(strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-H") == 0)) {
|
||||
help.HelpType = cmDocumentation::Help;
|
||||
i += int(get_opt_argument(i + 1, help.Argument));
|
||||
help.Argument = cmSystemTools::LowerCase(help.Argument);
|
||||
// special case for single command
|
||||
// special case for arbitrary keyword help
|
||||
if (!help.Argument.empty()) {
|
||||
help.HelpType = cmDocumentation::OneCommand;
|
||||
help.HelpType = cmDocumentation::OneArbitrary;
|
||||
i += int(get_opt_argument(i + 1, help.Filename));
|
||||
}
|
||||
} else if (strcmp(argv[i], "--help-properties") == 0) {
|
||||
help.HelpType = cmDocumentation::OneManual;
|
||||
@@ -400,7 +429,7 @@ void cmDocumentation::GlobHelp(std::vector<std::string>& files,
|
||||
{
|
||||
cmsys::Glob gl;
|
||||
std::string findExpr =
|
||||
cmSystemTools::GetCMakeRoot() + "/Help/" + pattern + ".rst";
|
||||
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/", pattern, ".rst");
|
||||
if (gl.FindFiles(findExpr)) {
|
||||
files = gl.GetFiles();
|
||||
}
|
||||
@@ -452,8 +481,8 @@ bool cmDocumentation::PrintHelpOneManual(std::ostream& os)
|
||||
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]")) {
|
||||
if (this->PrintFiles(os, cmStrCat("manual/", mname)) ||
|
||||
this->PrintFiles(os, cmStrCat("manual/", mname, ".[0-9]"))) {
|
||||
return true;
|
||||
}
|
||||
// Argument was not a manual. Complain.
|
||||
@@ -469,10 +498,43 @@ bool cmDocumentation::PrintHelpListManuals(std::ostream& os)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmDocumentation::PrintHelpOneArbitrary(std::ostream& os)
|
||||
{
|
||||
std::string word = cmSystemTools::HelpFileName(this->CurrentArgument);
|
||||
std::string word_m = GeneralizeKeyword(word);
|
||||
|
||||
// Support legacy style uppercase commands, with LANG and CONFIG
|
||||
// substitutions
|
||||
bool found = this->PrintFiles(os, cmStrCat("*/", word));
|
||||
if (found) {
|
||||
os << "\n";
|
||||
}
|
||||
found = this->PrintFiles(
|
||||
os, cmStrCat("command/", cmSystemTools::LowerCase(word))) ||
|
||||
found;
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
found = this->PrintFiles(os, cmStrCat("*/", word_m));
|
||||
if (found) {
|
||||
os << "\n";
|
||||
}
|
||||
found = this->PrintFiles(
|
||||
os, cmStrCat("command/", cmSystemTools::LowerCase(word_m))) ||
|
||||
found;
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
os << "Argument \"" << this->CurrentArgument
|
||||
<< "\" to --help did not match any keywords. "
|
||||
"Use --help without any arguments to print CMake help information.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmDocumentation::PrintHelpOneCommand(std::ostream& os)
|
||||
{
|
||||
std::string cname = cmSystemTools::LowerCase(this->CurrentArgument);
|
||||
if (this->PrintFiles(os, "command/" + cname)) {
|
||||
if (this->PrintFiles(os, cmStrCat("command/", cname))) {
|
||||
return true;
|
||||
}
|
||||
// Argument was not a command. Complain.
|
||||
@@ -491,7 +553,7 @@ bool cmDocumentation::PrintHelpListCommands(std::ostream& os)
|
||||
bool cmDocumentation::PrintHelpOneModule(std::ostream& os)
|
||||
{
|
||||
std::string mname = this->CurrentArgument;
|
||||
if (this->PrintFiles(os, "module/" + mname)) {
|
||||
if (this->PrintFiles(os, cmStrCat("module/", mname))) {
|
||||
return true;
|
||||
}
|
||||
// Argument was not a module. Complain.
|
||||
@@ -519,7 +581,7 @@ bool cmDocumentation::PrintHelpListModules(std::ostream& os)
|
||||
bool cmDocumentation::PrintHelpOneProperty(std::ostream& os)
|
||||
{
|
||||
std::string pname = cmSystemTools::HelpFileName(this->CurrentArgument);
|
||||
if (this->PrintFiles(os, "prop_*/" + pname)) {
|
||||
if (this->PrintFiles(os, cmStrCat("prop_*/", pname))) {
|
||||
return true;
|
||||
}
|
||||
// Argument was not a property. Complain.
|
||||
@@ -539,7 +601,7 @@ bool cmDocumentation::PrintHelpOnePolicy(std::ostream& os)
|
||||
{
|
||||
std::string pname = this->CurrentArgument;
|
||||
std::vector<std::string> files;
|
||||
if (this->PrintFiles(os, "policy/" + pname)) {
|
||||
if (this->PrintFiles(os, cmStrCat("policy/", pname))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -567,7 +629,7 @@ bool cmDocumentation::PrintHelpListGenerators(std::ostream& os)
|
||||
bool cmDocumentation::PrintHelpOneVariable(std::ostream& os)
|
||||
{
|
||||
std::string vname = cmSystemTools::HelpFileName(this->CurrentArgument);
|
||||
if (this->PrintFiles(os, "variable/" + vname)) {
|
||||
if (this->PrintFiles(os, cmStrCat("variable/", vname))) {
|
||||
return true;
|
||||
}
|
||||
// Argument was not a variable. Complain.
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
ListVariables,
|
||||
ListPolicies,
|
||||
ListGenerators,
|
||||
OneArbitrary,
|
||||
OneManual,
|
||||
OneCommand,
|
||||
OneModule,
|
||||
@@ -118,6 +119,7 @@ private:
|
||||
bool PrintUsage(std::ostream& os);
|
||||
bool PrintHelp(std::ostream& os);
|
||||
bool PrintHelpFull(std::ostream& os);
|
||||
bool PrintHelpOneArbitrary(std::ostream& os);
|
||||
bool PrintHelpOneManual(std::ostream& os);
|
||||
bool PrintHelpOneCommand(std::ostream& os);
|
||||
bool PrintHelpOneModule(std::ostream& os);
|
||||
@@ -154,4 +156,5 @@ private:
|
||||
cmDocumentationFormatter Formatter;
|
||||
|
||||
static void WarnFormFromFilename(RequestedHelpItem& request, bool& result);
|
||||
static std::string GeneralizeKeyword(std::string word);
|
||||
};
|
||||
|
||||
@@ -1125,3 +1125,5 @@ if(RunCMake_GENERATOR MATCHES "^Visual Studio 12 2013")
|
||||
run_cmake(DeprecateVS12-WARN-ON)
|
||||
run_cmake_with_options(DeprecateVS12-WARN-OFF -DCMAKE_WARN_VS12=OFF)
|
||||
endif()
|
||||
|
||||
run_cmake_with_options(help-arbitrary "--help" "CMAKE_CXX_IGNORE_EXTENSIONS")
|
||||
|
||||
7
Tests/RunCMake/CommandLine/help-arbitrary-stdout.txt
Normal file
7
Tests/RunCMake/CommandLine/help-arbitrary-stdout.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
CMAKE_<LANG>_IGNORE_EXTENSIONS
|
||||
------------------------------
|
||||
|
||||
File extensions that should be ignored by the build.
|
||||
|
||||
This is a list of file extensions that may be part of a project for a
|
||||
given language but are not compiled.
|
||||
Reference in New Issue
Block a user