Skip to content

Commit 7086ffa

Browse files
authored
fixed #12045 - print error when using an option which has not been compiled in instead of treating it as non-existent or a no-op (#5508)
Also disabled more internal code around those options and did some cleanups.
1 parent 41bd28c commit 7086ffa

6 files changed

Lines changed: 320 additions & 187 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 195 additions & 176 deletions
Large diffs are not rendered by default.

cli/cmdlineparser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class CmdLineParser {
9999
/**
100100
* Print help text to the console.
101101
*/
102-
void printHelp();
102+
void printHelp() const;
103103

104104
private:
105105
bool isCppcheckPremium() const;

cli/cppcheckexecutor.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ class CmdLineLoggerStd : public CmdLineLogger
108108

109109
// TODO: do not directly write to stdout
110110

111+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
111112
/*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout;
113+
#endif
112114

113115
CppCheckExecutor::~CppCheckExecutor()
114116
{
@@ -257,11 +259,7 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
257259
cppCheck.settings() = settings;
258260
mSettings = &settings;
259261

260-
int ret;
261-
if (settings.exceptionHandling)
262-
ret = check_wrapper(cppCheck);
263-
else
264-
ret = check_internal(cppCheck);
262+
const int ret = check_wrapper(cppCheck);
265263

266264
mSettings = nullptr;
267265
return ret;
@@ -270,12 +268,13 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
270268
int CppCheckExecutor::check_wrapper(CppCheck& cppcheck)
271269
{
272270
#ifdef USE_WINDOWS_SEH
273-
return check_wrapper_seh(*this, &CppCheckExecutor::check_internal, cppcheck);
271+
if (cppcheck.settings().exceptionHandling)
272+
return check_wrapper_seh(*this, &CppCheckExecutor::check_internal, cppcheck);
274273
#elif defined(USE_UNIX_SIGNAL_HANDLING)
275-
return check_wrapper_sig(*this, &CppCheckExecutor::check_internal, cppcheck);
276-
#else
277-
return check_internal(cppcheck);
274+
if (cppcheck.settings().exceptionHandling)
275+
return check_wrapper_sig(*this, &CppCheckExecutor::check_internal, cppcheck);
278276
#endif
277+
return check_internal(cppcheck);
279278
}
280279

281280
bool CppCheckExecutor::reportSuppressions(const Settings &settings, bool unusedFunctionCheckEnabled, const std::map<std::string, std::size_t> &files, ErrorLogger& errorLogger) {
@@ -522,6 +521,7 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg)
522521
reportErr(msg.toString(mSettings->verbose, mSettings->templateFormat, mSettings->templateLocation));
523522
}
524523

524+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
525525
void CppCheckExecutor::setExceptionOutput(FILE* exceptionOutput)
526526
{
527527
mExceptionOutput = exceptionOutput;
@@ -531,6 +531,7 @@ FILE* CppCheckExecutor::getExceptionOutput()
531531
{
532532
return mExceptionOutput;
533533
}
534+
#endif
534535

535536
bool CppCheckExecutor::tryLoadLibrary(Library& destination, const std::string& basepath, const char* filename)
536537
{

cli/cppcheckexecutor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,12 @@ class CppCheckExecutor : public ErrorLogger {
185185
*/
186186
std::time_t mLatestProgressOutputTime{};
187187

188+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
188189
/**
189190
* Output file name for exception handler
190191
*/
191192
static FILE* mExceptionOutput;
193+
#endif
192194

193195
/**
194196
* Error output

lib/settings.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,10 @@ class CPPCHECKLIB WARN_UNUSED Settings {
190190
/** @brief Name of the language that is enforced. Empty per default. */
191191
Language enforcedLang{};
192192

193+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
193194
/** @brief Is --exception-handling given */
194195
bool exceptionHandling{};
196+
#endif
195197

196198
// argv[0]
197199
std::string exename;
@@ -276,6 +278,7 @@ class CPPCHECKLIB WARN_UNUSED Settings {
276278
/** @brief --report-progress */
277279
int reportProgress{-1};
278280

281+
#ifdef HAVE_RULES
279282
/** Rule */
280283
struct CPPCHECKLIB Rule {
281284
std::string tokenlist = "normal"; // use normal tokenlist
@@ -285,7 +288,6 @@ class CPPCHECKLIB WARN_UNUSED Settings {
285288
Severity severity = Severity::style; // default severity
286289
};
287290

288-
#ifdef HAVE_RULES
289291
/**
290292
* @brief Extra rules
291293
*/

test/testcmdlineparser.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,16 @@ class TestCmdlineParser : public TestFixture {
255255
TEST_CASE(errorlistverbose1);
256256
TEST_CASE(errorlistverbose2);
257257
TEST_CASE(ignorepathsnopath);
258+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
258259
TEST_CASE(exceptionhandling);
259260
TEST_CASE(exceptionhandling2);
260261
TEST_CASE(exceptionhandling3);
261262
TEST_CASE(exceptionhandlingInvalid);
262263
TEST_CASE(exceptionhandlingInvalid2);
264+
#else
265+
TEST_CASE(exceptionhandlingNotSupported);
266+
TEST_CASE(exceptionhandlingNotSupported2);
267+
#endif
263268
TEST_CASE(clang);
264269
TEST_CASE(clang2);
265270
TEST_CASE(clangInvalid);
@@ -275,6 +280,8 @@ class TestCmdlineParser : public TestFixture {
275280
TEST_CASE(loadAverage);
276281
TEST_CASE(loadAverage2);
277282
TEST_CASE(loadAverageInvalid);
283+
#else
284+
TEST_CASE(loadAverageNotSupported);
278285
#endif
279286
TEST_CASE(maxCtuDepth);
280287
TEST_CASE(maxCtuDepthInvalid);
@@ -297,6 +304,19 @@ class TestCmdlineParser : public TestFixture {
297304
TEST_CASE(projectMissing);
298305
TEST_CASE(projectNoPaths);
299306
TEST_CASE(addon);
307+
#ifdef HAVE_RULES
308+
TEST_CASE(rule);
309+
#else
310+
TEST_CASE(ruleNotSupported);
311+
#endif
312+
#ifdef HAVE_RULES
313+
TEST_CASE(ruleFile);
314+
TEST_CASE(ruleFileEmpty);
315+
TEST_CASE(ruleFileMissing);
316+
TEST_CASE(ruleFileInvalid);
317+
#else
318+
TEST_CASE(ruleFileNotSupported);
319+
#endif
300320

301321
TEST_CASE(ignorepaths1);
302322
TEST_CASE(ignorepaths2);
@@ -1703,6 +1723,7 @@ class TestCmdlineParser : public TestFixture {
17031723
ASSERT_EQUALS("cppcheck: error: argument to '-i' is missing.\n", logger->str());
17041724
}
17051725

1726+
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
17061727
void exceptionhandling() {
17071728
REDIRECT;
17081729
const char * const argv[] = {"cppcheck", "--exception-handling", "file.cpp"};
@@ -1749,6 +1770,21 @@ class TestCmdlineParser : public TestFixture {
17491770
ASSERT_EQUALS(false, parser->parseFromArgs(2, argv));
17501771
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--exception-handling-foo\".\n", logger->str());
17511772
}
1773+
#else
1774+
void exceptionhandlingNotSupported() {
1775+
REDIRECT;
1776+
const char * const argv[] = {"cppcheck", "--exception-handling", "file.cpp"};
1777+
ASSERT(!parser->parseFromArgs(3, argv));
1778+
ASSERT_EQUALS("cppcheck: error: Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled.\n", logger->str());
1779+
}
1780+
1781+
void exceptionhandlingNotSupported2() {
1782+
REDIRECT;
1783+
const char * const argv[] = {"cppcheck", "--exception-handling=stderr", "file.cpp"};
1784+
ASSERT(!parser->parseFromArgs(3, argv));
1785+
ASSERT_EQUALS("cppcheck: error: Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled.\n", logger->str());
1786+
}
1787+
#endif
17521788

17531789
void clang() {
17541790
REDIRECT;
@@ -1866,6 +1902,13 @@ class TestCmdlineParser : public TestFixture {
18661902
ASSERT(!parser->parseFromArgs(4, argv));
18671903
ASSERT_EQUALS("cppcheck: error: argument to '-l' is not valid - not an integer.\n", logger->str());
18681904
}
1905+
#else
1906+
void loadAverageNotSupported() {
1907+
REDIRECT;
1908+
const char * const argv[] = {"cppcheck", "-l", "12", "file.cpp"};
1909+
ASSERT(!parser->parseFromArgs(4, argv));
1910+
ASSERT_EQUALS("cppcheck: error: Option -l cannot be used as Cppcheck has not been built with fork threading model.\n", logger->str());
1911+
}
18691912
#endif
18701913

18711914
void maxCtuDepth() {
@@ -2026,6 +2069,72 @@ class TestCmdlineParser : public TestFixture {
20262069
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
20272070
}
20282071

2072+
#ifdef HAVE_RULES
2073+
void rule() {
2074+
REDIRECT;
2075+
const char * const argv[] = {"cppcheck", "--rule=.+", "file.cpp"};
2076+
ASSERT(parser->parseFromArgs(3, argv));
2077+
ASSERT_EQUALS(1, settings->rules.size());
2078+
auto it = settings->rules.cbegin();
2079+
ASSERT_EQUALS(".+", it->pattern);
2080+
ASSERT_EQUALS("", logger->str());
2081+
}
2082+
#else
2083+
void ruleNotSupported() {
2084+
REDIRECT;
2085+
const char * const argv[] = {"cppcheck", "--rule=.+", "file.cpp"};
2086+
ASSERT(!parser->parseFromArgs(3, argv));
2087+
ASSERT_EQUALS("cppcheck: error: Option --rule cannot be used as Cppcheck has not been built with rules support.\n", logger->str());
2088+
}
2089+
#endif
2090+
2091+
#ifdef HAVE_RULES
2092+
void ruleFile() {
2093+
REDIRECT;
2094+
ScopedFile file("rule.xml",
2095+
"<rules>\n"
2096+
"<rule>\n"
2097+
"<pattern>.+</pattern>\n"
2098+
"</rule>\n"
2099+
"</rules>");
2100+
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
2101+
ASSERT(parser->parseFromArgs(3, argv));
2102+
ASSERT_EQUALS(1, settings->rules.size());
2103+
auto it = settings->rules.cbegin();
2104+
ASSERT_EQUALS(".+", it->pattern);
2105+
ASSERT_EQUALS("", logger->str());
2106+
}
2107+
2108+
void ruleFileEmpty() {
2109+
REDIRECT;
2110+
const char * const argv[] = {"cppcheck", "--rule-file=", "file.cpp"};
2111+
ASSERT(!parser->parseFromArgs(3, argv));
2112+
ASSERT_EQUALS("cppcheck: error: unable to load rule-file '' (XML_ERROR_FILE_NOT_FOUND).\n", logger->str());
2113+
}
2114+
2115+
void ruleFileMissing() {
2116+
REDIRECT;
2117+
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
2118+
ASSERT(!parser->parseFromArgs(3, argv));
2119+
ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' (XML_ERROR_FILE_NOT_FOUND).\n", logger->str());
2120+
}
2121+
2122+
void ruleFileInvalid() {
2123+
REDIRECT;
2124+
ScopedFile file("rule.xml", "");
2125+
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
2126+
ASSERT(!parser->parseFromArgs(3, argv));
2127+
ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' (XML_ERROR_EMPTY_DOCUMENT).\n", logger->str());
2128+
}
2129+
#else
2130+
void ruleFileNotSupported() {
2131+
REDIRECT;
2132+
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
2133+
ASSERT(!parser->parseFromArgs(3, argv));
2134+
ASSERT_EQUALS("cppcheck: error: Option --rule-file cannot be used as Cppcheck has not been built with rules support.\n", logger->str());
2135+
}
2136+
#endif
2137+
20292138
void ignorepaths1() {
20302139
REDIRECT;
20312140
const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};

0 commit comments

Comments
 (0)