diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index 6fd30581c..8f9b19b3b 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -89,11 +89,14 @@ bool MacroProcessor::ResolveMacro(const String& macro, const ResolverList& resol } for (const ResolverSpec& resolver : resolvers) { - if (!objName.IsEmpty() && objName != resolver.first) + if (!objName.IsEmpty() && objName != resolver.Name) continue; if (objName.IsEmpty()) { - CustomVarObject::Ptr dobj = dynamic_pointer_cast(resolver.second); + if (!resolver.ResolveShortMacros) + continue; + + CustomVarObject::Ptr dobj = dynamic_pointer_cast(resolver.Obj); if (dobj) { Dictionary::Ptr vars = dobj->GetVars(); @@ -106,12 +109,12 @@ bool MacroProcessor::ResolveMacro(const String& macro, const ResolverList& resol } } - auto *mresolver = dynamic_cast(resolver.second.get()); + auto *mresolver = dynamic_cast(resolver.Obj.get()); if (mresolver && mresolver->ResolveMacro(boost::algorithm::join(tokens, "."), cr, result)) return true; - Value ref = resolver.second; + Value ref = resolver.Obj; bool valid = true; for (const String& token : tokens) { @@ -172,7 +175,7 @@ Value MacroProcessor::EvaluateFunction(const Function::Ptr& func, const Resolver Dictionary::Ptr resolvers_this = new Dictionary(); for (const ResolverSpec& resolver : resolvers) { - resolvers_this->Set(resolver.first, resolver.second); + resolvers_this->Set(resolver.Name, resolver.Obj); } auto internalResolveMacrosShim = [resolvers, cr, resolvedMacros, useResolvedMacros, recursionLevel](const std::vector& args) { diff --git a/lib/icinga/macroprocessor.hpp b/lib/icinga/macroprocessor.hpp index d6c16107a..7e7482153 100644 --- a/lib/icinga/macroprocessor.hpp +++ b/lib/icinga/macroprocessor.hpp @@ -7,6 +7,7 @@ #include "icinga/checkable.hpp" #include "base/value.hpp" #include +#include namespace icinga { @@ -19,8 +20,21 @@ namespace icinga class MacroProcessor { public: + struct ResolverSpec + { + String Name; + Object::Ptr Obj; + + // Whether to resolve not only e.g. $host.address$, but also just $address$ + bool ResolveShortMacros; + + inline ResolverSpec(String name, Object::Ptr obj, bool resolveShortMacros = true) + : Name(std::move(name)), Obj(std::move(obj)), ResolveShortMacros(resolveShortMacros) + { + } + }; + typedef std::function EscapeCallback; - typedef std::pair ResolverSpec; typedef std::vector ResolverList; static Value ResolveMacros(const Value& str, const ResolverList& resolvers,