Пример #1
0
	static inline ExpressionResult For(ScriptFrame& frame, const String& fkvar, const String& fvvar, const Value& value, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
	{
		if (value.IsObjectType<Array>()) {
			if (!fvvar.IsEmpty())
				BOOST_THROW_EXCEPTION(ScriptError("Cannot use dictionary iterator for array.", debugInfo));

			Array::Ptr arr = value;

			for (Array::SizeType i = 0; i < arr->GetLength(); i++) {
				frame.Locals->Set(fkvar, arr->Get(i));
				ExpressionResult res = expression->Evaluate(frame);
				CHECK_RESULT_LOOP(res);
			}
		} else if (value.IsObjectType<Dictionary>()) {
			if (fvvar.IsEmpty())
				BOOST_THROW_EXCEPTION(ScriptError("Cannot use array iterator for dictionary.", debugInfo));

			Dictionary::Ptr dict = value;
			std::vector<String> keys;

			{
				ObjectLock olock(dict);
				BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
					keys.push_back(kv.first);
				}
			}

			BOOST_FOREACH(const String& key, keys) {
				frame.Locals->Set(fkvar, key);
				frame.Locals->Set(fvvar, dict->Get(key));
				ExpressionResult res = expression->Evaluate(frame);
				CHECK_RESULT_LOOP(res);
			}
Пример #2
0
/**
 * Executes the auto completion script via HTTP and returns HTTP and user errors.
 *
 * @param session Local session handler.
 * @param command The auto completion string.
 * @param sandboxed Whether to run this sandboxed.
 * @return Result value, also contains user errors.
 */
Array::Ptr ConsoleCommand::AutoCompleteScript(const String& session, const String& command, bool sandboxed)
{
	/* Extend the url parameters for the request. */
	l_Url->SetPath({ "v1", "console", "auto-complete-script" });

	l_Url->SetQuery({
		{"session",   session},
		{"command",   command},
		{"sandboxed", sandboxed ? "1" : "0"}
	});

	Dictionary::Ptr jsonResponse = SendRequest();

	/* Extract the result, and handle user input errors too. */
	Array::Ptr results = jsonResponse->Get("results");
	Array::Ptr suggestions;

	if (results && results->GetLength() > 0) {
		Dictionary::Ptr resultInfo = results->Get(0);

		if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) {
			suggestions = resultInfo->Get("suggestions");
		} else {
			String errorMessage = resultInfo->Get("status");
			BOOST_THROW_EXCEPTION(ScriptError(errorMessage));
		}
	}

	return suggestions;
}
Пример #3
0
void ApiClient::ExecuteScriptHttpCompletionCallback(HttpRequest& request,
	HttpResponse& response, const ExecuteScriptCompletionCallback& callback)
{
	Dictionary::Ptr result;

	String body;
	char buffer[1024];
	size_t count;

	while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0)
		body += String(buffer, buffer + count);

	try {
		if (response.StatusCode < 200 || response.StatusCode > 299) {
			std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body;

			BOOST_THROW_EXCEPTION(ScriptError(message));
		}

		result = JsonDecode(body);

		Array::Ptr results = result->Get("results");
		Value result;
		String errorMessage = "Unexpected result from API.";

		if (results && results->GetLength() > 0) {
			Dictionary::Ptr resultInfo = results->Get(0);
			errorMessage = resultInfo->Get("status");

			if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) {
				result = resultInfo->Get("result");
			} else {
				DebugInfo di;
				Dictionary::Ptr debugInfo = resultInfo->Get("debug_info");
				if (debugInfo) {
					di.Path = debugInfo->Get("path");
					di.FirstLine = debugInfo->Get("first_line");
					di.FirstColumn = debugInfo->Get("first_column");
					di.LastLine = debugInfo->Get("last_line");
					di.LastColumn = debugInfo->Get("last_column");
				}
				bool incompleteExpression = resultInfo->Get("incomplete_expression");
				BOOST_THROW_EXCEPTION(ScriptError(errorMessage, di, incompleteExpression));
			}
		}

		callback(boost::exception_ptr(), result);
	} catch (const std::exception&) {
		callback(boost::current_exception(), Empty);
	}
}
Пример #4
0
Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& key)
{
	Value varr = params->Get(key);

	if (!varr.IsObjectType<Array>())
		return varr;

	Array::Ptr arr = varr;

	if (arr->GetLength() == 0)
		return Empty;
	else
		return arr->Get(arr->GetLength() - 1);
}
Пример #5
0
static Value ArrayReduce(const Function::Ptr& function)
{
	ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
	Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);

	if (vframe->Sandboxed && !function->IsSideEffectFree())
		BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free."));

	if (self->GetLength() == 0)
		return Empty;

	Value result = self->Get(0);

	ObjectLock olock(self);
	for (size_t i = 1; i < self->GetLength(); i++) {
		std::vector<Value> args;
		args.push_back(result);
		args.push_back(self->Get(i));
		result = function->Invoke(args);
	}

	return result;
}
Пример #6
0
bool ObjectListUtility::PrintObject(std::ostream& fp, bool& first, const String& message, std::map<String, int>& type_count, const String& name_filter, const String& type_filter)
{
	Dictionary::Ptr object = JsonDecode(message);

	Dictionary::Ptr properties = object->Get("properties");

	String internal_name = properties->Get("__name");
	String name = object->Get("name");
	String type = object->Get("type");

	if (!name_filter.IsEmpty() && !Utility::Match(name_filter, name) && !Utility::Match(name_filter, internal_name))
		return false;
	if (!type_filter.IsEmpty() && !Utility::Match(type_filter, type))
		return false;

	if (first)
		first = false;
	else
		fp << "\n";

	Dictionary::Ptr debug_hints = object->Get("debug_hints");

	fp << "Object '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << internal_name << ConsoleColorTag(Console_Normal) << "'";
	fp << " of type '" << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << type << ConsoleColorTag(Console_Normal) << "':\n";

	Array::Ptr di = object->Get("debug_info");

	if (di) {
		fp << ConsoleColorTag(Console_ForegroundCyan) << "  % declared in '" << di->Get(0) << "', lines "
			<< di->Get(1) << ":" << di->Get(2) << "-" << di->Get(3) << ":" << di->Get(4) << ConsoleColorTag(Console_Normal) << "\n";
	}

	PrintProperties(fp, properties, debug_hints, 2);

	type_count[type]++;
	return true;
}
Пример #7
0
/**
 * Executes the DSL script via HTTP and returns HTTP and user errors.
 *
 * @param session Local session handler.
 * @param command The DSL string.
 * @param sandboxed Whether to run this sandboxed.
 * @return Result value, also contains user errors.
 */
Value ConsoleCommand::ExecuteScript(const String& session, const String& command, bool sandboxed)
{
	/* Extend the url parameters for the request. */
	l_Url->SetPath({"v1", "console", "execute-script"});

	l_Url->SetQuery({
		{"session",   session},
		{"command",   command},
		{"sandboxed", sandboxed ? "1" : "0"}
	});

	Dictionary::Ptr jsonResponse = SendRequest();

	/* Extract the result, and handle user input errors too. */
	Array::Ptr results = jsonResponse->Get("results");
	Value result;

	if (results && results->GetLength() > 0) {
		Dictionary::Ptr resultInfo = results->Get(0);

		if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) {
			result = resultInfo->Get("result");
		} else {
			String errorMessage = resultInfo->Get("status");

			DebugInfo di;
			Dictionary::Ptr debugInfo = resultInfo->Get("debug_info");

			if (debugInfo) {
				di.Path = debugInfo->Get("path");
				di.FirstLine = debugInfo->Get("first_line");
				di.FirstColumn = debugInfo->Get("first_column");
				di.LastLine = debugInfo->Get("last_line");
				di.LastColumn = debugInfo->Get("last_column");
			}

			bool incompleteExpression = resultInfo->Get("incomplete_expression");
			BOOST_THROW_EXCEPTION(ScriptError(errorMessage, di, incompleteExpression));
		}
	}

	return result;
}
Пример #8
0
void ApiClient::AutocompleteScriptHttpCompletionCallback(HttpRequest& request,
	HttpResponse& response, const AutocompleteScriptCompletionCallback& callback)
{
	Dictionary::Ptr result;

	String body;
	char buffer[1024];
	size_t count;

	while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0)
		body += String(buffer, buffer + count);

	try {
		if (response.StatusCode < 200 || response.StatusCode > 299) {
			std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body;

			BOOST_THROW_EXCEPTION(ScriptError(message));
		}

		result = JsonDecode(body);

		Array::Ptr results = result->Get("results");
		Array::Ptr suggestions;
		String errorMessage = "Unexpected result from API.";

		if (results && results->GetLength() > 0) {
			Dictionary::Ptr resultInfo = results->Get(0);
			errorMessage = resultInfo->Get("status");

			if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299)
				suggestions = resultInfo->Get("suggestions");
			else
				BOOST_THROW_EXCEPTION(ScriptError(errorMessage));
		}

		callback(boost::exception_ptr(), suggestions);
	} catch (const std::exception&) {
		callback(boost::current_exception(), nullptr);
	}
}
Пример #9
0
static Value ArrayGet(int index)
{
	ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
	Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
	return self->Get(index);
}
Пример #10
0
String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, StackTrace *stack, ContextTrace *context)
{
	std::ostringstream result;

	String message = ex.what();

	const ValidationError *vex = dynamic_cast<const ValidationError *>(&ex);

	if (message.IsEmpty())
		result << boost::diagnostic_information(ex);
	else
		result << "Error: " << message;

	const ScriptError *dex = dynamic_cast<const ScriptError *>(&ex);

	if (dex && !dex->GetDebugInfo().Path.IsEmpty()) {
		result << "\nLocation:\n";
		ShowCodeFragment(result, dex->GetDebugInfo());
	}

	if (vex) {
		DebugInfo di;

		ConfigObject::Ptr dobj = vex->GetObject();
		if (dobj)
			di = dobj->GetDebugInfo();

		Dictionary::Ptr currentHint = vex->GetDebugHint();
		Array::Ptr messages;

		if (currentHint) {
			BOOST_FOREACH(const String& attr, vex->GetAttributePath()) {
				Dictionary::Ptr props = currentHint->Get("properties");

				if (!props)
					break;

				currentHint = props->Get(attr);

				if (!currentHint)
					break;

				messages = currentHint->Get("messages");
			}
		}

		if (messages && messages->GetLength() > 0) {
			Array::Ptr message = messages->Get(messages->GetLength() - 1);

			di.Path = message->Get(1);
			di.FirstLine = message->Get(2);
			di.FirstColumn = message->Get(3);
			di.LastLine = message->Get(4);
			di.LastColumn = message->Get(5);
		}

		if (!di.Path.IsEmpty()) {
			result << "\nLocation:\n";
			ShowCodeFragment(result, di);
		}
	}

	const user_error *uex = dynamic_cast<const user_error *>(&ex);
	const posix_error *pex = dynamic_cast<const posix_error *>(&ex);

	if (!uex && !pex && verbose) {
		const StackTrace *st = boost::get_error_info<StackTraceErrorInfo>(ex);

		if (st) {
			result << *st;
		} else {
			result << std::endl;

			if (!stack)
				stack = GetLastExceptionStack();

			if (stack)
				result << *stack;

		}

		if (boost::get_error_info<ContextTraceErrorInfo>(ex) == NULL) {
			result << std::endl;

			if (!context)
				context = GetLastExceptionContext();

			if (context)
				result << *context;
		}
	}

	return result.str();
}
Пример #11
0
void ObjectListUtility::PrintHint(std::ostream& fp, const Array::Ptr& msg, int indent)
{
	fp << std::setw(indent) << " " << ConsoleColorTag(Console_ForegroundCyan) << "% " << msg->Get(0) << " modified in '" << msg->Get(1) << "', lines "
		<< msg->Get(2) << ":" << msg->Get(3) << "-" << msg->Get(4) << ":" << msg->Get(5) << ConsoleColorTag(Console_Normal) << "\n";
}