Fixed #4827 (allow checking multiple configurations when using -D by also using --max-configs or --force)
This commit is contained in:
parent
10849e220b
commit
4e09b06bc1
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue