From 1c075ffd60ba9354f8aaf314f0938aeb4247adc8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Oct 2017 08:21:22 -0400 Subject: cmcmd: Rename loop iteration variable for clarity --- Source/cmcmd.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ed507fd..3ca0513 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -358,8 +358,8 @@ int cmcmd::HandleCoCompileCommands(std::vector& args) std::string commandFound; // the command that was in the args list std::vector orig_cmd; bool doing_options = true; - for (std::string::size_type cc = 2; cc < args.size(); cc++) { - std::string const& arg = args[cc]; + for (std::string::size_type i = 2; i < args.size(); ++i) { + std::string const& arg = args[i]; // if the arg is -- then the rest of the args after // go into orig_cmd if (arg == "--") { -- cgit v0.12 From a5197eeac7a28046729c40067ee02cd7e3e8e01b Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Oct 2017 08:30:20 -0400 Subject: cmcmd: Convert lint handlers to file-static functions These do not need to be declared in the header. --- Source/cmcmd.cxx | 23 ++++++++++++----------- Source/cmcmd.h | 18 ------------------ 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 3ca0513..abf6447 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -160,7 +160,8 @@ static bool cmTarFilesFrom(std::string const& file, return true; } -int cmcmd::HandleIWYU(const std::string& runCmd, const std::string&, +static int HandleIWYU(const std::string& runCmd, + const std::string& /* sourceFile */, const std::vector& orig_cmd) { // Construct the iwyu command line by taking what was given @@ -187,7 +188,7 @@ int cmcmd::HandleIWYU(const std::string& runCmd, const std::string&, return 0; } -int cmcmd::HandleTidy(const std::string& runCmd, const std::string& sourceFile, +static int HandleTidy(const std::string& runCmd, const std::string& sourceFile, const std::vector& orig_cmd) { // Construct the clang-tidy command line by taking what was given @@ -218,7 +219,8 @@ int cmcmd::HandleTidy(const std::string& runCmd, const std::string& sourceFile, return ret; } -int cmcmd::HandleLWYU(const std::string& runCmd, const std::string&, +static int HandleLWYU(const std::string& runCmd, + const std::string& /* sourceFile */, const std::vector&) { // Construct the ldd -r -u (link what you use lwyu) command line @@ -250,7 +252,7 @@ int cmcmd::HandleLWYU(const std::string& runCmd, const std::string&, return 0; } -int cmcmd::HandleCppLint(const std::string& runCmd, +static int HandleCppLint(const std::string& runCmd, const std::string& sourceFile, const std::vector&) { @@ -274,7 +276,7 @@ int cmcmd::HandleCppLint(const std::string& runCmd, return ret; } -int cmcmd::HandleCppCheck(const std::string& runCmd, +static int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile, const std::vector& orig_cmd) { @@ -340,12 +342,11 @@ int cmcmd::HandleCoCompileCommands(std::vector& args) // 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(&cmcmd::HandleIWYU, a1, a2, a3); - coCompileTypes["--tidy="] = std::bind(&cmcmd::HandleTidy, a1, a2, a3); - coCompileTypes["--lwyu="] = std::bind(&cmcmd::HandleLWYU, a1, a2, a3); - coCompileTypes["--cpplint="] = std::bind(&cmcmd::HandleCppLint, a1, a2, a3); - coCompileTypes["--cppcheck="] = - std::bind(&cmcmd::HandleCppCheck, a1, a2, a3); + 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 commandOptions; commandOptions.reserve(coCompileTypes.size()); diff --git a/Source/cmcmd.h b/Source/cmcmd.h index 090ca08..d1e03d0 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h @@ -18,24 +18,6 @@ public: */ static int ExecuteCMakeCommand(std::vector&); - // define co-compile command handlers they must be public - // because they are used in a std::function map - static int HandleIWYU(const std::string& runCmd, - const std::string& sourceFile, - const std::vector& orig_cmd); - static int HandleTidy(const std::string& runCmd, - const std::string& sourceFile, - const std::vector& orig_cmd); - static int HandleLWYU(const std::string& runCmd, - const std::string& sourceFile, - const std::vector& orig_cmd); - static int HandleCppLint(const std::string& runCmd, - const std::string& sourceFile, - const std::vector& orig_cmd); - static int HandleCppCheck(const std::string& runCmd, - const std::string& sourceFile, - const std::vector& orig_cmd); - protected: static int HandleCoCompileCommands(std::vector& args); static int HashSumFile(std::vector& args, -- cgit v0.12 From 992962c76dd472fa9d122231c89d8d11aedd3288 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Oct 2017 08:31:34 -0400 Subject: 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. --- Source/cmcmd.cxx | 122 +++++++++++---------- Tests/RunCMake/CMakeLists.txt | 6 + .../E___run_co_compile-no-iwyu-stderr.txt | 11 +- Tests/RunCMake/MultiLint/C-Build-stdout.txt | 8 ++ Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt | 8 ++ Tests/RunCMake/MultiLint/C-launch.cmake | 3 + Tests/RunCMake/MultiLint/C.cmake | 6 + Tests/RunCMake/MultiLint/CMakeLists.txt | 3 + Tests/RunCMake/MultiLint/CXX-Build-stdout.txt | 8 ++ .../RunCMake/MultiLint/CXX-launch-Build-stdout.txt | 8 ++ Tests/RunCMake/MultiLint/CXX-launch.cmake | 3 + Tests/RunCMake/MultiLint/CXX.cmake | 6 + Tests/RunCMake/MultiLint/RunCMakeTest.cmake | 27 +++++ Tests/RunCMake/MultiLint/main.c | 4 + Tests/RunCMake/MultiLint/main.cxx | 4 + 15 files changed, 166 insertions(+), 61 deletions(-) create mode 100644 Tests/RunCMake/MultiLint/C-Build-stdout.txt create mode 100644 Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/MultiLint/C-launch.cmake create mode 100644 Tests/RunCMake/MultiLint/C.cmake create mode 100644 Tests/RunCMake/MultiLint/CMakeLists.txt create mode 100644 Tests/RunCMake/MultiLint/CXX-Build-stdout.txt create mode 100644 Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt create mode 100644 Tests/RunCMake/MultiLint/CXX-launch.cmake create mode 100644 Tests/RunCMake/MultiLint/CXX.cmake create mode 100644 Tests/RunCMake/MultiLint/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/MultiLint/main.c create mode 100644 Tests/RunCMake/MultiLint/main.cxx 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 -#include #include -#include #include // IWYU pragma: keep #include #include #include +#include #include -#include 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&); + +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& args) { - // initialize a map from command option to handler function - std::map&)>> - 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 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 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 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& 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& 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)) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 57cc144..29325ff 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -370,6 +370,12 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$) add_RunCMake_test(Cpplint -DPSEUDO_CPPLINT=$) add_RunCMake_test(Cppcheck -DPSEUDO_CPPCHECK=$) + add_RunCMake_test(MultiLint + -DPSEUDO_TIDY=$ + -DPSEUDO_IWYU=$ + -DPSEUDO_CPPLINT=$ + -DPSEUDO_CPPCHECK=$ + ) if(DEFINED CMake_TEST_CUDA) list(APPEND CompilerLauncher_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA}) endif() diff --git a/Tests/RunCMake/CommandLine/E___run_co_compile-no-iwyu-stderr.txt b/Tests/RunCMake/CommandLine/E___run_co_compile-no-iwyu-stderr.txt index ffa1da8..a7fbad6 100644 --- a/Tests/RunCMake/CommandLine/E___run_co_compile-no-iwyu-stderr.txt +++ b/Tests/RunCMake/CommandLine/E___run_co_compile-no-iwyu-stderr.txt @@ -1,5 +1,6 @@ -^__run_co_compile missing command to run. Looking for one of the following: -.*--cppcheck= -.*--cpplint= -.*--iwyu= -.*--tidy= +^__run_co_compile missing command to run. Looking for one or more of the following: +--cppcheck= +--cpplint= +--iwyu= +--lwyu= +--tidy= diff --git a/Tests/RunCMake/MultiLint/C-Build-stdout.txt b/Tests/RunCMake/MultiLint/C-Build-stdout.txt new file mode 100644 index 0000000..d10427e --- /dev/null +++ b/Tests/RunCMake/MultiLint/C-Build-stdout.txt @@ -0,0 +1,8 @@ +Warning: include-what-you-use reported diagnostics: +should add these lines: +* +#include <\.\.\.> ++ +.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.c:0:0: warning: message \[checker\].* +Total errors found: 0 +.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.* diff --git a/Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt b/Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt new file mode 100644 index 0000000..d10427e --- /dev/null +++ b/Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt @@ -0,0 +1,8 @@ +Warning: include-what-you-use reported diagnostics: +should add these lines: +* +#include <\.\.\.> ++ +.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.c:0:0: warning: message \[checker\].* +Total errors found: 0 +.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.* diff --git a/Tests/RunCMake/MultiLint/C-launch.cmake b/Tests/RunCMake/MultiLint/C-launch.cmake new file mode 100644 index 0000000..e66ca20 --- /dev/null +++ b/Tests/RunCMake/MultiLint/C-launch.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(C.cmake) diff --git a/Tests/RunCMake/MultiLint/C.cmake b/Tests/RunCMake/MultiLint/C.cmake new file mode 100644 index 0000000..495d6f0 --- /dev/null +++ b/Tests/RunCMake/MultiLint/C.cmake @@ -0,0 +1,6 @@ +enable_language(C) +set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args) +set(CMAKE_C_CLANG_TIDY "${PSEUDO_TIDY}" -some -args) +set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80) +set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}") +add_executable(main main.c) diff --git a/Tests/RunCMake/MultiLint/CMakeLists.txt b/Tests/RunCMake/MultiLint/CMakeLists.txt new file mode 100644 index 0000000..bf2ef15 --- /dev/null +++ b/Tests/RunCMake/MultiLint/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.10) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/MultiLint/CXX-Build-stdout.txt b/Tests/RunCMake/MultiLint/CXX-Build-stdout.txt new file mode 100644 index 0000000..aaf5fd7 --- /dev/null +++ b/Tests/RunCMake/MultiLint/CXX-Build-stdout.txt @@ -0,0 +1,8 @@ +Warning: include-what-you-use reported diagnostics: +should add these lines: +* +#include <\.\.\.> ++ +.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.cxx:0:0: warning: message \[checker\].* +Total errors found: 0 +.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.* diff --git a/Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt b/Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt new file mode 100644 index 0000000..aaf5fd7 --- /dev/null +++ b/Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt @@ -0,0 +1,8 @@ +Warning: include-what-you-use reported diagnostics: +should add these lines: +* +#include <\.\.\.> ++ +.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.cxx:0:0: warning: message \[checker\].* +Total errors found: 0 +.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.* diff --git a/Tests/RunCMake/MultiLint/CXX-launch.cmake b/Tests/RunCMake/MultiLint/CXX-launch.cmake new file mode 100644 index 0000000..3002c9d --- /dev/null +++ b/Tests/RunCMake/MultiLint/CXX-launch.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(CXX.cmake) diff --git a/Tests/RunCMake/MultiLint/CXX.cmake b/Tests/RunCMake/MultiLint/CXX.cmake new file mode 100644 index 0000000..dc30146 --- /dev/null +++ b/Tests/RunCMake/MultiLint/CXX.cmake @@ -0,0 +1,6 @@ +enable_language(CXX) +set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args) +set(CMAKE_CXX_CLANG_TIDY "${PSEUDO_TIDY}" -some -args) +set(CMAKE_CXX_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80) +set(CMAKE_CXX_CPPCHECK "${PSEUDO_CPPCHECK}") +add_executable(main main.cxx) diff --git a/Tests/RunCMake/MultiLint/RunCMakeTest.cmake b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake new file mode 100644 index 0000000..afd98fd --- /dev/null +++ b/Tests/RunCMake/MultiLint/RunCMakeTest.cmake @@ -0,0 +1,27 @@ +include(RunCMake) + +set(RunCMake_TEST_OPTIONS + "-DPSEUDO_CPPCHECK=${PSEUDO_CPPCHECK}" + "-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}" + "-DPSEUDO_IWYU=${PSEUDO_IWYU}" + "-DPSEUDO_TIDY=${PSEUDO_TIDY}" + ) + +function(run_multilint lang) + # Use a single build tree for tests without cleaning. + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${lang}-build") + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + run_cmake(${lang}) + set(RunCMake_TEST_OUTPUT_MERGE 1) + run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build .) +endfunction() + +run_multilint(C) +run_multilint(CXX) + +if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") + run_multilint(C-launch) + run_multilint(CXX-launch) +endif() diff --git a/Tests/RunCMake/MultiLint/main.c b/Tests/RunCMake/MultiLint/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/MultiLint/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/MultiLint/main.cxx b/Tests/RunCMake/MultiLint/main.cxx new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/RunCMake/MultiLint/main.cxx @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} -- cgit v0.12