]> granicus.if.org Git - icinga2/commitdiff
DSL: warn on x=y if x is a global variable
authorAlexander A. Klimov <alexander.klimov@icinga.com>
Tue, 27 Aug 2019 11:19:05 +0000 (13:19 +0200)
committerAlexander A. Klimov <alexander.klimov@icinga.com>
Tue, 27 Aug 2019 11:30:02 +0000 (13:30 +0200)
lib/config/expression.cpp

index 814a153047881c606298f160df2456fa1a89c3bc..b02f2b73cfa67688a4e6b8ae2c9a49eb88a3ea88 100644 (file)
@@ -552,6 +552,58 @@ ExpressionResult GetScopeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *d
                VERIFY(!"Invalid scope.");
 }
 
+static inline
+void WarnOnImplicitlySetGlobalVar(const std::unique_ptr<Expression>& setLhs, const Value& setLhsParent, CombinedSetOp setOp, const DebugInfo& debug)
+{
+       auto var (dynamic_cast<VariableExpression*>(setLhs.get()));
+
+       if (var && setLhsParent.IsObject()) {
+               auto ns (dynamic_pointer_cast<Namespace>(setLhsParent.Get<Object::Ptr>()));
+
+               if (ns && ns == ScriptGlobal::GetGlobals()) {
+                       const char *opStr = nullptr;
+
+                       switch (setOp) {
+                               case OpSetLiteral:
+                                       opStr = "=";
+                                       break;
+                               case OpSetAdd:
+                                       opStr = "+=";
+                                       break;
+                               case OpSetSubtract:
+                                       opStr = "-=";
+                                       break;
+                               case OpSetMultiply:
+                                       opStr = "*=";
+                                       break;
+                               case OpSetDivide:
+                                       opStr = "/=";
+                                       break;
+                               case OpSetModulo:
+                                       opStr = "%=";
+                                       break;
+                               case OpSetXor:
+                                       opStr = "^=";
+                                       break;
+                               case OpSetBinaryAnd:
+                                       opStr = "&=";
+                                       break;
+                               case OpSetBinaryOr:
+                                       opStr = "|=";
+                                       break;
+                               default:
+                                       VERIFY(!"Invalid opcode.");
+                       }
+
+                       auto varName (var->GetVariable());
+
+                       Log(LogWarning, "config")
+                               << "Global variable '" << varName << "' has been set implicitly via '" << varName << ' ' << opStr << " ...' " << debug << "."
+                               " Please set it explicitly via 'globals." << varName << ' ' << opStr << " ...' instead.";
+               }
+       }
+}
+
 ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
 {
        if (frame.Sandboxed)
@@ -610,6 +662,8 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
                        delete psdhint;
        }
 
+       WarnOnImplicitlySetGlobalVar(m_Operand1, parent, m_Op, m_DebugInfo);
+
        return Empty;
 }