From 42de7ab196a0cc82c1a40adffcea7b481a09e11c Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 4 Jun 2021 10:04:26 +0200 Subject: lib: implement `sourcepath()` function The sourcepath() function allows querying the filesystem path of the source file currently being executed by ucode. The optional depth argument can be used to walk up the include stack to determine the path of the file that included the current file, the path of the parent file of the parent file and so on. By specifying a truish value as second argument, only the directory portion of the source file path is returned. This is useful to e.g. discover ressources relative to the current source file directory. Signed-off-by: Jo-Philipp Wich --- lib.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'lib.c') diff --git a/lib.c b/lib.c index f0f934d..89fb4d0 100644 --- a/lib.c +++ b/lib.c @@ -2523,6 +2523,49 @@ uc_wildcard(uc_vm *vm, size_t nargs) return ucv_boolean_new(rv == 0); } +static uc_value_t * +uc_sourcepath(uc_vm *vm, size_t nargs) +{ + uc_value_t *calldepth = uc_get_arg(0); + uc_value_t *dironly = uc_get_arg(1); + uc_value_t *rv = NULL; + uc_callframe *frame; + char *path = NULL; + int64_t depth; + size_t i; + + depth = uc_cast_int64(calldepth); + + if (errno) + depth = 0; + + for (i = vm->callframes.count; i > 0; i--) { + frame = &vm->callframes.entries[i - 1]; + + if (!frame->closure) + continue; + + if (depth > 0) { + depth--; + continue; + } + + path = realpath(frame->closure->function->source->filename, NULL); + break; + } + + if (path) { + if (uc_val_is_truish(dironly)) + rv = ucv_string_new(dirname(path)); + else + rv = ucv_string_new(path); + + free(path); + } + + return rv; +} + static const uc_cfunction_list functions[] = { { "chr", uc_chr }, { "die", uc_die }, @@ -2575,7 +2618,8 @@ static const uc_cfunction_list functions[] = { { "assert", uc_assert }, { "render", uc_render }, { "regexp", uc_regexp }, - { "wildcard", uc_wildcard } + { "wildcard", uc_wildcard }, + { "sourcepath", uc_sourcepath } }; -- cgit v1.2.3