Changed CppCheck::parseFromArgs() to return boolean value and reportOut() in case of error.

It used to throw exception and return error message with the exception.
This commit is contained in:
Reijo Tomperi 2010-04-11 22:53:21 +03:00
parent 6f74c0af5e
commit 9a4cbe0540
4 changed files with 80 additions and 46 deletions

View File

@ -22,7 +22,6 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <cstdlib> // EXIT_SUCCESS and EXIT_FAILURE #include <cstdlib> // EXIT_SUCCESS and EXIT_FAILURE
#include <stdexcept>
CppCheckExecutor::CppCheckExecutor() CppCheckExecutor::CppCheckExecutor()
{ {
@ -37,13 +36,8 @@ CppCheckExecutor::~CppCheckExecutor()
int CppCheckExecutor::check(int argc, const char* const argv[]) int CppCheckExecutor::check(int argc, const char* const argv[])
{ {
CppCheck cppCheck(*this); 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; return EXIT_FAILURE;
} }

View File

@ -107,7 +107,7 @@ static void AddFilesToList(const std::string& FileList, std::vector<std::string>
} }
} }
void CppCheck::parseFromArgs(int argc, const char* const argv[]) bool CppCheck::parseFromArgs(int argc, const char* const argv[])
{ {
std::vector<std::string> pathnames; std::vector<std::string> pathnames;
bool showHelp = false; bool showHelp = false;
@ -116,7 +116,7 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
if (strcmp(argv[i], "--version") == 0) if (strcmp(argv[i], "--version") == 0)
{ {
reportOut(std::string("Cppcheck ") + version()); reportOut(std::string("Cppcheck ") + version());
return; return true;
} }
// Flag used for various purposes during debugging // Flag used for various purposes during debugging
@ -142,11 +142,17 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
++i; ++i;
if (i >= argc) 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]); std::ifstream f(argv[i]);
if (!f.is_open()) 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); _settings.nomsg.parseFile(f);
} }
@ -156,11 +162,17 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
++i; ++i;
if (i >= argc) 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]); std::ifstream f(argv[i]);
if (!f.is_open()) 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); _settings.nofail.parseFile(f);
} }
@ -216,7 +228,8 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
if (!(iss >> _settings._exitCode)) if (!(iss >> _settings._exitCode))
{ {
_settings._exitCode = 0; _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; ++i;
if (i >= argc) 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]; path = argv[i];
} }
@ -262,7 +278,10 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
// "--template path/" // "--template path/"
++i; ++i;
if (i >= argc) 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]; _settings._outputFormat = argv[i];
if (_settings._outputFormat == "gcc") if (_settings._outputFormat == "gcc")
@ -282,7 +301,10 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
{ {
++i; ++i;
if (i >= argc) 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]; numberString = argv[i];
} }
@ -296,11 +318,15 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
std::istringstream iss(numberString); std::istringstream iss(numberString);
if (!(iss >> _settings._jobs)) 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) 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; ++i;
if (i >= argc || !strstr(argv[i], ".lst")) 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]); std::ifstream f(argv[i]);
if (!f.is_open()) 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); _settings.autoDealloc(f);
} }
@ -338,13 +371,14 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
std::string doc2(doc.str()); std::string doc2(doc.str());
while (doc2.find("\n\n\n") != std::string::npos) while (doc2.find("\n\n\n") != std::string::npos)
doc2.erase(doc2.find("\n\n\n"), 1); doc2.erase(doc2.find("\n\n\n"), 1);
std::cout << doc2; reportOut(doc2);
return; return true;
} }
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) 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 else
@ -435,8 +469,11 @@ void CppCheck::parseFromArgs(int argc, const char* const argv[])
} }
else if (_filenames.empty()) 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() unsigned int CppCheck::check()

View File

@ -102,9 +102,9 @@ public:
* *
* @param argc argc from main() * @param argc argc from main()
* @param argv argv 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. * @brief Returns current version number as a string.

View File

@ -59,60 +59,63 @@ private:
TEST_CASE(templateFormat); TEST_CASE(templateFormat);
TEST_CASE(getErrorMessages); TEST_CASE(getErrorMessages);
TEST_CASE(parseOutputtingArgs); TEST_CASE(parseOutputtingArgs);
TEST_CASE(parseOutputtingInvalidArgs);
} }
void argCheck(int argc, const char *argv[]) bool argCheck(int argc, const char *argv[])
{ {
errout.str(""); errout.str("");
output.str(""); output.str("");
CppCheck cppCheck(*this); CppCheck cppCheck(*this);
cppCheck.parseFromArgs(argc, argv); return cppCheck.parseFromArgs(argc, argv);
} }
void parseOutputtingArgs() void parseOutputtingArgs()
{ {
{ {
const char *argv[] = {"cppcheck", "--help"}; const char *argv[] = {"cppcheck", "--help"};
argCheck(2, argv); ASSERT_EQUALS(true, argCheck(2, argv));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos);
} }
{ {
const char *argv[] = {"cppcheck"}; const char *argv[] = {"cppcheck"};
argCheck(1, argv); ASSERT_EQUALS(true, argCheck(1, argv));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos);
} }
{ {
const char *argv[] = {"cppcheck", "--version"}; const char *argv[] = {"cppcheck", "--version"};
argCheck(2, argv); ASSERT_EQUALS(true, argCheck(2, argv));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS(std::string("Cppcheck ") + CppCheck::version() + "\n", output.str()); ASSERT_EQUALS(std::string("Cppcheck ") + CppCheck::version() + "\n", output.str());
} }
{ {
const char *argv[] = {"cppcheck", "--doc"}; const char *argv[] = {"cppcheck", "--doc"};
argCheck(2, argv); ASSERT_EQUALS(true, argCheck(2, argv));
ASSERT_EQUALS("", errout.str()); 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 void parseOutputtingInvalidArgs()
// be tested. Add test here when it is changed. {
TODO_ASSERT_EQUALS("Something", output.str()); {
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"}; const char *argv[] = {"cppcheck", "--suppressions"};
try ASSERT_EQUALS(false, argCheck(2, argv));
{ ASSERT_EQUALS("", errout.str());
argCheck(2, argv); ASSERT_EQUALS("cppcheck: No file specified for the --suppressions option\n", output.str());
ASSERT_EQUALS("", "Should not come here");
}
catch (std::runtime_error &e)
{
ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--invalidArg\"", e.what());
}
} }
} }