]> granicus.if.org Git - icinga2/commitdiff
Remove the FutureExpression class
authorGunnar Beutner <gunnar@beutner.name>
Mon, 24 Aug 2015 09:04:26 +0000 (11:04 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Mon, 24 Aug 2015 09:04:26 +0000 (11:04 +0200)
fixes #9972

doc/19-language-reference.md
lib/config/config_lexer.ll
lib/config/config_parser.yy
lib/config/configcompiler.cpp
lib/config/configcompiler.hpp
lib/config/expression.cpp
lib/config/expression.hpp

index e7f039fbdaa58db010a0c5742c72c8745feec45f..6c23c242af040bf472e29a5ff069d2ae5db1650b 100644 (file)
@@ -783,6 +783,17 @@ The `continue` and `break` keywords can be used to control how the loop is execu
 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
 breaks out of the loop.
 
+## <a id="throw"></a> Exceptions
+
+Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
+using the `throw` keyword.
+
+Example:
+
+    throw "An error occurred."
+
+There is currently no way for scripts to catch exceptions.
+
 ## <a id="types"></a> Types
 
 All values have a static type. The `typeof` function can be used to determine the type of a value:
index 9455eb1b41642c57e1aca0625335930caf32375e..f03ea8e83c3af3bfaf141210e03656bc803c4695 100644 (file)
@@ -196,6 +196,7 @@ for                         return T_FOR;
 if                             return T_IF;
 else                           return T_ELSE;
 while                          return T_WHILE;
+throw                          return T_THROW;
 =\>                            return T_FOLLOWS;
 \<\<                           return T_SHIFT_LEFT;
 \>\>                           return T_SHIFT_RIGHT;
index f713aefadc2e45bb3025401a34d0b87fe17da2be..f23b377bee60108664c1b3bb16493cdc99b538ac 100644 (file)
@@ -165,6 +165,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
 %token T_IF "if (T_IF)"
 %token T_ELSE "else (T_ELSE)"
 %token T_WHILE "while (T_WHILE)"
+%token T_THROW "throw (T_THROW)"
 %token T_FOLLOWS "=> (T_FOLLOWS)"
 %token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)"
 %token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)"
@@ -566,6 +567,10 @@ lterm: library
 
                $$ = new WhileExpression($3, $5, @$);
        }
+       | T_THROW rterm
+       {
+               $$ = new ThrowExpression($2, @$);
+       }
        | rterm_side_effect
        ;
        
index b678b735d79a93ffe7232754f43630c065d090c4..a9f99d4852c6c772f676a7f50109350324a08329 100644 (file)
@@ -54,7 +54,6 @@ ConfigCompiler::ConfigCompiler(const String& path, std::istream *input,
 ConfigCompiler::~ConfigCompiler(void)
 {
        DestroyScanner();
-       delete m_Input;
 }
 
 /**
@@ -227,17 +226,6 @@ void ConfigCompiler::HandleLibrary(const String& library)
        Loader::LoadExtensionLibrary(library);
 }
 
-void ConfigCompiler::CompileHelper(void)
-{
-       try {
-               m_Promise.set_value(boost::shared_ptr<Expression>(Compile()));
-       } catch (...) {
-               m_Promise.set_exception(boost::current_exception());
-       }
-
-       delete this;
-}
-
 /**
  * Compiles a stream.
  *
@@ -252,25 +240,14 @@ Expression *ConfigCompiler::CompileStream(const String& path,
 
        stream->exceptions(std::istream::badbit);
 
-       ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone, module);
+       ConfigCompiler ctx(path, stream, zone, module);
 
-       if (async) {
-               boost::shared_future<boost::shared_ptr<Expression> > ftr = boost::shared_future<boost::shared_ptr<Expression> >(ctx->m_Promise.get_future());
-
-               Utility::QueueAsyncCallback(boost::bind(&ConfigCompiler::CompileHelper, ctx));
-               return new FutureExpression(ftr);
-       } else {
-               Expression *expr;
-
-               try {
-                       expr = ctx->Compile();
-               } catch (...) {
-                       delete ctx;
-                       throw;
-               }
-
-               delete ctx;
-               return expr;
+       try {
+               return ctx.Compile();
+       } catch (const ScriptError& ex) {
+               return new ThrowExpression(MakeLiteral(ex.what()), ex.GetDebugInfo());
+       } catch (const std::exception& ex) {
+               return new ThrowExpression(MakeLiteral(DiagnosticInformation(ex)));
        }
 }
 
@@ -285,10 +262,9 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async,
 {
        CONTEXT("Compiling configuration file '" + path + "'");
 
-       std::ifstream *stream = new std::ifstream();
-       stream->open(path.CStr(), std::ifstream::in);
+       std::ifstream stream(path.CStr(), std::ifstream::in);
 
-       if (!*stream)
+       if (!stream)
                BOOST_THROW_EXCEPTION(posix_error()
                        << boost::errinfo_api_function("std::ifstream::open")
                        << boost::errinfo_errno(errno)
@@ -297,7 +273,7 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async,
        Log(LogInformation, "ConfigCompiler")
            << "Compiling config file: " << path;
 
-       return CompileStream(path, stream, async, zone, module);
+       return CompileStream(path, &stream, async, zone, module);
 }
 
 /**
@@ -310,8 +286,8 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async,
 Expression *ConfigCompiler::CompileText(const String& path, const String& text,
     bool async, const String& zone, const String& module)
 {
-       std::stringstream *stream = new std::stringstream(text);
-       return CompileStream(path, stream, async, zone, module);
+       std::stringstream stream(text);
+       return CompileStream(path, &stream, async, zone, module);
 }
 
 /**
@@ -378,6 +354,7 @@ const std::vector<String>& ConfigCompiler::GetKeywords(void)
                keywords.push_back("if");
                keywords.push_back("else");
                keywords.push_back("while");
+               keywords.push_back("throw");
        }
 
        return keywords;
index d1513a24d0c89a3c656a526242e7d25fc0b5e602..3a9a08257babec14eb2c82f98e760b9433c49ade 100644 (file)
@@ -135,8 +135,6 @@ private:
        void InitializeScanner(void);
        void DestroyScanner(void);
 
-       void CompileHelper(void);
-
        void HandleIncludeZone(const String& tag, const String& path, const String& pattern, std::vector<Expression *>& expressions);
 
 public:
index 65d910bcc4878fd43323ffc67315a80a20be31c1..58a65de7766e44733a313a5967c562ec4816877b 100644 (file)
@@ -702,6 +702,14 @@ void icinga::BindToScope(Expression *& expr, ScopeSpecifier scopeSpec)
        }
 }
 
+ExpressionResult ThrowExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
+{
+       ExpressionResult messageres = m_Message->Evaluate(frame);
+       CHECK_RESULT(messageres);
+       Value message = messageres.GetValue();
+       BOOST_THROW_EXCEPTION(ScriptError(message, m_DebugInfo));
+}
+
 ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
 {
        if (frame.Sandboxed)
index b4bb1eb6fbd455195f90bfe0618c7592e0e6f37e..6c75e3cfcef029ed237610b58dd0db9e36ffee14 100644 (file)
@@ -224,28 +224,6 @@ private:
        boost::shared_ptr<Expression> m_Expression;
 };
 
-class I2_CONFIG_API FutureExpression : public Expression
-{
-public:
-       FutureExpression(const boost::shared_future<boost::shared_ptr<Expression> >& future)
-               : m_Future(future)
-       { }
-
-protected:
-       virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override
-       {
-               return m_Future.get()->DoEvaluate(frame, dhint);
-       }
-
-       virtual const DebugInfo& GetDebugInfo(void) const override
-       {
-               return m_Future.get()->GetDebugInfo();
-       }
-
-private:
-       mutable boost::shared_future<boost::shared_ptr<Expression> > m_Future;
-};
-
 class I2_CONFIG_API LiteralExpression : public Expression
 {
 public:
@@ -767,6 +745,25 @@ protected:
 
 I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec);
 
+class I2_CONFIG_API ThrowExpression : public DebuggableExpression
+{
+public:
+       ThrowExpression(Expression *message, const DebugInfo& debugInfo = DebugInfo())
+               : DebuggableExpression(debugInfo), m_Message(message)
+       { }
+
+       ~ThrowExpression(void)
+       {
+               delete m_Message;
+       }
+
+protected:
+       virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
+
+private:
+       Expression *m_Message;
+};
+
 class I2_CONFIG_API ImportExpression : public DebuggableExpression
 {
 public: