Skip to content

Commit 4e09b06

Browse files
committed
Fixed cppcheck-opensource#4827 (allow checking multiple configurations when using -D by also using --max-configs or --force)
1 parent 10849e2 commit 4e09b06

5 files changed

Lines changed: 63 additions & 18 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ void CmdLineParser::PrintMessage(const std::string &message)
102102

103103
bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
104104
{
105+
bool def = false;
106+
bool maxconfigs = false;
107+
105108
for (int i = 1; i < argc; i++) {
106109
if (std::strcmp(argv[i], "--version") == 0) {
107110
_showVersion = true;
@@ -366,6 +369,8 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
366369
if (!_settings->userDefines.empty())
367370
_settings->userDefines += ";";
368371
_settings->userDefines += define;
372+
373+
def = true;
369374
}
370375
// User undef
371376
else if (std::strncmp(argv[i], "-U", 2) == 0) {
@@ -662,6 +667,8 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
662667
PrintMessage("cppcheck: argument to '--max-configs=' must be greater than 0.");
663668
return false;
664669
}
670+
671+
maxconfigs = true;
665672
}
666673

667674
// Print help
@@ -687,6 +694,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
687694
}
688695
}
689696

697+
if (def && !_settings->_force && !maxconfigs)
698+
_settings->_maxConfigs = 1U;
699+
700+
if (_settings->_force)
701+
_settings->_maxConfigs = ~0U;
702+
690703
if (_settings->isEnabled("unusedFunction") && _settings->_jobs > 1) {
691704
PrintMessage("cppcheck: unusedFunction check can't be used with '-j' option, so it's disabled.");
692705
}

lib/cppcheck.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ unsigned int CppCheck::processFile(const std::string& filename)
166166
return 0;
167167
}
168168

169-
if (!_settings.userDefines.empty()) {
169+
if (!_settings.userDefines.empty() && _settings._maxConfigs==1U) {
170170
configurations.clear();
171171
configurations.push_back(_settings.userDefines);
172172
}
@@ -195,8 +195,14 @@ unsigned int CppCheck::processFile(const std::string& filename)
195195
_errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
196196
}
197197

198+
if (!_settings.userDefines.empty()) {
199+
if (!cfg.empty())
200+
cfg = ";" + cfg;
201+
cfg = _settings.userDefines + cfg;
202+
}
203+
198204
Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
199-
const std::string codeWithoutCfg = preprocessor.getcode(filedata, *it, filename, _settings.userDefines.empty());
205+
const std::string codeWithoutCfg = preprocessor.getcode(filedata, cfg, filename, _settings._maxConfigs == 1U);
200206
t.Stop();
201207

202208
const std::string &appendCode = _settings.append();

lib/preprocessor.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,9 @@ void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::str
710710
std::string data;
711711
preprocess(istr, data, configs, filename, includePaths);
712712
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) {
713-
if (_settings && (_settings->userUndefs.find(*it) == _settings->userUndefs.end()))
713+
if (_settings && (_settings->userUndefs.find(*it) == _settings->userUndefs.end())) {
714714
result[ *it ] = getcode(data, *it, filename);
715+
}
715716
}
716717
}
717718

@@ -803,7 +804,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
803804

804805
processedFile = read(srcCodeStream, filename);
805806

806-
if (_settings && !_settings->userIncludes.empty()) {
807+
if (_settings && _settings->_maxConfigs == 1U) {
807808
for (std::list<std::string>::iterator it = _settings->userIncludes.begin();
808809
it != _settings->userIncludes.end();
809810
++it) {
@@ -870,9 +871,9 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
870871
processedFile = ostr.str();
871872
}
872873

873-
if (_settings && !_settings->userDefines.empty()) {
874-
std::map<std::string, std::string> defs;
874+
std::map<std::string, std::string> defs;
875875

876+
if (_settings && !_settings->userDefines.empty()) {
876877
// TODO: break out this code. There is other similar code.
877878
std::string::size_type pos1 = 0;
878879
while (pos1 != std::string::npos) {
@@ -897,19 +898,18 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
897898
if (pos1 != std::string::npos)
898899
pos1++;
899900
}
901+
}
900902

903+
if (_settings && _settings->_maxConfigs == 1U) {
901904
processedFile = handleIncludes(processedFile, filename, includePaths, defs);
902-
if (_settings->userIncludes.empty())
903-
resultConfigurations = getcfgs(processedFile, filename);
904-
905+
resultConfigurations = getcfgs(processedFile, filename, defs);
905906
} else {
906-
907907
handleIncludes(processedFile, filename, includePaths);
908908

909909
processedFile = replaceIfDefined(processedFile);
910910

911911
// Get all possible configurations..
912-
resultConfigurations = getcfgs(processedFile, filename);
912+
resultConfigurations = getcfgs(processedFile, filename, defs);
913913

914914
// Remove configurations that are disabled by -U
915915
handleUndef(resultConfigurations);
@@ -1050,7 +1050,7 @@ static void simplifyVarMap(std::map<std::string, std::string> &variables)
10501050
}
10511051
}
10521052

1053-
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename)
1053+
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename, const std::map<std::string, std::string> &defs)
10541054
{
10551055
std::list<std::string> ret;
10561056
ret.push_back("");
@@ -1169,7 +1169,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
11691169

11701170
// Replace defined constants
11711171
{
1172-
std::map<std::string, std::string> varmap;
1172+
std::map<std::string, std::string> varmap(defs);
11731173
for (std::set<std::string>::const_iterator it = defines.begin(); it != defines.end(); ++it) {
11741174
std::string::size_type pos = it->find_first_of("=(");
11751175
if (pos == std::string::npos)

lib/preprocessor.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,15 @@ class CPPCHECKLIB Preprocessor {
202202
*/
203203
static std::string removeSpaceNearNL(const std::string &str);
204204

205+
static std::string getdef(std::string line, bool def);
206+
207+
public:
208+
205209
/**
206210
* Get all possible configurations sorted in alphabetical order.
207211
* By looking at the ifdefs and ifndefs in filedata
208212
*/
209-
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename);
210-
211-
static std::string getdef(std::string line, bool def);
212-
213-
public:
213+
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename, const std::map<std::string, std::string> &defs);
214214

215215
/**
216216
* Remove asm(...) from a string

test/testpreprocessor.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ class TestPreprocessor : public TestFixture {
256256
TEST_CASE(predefine3);
257257
TEST_CASE(predefine4);
258258
TEST_CASE(predefine5); // automatically define __cplusplus
259+
TEST_CASE(predefine6); // using -D and -f => check all matching configurations
259260

260261
// Test Preprocessor::simplifyCondition
261262
TEST_CASE(simplifyCondition);
@@ -3176,6 +3177,31 @@ class TestPreprocessor : public TestFixture {
31763177
ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp"));
31773178
}
31783179

3180+
void predefine6() { // #3737 - using -D and -f => check all matching configurations
3181+
const char filedata[] = "#ifdef A\n"
3182+
"1\n"
3183+
"#else\n"
3184+
"2\n"
3185+
"#endif\n"
3186+
"#ifdef B\n"
3187+
"3\n"
3188+
"#else\n"
3189+
"4\n"
3190+
"#endif";
3191+
3192+
// actual result..
3193+
Settings settings;
3194+
Preprocessor preprocessor(&settings, this);
3195+
std::map<std::string, std::string> defs;
3196+
defs["A"] = "1";
3197+
const std::list<std::string> configs = preprocessor.getcfgs(filedata, "test1.c", defs);
3198+
3199+
// Compare actual result with expected result..
3200+
ASSERT_EQUALS(2U, configs.size());
3201+
ASSERT_EQUALS("", configs.front());
3202+
ASSERT_EQUALS("B", configs.back());
3203+
}
3204+
31793205

31803206
void simplifyCondition() {
31813207
// Ticket #2794

0 commit comments

Comments
 (0)