diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 964fd55e7d6..ac4da192776 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -545,6 +545,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0) mSettings->maxCtuDepth = std::atoi(argv[i] + 16); + // output file management + else if (std::strncmp(argv[i], "--output-file-type=", 19) == 0) + mSettings->outputFileType = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 19)); + // Write results in file else if (std::strncmp(argv[i], "--output-file=", 14) == 0) mSettings->outputFile = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 14)); @@ -1109,6 +1113,9 @@ void CmdLineParser::printHelp() " is 2. A larger value will mean more errors can be found\n" " but also means the analysis will be slower.\n" " --output-file= Write results to file, rather than standard error.\n" + " --output-file-type=\n" + " append: will append to file if it exists\n" + " uniq: will generate a filename base on --output-file and the files being analyzed\n" " --project= Run Cppcheck on project. The can be a Visual\n" " Studio Solution (*.sln), Visual Studio Project\n" " (*.vcxproj), compile database (compile_commands.json),\n" diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 5066ff3d386..269a869eab9 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -893,7 +893,29 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha mLatestProgressOutputTime = std::time(nullptr); if (!settings.outputFile.empty()) { + + if (settings.outputFileType == "append") { + using std::ios; + + mErrorOutput = new std::ofstream(settings.outputFile, ios::app); // open it in append mode + } else if (settings.outputFileType == "uniq") { + std::string filename = settings.outputFile; + std::size_t extensionOffset = settings.outputFile.find_last_of("."); + if (extensionOffset != std::string::npos) + filename = filename.substr(0, extensionOffset); + + for (std::map::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i) { + std::size_t curFileNameOffset = i->first.find_last_of("/\\"); + std::string tmp = i->first.substr(curFileNameOffset + 1); + std::replace(tmp.begin(), tmp.end(), '.', '_'); + filename += "_" + tmp; + } + if (extensionOffset != std::string::npos) + filename += settings.outputFile.substr(extensionOffset); + mErrorOutput = new std::ofstream(filename); // open it in uniq mode + } else { mErrorOutput = new std::ofstream(settings.outputFile); + } } if (settings.xml) { @@ -1207,4 +1229,3 @@ bool CppCheckExecutor::executeCommand(std::string exe, std::vector *output_ += buffer; return true; } - diff --git a/lib/settings.h b/lib/settings.h index 2cfc2d60f65..b5979dabe13 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -246,6 +246,9 @@ class CPPCHECKLIB Settings : public cppcheck::Platform { /** @brief suppress message (--suppressions) */ Suppressions nomsg; + /** @brief write results type (--output-file-type=<None|append|uniq>) */ + std::string outputFileType; + /** @brief write results (--output-file=<file>) */ std::string outputFile;