|
|
@@ -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)) {
|