diff --git a/lib/cli/objectlistcommand.cpp b/lib/cli/objectlistcommand.cpp index 7d48075e8..951dd12b8 100644 --- a/lib/cli/objectlistcommand.cpp +++ b/lib/cli/objectlistcommand.cpp @@ -188,10 +188,12 @@ void ObjectListCommand::PrintHints(std::ostream& fp, const Dictionary::Ptr& debu Array::Ptr messages = debug_hints->Get("messages"); - ObjectLock olock(messages); + if (messages) { + ObjectLock olock(messages); - BOOST_FOREACH(const Value& msg, messages) { - PrintHint(fp, msg, indent); + BOOST_FOREACH(const Value& msg, messages) { + PrintHint(fp, msg, indent); + } } } diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index f80c0fc08..13c587ec3 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -282,7 +282,8 @@ Value DictExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) c Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - DebugHint *sdhint = dhint; + DebugHint *psdhint = dhint; + DebugHint sdhint; Value parent, object; String index; @@ -291,8 +292,10 @@ Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) co Expression *indexExpr = m_Indexer[i]; String tempindex = indexExpr->Evaluate(context, dhint); - if (sdhint) - sdhint = sdhint->GetChild(tempindex); + if (psdhint) { + sdhint = psdhint->GetChild(tempindex); + psdhint = &sdhint; + } if (i == 0) parent = context; @@ -311,7 +314,7 @@ Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) co LiteralExpression *eindex = MakeLiteral(tempindex); IndexerExpression eip(eparent, eindex, m_DebugInfo); - object = eip.Evaluate(context, sdhint); + object = eip.Evaluate(context, psdhint); if (i != m_Indexer.size() - 1 && object.IsEmpty()) { object = new Dictionary(); @@ -346,8 +349,8 @@ Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) co SetField(parent, index, right); - if (sdhint) - sdhint->AddMessage("=", m_DebugInfo); + if (psdhint) + psdhint->AddMessage("=", m_DebugInfo); return right; } @@ -524,37 +527,6 @@ Value ForExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) co return Empty; } -Dictionary::Ptr DebugHint::ToDictionary(void) const -{ - Dictionary::Ptr result = new Dictionary(); - - Array::Ptr messages = new Array(); - typedef std::pair MessageType; - BOOST_FOREACH(const MessageType& message, Messages) { - Array::Ptr amsg = new Array(); - amsg->Add(message.first); - amsg->Add(message.second.Path); - amsg->Add(message.second.FirstLine); - amsg->Add(message.second.FirstColumn); - amsg->Add(message.second.LastLine); - amsg->Add(message.second.LastColumn); - messages->Add(amsg); - } - - result->Set("messages", messages); - - Dictionary::Ptr properties = new Dictionary(); - - typedef std::map::value_type ChildType; - BOOST_FOREACH(const ChildType& kv, Children) { - properties->Set(kv.first, kv.second.ToDictionary()); - } - - result->Set("properties", properties); - - return result; -} - bool Expression::HasField(const Object::Ptr& context, const String& field) { Dictionary::Ptr dict = dynamic_pointer_cast(context); diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index de618db92..9c2b6fb56 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -31,20 +31,60 @@ namespace icinga struct DebugHint { - std::vector > Messages; - std::map Children; +public: + DebugHint(const Dictionary::Ptr& hints = Dictionary::Ptr()) + : m_Hints(hints) + { } inline void AddMessage(const String& message, const DebugInfo& di) { - Messages.push_back(std::make_pair(message, di)); + if (!m_Hints) + m_Hints = new Dictionary(); + + if (!m_Messages) { + m_Messages = new Array(); + m_Hints->Set("messages", m_Messages); + } + + Array::Ptr amsg = new Array(); + amsg->Add(message); + amsg->Add(di.Path); + amsg->Add(di.FirstLine); + amsg->Add(di.FirstColumn); + amsg->Add(di.LastLine); + amsg->Add(di.LastColumn); + m_Messages->Add(amsg); } - inline DebugHint *GetChild(const String& name) + inline DebugHint GetChild(const String& name) { - return &Children[name]; + if (!m_Hints) + m_Hints = new Dictionary(); + + if (!m_Children) { + m_Children = new Dictionary; + m_Hints->Set("properties", m_Children); + } + + Dictionary::Ptr child = m_Children->Get(name); + + if (!child) { + child = new Dictionary(); + m_Children->Set(name, child); + } + + return DebugHint(child); } - Dictionary::Ptr ToDictionary(void) const; + Dictionary::Ptr ToDictionary(void) const + { + return m_Hints; + } + +private: + Dictionary::Ptr m_Hints; + Array::Ptr m_Messages; + Dictionary::Ptr m_Children; }; enum CombinedSetOp