@@ -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.clear ();
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