diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index a1d0a52de..92a8f1c95 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -22,7 +22,6 @@ #include #include #include // EXIT_SUCCESS and EXIT_FAILURE -#include CppCheckExecutor::CppCheckExecutor() { @@ -37,13 +36,8 @@ CppCheckExecutor::~CppCheckExecutor() int CppCheckExecutor::check(int argc, const char* const argv[]) { CppCheck cppCheck(*this); - try + if (!cppCheck.parseFromArgs(argc, argv)) { - cppCheck.parseFromArgs(argc, argv); - } - catch (std::runtime_error &e) - { - std::cerr << e.what() << std::endl; return EXIT_FAILURE; } diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 73c00662c..1522a1949 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -107,7 +107,7 @@ static void AddFilesToList(const std::string& FileList, std::vector } } -void CppCheck::parseFromArgs(int argc, const char* const argv[]) +bool CppCheck::parseFromArgs(int argc, const char* const argv[]) { std::vector pathnames; bool showHelp = false; @@ -116,7 +116,7 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) if (strcmp(argv[i], "--version") == 0) { reportOut(std::string("Cppcheck ") + version()); - return; + return true; } // Flag used for various purposes during debugging @@ -142,11 +142,17 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) ++i; if (i >= argc) - throw std::runtime_error("cppcheck: No file specified for the --suppressions option"); + { + reportOut("cppcheck: No file specified for the --suppressions option"); + return false; + } std::ifstream f(argv[i]); if (!f.is_open()) - throw std::runtime_error("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\""); + { + reportOut("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\""); + return false; + } _settings.nomsg.parseFile(f); } @@ -156,11 +162,17 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) ++i; if (i >= argc) - throw std::runtime_error("cppcheck: No file specified for the --exitcode-suppressions option"); + { + reportOut("cppcheck: No file specified for the --exitcode-suppressions option"); + return false; + } std::ifstream f(argv[i]); if (!f.is_open()) - throw std::runtime_error("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\""); + { + reportOut("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\""); + return false; + } _settings.nofail.parseFile(f); } @@ -216,7 +228,8 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) if (!(iss >> _settings._exitCode)) { _settings._exitCode = 0; - throw std::runtime_error("cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'"); + reportOut("cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'"); + return false; } } @@ -230,7 +243,10 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) { ++i; if (i >= argc) - throw std::runtime_error("cppcheck: argument to '-I' is missing"); + { + reportOut("cppcheck: argument to '-I' is missing"); + return false; + } path = argv[i]; } @@ -262,7 +278,10 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) // "--template path/" ++i; if (i >= argc) - throw std::runtime_error("cppcheck: argument to '--template' is missing"); + { + reportOut("cppcheck: argument to '--template' is missing"); + return false; + } _settings._outputFormat = argv[i]; if (_settings._outputFormat == "gcc") @@ -282,7 +301,10 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) { ++i; if (i >= argc) - throw std::runtime_error("cppcheck: argument to '-j' is missing"); + { + reportOut("cppcheck: argument to '-j' is missing"); + return false; + } numberString = argv[i]; } @@ -296,11 +318,15 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) std::istringstream iss(numberString); if (!(iss >> _settings._jobs)) - throw std::runtime_error("cppcheck: argument to '-j' is not a number"); + { + reportOut("cppcheck: argument to '-j' is not a number"); + return false; + } if (_settings._jobs > 1000) { - throw std::runtime_error("cppcheck: argument for '-j' is allowed to be 1000 at max"); + reportOut("cppcheck: argument for '-j' is allowed to be 1000 at max"); + return false; } } @@ -310,11 +336,18 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) ++i; if (i >= argc || !strstr(argv[i], ".lst")) - throw std::runtime_error("cppcheck: No .lst file specified for the --auto-dealloc option"); + { + reportOut("cppcheck: No .lst file specified for the --auto-dealloc option"); + return false; + } std::ifstream f(argv[i]); if (!f.is_open()) - throw std::runtime_error("cppcheck: couldn't open the file \"" + std::string(argv[i+1]) + "\""); + { + reportOut("cppcheck: couldn't open the file \"" + std::string(argv[i+1]) + "\""); + return false; + } + _settings.autoDealloc(f); } @@ -338,13 +371,14 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) std::string doc2(doc.str()); while (doc2.find("\n\n\n") != std::string::npos) doc2.erase(doc2.find("\n\n\n"), 1); - std::cout << doc2; - return; + reportOut(doc2); + return true; } else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) { - throw std::runtime_error("cppcheck: error: unrecognized command line option \"" + std::string(argv[i]) + "\""); + reportOut("cppcheck: error: unrecognized command line option \"" + std::string(argv[i]) + "\""); + return false; } else @@ -435,8 +469,11 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[]) } else if (_filenames.empty()) { - throw std::runtime_error("cppcheck: No C or C++ source files found."); + reportOut("cppcheck: No C or C++ source files found."); + return false; } + + return true; } unsigned int CppCheck::check() diff --git a/lib/cppcheck.h b/lib/cppcheck.h index ac0376738..4e46a7b37 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -102,9 +102,9 @@ public: * * @param argc argc from main() * @param argv argv from main() - * @throw std::runtime_error when errors are found in the input + * @return false when errors are found in the input */ - void parseFromArgs(int argc, const char* const argv[]); + bool parseFromArgs(int argc, const char* const argv[]); /** * @brief Returns current version number as a string. diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 67b3ccede..a6d6e43ae 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -59,60 +59,63 @@ private: TEST_CASE(templateFormat); TEST_CASE(getErrorMessages); TEST_CASE(parseOutputtingArgs); + TEST_CASE(parseOutputtingInvalidArgs); } - void argCheck(int argc, const char *argv[]) + bool argCheck(int argc, const char *argv[]) { errout.str(""); output.str(""); CppCheck cppCheck(*this); - cppCheck.parseFromArgs(argc, argv); + return cppCheck.parseFromArgs(argc, argv); } void parseOutputtingArgs() { { const char *argv[] = {"cppcheck", "--help"}; - argCheck(2, argv); + ASSERT_EQUALS(true, argCheck(2, argv)); ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); } { const char *argv[] = {"cppcheck"}; - argCheck(1, argv); + ASSERT_EQUALS(true, argCheck(1, argv)); ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); } { const char *argv[] = {"cppcheck", "--version"}; - argCheck(2, argv); + ASSERT_EQUALS(true, argCheck(2, argv)); ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS(std::string("Cppcheck ") + CppCheck::version() + "\n", output.str()); } { const char *argv[] = {"cppcheck", "--doc"}; - argCheck(2, argv); + ASSERT_EQUALS(true, argCheck(2, argv)); ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS(true, output.str().find("===Bounds checking===") != std::string::npos); + ASSERT_EQUALS(true, output.str().find("===Unused functions===") != std::string::npos); + } + } - // TODO: --doc prints output directly to stdout, so it can't - // be tested. Add test here when it is changed. - TODO_ASSERT_EQUALS("Something", output.str()); + void parseOutputtingInvalidArgs() + { + { + const char *argv[] = {"cppcheck", "--invalidArg"}; + ASSERT_EQUALS(false, argCheck(2, argv)); + ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--invalidArg\"\n", output.str()); } { - const char *argv[] = {"cppcheck", "--invalidArg"}; - try - { - argCheck(2, argv); - ASSERT_EQUALS("", "Should not come here"); - } - catch (std::runtime_error &e) - { - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--invalidArg\"", e.what()); - } + const char *argv[] = {"cppcheck", "--suppressions"}; + ASSERT_EQUALS(false, argCheck(2, argv)); + ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("cppcheck: No file specified for the --suppressions option\n", output.str()); } }