Fixed #4827 (allow checking multiple configurations when using -D by also using --max-configs or --force)

This commit is contained in:
Daniel Marjamki 2013-06-08 16:46:54 +02:00
parent 10849e220b
commit 4e09b06bc1
5 changed files with 63 additions and 18 deletions

View File

@ -102,6 +102,9 @@ void CmdLineParser::PrintMessage(const std::string &message)
bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
{ {
bool def = false;
bool maxconfigs = false;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (std::strcmp(argv[i], "--version") == 0) { if (std::strcmp(argv[i], "--version") == 0) {
_showVersion = true; _showVersion = true;
@ -366,6 +369,8 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
if (!_settings->userDefines.empty()) if (!_settings->userDefines.empty())
_settings->userDefines += ";"; _settings->userDefines += ";";
_settings->userDefines += define; _settings->userDefines += define;
def = true;
} }
// User undef // User undef
else if (std::strncmp(argv[i], "-U", 2) == 0) { else if (std::strncmp(argv[i], "-U", 2) == 0) {
@ -662,6 +667,8 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
PrintMessage("cppcheck: argument to '--max-configs=' must be greater than 0."); PrintMessage("cppcheck: argument to '--max-configs=' must be greater than 0.");
return false; return false;
} }
maxconfigs = true;
} }
// Print help // Print help
@ -687,6 +694,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
} }
} }
if (def && !_settings->_force && !maxconfigs)
_settings->_maxConfigs = 1U;
if (_settings->_force)
_settings->_maxConfigs = ~0U;
if (_settings->isEnabled("unusedFunction") && _settings->_jobs > 1) { if (_settings->isEnabled("unusedFunction") && _settings->_jobs > 1) {
PrintMessage("cppcheck: unusedFunction check can't be used with '-j' option, so it's disabled."); PrintMessage("cppcheck: unusedFunction check can't be used with '-j' option, so it's disabled.");
} }

View File

@ -166,7 +166,7 @@ unsigned int CppCheck::processFile(const std::string& filename)
return 0; return 0;
} }
if (!_settings.userDefines.empty()) { if (!_settings.userDefines.empty() && _settings._maxConfigs==1U) {
configurations.clear(); configurations.clear();
configurations.push_back(_settings.userDefines); configurations.push_back(_settings.userDefines);
} }
@ -195,8 +195,14 @@ unsigned int CppCheck::processFile(const std::string& filename)
_errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("...")); _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
} }
if (!_settings.userDefines.empty()) {
if (!cfg.empty())
cfg = ";" + cfg;
cfg = _settings.userDefines + cfg;
}
Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults); Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
const std::string codeWithoutCfg = preprocessor.getcode(filedata, *it, filename, _settings.userDefines.empty()); const std::string codeWithoutCfg = preprocessor.getcode(filedata, cfg, filename, _settings._maxConfigs == 1U);
t.Stop(); t.Stop();
const std::string &appendCode = _settings.append(); const std::string &appendCode = _settings.append();

View File

@ -710,9 +710,10 @@ void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::str
std::string data; std::string data;
preprocess(istr, data, configs, filename, includePaths); preprocess(istr, data, configs, filename, includePaths);
for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) { for (std::list<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) {
if (_settings && (_settings->userUndefs.find(*it) == _settings->userUndefs.end())) if (_settings && (_settings->userUndefs.find(*it) == _settings->userUndefs.end())) {
result[ *it ] = getcode(data, *it, filename); result[ *it ] = getcode(data, *it, filename);
} }
}
} }
std::string Preprocessor::removeSpaceNearNL(const std::string &str) std::string Preprocessor::removeSpaceNearNL(const std::string &str)
@ -803,7 +804,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = read(srcCodeStream, filename); processedFile = read(srcCodeStream, filename);
if (_settings && !_settings->userIncludes.empty()) { if (_settings && _settings->_maxConfigs == 1U) {
for (std::list<std::string>::iterator it = _settings->userIncludes.begin(); for (std::list<std::string>::iterator it = _settings->userIncludes.begin();
it != _settings->userIncludes.end(); it != _settings->userIncludes.end();
++it) { ++it) {
@ -870,9 +871,9 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str(); processedFile = ostr.str();
} }
if (_settings && !_settings->userDefines.empty()) {
std::map<std::string, std::string> defs; std::map<std::string, std::string> defs;
if (_settings && !_settings->userDefines.empty()) {
// TODO: break out this code. There is other similar code. // TODO: break out this code. There is other similar code.
std::string::size_type pos1 = 0; std::string::size_type pos1 = 0;
while (pos1 != std::string::npos) { while (pos1 != std::string::npos) {
@ -897,19 +898,18 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
if (pos1 != std::string::npos) if (pos1 != std::string::npos)
pos1++; pos1++;
} }
}
if (_settings && _settings->_maxConfigs == 1U) {
processedFile = handleIncludes(processedFile, filename, includePaths, defs); processedFile = handleIncludes(processedFile, filename, includePaths, defs);
if (_settings->userIncludes.empty()) resultConfigurations = getcfgs(processedFile, filename, defs);
resultConfigurations = getcfgs(processedFile, filename);
} else { } else {
handleIncludes(processedFile, filename, includePaths); handleIncludes(processedFile, filename, includePaths);
processedFile = replaceIfDefined(processedFile); processedFile = replaceIfDefined(processedFile);
// Get all possible configurations.. // Get all possible configurations..
resultConfigurations = getcfgs(processedFile, filename); resultConfigurations = getcfgs(processedFile, filename, defs);
// Remove configurations that are disabled by -U // Remove configurations that are disabled by -U
handleUndef(resultConfigurations); handleUndef(resultConfigurations);
@ -1050,7 +1050,7 @@ static void simplifyVarMap(std::map<std::string, std::string> &variables)
} }
} }
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename) std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename, const std::map<std::string, std::string> &defs)
{ {
std::list<std::string> ret; std::list<std::string> ret;
ret.push_back(""); ret.push_back("");
@ -1169,7 +1169,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
// Replace defined constants // Replace defined constants
{ {
std::map<std::string, std::string> varmap; std::map<std::string, std::string> varmap(defs);
for (std::set<std::string>::const_iterator it = defines.begin(); it != defines.end(); ++it) { for (std::set<std::string>::const_iterator it = defines.begin(); it != defines.end(); ++it) {
std::string::size_type pos = it->find_first_of("=("); std::string::size_type pos = it->find_first_of("=(");
if (pos == std::string::npos) if (pos == std::string::npos)

View File

@ -202,15 +202,15 @@ private:
*/ */
static std::string removeSpaceNearNL(const std::string &str); static std::string removeSpaceNearNL(const std::string &str);
static std::string getdef(std::string line, bool def);
public:
/** /**
* Get all possible configurations sorted in alphabetical order. * Get all possible configurations sorted in alphabetical order.
* By looking at the ifdefs and ifndefs in filedata * By looking at the ifdefs and ifndefs in filedata
*/ */
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename); std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename, const std::map<std::string, std::string> &defs);
static std::string getdef(std::string line, bool def);
public:
/** /**
* Remove asm(...) from a string * Remove asm(...) from a string

View File

@ -256,6 +256,7 @@ private:
TEST_CASE(predefine3); TEST_CASE(predefine3);
TEST_CASE(predefine4); TEST_CASE(predefine4);
TEST_CASE(predefine5); // automatically define __cplusplus TEST_CASE(predefine5); // automatically define __cplusplus
TEST_CASE(predefine6); // using -D and -f => check all matching configurations
// Test Preprocessor::simplifyCondition // Test Preprocessor::simplifyCondition
TEST_CASE(simplifyCondition); TEST_CASE(simplifyCondition);
@ -3176,6 +3177,31 @@ private:
ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp")); ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp"));
} }
void predefine6() { // #3737 - using -D and -f => check all matching configurations
const char filedata[] = "#ifdef A\n"
"1\n"
"#else\n"
"2\n"
"#endif\n"
"#ifdef B\n"
"3\n"
"#else\n"
"4\n"
"#endif";
// actual result..
Settings settings;
Preprocessor preprocessor(&settings, this);
std::map<std::string, std::string> defs;
defs["A"] = "1";
const std::list<std::string> configs = preprocessor.getcfgs(filedata, "test1.c", defs);
// Compare actual result with expected result..
ASSERT_EQUALS(2U, configs.size());
ASSERT_EQUALS("", configs.front());
ASSERT_EQUALS("B", configs.back());
}
void simplifyCondition() { void simplifyCondition() {
// Ticket #2794 // Ticket #2794