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 | |
parent | 0cb10c62a0d663fe42cebb4134e7cfcd3c461156 (diff) |
lib: implement render(), an include variant capturing output in a string
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | lib.c | 50 |
2 files changed, 56 insertions, 2 deletions
@@ -998,7 +998,7 @@ json('{"a":true, "b":123}') // { "a": true, "b": 123 } json('[1,2,') // Throws exception ``` -#### 6.50. `include(path, scope)` +#### 6.50. `include(path[, scope])` Evaluate and include the file at the given path and optionally override the execution scope with the given scope object. @@ -1113,3 +1113,9 @@ an invalid value was passed, otherwise `true`. Raise an exception with the given `message` parameter if the value in `cond` is not truish. When `message` is omitted, the default value is `Assertion failed`. + +#### 6.57. `render(path[, scope])` + +Like `include()` but capture output of included file as string and return it. + +See `include()` for details on scoping. @@ -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 } }; |