diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2017-08-16 16:24:44 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-08-30 14:23:46 (GMT) |
commit | 311b7b1a7095ec460fab950a6767571eb3b9652c (patch) | |
tree | 23843c9cd26d9d150e76fadda88a8fbf47d5f12c /Source/cmcmd.cxx | |
parent | fff28e30cd01a88b2e5f67db2aaf4c068f1bfc89 (diff) | |
download | CMake-311b7b1a7095ec460fab950a6767571eb3b9652c.zip CMake-311b7b1a7095ec460fab950a6767571eb3b9652c.tar.gz CMake-311b7b1a7095ec460fab950a6767571eb3b9652c.tar.bz2 |
Add properties to run cppcheck along with the compiler
Create a `<LANG>_CPPCHECK` target property (initialized by a
`CMAKE_<LANG>_CPPCHECK` variable) to specify a `cppcheck` command line
to be run along with the compiler.
Diffstat (limited to 'Source/cmcmd.cxx')
-rw-r--r-- | Source/cmcmd.cxx | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index bf5479c..0791cb3 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -297,6 +297,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) std::string sourceFile; std::string lwyu; std::string cpplint; + std::string cppcheck; for (std::string::size_type cc = 2; cc < args.size(); cc++) { std::string const& arg = args[cc]; if (arg == "--") { @@ -311,6 +312,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) lwyu = arg.substr(7); } else if (doing_options && cmHasLiteralPrefix(arg, "--cpplint=")) { cpplint = arg.substr(10); + } else if (doing_options && cmHasLiteralPrefix(arg, "--cppcheck=")) { + cppcheck = arg.substr(11); } else if (doing_options) { std::cerr << "__run_iwyu given unknown argument: " << arg << "\n"; return 1; @@ -318,14 +321,16 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) orig_cmd.push_back(arg); } } - if (tidy.empty() && iwyu.empty() && lwyu.empty() && cpplint.empty()) { - std::cerr << "__run_iwyu missing --cpplint=, --iwyu=, --lwyu=, and/or" - " --tidy=\n"; + if (tidy.empty() && iwyu.empty() && lwyu.empty() && cpplint.empty() && + cppcheck.empty()) { + std::cerr << "__run_iwyu missing --cpplint=, --iwyu=, --lwyu=, " + "--cppcheck= and/or --tidy=\n"; return 1; } - if ((!cpplint.empty() || !tidy.empty()) && sourceFile.empty()) { - std::cerr << "__run_iwyu --cpplint= and/or __run_iwyu --tidy=" - " require --source=\n"; + if ((!cpplint.empty() || !tidy.empty() || !cppcheck.empty()) && + sourceFile.empty()) { + std::cerr << "__run_iwyu --cpplint=, __run_iwyu --tidy=" + ", __run_iwyu --cppcheck require --source=\n"; return 1; } if (orig_cmd.empty() && lwyu.empty()) { @@ -445,8 +450,56 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) } } + if (!cppcheck.empty()) { + // Construct the cpplint command line. + std::vector<std::string> cppcheck_cmd; + cmSystemTools::ExpandListArgument(cppcheck, cppcheck_cmd, true); + // extract all the -D, -U, and -I options from the compile line + for (size_t i = 0; i < orig_cmd.size(); i++) { + std::string& opt = orig_cmd[i]; + if (opt.size() > 2) { + if ((opt[0] == '-') && + ((opt[1] == 'D') || (opt[1] == 'I') || (opt[1] == 'U'))) { + cppcheck_cmd.push_back(opt); +#if defined(_WIN32) + } else if ((opt[0] == '/') && + ((opt[1] == 'D') || (opt[1] == 'I') || + (opt[1] == 'U'))) { + std::string optcopy = opt; + optcopy[0] = '-'; + cppcheck_cmd.push_back(optcopy); +#endif + } + } + } + // add the source file + cppcheck_cmd.push_back(sourceFile); + + // Run the cpplint command line. Capture its output. + std::string stdOut; + if (!cmSystemTools::RunSingleCommand(cppcheck_cmd, &stdOut, &stdOut, + &ret, nullptr, + cmSystemTools::OUTPUT_NONE)) { + std::cerr << "Error running '" << cppcheck_cmd[0] << "': " << stdOut + << "\n"; + return 1; + } + // Output the output from cpplint to stderr + if (stdOut.find("(error)") != std::string::npos || + stdOut.find("(warning)") != std::string::npos || + stdOut.find("(style)") != std::string::npos || + stdOut.find("(performance)") != std::string::npos || + stdOut.find("(portability)") != std::string::npos || + stdOut.find("(information)") != std::string::npos) { + std::cerr << "Warning: cppcheck reported diagnostics:\n"; + } + std::cerr << stdOut; + } + // ignore the cppcheck error code because it is likely to have them + // from bad -D stuff ret = 0; - // Now run the real compiler command and return its result value. + // Now run the real compiler command and return its result value + // unless we are lwyu if (lwyu.empty() && !cmSystemTools::RunSingleCommand( orig_cmd, nullptr, nullptr, &ret, nullptr, |