From 3bb79715fababdf5567fc25fc4834cf5ca747513 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sat, 15 Nov 2014 15:57:23 +0100 Subject: [PATCH] Fix: Names for nested objects are evaluated at the wrong time fixes #7689 --- lib/config/configitem.cpp | 77 ++++++++++++++++++++++----------------- lib/config/configitem.hpp | 2 + lib/config/configtype.cpp | 2 +- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 2ac90c152..0b48c8a81 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -151,11 +151,12 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard) Dictionary::Ptr locals = new Dictionary(); locals->Set("__parent", m_Scope); m_Scope.reset(); - locals->Set("name", m_Name); dobj->SetParentScope(locals); locals.reset(); + dobj->SetName(m_Name); + DebugHint debugHints; try { @@ -269,52 +270,59 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name) return ConfigItem::Ptr(); } -bool ConfigItem::ValidateItems(void) +bool ConfigItem::CommitNewItems(void) { - if (ConfigCompilerContext::GetInstance()->HasErrors()) - return false; + std::vector items; - ParallelWorkQueue upq; + do { + ParallelWorkQueue upq; - Log(LogInformation, "ConfigItem", "Committing config items"); + items.clear(); - BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) { - upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second, false)); - } + { + boost::mutex::scoped_lock lock(m_Mutex); - BOOST_FOREACH(const ConfigItem::Ptr& item, m_UnnamedItems) { - upq.Enqueue(boost::bind(&ConfigItem::Commit, item, true)); - } + BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) { + if (!kv.second->m_Abstract && !kv.second->m_Object) { + upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second, false)); + items.push_back(kv.second); + } + } - upq.Join(); + BOOST_FOREACH(const ConfigItem::Ptr& item, m_UnnamedItems) { + if (!item->m_Abstract && !item->m_Object) { + upq.Enqueue(boost::bind(&ConfigItem::Commit, item, true)); + items.push_back(item); + } + } - if (ConfigCompilerContext::GetInstance()->HasErrors()) - return false; + m_UnnamedItems.clear(); + } - std::vector objects; - BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) { - DynamicObject::Ptr object = kv.second->m_Object; + upq.Join(); - if (object) - objects.push_back(object); - } + if (ConfigCompilerContext::GetInstance()->HasErrors()) + return false; - BOOST_FOREACH(const ConfigItem::Ptr& item, m_UnnamedItems) { - DynamicObject::Ptr object = item->m_Object; + BOOST_FOREACH(const ConfigItem::Ptr& item, items) { + upq.Enqueue(boost::bind(&DynamicObject::OnConfigLoaded, item->m_Object)); + } - if (object) - objects.push_back(object); - } + upq.Join(); + } while (!items.empty()); - m_UnnamedItems.clear(); + return true; +} - Log(LogInformation, "ConfigItem", "Triggering OnConfigLoaded signal for config items"); +bool ConfigItem::ValidateItems(void) +{ + if (ConfigCompilerContext::GetInstance()->HasErrors()) + return false; - BOOST_FOREACH(const DynamicObject::Ptr& object, objects) { - upq.Enqueue(boost::bind(&DynamicObject::OnConfigLoaded, object)); - } + Log(LogInformation, "ConfigItem", "Committing config items"); - upq.Join(); + if (!CommitNewItems()) + return false; Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 1)..."); ObjectRule::EvaluateRules(false); @@ -322,11 +330,12 @@ bool ConfigItem::ValidateItems(void) Log(LogInformation, "ConfigItem", "Evaluating 'apply' rules..."); ApplyRule::EvaluateRules(true); + if (!CommitNewItems()) + return false; + Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)..."); ObjectRule::EvaluateRules(true); - upq.Join(); - ConfigItem::DiscardItems(); ConfigType::DiscardTypes(); diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index b3b1ad7dd..390f8ce72 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -87,6 +87,8 @@ private: static ConfigItem::Ptr GetObjectUnlocked(const String& type, const String& name); + + static bool CommitNewItems(void); }; } diff --git a/lib/config/configtype.cpp b/lib/config/configtype.cpp index dcd07d9c2..9970a440c 100644 --- a/lib/config/configtype.cpp +++ b/lib/config/configtype.cpp @@ -115,7 +115,7 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary, Value value = dictionary->Get(require); - if (value.IsEmpty()) { + if (value.IsEmpty() || (value.IsString() && static_cast(value).IsEmpty())) { ConfigCompilerContext::GetInstance()->AddMessage(true, "Required attribute is missing: " + LocationToString(locations)); } -- 2.40.0