diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-05-10 16:29:16 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-05-10 16:31:50 +0200 |
commit | e546bbaf6bbee16356beb675cc3e806d9793688e (patch) | |
tree | fc7643b7fa5384b0abf8ff3780bca72f38ca1db1 /lib.c | |
parent | 0cb10c62a0d663fe42cebb4134e7cfcd3c461156 (diff) |
lib: implement render(), an include variant capturing output in a string
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 50 |
1 files changed, 49 insertions, 1 deletions
@@ -2199,6 +2199,53 @@ uc_include(uc_vm *vm, size_t nargs) } static uc_value_t * +uc_render(uc_vm *vm, size_t nargs) +{ + uc_string_t *ustr = NULL; + FILE *mem, *prev; + size_t len = 0; + + mem = open_memstream((char **)&ustr, &len); + + if (!mem) + goto out; + + /* reserve space for uc_string_t header... */ + if (fseek(mem, sizeof(*ustr), SEEK_SET)) + goto out; + + /* divert VM output to memory fd */ + prev = vm->output; + vm->output = mem; + + /* execute include */ + (void) uc_include(vm, nargs); + + /* restore previous VM output */ + vm->output = prev; + fclose(mem); + + /* update uc_string_t length */ + ustr->header.type = UC_STRING; + ustr->header.refcount = 1; + ustr->length = len - sizeof(*ustr); + + return &ustr->header; + +out: + uc_vm_raise_exception(vm, EXCEPTION_RUNTIME, + "Unable to initialize output memory: %s", + strerror(errno)); + + if (mem) + fclose(mem); + + free(ustr); + + return NULL; +} + +static uc_value_t * uc_warn(uc_vm *vm, size_t nargs) { return uc_print_common(vm, nargs, stderr); @@ -2473,7 +2520,8 @@ static const uc_cfunction_list functions[] = { { "trace", uc_trace }, { "proto", uc_proto }, { "sleep", uc_sleep }, - { "assert", uc_assert } + { "assert", uc_assert }, + { "render", uc_render } }; |