mirror of https://github.com/Icinga/icinga2.git
parent
4d401a7cc5
commit
b016003eb5
|
@ -242,7 +242,7 @@ Value FunctionCallExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||
return Empty;
|
||||
|
||||
Value index = m_IName[i]->Evaluate(frame);
|
||||
result = VMOps::GetField(result, index);
|
||||
result = VMOps::GetField(result, index, GetDebugInfo());
|
||||
|
||||
if (i == m_IName.size() - 2) {
|
||||
if (!result.IsObject())
|
||||
|
@ -349,7 +349,7 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||
break;
|
||||
}
|
||||
|
||||
object = VMOps::GetField(parent, tempindex);
|
||||
object = VMOps::GetField(parent, tempindex, GetDebugInfo());
|
||||
|
||||
if (i != m_Indexer.size() - 1 && object.IsEmpty()) {
|
||||
object = new Dictionary();
|
||||
|
@ -424,7 +424,7 @@ Value IndexerExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||
|
||||
Value ImportExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
String type = VMOps::GetField(frame.Self, "type");
|
||||
String type = VMOps::GetField(frame.Self, "type", GetDebugInfo());
|
||||
Value name = m_Name->Evaluate(frame);
|
||||
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
return func->Invoke(arguments);
|
||||
}
|
||||
|
||||
static inline Value Indexer(VMFrame& frame, const std::vector<Expression *>& indexer)
|
||||
static inline Value Indexer(VMFrame& frame, const std::vector<Expression *>& indexer, const DebugInfo& debugInfo = DebugInfo())
|
||||
{
|
||||
Value result = indexer[0]->Evaluate(frame);
|
||||
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
return Empty;
|
||||
|
||||
Value index = indexer[i]->Evaluate(frame);
|
||||
result = GetField(result, index);
|
||||
result = GetField(result, index, debugInfo);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -188,6 +188,16 @@ public:
|
|||
frame.Locals->Set(fkvar, value);
|
||||
expression->Evaluate(frame);
|
||||
}
|
||||
} else if (value.IsString()) {
|
||||
if (!fvvar.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot use dictionary iterator for string.", debugInfo));
|
||||
|
||||
String str = value;
|
||||
|
||||
BOOST_FOREACH(char ch, str) {
|
||||
frame.Locals->Set(fkvar, String(1, ch));
|
||||
expression->Evaluate(frame);
|
||||
}
|
||||
} else if (value.IsObjectType<Dictionary>()) {
|
||||
if (fvvar.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot use array iterator for dictionary.", debugInfo));
|
||||
|
@ -200,8 +210,7 @@ public:
|
|||
frame.Locals->Set(fvvar, kv.second);
|
||||
expression->Evaluate(frame);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Invalid type in for expression: " + value.GetTypeName(), debugInfo));
|
||||
|
||||
return Empty;
|
||||
|
@ -223,21 +232,34 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
static inline Value GetField(const Object::Ptr& context, const String& field)
|
||||
static inline Value GetField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo())
|
||||
{
|
||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
||||
if (context.IsString()) {
|
||||
String str = context;
|
||||
int index = Convert::ToLong(field);
|
||||
if (index < 0 || index >= str.GetLength())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Index is out of bounds", debugInfo));
|
||||
return String(1, str[index]);
|
||||
}
|
||||
|
||||
if (!context.IsObject())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Tried to access invalid field '" + field + "' on object of type '" + context.GetTypeName() + "'", debugInfo));
|
||||
|
||||
Object::Ptr object = context;
|
||||
|
||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(object);
|
||||
|
||||
if (dict)
|
||||
return dict->Get(field);
|
||||
|
||||
Array::Ptr arr = dynamic_pointer_cast<Array>(context);
|
||||
Array::Ptr arr = dynamic_pointer_cast<Array>(object);
|
||||
|
||||
if (arr) {
|
||||
int index = Convert::ToLong(field);
|
||||
return arr->Get(index);
|
||||
}
|
||||
|
||||
Type::Ptr type = context->GetReflectionType();
|
||||
Type::Ptr type = object->GetReflectionType();
|
||||
|
||||
if (!type)
|
||||
return Empty;
|
||||
|
@ -247,7 +269,7 @@ public:
|
|||
if (fid == -1)
|
||||
return Empty;
|
||||
|
||||
return context->GetField(fid);
|
||||
return object->GetField(fid);
|
||||
}
|
||||
|
||||
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value, const DebugInfo& debugInfo = DebugInfo())
|
||||
|
|
|
@ -294,6 +294,10 @@ BOOST_AUTO_TEST_CASE(advanced)
|
|||
expr = ConfigCompiler::CompileText("<test>", "7 & 15 > 6");
|
||||
BOOST_CHECK(expr->Evaluate(frame));
|
||||
delete expr;
|
||||
|
||||
expr = ConfigCompiler::CompileText("<test>", "s = \"test\"; s[2]");
|
||||
BOOST_CHECK(expr->Evaluate(frame) == "s");
|
||||
delete expr;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Reference in New Issue