diff options
author | Brad King <brad.king@kitware.com> | 2017-10-27 12:31:34 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-10-27 13:26:50 (GMT) |
commit | 992962c76dd472fa9d122231c89d8d11aedd3288 (patch) | |
tree | de761b94f411e05bba39e27f188f4a9087e13da2 /Source | |
parent | a5197eeac7a28046729c40067ee02cd7e3e8e01b (diff) | |
download | CMake-992962c76dd472fa9d122231c89d8d11aedd3288.zip CMake-992962c76dd472fa9d122231c89d8d11aedd3288.tar.gz CMake-992962c76dd472fa9d122231c89d8d11aedd3288.tar.bz2 |
cmcmd: Restore support for running multiple lint tools
Refactoring in commit v3.10.0-rc1~115^2 (Clean up iwyu code to not be
one big if statement, 2017-08-28) incorrectly changed the logic to run
only one lint tool at a time. Restore support for running all tools
specified on the command-line.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmcmd.cxx | 122 |
1 files changed, 66 insertions, 56 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index abf6447..b4772a9 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -33,15 +33,13 @@ #include "cmsys/Process.h" #include "cmsys/Terminal.h" #include <algorithm> -#include <functional> #include <iostream> -#include <map> #include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <time.h> -#include <utility> class cmConnection; @@ -328,35 +326,41 @@ static int HandleCppCheck(const std::string& runCmd, return 0; } +typedef int (*CoCompileHandler)(const std::string&, const std::string&, + const std::vector<std::string>&); + +struct CoCompiler +{ + const char* Option; + CoCompileHandler Handler; + bool NoOriginalCommand; +}; + +static CoCompiler CoCompilers[] = { // Table of options and handlers. + { "--cppcheck=", HandleCppCheck, false }, + { "--cpplint=", HandleCppLint, false }, + { "--iwyu=", HandleIWYU, false }, + { "--lwyu=", HandleLWYU, true }, + { "--tidy=", HandleTidy, false } +}; + +struct CoCompileJob +{ + std::string Command; + CoCompileHandler Handler; +}; + // called when args[0] == "__run_co_compile" int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args) { - // initialize a map from command option to handler function - std::map<std::string, - std::function<int(const std::string&, const std::string&, - const std::vector<std::string>&)>> - coCompileTypes; - auto a1 = std::placeholders::_1; - auto a2 = std::placeholders::_2; - auto a3 = std::placeholders::_3; - // create a map from option to handler function for option - // if the option does not call the original command then it will need - // to set runOriginalCmd to false later in this function - coCompileTypes["--iwyu="] = std::bind(&HandleIWYU, a1, a2, a3); - coCompileTypes["--tidy="] = std::bind(&HandleTidy, a1, a2, a3); - coCompileTypes["--lwyu="] = std::bind(&HandleLWYU, a1, a2, a3); - coCompileTypes["--cpplint="] = std::bind(&HandleCppLint, a1, a2, a3); - coCompileTypes["--cppcheck="] = std::bind(&HandleCppCheck, a1, a2, a3); - // copy the command options to a vector of strings - std::vector<std::string> commandOptions; - commandOptions.reserve(coCompileTypes.size()); - for (const auto& i : coCompileTypes) { - commandOptions.push_back(i.first); - } - - std::string runCmd; // command to be run from --thing=command - std::string sourceFile; // store --source= - std::string commandFound; // the command that was in the args list + std::vector<CoCompileJob> jobs; + std::string sourceFile; // store --source= + + // Default is to run the original command found after -- if the option + // does not need to do that, it should be specified here, currently only + // lwyu does that. + bool runOriginalCmd = true; + std::vector<std::string> orig_cmd; bool doing_options = true; for (std::string::size_type i = 2; i < args.size(); ++i) { @@ -367,20 +371,25 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args) doing_options = false; } else if (doing_options) { bool optionFound = false; - // check arg against all the commandOptions - for (auto const& command : commandOptions) { - if (arg.compare(0, command.size(), command) == 0) { + for (CoCompiler const* cc = cmArrayBegin(CoCompilers); + cc != cmArrayEnd(CoCompilers); ++cc) { + size_t optionLen = strlen(cc->Option); + if (arg.compare(0, optionLen, cc->Option) == 0) { optionFound = true; - runCmd = arg.substr(command.size()); - commandFound = command; + CoCompileJob job; + job.Command = arg.substr(optionLen); + job.Handler = cc->Handler; + jobs.push_back(std::move(job)); + if (cc->NoOriginalCommand) { + runOriginalCmd = false; + } } } - // check arg with --source= if (cmHasLiteralPrefix(arg, "--source=")) { sourceFile = arg.substr(9); optionFound = true; } - // if it was not a commandOptions or --source then error + // if it was not a co-compiler or --source then error if (!optionFound) { std::cerr << "__run_co_compile given unknown argument: " << arg << "\n"; @@ -390,39 +399,40 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args) orig_cmd.push_back(arg); } } - if (commandFound.empty()) { - std::cerr << "__run_co_compile missing command to run. Looking for one of " - "the following:\n"; - for (const auto& i : commandOptions) { - std::cerr << i << "\n"; + if (jobs.empty()) { + std::cerr << "__run_co_compile missing command to run. " + "Looking for one or more of the following:\n"; + for (CoCompiler const* cc = cmArrayBegin(CoCompilers); + cc != cmArrayEnd(CoCompilers); ++cc) { + std::cerr << cc->Option << "\n"; } return 1; } - // Default is to run the original command found after -- if the option - // does not need to do that, it should be specified here, currently only - // lwyu does that. - bool runOriginalCmd = true; - if (commandFound == "--lwyu=") { - runOriginalCmd = false; - } + if (runOriginalCmd && orig_cmd.empty()) { std::cerr << "__run_co_compile missing compile command after --\n"; return 1; } - // call the command handler here - int ret = coCompileTypes[commandFound](runCmd, sourceFile, orig_cmd); - // if the command returns non-zero then return and fail. - // for commands that do not want to break the build, they should return - // 0 no matter what. - if (ret != 0) { - return ret; + for (CoCompileJob const& job : jobs) { + // call the command handler here + int ret = job.Handler(job.Command, sourceFile, orig_cmd); + + // if the command returns non-zero then return and fail. + // for commands that do not want to break the build, they should return + // 0 no matter what. + if (ret != 0) { + return ret; + } } + // if there is no original command to run return now if (!runOriginalCmd) { - return ret; + return 0; } + // Now run the real compiler command and return its result value + int ret; if (!cmSystemTools::RunSingleCommand(orig_cmd, nullptr, nullptr, &ret, nullptr, cmSystemTools::OUTPUT_PASSTHROUGH)) { |