mirror of
https://github.com/rizinorg/jsdec.git
synced 2026-11-07 06:45:57 -10:00
146 lines
3.3 KiB
C
146 lines
3.3 KiB
C
// SPDX-FileCopyrightText: 2018-2023 Giovanni Dante Grazioli <[email protected]>
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "jsdec.h"
|
|
#define errorf(...) fprintf(stderr, __VA_ARGS__)
|
|
|
|
static JSValue shared;
|
|
|
|
int is_regular_file(const char *path) {
|
|
if (!path || !*path) {
|
|
return 0;
|
|
}
|
|
struct stat path_stat;
|
|
stat(path, &path_stat);
|
|
return S_ISREG(path_stat.st_mode);
|
|
}
|
|
|
|
static char *read_file(const char *filename) {
|
|
FILE *fp = NULL;
|
|
long size = 0;
|
|
char *buffer = NULL;
|
|
|
|
if (!is_regular_file(filename)) {
|
|
errorf("Error: path '%s' is not a file\n", filename);
|
|
return NULL;
|
|
}
|
|
|
|
fp = fopen(filename, "rb");
|
|
if (!fp) {
|
|
errorf("Error: failed opening file '%s'\n", filename);
|
|
return NULL;
|
|
}
|
|
|
|
fseek(fp, 0, SEEK_END); // non-portable
|
|
size = ftell(fp);
|
|
rewind(fp);
|
|
if (size < 1) {
|
|
errorf("Error: negative size (%ld) of '%s'\n", size, filename);
|
|
goto fail;
|
|
}
|
|
|
|
if (!(buffer = malloc(size + 1))) {
|
|
errorf("Error: ENOMEM (%ld bytes) of '%s'\n", size, filename);
|
|
goto fail;
|
|
}
|
|
|
|
int read_bytes = fread(buffer, 1, size, fp);
|
|
if (read_bytes != size) {
|
|
errorf("Error: failed to read (%d/%ld bytes) from '%s'\n", read_bytes, size, filename);
|
|
goto fail;
|
|
}
|
|
|
|
// + 1 as on malloc
|
|
buffer[size] = 0;
|
|
fclose(fp);
|
|
return buffer;
|
|
|
|
fail:
|
|
fclose(fp);
|
|
free(buffer);
|
|
return NULL;
|
|
}
|
|
|
|
static JSValue js_console_log(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
|
|
for (int i = 0; i < argc; ++i) {
|
|
if (i != 0) {
|
|
fputc(' ', stdout);
|
|
}
|
|
const char *str = JS_ToCString(ctx, argv[i]);
|
|
if (!str) {
|
|
return JS_EXCEPTION;
|
|
}
|
|
fputs(str, stdout);
|
|
JS_FreeCString(ctx, str);
|
|
}
|
|
fputc('\n', stdout);
|
|
fflush(stdout);
|
|
return JS_UNDEFINED;
|
|
}
|
|
|
|
static JSValue js_get_global(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
|
|
return JS_GetPropertyStr(ctx, shared, "Shared");
|
|
}
|
|
|
|
static int init_testsuite(jsdec_t *dec, const char *file, const char *raw) {
|
|
JSContext *ctx = jsdec_context(dec);
|
|
|
|
shared = JS_NewObject(ctx);
|
|
JS_SetPropertyStr(ctx, shared, "Shared", JS_NewObject(ctx));
|
|
|
|
JSValue global = JS_GetGlobalObject(ctx);
|
|
JS_SetPropertyStr(ctx, global, "Global", JS_NewCFunction(ctx, js_get_global, "Global", 1));
|
|
JS_SetPropertyStr(ctx, global, "rizin", JS_NULL);
|
|
|
|
JSValue console = JS_NewObject(ctx);
|
|
JS_SetPropertyStr(ctx, global, "console", console);
|
|
JS_SetPropertyStr(ctx, console, "log", JS_NewCFunction(ctx, js_console_log, "log", 1));
|
|
|
|
JSValue unit = JS_NewObject(ctx);
|
|
JS_SetPropertyStr(ctx, global, "unit", unit);
|
|
JS_SetPropertyStr(ctx, unit, "file", JS_NewString(ctx, file));
|
|
JS_SetPropertyStr(ctx, unit, "raw", JS_NewString(ctx, raw));
|
|
|
|
JS_FreeValue(ctx, global);
|
|
return 1;
|
|
}
|
|
|
|
static void fini_testsuite(jsdec_t *dec) {
|
|
JSContext *ctx = jsdec_context(dec);
|
|
JS_FreeValue(ctx, shared);
|
|
jsdec_free(dec);
|
|
}
|
|
|
|
int main(int argc, char const *argv[]) {
|
|
if (argc != 2 || !strcmp(argv[1], "-h")) {
|
|
errorf("usage: %s <issue.json>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
jsdec_t *dec = NULL;
|
|
char *raw = read_file(argv[1]);
|
|
if (!raw) {
|
|
return 1;
|
|
}
|
|
|
|
if (!(dec = jsdec_new())) {
|
|
free(raw);
|
|
return 1;
|
|
}
|
|
|
|
init_testsuite(dec, argv[1], raw);
|
|
free(raw);
|
|
|
|
int ret = !jsdec_run(dec);
|
|
|
|
fini_testsuite(dec);
|
|
return ret;
|
|
}
|