]> granicus.if.org Git - icinga2/commitdiff
Implement support for the "package" keyword.
authorGunnar Beutner <gunnar@beutner.name>
Sat, 3 May 2014 18:01:23 +0000 (20:01 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 8 May 2014 07:13:04 +0000 (09:13 +0200)
Refs #6107

lib/base/dynamicobject.ti
lib/config/aexpression.cpp
lib/config/base-type.conf
lib/config/config_lexer.ll
lib/config/config_parser.yy
lib/config/configitem.cpp
lib/config/configitem.h
lib/config/configitembuilder.cpp
lib/config/configitembuilder.h

index 04ac40d26c5cb2c7344521f9602a3c66361c9def..6adbcc5ef8e09df98396ed1fc8d9c45976f63fae 100644 (file)
@@ -20,6 +20,7 @@ abstract class DynamicObject
                }}}
        };
        [config, get_protected] String type (TypeName);
+       [config] String package;
        [config, get_protected] Array::Ptr templates;
        [config] Dictionary::Ptr methods;
        [config] Dictionary::Ptr vars (VarsRaw);
index 81ba0290fbdf838ab6006f3c026460d121127c70..8d152188f27d648b8a491a004448edd9e546df64 100644 (file)
@@ -523,6 +523,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca
        String type = left->Get(1);
        AExpression::Ptr aname = left->Get(2);
        AExpression::Ptr filter = left->Get(3);
+       String package = left->Get(4);
 
        String name = aname->Evaluate(locals);
 
@@ -560,6 +561,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca
        item->AddExpression(exprl);
        item->SetAbstract(abstract);
        item->SetScope(locals);
+       item->SetPackage(package);
        item->Compile()->Register();
 
        ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals);
index 75c3a6d5f6aa36f386d9b338444879c0223f9924..46ee8b606e8f8eec615b94afe67ff281ae43341f 100644 (file)
@@ -24,6 +24,8 @@
        %require "type",
        %attribute %string "type",
 
+       %attribute %string "package",
+
        %attribute %array "templates" {
                %attribute %string "*"
        },
index 017affc0a95062397acf6683c495a5e0a54ce217..c7564e46a0a248e84639d56e9a8b7120d2c74618 100644 (file)
@@ -231,6 +231,7 @@ ignore                              return T_IGNORE;
 function                       return T_FUNCTION;
 lambda                         return T_LAMBDA;
 return                         return T_RETURN;
+package                                return T_PACKAGE;
 \<\<                           { yylval->op = &AExpression::OpShiftLeft; return T_SHIFT_LEFT; }
 \>\>                           { yylval->op = &AExpression::OpShiftRight; return T_SHIFT_RIGHT; }
 \<=                            { yylval->op = &AExpression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; }
index 841105eb736641ed1d49954e886802aa6c3e5f1c..4dd436dbb80a28313bdefac42aa43b62eff7007b 100644 (file)
@@ -160,6 +160,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
 %token T_FUNCTION "function (T_FUNCTION)"
 %token T_LAMBDA "lambda (T_LAMBDA)"
 %token T_RETURN "return (T_RETURN)"
+%token T_PACKAGE "package (T_PACKAGE)"
 
 %type <text> identifier
 %type <array> rterm_items
@@ -213,6 +214,8 @@ static std::stack<TypeRuleList::Ptr> m_RuleLists;
 static ConfigType::Ptr m_Type;
 
 static Dictionary::Ptr m_ModuleScope;
+static String m_Package;
+static int m_StatementNum;
 
 static bool m_Apply;
 static bool m_ObjectAssign;
@@ -223,6 +226,10 @@ static AExpression::Ptr m_Ignore;
 void ConfigCompiler::Compile(void)
 {
        m_ModuleScope = make_shared<Dictionary>();
+       
+       String parentPackage = m_Package;
+       int parentStatementNum = m_StatementNum;
+       m_StatementNum = 0;
 
        try {
                yyparse(this);
@@ -232,6 +239,9 @@ void ConfigCompiler::Compile(void)
        } catch (const std::exception& ex) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
        }
+
+       m_Package = parentPackage;
+       m_StatementNum = parentStatementNum;
 }
 
 #define scanner (context->GetScanner())
@@ -243,13 +253,54 @@ statements: /* empty */
        | statements statement
        ;
 
-statement: type | include | include_recursive | library | constant | newlines
+statement: type | package | include | include_recursive | library | constant
+       {
+               m_StatementNum++;
+       }
+       | newlines
        { }
        | lterm
        {
                AExpression::Ptr aexpr = *$1;
                aexpr->Evaluate(m_ModuleScope);
                delete $1;
+
+               m_StatementNum++;
+       }
+       ;
+
+package: T_PACKAGE rterm sep
+       {
+               AExpression::Ptr aexpr = *$2;
+               delete $2;
+
+               if (!m_Package.IsEmpty())
+                       BOOST_THROW_EXCEPTION(std::invalid_argument("Package name cannot be changed once it's been set."));
+
+               if (m_StatementNum != 0)
+                       BOOST_THROW_EXCEPTION(std::invalid_argument("'package' directive must be the first statement in a file."));
+
+               m_Package = aexpr->Evaluate(m_ModuleScope);
+       }
+       | T_PACKAGE rterm rterm_scope sep
+       {
+               AExpression::Ptr aexpr = *$2;
+               delete $2;
+
+               AExpression::Ptr ascope = *$3;
+               delete $3;
+
+               if (!m_Package.IsEmpty())
+                       BOOST_THROW_EXCEPTION(std::invalid_argument("Package name cannot be changed once it's been set."));
+
+               m_Package = aexpr->Evaluate(m_ModuleScope);
+
+               try {
+                       ascope->Evaluate(m_ModuleScope);
+                       m_Package = String();
+               } catch (...) {
+                       m_Package = String();
+               }
        }
        ;
 
@@ -433,7 +484,7 @@ object:
                m_Assign = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
                m_Ignore = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
        }
-       object_declaration identifier rterm rterm_scope sep
+       object_declaration identifier rterm rterm_scope
        {
                m_ObjectAssign = false;
 
@@ -460,6 +511,8 @@ object:
 
                args->Add(filter);
 
+               args->Add(m_Package);
+
                $$ = new Value(make_shared<AExpression>(&AExpression::OpObject, args, exprl, DebugInfoRange(@2, @5)));
 
                m_Assign.reset();
index 194fa9c270c21a131f07e2a7be6c3a0d7dd59d04..e405d8dff21f21de9a79d7c96addb1749ee3e6c7 100644 (file)
@@ -49,10 +49,11 @@ ConfigItem::ItemMap ConfigItem::m_Items;
  */
 ConfigItem::ConfigItem(const String& type, const String& name,
     bool abstract, const AExpression::Ptr& exprl,
-    const DebugInfo& debuginfo, const Dictionary::Ptr& scope)
+    const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
+    const String& package)
        : m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
          m_ExpressionList(exprl), m_DebugInfo(debuginfo),
-         m_Scope(scope)
+         m_Scope(scope), m_Package(package)
 {
 }
 
index 370195ec88304970ae2094e1531d2c0e39d8085f..743d111c2a1174d39752855f668e2a0984372a92 100644 (file)
@@ -39,7 +39,7 @@ public:
 
        ConfigItem(const String& type, const String& name, bool abstract,
            const AExpression::Ptr& exprl, const DebugInfo& debuginfo,
-           const Dictionary::Ptr& scope);
+           const Dictionary::Ptr& scope, const String& package);
 
        String GetType(void) const;
        String GetName(void) const;
@@ -57,6 +57,8 @@ public:
 
        Dictionary::Ptr GetScope(void) const;
 
+       String GetPackage(void) const;
+
        static ConfigItem::Ptr GetObject(const String& type,
            const String& name);
        static bool HasObject(const String& type, const String& name);
@@ -79,6 +81,7 @@ private:
                                       items. */
        DebugInfo m_DebugInfo; /**< Debug information. */
        Dictionary::Ptr m_Scope; /**< variable scope. */
+       String m_Package; /**< The package. */
 
        DynamicObject::Ptr m_Object;
 
index 4a6a8d6dda94c3ffc72e6c0608875b034c94ec62..3d29016548d9ccf5186229a1f191db2ff6700ea2 100644 (file)
@@ -60,6 +60,11 @@ void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
        m_Scope = scope;
 }
 
+void ConfigItemBuilder::SetPackage(const String& package)
+{
+       m_Package = package;
+}
+
 void ConfigItemBuilder::AddExpression(const AExpression::Ptr& expr)
 {
        m_Expressions->Add(expr);
@@ -99,5 +104,5 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
        AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
 
        return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
-           m_DebugInfo, m_Scope);
+           m_DebugInfo, m_Scope, m_Package);
 }
index 14537f1d852c878fda578de1d6e3301817f10145..c9609a9cd3aaf21b8adf6efe4dc519bcda57ee3d 100644 (file)
@@ -46,6 +46,7 @@ public:
        void SetName(const String& name);
        void SetAbstract(bool abstract);
        void SetScope(const Dictionary::Ptr& scope);
+       void SetPackage(const String& name);
 
        void AddExpression(const AExpression::Ptr& expr);
 
@@ -58,6 +59,7 @@ private:
        Array::Ptr m_Expressions; /**< Expressions for this item. */
        DebugInfo m_DebugInfo; /**< Debug information. */
        Dictionary::Ptr m_Scope; /**< variable scope. */
+       String m_Package; /**< The package. */
 };
 
 }