summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-10-27 12:31:34 (GMT)
committerBrad King <brad.king@kitware.com>2017-10-27 13:26:50 (GMT)
commit992962c76dd472fa9d122231c89d8d11aedd3288 (patch)
treede761b94f411e05bba39e27f188f4a9087e13da2 /Source
parenta5197eeac7a28046729c40067ee02cd7e3e8e01b (diff)
downloadCMake-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.cxx122
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)) {