Skip to content

Commit 578a18e

Browse files
committed
Add look for duplicates and select most general in config list in getConfig.
* Added checks that makes sure that no duplicated of a configuration (like X & X=X, in that case only X is kept) ends up in getConfig ret.
1 parent c9b880e commit 578a18e

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

lib/preprocessor.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,12 @@ static bool hasDefine(const std::string &userDefines, const std::string &cfg)
473473
}
474474

475475
std::string::size_type pos = 0;
476+
const std::string cfgname = cfg.substr(0, cfg.find('='));
476477
while (pos < userDefines.size()) {
477-
const std::string::size_type eq = cfg.find('=');
478-
pos = (eq == std::string::npos) ? userDefines.find(cfg, pos) : userDefines.find(cfg.substr(0, eq), pos);
478+
pos = userDefines.find(cfgname, pos);
479479
if (pos == std::string::npos)
480480
break;
481-
const std::string::size_type pos2 = (eq == std::string::npos) ? pos + cfg.size() : pos + eq;
481+
const std::string::size_type pos2 = pos + cfgname.size();
482482
if ((pos == 0 || userDefines[pos-1U] == ';') && (pos2 == userDefines.size() || userDefines[pos2] == '='))
483483
return true;
484484
pos = pos2;
@@ -608,6 +608,24 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set<std::string>
608608
}
609609
}
610610

611+
// check if config already exists in the ret set, but as a more general or more specific version
612+
if (cmdtok->str() != "ifndef")
613+
{
614+
const std::string::size_type eq = config.find('=');
615+
const std::string config2 = (eq != std::string::npos) ? config.substr(0, eq) : config + "=" + config;
616+
const std::set<std::string>::iterator it2 = ret.find(config2);
617+
if (it2 != ret.end()) {
618+
if (eq == std::string::npos) {
619+
// The instance in ret is more specific than the one in config (no =value), replace it with the one in config
620+
ret.erase(it2);
621+
} else {
622+
// The instance in ret is more general than the one in config (have =value), keep the one in ret
623+
config.erase();
624+
continue;
625+
}
626+
}
627+
}
628+
611629
configs_if.push_back((cmdtok->str() == "ifndef") ? std::string() : config);
612630
configs_ifndef.push_back((cmdtok->str() == "ifndef") ? std::move(config) : std::string());
613631
ret.insert(cfg(configs_if,userDefines));
@@ -641,8 +659,18 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set<std::string>
641659
configs_if.push_back(std::move(config));
642660
ret.insert(cfg(configs_if, userDefines));
643661
} else if (!configs_ifndef.empty()) {
644-
configs_if.push_back(configs_ifndef.back());
645-
ret.insert(cfg(configs_if, userDefines));
662+
//Check if ifndef already existing in ret as more general/specific version
663+
const std::string &confCandidate = configs_ifndef.back();
664+
if (ret.find(confCandidate) == ret.end()) {
665+
// No instance of config_ifndef in ret. Check if a more specific version exists, in that case replace it
666+
const std::set<std::string>::iterator it = ret.find(confCandidate + "=" + confCandidate);
667+
if (it != ret.end()) {
668+
// The instance in ret is more specific than the one in confCandidate (no =value), replace it with the one in confCandidate
669+
ret.erase(it);
670+
}
671+
configs_if.push_back(configs_ifndef.back());
672+
ret.insert(cfg(configs_if, userDefines));
673+
}
646674
}
647675
} else if (cmdtok->str() == "endif" && !sameline(tok, cmdtok->next)) {
648676
if (!configs_if.empty())

0 commit comments

Comments
 (0)