Remove the FutureExpression class

fixes #9972
This commit is contained in:
Gunnar Beutner 2015-08-24 11:04:26 +02:00
parent 380b1275b7
commit 6a8f890e7c
7 changed files with 57 additions and 60 deletions

View 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 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
breaks out of the loop. 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 ## <a id="types"></a> Types
All values have a static type. The `typeof` function can be used to determine the type of a value: All values have a static type. The `typeof` function can be used to determine the type of a value:

View File

@ -196,6 +196,7 @@ for return T_FOR;
if return T_IF; if return T_IF;
else return T_ELSE; else return T_ELSE;
while return T_WHILE; while return T_WHILE;
throw return T_THROW;
=\> return T_FOLLOWS; =\> return T_FOLLOWS;
\<\< return T_SHIFT_LEFT; \<\< return T_SHIFT_LEFT;
\>\> return T_SHIFT_RIGHT; \>\> return T_SHIFT_RIGHT;

View File

@ -165,6 +165,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
%token T_IF "if (T_IF)" %token T_IF "if (T_IF)"
%token T_ELSE "else (T_ELSE)" %token T_ELSE "else (T_ELSE)"
%token T_WHILE "while (T_WHILE)" %token T_WHILE "while (T_WHILE)"
%token T_THROW "throw (T_THROW)"
%token T_FOLLOWS "=> (T_FOLLOWS)" %token T_FOLLOWS "=> (T_FOLLOWS)"
%token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)" %token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)"
%token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)" %token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)"
@ -566,6 +567,10 @@ lterm: library
$$ = new WhileExpression($3, $5, @$); $$ = new WhileExpression($3, $5, @$);
} }
| T_THROW rterm
{
$$ = new ThrowExpression($2, @$);
}
| rterm_side_effect | rterm_side_effect
; ;

View File

@ -54,7 +54,6 @@ ConfigCompiler::ConfigCompiler(const String& path, std::istream *input,
ConfigCompiler::~ConfigCompiler(void) ConfigCompiler::~ConfigCompiler(void)
{ {
DestroyScanner(); DestroyScanner();
delete m_Input;
} }
/** /**
@ -227,17 +226,6 @@ void ConfigCompiler::HandleLibrary(const String& library)
Loader::LoadExtensionLibrary(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. * Compiles a stream.
* *
@ -252,25 +240,14 @@ Expression *ConfigCompiler::CompileStream(const String& path,
stream->exceptions(std::istream::badbit); stream->exceptions(std::istream::badbit);
ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone, module); ConfigCompiler ctx(path, stream, zone, module);
if (async) { try {
boost::shared_future<boost::shared_ptr<Expression> > ftr = boost::shared_future<boost::shared_ptr<Expression> >(ctx->m_Promise.get_future()); return ctx.Compile();
} catch (const ScriptError& ex) {
Utility::QueueAsyncCallback(boost::bind(&ConfigCompiler::CompileHelper, ctx)); return new ThrowExpression(MakeLiteral(ex.what()), ex.GetDebugInfo());
return new FutureExpression(ftr); } catch (const std::exception& ex) {
} else { return new ThrowExpression(MakeLiteral(DiagnosticInformation(ex)));
Expression *expr;
try {
expr = ctx->Compile();
} catch (...) {
delete ctx;
throw;
}
delete ctx;
return expr;
} }
} }
@ -285,10 +262,9 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async,
{ {
CONTEXT("Compiling configuration file '" + path + "'"); CONTEXT("Compiling configuration file '" + path + "'");
std::ifstream *stream = new std::ifstream(); std::ifstream stream(path.CStr(), std::ifstream::in);
stream->open(path.CStr(), std::ifstream::in);
if (!*stream) if (!stream)
BOOST_THROW_EXCEPTION(posix_error() BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("std::ifstream::open") << boost::errinfo_api_function("std::ifstream::open")
<< boost::errinfo_errno(errno) << boost::errinfo_errno(errno)
@ -297,7 +273,7 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async,
Log(LogInformation, "ConfigCompiler") Log(LogInformation, "ConfigCompiler")
<< "Compiling config file: " << path; << "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, Expression *ConfigCompiler::CompileText(const String& path, const String& text,
bool async, const String& zone, const String& module) bool async, const String& zone, const String& module)
{ {
std::stringstream *stream = new std::stringstream(text); std::stringstream stream(text);
return CompileStream(path, stream, async, zone, module); 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("if");
keywords.push_back("else"); keywords.push_back("else");
keywords.push_back("while"); keywords.push_back("while");
keywords.push_back("throw");
} }
return keywords; return keywords;

View File

@ -135,8 +135,6 @@ private:
void InitializeScanner(void); void InitializeScanner(void);
void DestroyScanner(void); void DestroyScanner(void);
void CompileHelper(void);
void HandleIncludeZone(const String& tag, const String& path, const String& pattern, std::vector<Expression *>& expressions); void HandleIncludeZone(const String& tag, const String& path, const String& pattern, std::vector<Expression *>& expressions);
public: public:

View 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 ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{ {
if (frame.Sandboxed) if (frame.Sandboxed)

View File

@ -224,28 +224,6 @@ private:
boost::shared_ptr<Expression> m_Expression; 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 class I2_CONFIG_API LiteralExpression : public Expression
{ {
public: public:
@ -767,6 +745,25 @@ protected:
I2_CONFIG_API void BindToScope(Expression *& expr, ScopeSpecifier scopeSpec); 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 class I2_CONFIG_API ImportExpression : public DebuggableExpression
{ {
public: public: