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 def = false;
bool maxconfigs = false;
for (int i = 1; i < argc; i++) {
if (std::strcmp(argv[i], "--version") == 0) {
_showVersion = true;
@ -366,6 +369,8 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
if (!_settings->userDefines.empty())
_settings->userDefines += ";";
_settings->userDefines += define;
def = true;
}
// User undef
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.");
return false;
}
maxconfigs = true;
}
// 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) {
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;
}
if (!_settings.userDefines.empty()) {
if (!_settings.userDefines.empty() && _settings._maxConfigs==1U) {
configurations.clear();
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("..."));
}
if (!_settings.userDefines.empty()) {
if (!cfg.empty())
cfg = ";" + cfg;
cfg = _settings.userDefines + cfg;
}
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();
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;
preprocess(istr, data, configs, filename, includePaths);
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);
}
}
}
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);
if (_settings && !_settings->userIncludes.empty()) {
if (_settings && _settings->_maxConfigs == 1U) {
for (std::list<std::string>::iterator it = _settings->userIncludes.begin();
it != _settings->userIncludes.end();
++it) {
@ -870,9 +871,9 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str();
}
if (_settings && !_settings->userDefines.empty()) {
std::map<std::string, std::string> defs;
if (_settings && !_settings->userDefines.empty()) {
// TODO: break out this code. There is other similar code.
std::string::size_type pos1 = 0;
while (pos1 != std::string::npos) {
@ -897,19 +898,18 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
if (pos1 != std::string::npos)
pos1++;
}
}
if (_settings && _settings->_maxConfigs == 1U) {
processedFile = handleIncludes(processedFile, filename, includePaths, defs);
if (_settings->userIncludes.empty())
resultConfigurations = getcfgs(processedFile, filename);
resultConfigurations = getcfgs(processedFile, filename, defs);
} else {
handleIncludes(processedFile, filename, includePaths);
processedFile = replaceIfDefined(processedFile);
// Get all possible configurations..
resultConfigurations = getcfgs(processedFile, filename);
resultConfigurations = getcfgs(processedFile, filename, defs);
// Remove configurations that are disabled by -U
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;
ret.push_back("");
@ -1169,7 +1169,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
// 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) {
std::string::size_type pos = it->find_first_of("=(");
if (pos == std::string::npos)

View File

@ -202,15 +202,15 @@ private:
*/
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.
* By looking at the ifdefs and ifndefs in filedata
*/
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename);
static std::string getdef(std::string line, bool def);
public:
std::list<std::string> getcfgs(const std::string &filedata, const std::string &filename, const std::map<std::string, std::string> &defs);
/**
* Remove asm(...) from a string

View File

@ -256,6 +256,7 @@ private:
TEST_CASE(predefine3);
TEST_CASE(predefine4);
TEST_CASE(predefine5); // automatically define __cplusplus
TEST_CASE(predefine6); // using -D and -f => check all matching configurations
// Test Preprocessor::simplifyCondition
TEST_CASE(simplifyCondition);
@ -3176,6 +3177,31 @@ private:
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() {
// Ticket #2794