]> granicus.if.org Git - icinga2/blobdiff - lib/config/vmops.hpp
Workaround for GCC bug 61321
[icinga2] / lib / config / vmops.hpp
index 948cce1da7b4eb0b7ac9153fcdced9a94d79b7e3..323ba51ee47e58b30c05b994e257b47662f9b0ed 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-2016 Icinga Development Team (https://www.icinga.org/)  *
+ * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)  *
  *                                                                            *
  * This program is free software; you can redistribute it and/or              *
  * modify it under the terms of the GNU General Public License                *
@@ -33,7 +33,6 @@
 #include "base/exception.hpp"
 #include "base/convert.hpp"
 #include "base/objectlock.hpp"
-#include <boost/smart_ptr/make_shared.hpp>
 #include <map>
 #include <vector>
 
@@ -102,25 +101,41 @@ public:
 
        static inline Value FunctionCall(ScriptFrame& frame, const Value& self, const Function::Ptr& func, const std::vector<Value>& arguments)
        {
-               ScriptFrame vframe;
-               
                if (!self.IsEmpty() || self.IsString())
-                       return func->Invoke(self, arguments);
+                       return func->InvokeThis(self, arguments);
                else
                        return func->Invoke(arguments);
 
        }
 
-       static inline Value NewFunction(ScriptFrame& frame, const String& name, const std::vector<String>& args,
-           std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression)
+       static inline Value NewFunction(ScriptFrame& frame, const String& name, const std::vector<String>& argNames,
+           const std::map<String, std::unique_ptr<Expression> >& closedVars, const std::shared_ptr<Expression>& expression)
        {
-               return new Function(name, boost::bind(&FunctionWrapper, _1, args,
-                   EvaluateClosedVars(frame, closedVars), expression));
+               auto evaluatedClosedVars = EvaluateClosedVars(frame, closedVars);
+
+               auto wrapper = [argNames, evaluatedClosedVars, expression](const std::vector<Value>& arguments) -> Value {
+                       if (arguments.size() < argNames.size())
+                               BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
+
+                       ScriptFrame *frame = ScriptFrame::GetCurrentFrame();
+
+                       frame->Locals = new Dictionary();
+
+                       if (evaluatedClosedVars)
+                               evaluatedClosedVars->CopyTo(frame->Locals);
+
+                       for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), argNames.size()); i++)
+                               frame->Locals->Set(argNames[i], arguments[i]);
+
+                       return expression->Evaluate(*frame);
+               };
+
+               return new Function(name, wrapper, argNames);
        }
 
-       static inline Value NewApply(ScriptFrame& frame, const String& type, const String& target, const String& name, const boost::shared_ptr<Expression>& filter,
-               const String& package, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, std::map<String, Expression *> *closedVars,
-               bool ignoreOnError, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
+       static inline Value NewApply(ScriptFrame& frame, const String& type, const String& target, const String& name, const std::shared_ptr<Expression>& filter,
+               const String& package, const String& fkvar, const String& fvvar, const std::shared_ptr<Expression>& fterm, const std::map<String, std::unique_ptr<Expression> >& closedVars,
+               bool ignoreOnError, const std::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
        {
                ApplyRule::AddRule(type, target, name, expression, filter, package, fkvar,
                    fvvar, fterm, ignoreOnError, debugInfo, EvaluateClosedVars(frame, closedVars));
@@ -128,20 +143,18 @@ public:
                return Empty;
        }
 
-       static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter,
-               const String& zone, const String& package, bool ignoreOnError, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
+       static inline Value NewObject(ScriptFrame& frame, bool abstract, const Type::Ptr& type, const String& name, const std::shared_ptr<Expression>& filter,
+               const String& zone, const String& package, bool defaultTmpl, bool ignoreOnError, const std::map<String, std::unique_ptr<Expression> >& closedVars, const std::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
        {
                ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo);
 
                String checkName = name;
 
                if (!abstract) {
-                       Type::Ptr ptype = Type::GetByName(type);
-
-                       NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get());
+                       NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
 
                        if (nc)
-                               checkName = nc->MakeName(name, Dictionary::Ptr());
+                               checkName = nc->MakeName(name, nullptr);
                }
 
                if (!checkName.IsEmpty()) {
@@ -149,27 +162,37 @@ public:
 
                        if (oldItem) {
                                std::ostringstream msgbuf;
-                               msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo();
+                               msgbuf << "Object '" << name << "' of type '" << type->GetName() << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo();
                                BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
                        }
                }
 
+               if (filter && !ObjectRule::IsValidSourceType(type->GetName())) {
+                       std::ostringstream msgbuf;
+                       msgbuf << "Object '" << name << "' of type '" << type->GetName() << "' must not have 'assign where' and 'ignore where' rules: " << debugInfo;
+                       BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
+               }
+
                item->SetType(type);
                item->SetName(name);
 
+               if (!abstract)
+                       item->AddExpression(new ImportDefaultTemplatesExpression());
+
                item->AddExpression(new OwnedExpression(expression));
                item->SetAbstract(abstract);
                item->SetScope(EvaluateClosedVars(frame, closedVars));
                item->SetZone(zone);
                item->SetPackage(package);
                item->SetFilter(filter);
+               item->SetDefaultTemplate(defaultTmpl);
                item->SetIgnoreOnError(ignoreOnError);
                item->Compile()->Register();
 
                return Empty;
        }
 
-       static inline ExpressionResult For(ScriptFrame& frame, const String& fkvar, const String& fvvar, const Value& value, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
+       static inline ExpressionResult For(ScriptFrame& frame, const String& fkvar, const String& fvvar, const Value& value, const std::unique_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
        {
                if (value.IsObjectType<Array>()) {
                        if (!fvvar.IsEmpty())
@@ -230,32 +253,14 @@ public:
        }
 
 private:
-       static inline Value FunctionWrapper(const std::vector<Value>& arguments,
-           const std::vector<String>& funcargs, const Dictionary::Ptr& closedVars, const boost::shared_ptr<Expression>& expr)
-       {
-               if (arguments.size() < funcargs.size())
-                       BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
-
-               ScriptFrame *frame = ScriptFrame::GetCurrentFrame();
-
-               if (closedVars)
-                       closedVars->CopyTo(frame->Locals);
-
-               for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs.size()); i++)
-                       frame->Locals->Set(funcargs[i], arguments[i]);
-
-               return expr->Evaluate(*frame);
-       }
-
-       static inline Dictionary::Ptr EvaluateClosedVars(ScriptFrame& frame, std::map<String, Expression *> *closedVars)
+       static inline Dictionary::Ptr EvaluateClosedVars(ScriptFrame& frame, const std::map<String, std::unique_ptr<Expression> >& closedVars)
        {
                Dictionary::Ptr locals;
 
-               if (closedVars) {
+               if (!closedVars.empty()) {
                        locals = new Dictionary();
 
-                       typedef std::pair<String, Expression *> ClosedVar;
-                       for (const ClosedVar& cvar : *closedVars) {
+                       for (const auto& cvar : closedVars) {
                                locals->Set(cvar.first, cvar.second->Evaluate(frame));
                        }
                }