diff --git a/Makefile b/Makefile index aa170d293..f4df0927a 100644 --- a/Makefile +++ b/Makefile @@ -639,10 +639,10 @@ $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp cli/cppcheckexecutorseh.o: cli/cppcheckexecutorseh.cpp cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/utils.h @@ -720,7 +720,7 @@ test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/clangimport.h l test/testclass.o: test/testclass.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp test/testcolor.o: test/testcolor.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h diff --git a/cli/cmdlinelogger.h b/cli/cmdlinelogger.h new file mode 100644 index 000000000..97bb2821e --- /dev/null +++ b/cli/cmdlinelogger.h @@ -0,0 +1,33 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2023 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CMD_LINE_LOGGER_H +#define CMD_LINE_LOGGER_H + +#include + +class CmdLineLogger +{ +public: + virtual ~CmdLineLogger() = default; + + virtual void printMessage(const std::string &message) = 0; + virtual void printError(const std::string &message) = 0; +}; + +#endif // CMD_LINE_LOGGER_H diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 3045f52d4..0eb07362f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -109,22 +109,13 @@ static bool addPathsToSet(const std::string& fileName, std::set& se return true; } -CmdLineParser::CmdLineParser(Settings &settings, Suppressions &suppressions, Suppressions &suppressionsNoFail) - : mSettings(settings) +CmdLineParser::CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions, Suppressions &suppressionsNoFail) + : mLogger(logger) + , mSettings(settings) , mSuppressions(suppressions) , mSuppressionsNoFail(suppressionsNoFail) {} -void CmdLineParser::printMessage(const std::string &message) -{ - std::cout << "cppcheck: " << message << std::endl; -} - -void CmdLineParser::printError(const std::string &message) -{ - printMessage("error: " + message); -} - // TODO: normalize/simplify/native all path parameters // TODO: error out on all missing given files/paths bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) @@ -144,7 +135,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-D") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-D' is missing."); + mLogger.printError("argument to '-D' is missing."); return false; } @@ -180,7 +171,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-I") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-I' is missing."); + mLogger.printError("argument to '-I' is missing."); return false; } path = argv[i]; @@ -208,7 +199,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-U") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-U' is missing."); + mLogger.printError("argument to '-U' is missing."); return false; } @@ -270,7 +261,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // open this file and read every input file (1 file name per line) const std::string cfgExcludesFile(23 + argv[i]); if (!addPathsToSet(cfgExcludesFile, mSettings.configExcludePaths)) { - printError("unable to open config excludes file at '" + cfgExcludesFile + "'"); + mLogger.printError("unable to open config excludes file at '" + cfgExcludesFile + "'"); return false; } } @@ -281,7 +272,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings.buildDir.pop_back(); if (!Path::isDirectory(mSettings.buildDir)) { - printError("Directory '" + mSettings.buildDir + "' specified by --cppcheck-build-dir argument has to be existent."); + mLogger.printError("Directory '" + mSettings.buildDir + "' specified by --cppcheck-build-dir argument has to be existent."); return false; } } @@ -306,7 +297,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strncmp(argv[i], "--disable=", 10) == 0) { const std::string errmsg = mSettings.removeEnabled(argv[i] + 10); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } } @@ -336,7 +327,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) const std::string enable_arg = argv[i] + 9; const std::string errmsg = mSettings.addEnabled(enable_arg); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } // when "style" is enabled, also enable "warning", "performance" and "portability" @@ -347,7 +338,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) } if (enable_arg.find("information") != std::string::npos) { mSettings.addEnabled("missingInclude"); - printMessage("'--enable=information' will no longer implicitly enable 'missingInclude' starting with 2.16. Please enable it explicitly if you require it."); + mLogger.printMessage("'--enable=information' will no longer implicitly enable 'missingInclude' starting with 2.16. Please enable it explicitly if you require it."); } } @@ -373,7 +364,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strncmp(argv[i], "--exception-handling=", 21) == 0) { const std::string exceptionOutfilename = argv[i] + 21; if (exceptionOutfilename != "stderr" && exceptionOutfilename != "stdout") { - printError("invalid '--exception-handling' argument"); + mLogger.printError("invalid '--exception-handling' argument"); return false; } mSettings.exceptionHandling = true; @@ -387,12 +378,12 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) std::ifstream f(filename); if (!f.is_open()) { - printError("couldn't open the file: \"" + filename + "\"."); + mLogger.printError("couldn't open the file: \"" + filename + "\"."); return false; } const std::string errmsg(mSuppressionsNoFail.parseFile(f)); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } } @@ -406,7 +397,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // open this file and read every input file (1 file name per line) const std::string fileList = argv[i] + 12; if (!addFilesToList(fileList, mPathNames)) { - printError("couldn't open the file: \"" + fileList + "\"."); + mLogger.printError("couldn't open the file: \"" + fileList + "\"."); return false; } } @@ -431,7 +422,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-i") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-i' is missing."); + mLogger.printError("argument to '-i' is missing."); return false; } path = argv[i]; @@ -464,7 +455,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // open this file and read every input file (1 file name per line) const std::string includesFile(16 + argv[i]); if (!addIncludePathsToList(includesFile, mSettings.includePaths)) { - printError("unable to open includes file at '" + includesFile + "'"); + mLogger.printError("unable to open includes file at '" + includesFile + "'"); return false; } } @@ -485,7 +476,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-j") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-j' is missing."); + mLogger.printError("argument to '-j' is missing."); return false; } @@ -499,20 +490,20 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) unsigned int tmp; std::string err; if (!strToInt(numberString, tmp, &err)) { - printError("argument to '-j' is not valid - " + err + "."); + mLogger.printError("argument to '-j' is not valid - " + err + "."); return false; } if (tmp == 0) { // TODO: implement get CPU logical core count and use that. // Usually, -j 0 would mean "use all available cores," but // if we get a 0, we just stall and don't do any work. - printError("argument for '-j' must be greater than 0."); + mLogger.printError("argument for '-j' must be greater than 0."); return false; } if (tmp > 1024) { // Almost nobody has 1024 logical cores, but somebody out // there does. - printError("argument for '-j' is allowed to be 1024 at max."); + mLogger.printError("argument for '-j' is allowed to be 1024 at max."); return false; } mSettings.jobs = tmp; @@ -526,7 +517,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (std::strcmp(argv[i], "-l") == 0) { ++i; if (i >= argc || argv[i][0] == '-') { - printError("argument to '-l' is missing."); + mLogger.printError("argument to '-l' is missing."); return false; } @@ -540,7 +531,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) int tmp; std::string err; if (!strToInt(numberString, tmp, &err)) { - printError("argument to '-l' is not valid - " + err + "."); + mLogger.printError("argument to '-l' is not valid - " + err + "."); return false; } mSettings.loadAverage = tmp; @@ -555,7 +546,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) } else { i++; if (i >= argc || argv[i][0] == '-') { - printError("no language given to '-x' option."); + mLogger.printError("no language given to '-x' option."); return false; } str = argv[i]; @@ -566,7 +557,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (str == "c++") mSettings.enforcedLang = Settings::Language::CPP; else { - printError("unknown language '" + str + "' enforced."); + mLogger.printError("unknown language '" + str + "' enforced."); return false; } } @@ -582,7 +573,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) if (!parseNumberArg(argv[i], 14, tmp)) return false; if (tmp < 1) { - printError("argument to '--max-configs=' must be greater than 0."); + mLogger.printError("argument to '--max-configs=' must be greater than 0."); return false; } @@ -620,7 +611,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) std::string errstr; const std::vector paths = {argv[0]}; if (!mSettings.platform.set(platform, errstr, paths)) { - printError(errstr); + mLogger.printError(errstr); return false; } @@ -646,7 +637,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) std::string message("plist folder does not exist: \""); message += plistOutput; message += "\"."; - printError(message); + mLogger.printError(message); return false; } } @@ -680,14 +671,14 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // keep existing platform from command-line intact if (!platform.empty()) { if (platform == "Unspecified") { - printMessage("'Unspecified' is a deprecated platform type and will be removed in Cppcheck 2.14. Please use 'unspecified' instead."); + mLogger.printMessage("'Unspecified' is a deprecated platform type and will be removed in Cppcheck 2.14. Please use 'unspecified' instead."); platform = "unspecified"; } std::string errstr; const std::vector paths = {projectFile, argv[0]}; if (!mSettings.platform.set(platform, errstr, paths)) { - printError(errstr); + mLogger.printError(errstr); return false; } } @@ -702,20 +693,20 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings.project.selectOneVsConfig(mSettings.platform.type); if (!CppCheckExecutor::tryLoadLibrary(mSettings.library, argv[0], "windows.cfg")) { // This shouldn't happen normally. - printError("failed to load 'windows.cfg'. Your Cppcheck installation is broken. Please re-install."); + mLogger.printError("failed to load 'windows.cfg'. Your Cppcheck installation is broken. Please re-install."); return false; } } if (projType == ImportProject::Type::MISSING) { - printError("failed to open project '" + projectFile + "'. The file does not exist."); + mLogger.printError("failed to open project '" + projectFile + "'. The file does not exist."); return false; } if (projType == ImportProject::Type::UNKNOWN) { - printError("failed to load project '" + projectFile + "'. The format is unknown."); + mLogger.printError("failed to load project '" + projectFile + "'. The format is unknown."); return false; } if (projType == ImportProject::Type::FAILURE) { - printError("failed to load project '" + projectFile + "'. An error occurred."); + mLogger.printError("failed to load project '" + projectFile + "'. An error occurred."); return false; } } @@ -748,7 +739,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) paths.erase(0, pos + 1); } } else { - printError("no paths specified for the '" + std::string(argv[i]) + "' option."); + mLogger.printError("no paths specified for the '" + std::string(argv[i]) + "' option."); return false; } } @@ -811,7 +802,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings.rules.emplace_back(std::move(rule)); } } else { - printError("unable to load rule-file: " + std::string(12+argv[i])); + mLogger.printError("unable to load rule-file: " + std::string(12+argv[i])); return false; } } @@ -831,7 +822,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (showtimeMode.empty()) mSettings.showtime = SHOWTIME_MODES::SHOWTIME_NONE; else { - printError("unrecognized showtime mode: \"" + showtimeMode + "\". Supported modes: file, file-total, summary, top5."); + mLogger.printError("unrecognized showtime mode: \"" + showtimeMode + "\". Supported modes: file, file-total, summary, top5."); return false; } } @@ -847,7 +838,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings.standards.c = Standards::getC(std); } else { - printError("unknown --std value '" + std + "'"); + mLogger.printError("unknown --std value '" + std + "'"); return false; } } @@ -856,7 +847,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) const std::string suppression = argv[i]+11; const std::string errmsg(mSuppressions.addSuppressionLine(suppression)); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } } @@ -878,12 +869,12 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) message += "\n cppcheck --suppressions-list=a.txt --suppressions-list=b.txt file.cpp"; } - printError(message); + mLogger.printError(message); return false; } const std::string errmsg(mSuppressions.parseFile(f)); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } } @@ -892,7 +883,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) const char * filename = argv[i] + 15; const std::string errmsg(mSuppressions.parseXmlFile(filename)); if (!errmsg.empty()) { - printError(errmsg); + mLogger.printError(errmsg); return false; } } @@ -965,7 +956,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) return false; if (tmp != 2) { // We only have xml version 2 - printError("'--xml-version' can only be 2."); + mLogger.printError("'--xml-version' can only be 2."); return false; } @@ -978,7 +969,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) std::string message("unrecognized command line option: \""); message += argv[i]; message += "\"."; - printError(message); + mLogger.printError(message); return false; } } @@ -1012,7 +1003,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings.maxConfigs = 1U; if (mSettings.checks.isEnabled(Checks::unusedFunction) && mSettings.jobs > 1 && mSettings.buildDir.empty()) { - printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); + mLogger.printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); } if (argc <= 1) { @@ -1027,7 +1018,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // Print error only if we have "real" command and expect files if (!mExitAfterPrint && mPathNames.empty() && mSettings.project.fileSettings.empty()) { - printError("no C or C++ source files found."); + mLogger.printError("no C or C++ source files found."); return false; } diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 3832b6851..51770969f 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -23,6 +23,7 @@ #include #include +#include "cmdlinelogger.h" #include "utils.h" class Settings; @@ -44,12 +45,13 @@ class CmdLineParser { public: /** * The constructor. + * @param logger The logger instance to log messages through * @param settings Settings instance that will be modified according to * options user has given. * @param suppressions Suppressions instance that keeps the suppressions * @param suppressionsNoFail Suppressions instance that keeps the "do not fail" suppressions */ - CmdLineParser(Settings &settings, Suppressions &suppressions, Suppressions &suppressionsNoFail); + CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions, Suppressions &suppressionsNoFail); /** * Parse given command line. @@ -99,36 +101,28 @@ protected: */ void printHelp(); - /** - * Print message (to stdout). - */ - static void printMessage(const std::string &message); - - /** - * Print error message (to stdout). - */ - static void printError(const std::string &message); - private: bool isCppcheckPremium() const; template - static bool parseNumberArg(const char* const arg, std::size_t offset, T& num, bool mustBePositive = false) + bool parseNumberArg(const char* const arg, std::size_t offset, T& num, bool mustBePositive = false) { T tmp; std::string err; if (!strToInt(arg + offset, tmp, &err)) { - printError("argument to '" + std::string(arg, offset) + "' is not valid - " + err + "."); + mLogger.printError("argument to '" + std::string(arg, offset) + "' is not valid - " + err + "."); return false; } if (mustBePositive && tmp < 0) { - printError("argument to '" + std::string(arg, offset) + "' needs to be a positive integer."); + mLogger.printError("argument to '" + std::string(arg, offset) + "' needs to be a positive integer."); return false; } num = tmp; return true; } + CmdLineLogger &mLogger; + std::vector mPathNames; std::vector mIgnoredPaths; Settings &mSettings; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 71ab17e18..2e2f8a915 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -85,6 +85,22 @@ class XMLErrorMessagesLogger : public ErrorLogger {} }; +class CmdLineLoggerStd : public CmdLineLogger +{ +public: + CmdLineLoggerStd() = default; + + void printMessage(const std::string &message) override + { + std::cout << "cppcheck: " << message << std::endl; + } + + void printError(const std::string &message) override + { + printMessage("error: " + message); + } +}; + // TODO: do not directly write to stdout /*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout; @@ -96,7 +112,8 @@ CppCheckExecutor::~CppCheckExecutor() bool CppCheckExecutor::parseFromArgs(Settings &settings, int argc, const char* const argv[]) { - CmdLineParser parser(settings, settings.nomsg, settings.nofail); + CmdLineLoggerStd logger; + CmdLineParser parser(logger, settings, settings.nomsg, settings.nofail); const bool success = parser.parseFromArgs(argc, argv); if (success) { diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 714a0ed2a..ab360dcc6 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -43,12 +44,29 @@ public: {} private: + class CmdLineLoggerTest : public CmdLineLogger + { + public: + CmdLineLoggerTest() = default; + + void printMessage(const std::string &message) override + { + std::cout << "cppcheck: " << message << std::endl; + } + + void printError(const std::string &message) override + { + printMessage("error: " + message); + } + }; + + CmdLineLoggerTest logger; std::unique_ptr settings; std::unique_ptr parser; void prepareTestInternal() override { settings.reset(new Settings()); - parser.reset(new CmdLineParser(*settings, settings->nomsg, settings->nofail)); + parser.reset(new CmdLineParser(logger, *settings, settings->nomsg, settings->nofail)); } void run() override {