| 21 | thread_local Dictionary::Ptr MacroResolver::OverrideMacros; |
| 22 | |
| 23 | Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolvers, |
| 24 | const CheckResult::Ptr& cr, String *missingMacro, |
| 25 | const MacroProcessor::EscapeCallback& escapeFn, const Dictionary::Ptr& resolvedMacros, |
| 26 | bool useResolvedMacros, int recursionLevel) |
| 27 | { |
| 28 | if (useResolvedMacros) |
| 29 | REQUIRE_NOT_NULL(resolvedMacros); |
| 30 | |
| 31 | Value result; |
| 32 | |
| 33 | if (str.IsEmpty()) |
| 34 | return Empty; |
| 35 | |
| 36 | if (str.IsScalar()) { |
| 37 | result = InternalResolveMacros(str, resolvers, cr, missingMacro, escapeFn, |
| 38 | resolvedMacros, useResolvedMacros, recursionLevel + 1); |
| 39 | } else if (str.IsObjectType<Array>()) { |
| 40 | ArrayData resultArr; |
| 41 | Array::Ptr arr = str; |
| 42 | |
| 43 | ObjectLock olock(arr); |
| 44 | |
| 45 | for (const Value& arg : arr) { |
| 46 | /* Note: don't escape macros here. */ |
| 47 | Value value = InternalResolveMacros(arg, resolvers, cr, missingMacro, |
| 48 | EscapeCallback(), resolvedMacros, useResolvedMacros, recursionLevel + 1); |
| 49 | |
| 50 | if (value.IsObjectType<Array>()) |
| 51 | resultArr.push_back(Utility::Join(value, ';')); |
| 52 | else |
| 53 | resultArr.push_back(value); |
| 54 | } |
| 55 | |
| 56 | result = new Array(std::move(resultArr)); |
| 57 | } else if (str.IsObjectType<Dictionary>()) { |
| 58 | Dictionary::Ptr resultDict = new Dictionary(); |
| 59 | Dictionary::Ptr dict = str; |
| 60 | |
| 61 | ObjectLock olock(dict); |
| 62 | |
| 63 | for (const Dictionary::Pair& kv : dict) { |
| 64 | /* Note: don't escape macros here. */ |
| 65 | resultDict->Set(kv.first, InternalResolveMacros(kv.second, resolvers, cr, missingMacro, |
| 66 | EscapeCallback(), resolvedMacros, useResolvedMacros, recursionLevel + 1)); |
| 67 | } |
| 68 | |
| 69 | result = resultDict; |
| 70 | } else if (str.IsObjectType<Function>()) { |
| 71 | result = EvaluateFunction(str, resolvers, cr, resolvedMacros, useResolvedMacros, 0); |
| 72 | } else { |
| 73 | BOOST_THROW_EXCEPTION(std::invalid_argument("Macro is not a string or array.")); |
| 74 | } |
| 75 | |
| 76 | return result; |
| 77 | } |
| 78 | |
| 79 | static const EnvResolver::Ptr l_EnvResolver = new EnvResolver(); |
| 80 | |