Loading parser.cpp +15 −3 Changes for parser.cpp: 15 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -852,6 +852,18 @@ std::string Parser::expand(const std::string& input, const Makefile& mf) const { return do_expand(input, mf, nullptr); } std::string Parser::expand_recursive_var( const std::string& name, const std::string& value, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const { // Break self-referential expansion cycles. GNU make aborts with // "Recursive variable references itself"; we instead treat the recursive // reference as empty so a single legitimate self-append still terminates. if (!expanding_.insert(name).second) return ""; std::string out = do_expand(value, mf, auto_vars); expanding_.erase(name); return out; } std::string Parser::expand_with_automatic(const std::string& input, const Makefile& mf, const std::string& target, const std::string& first_prereq, Loading Loading @@ -943,7 +955,7 @@ std::string Parser::do_expand(const std::string& input, const Makefile& mf, auto it = mf.variables.find(varname); if (it != mf.variables.end()) { if (it->second.flavor == VarFlavor::Recursive) { result += do_expand(it->second.value, mf, auto_vars); result += expand_recursive_var(varname, it->second.value, mf, auto_vars); } else { result += it->second.value; } Loading Loading @@ -997,7 +1009,7 @@ std::string Parser::expand_ref(const std::string& content, const Makefile& mf, auto vit = mf.variables.find(var); if (vit != mf.variables.end()) { val = (vit->second.flavor == VarFlavor::Recursive) ? do_expand(vit->second.value, mf, auto_vars) ? expand_recursive_var(var, vit->second.value, mf, auto_vars) : vit->second.value; } } Loading @@ -1019,7 +1031,7 @@ std::string Parser::expand_ref(const std::string& content, const Makefile& mf, auto it = mf.variables.find(expanded_name); if (it != mf.variables.end()) { if (it->second.flavor == VarFlavor::Recursive) { return do_expand(it->second.value, mf, auto_vars); return expand_recursive_var(expanded_name, it->second.value, mf, auto_vars); } return it->second.value; } Loading parser.h +10 −0 Changes for parser.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -93,6 +93,16 @@ private: std::string do_expand(const std::string& input, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; // Names of recursively-expanded variables currently being expanded, used to // break self-referential cycles (e.g. "X = $(X) more") that would otherwise // recurse until the process exhausts memory. Matches GNU make, which refuses // to expand a variable that references itself. mutable std::set<std::string> expanding_; // Expand a recursively-flavored variable's value while guarding against // cycles; returns "" if 'name' is already on the expansion stack. std::string expand_recursive_var(const std::string& name, const std::string& value, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; std::string expand_ref(const std::string& content, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; std::string expand_function(const std::string& name, const std::string& args, Loading Loading
parser.cpp +15 −3 Changes for parser.cpp: 15 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -852,6 +852,18 @@ std::string Parser::expand(const std::string& input, const Makefile& mf) const { return do_expand(input, mf, nullptr); } std::string Parser::expand_recursive_var( const std::string& name, const std::string& value, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const { // Break self-referential expansion cycles. GNU make aborts with // "Recursive variable references itself"; we instead treat the recursive // reference as empty so a single legitimate self-append still terminates. if (!expanding_.insert(name).second) return ""; std::string out = do_expand(value, mf, auto_vars); expanding_.erase(name); return out; } std::string Parser::expand_with_automatic(const std::string& input, const Makefile& mf, const std::string& target, const std::string& first_prereq, Loading Loading @@ -943,7 +955,7 @@ std::string Parser::do_expand(const std::string& input, const Makefile& mf, auto it = mf.variables.find(varname); if (it != mf.variables.end()) { if (it->second.flavor == VarFlavor::Recursive) { result += do_expand(it->second.value, mf, auto_vars); result += expand_recursive_var(varname, it->second.value, mf, auto_vars); } else { result += it->second.value; } Loading Loading @@ -997,7 +1009,7 @@ std::string Parser::expand_ref(const std::string& content, const Makefile& mf, auto vit = mf.variables.find(var); if (vit != mf.variables.end()) { val = (vit->second.flavor == VarFlavor::Recursive) ? do_expand(vit->second.value, mf, auto_vars) ? expand_recursive_var(var, vit->second.value, mf, auto_vars) : vit->second.value; } } Loading @@ -1019,7 +1031,7 @@ std::string Parser::expand_ref(const std::string& content, const Makefile& mf, auto it = mf.variables.find(expanded_name); if (it != mf.variables.end()) { if (it->second.flavor == VarFlavor::Recursive) { return do_expand(it->second.value, mf, auto_vars); return expand_recursive_var(expanded_name, it->second.value, mf, auto_vars); } return it->second.value; } Loading
parser.h +10 −0 Changes for parser.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -93,6 +93,16 @@ private: std::string do_expand(const std::string& input, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; // Names of recursively-expanded variables currently being expanded, used to // break self-referential cycles (e.g. "X = $(X) more") that would otherwise // recurse until the process exhausts memory. Matches GNU make, which refuses // to expand a variable that references itself. mutable std::set<std::string> expanding_; // Expand a recursively-flavored variable's value while guarding against // cycles; returns "" if 'name' is already on the expansion stack. std::string expand_recursive_var(const std::string& name, const std::string& value, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; std::string expand_ref(const std::string& content, const Makefile& mf, const std::map<std::string, std::string>* auto_vars) const; std::string expand_function(const std::string& name, const std::string& args, Loading