This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
ScriptCraft/scriptcraft/src/main/c/console.c

119 lines
3.4 KiB
C

#include "asprintf.h"
#include <stdio.h>
#include <stdlib.h>
#include <quickjs.h>
#include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h"
static JSValue js_print_internal(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int err, int prepend_throw) {
int i;
char *out;
if (prepend_throw) {
out = (char *) "Throw: ";
} else {
out = (char *) "";
}
const char *str;
for (i = 0; i < argc; i++) {
if (i != 0) {
asprintf(&out, "%s ", out);
}
str = JS_ToCString(ctx, argv[i]);
if (!str) {
return JS_EXCEPTION;
}
asprintf(&out, "%s%s", out, str);
JS_FreeCString(ctx, str);
}
print_data(out, err);
free(out);
return JS_UNDEFINED;
}
static JSValue js_print(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
return js_print_internal(ctx, this_val, argc, argv, 0, 0);
}
static JSValue js_print_err(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
return js_print_internal(ctx, this_val, argc, argv, 1, 0);
}
static JSValue js_assert(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
int i;
const char *str;
if (argc < 1) {
return JS_EXCEPTION;
}
int bool_val = JS_ToBool(ctx, argv[0]);
if (bool_val == -1) {
return JS_EXCEPTION;
}
if (!bool_val) {
char *out = (char *) "Assertion failed";
for (i = 1; i < argc; i++) {
if (i != 1) {
asprintf(&out, "%s ", out);
} else {
asprintf(&out, "%s: ", out);
}
str = JS_ToCString(ctx, argv[i]);
if (!str) {
return JS_EXCEPTION;
}
asprintf(&out, "%s%s", out, str);
JS_FreeCString(ctx, str);
}
print_data(out, 1);
free(out);
}
return JS_UNDEFINED;
}
static const JSCFunctionListEntry js_console_funcs[] = {
JS_CFUNC_DEF("log", 1, js_print),
JS_CFUNC_DEF("info", 1, js_print),
JS_CFUNC_DEF("warn", 1, js_print),
JS_CFUNC_DEF("error", 1, js_print_err),
JS_CFUNC_DEF("dir", 1, js_print),
JS_CFUNC_DEF("debug", 1, js_print),
JS_CFUNC_DEF("trace", 1, js_print),
JS_CFUNC_DEF("assert", 1, js_assert),
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Console", JS_PROP_CONFIGURABLE)
};
void js_console_init(JSContext *ctx) {
JSValue global_obj, console;
/* XXX: should these global definitions be enumerable? */
global_obj = JS_GetGlobalObject(ctx);
console = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, console, js_console_funcs, sizeof js_console_funcs / sizeof (JSCFunctionListEntry));
JS_SetPropertyStr(ctx, global_obj, "console", console);
JS_FreeValue(ctx, global_obj);
}
void js_std_dump_error(JSContext *ctx) {
JSValue exception_val, val;
const char *stack;
int is_error;
exception_val = JS_GetException(ctx);
is_error = JS_IsError(ctx, exception_val);
js_print_internal(ctx, JS_NULL, 1, (JSValueConst *) &exception_val, 1, !is_error);
if (is_error) {
val = JS_GetPropertyStr(ctx, exception_val, "stack");
if (JS_ToBool(ctx, val)) {
stack = JS_ToCString(ctx, val);
print_data((char *) stack, 1);
JS_FreeCString(ctx, stack);
}
JS_FreeValue(ctx, val);
}
JS_FreeValue(ctx, exception_val);
}