diff options
-rw-r--r-- | include/ucode/types.h | 20 | ||||
-rw-r--r-- | main.c | 60 | ||||
-rw-r--r-- | types.c | 18 | ||||
-rw-r--r-- | vm.c | 7 |
4 files changed, 77 insertions, 28 deletions
diff --git a/include/ucode/types.h b/include/ucode/types.h index b810744..c32829f 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -217,13 +217,33 @@ typedef struct uc_program { /* Parser definitions */ +uc_declare_vector(uc_search_path_t, char *); + typedef struct { bool lstrip_blocks; bool trim_blocks; bool strict_declarations; bool raw_mode; + uc_search_path_t module_search_path; } uc_parse_config_t; +extern uc_parse_config_t uc_default_parse_config; + +void uc_search_path_init(uc_search_path_t *search_path); + +static inline void +uc_search_path_add(uc_search_path_t *search_path, char *path) { + uc_vector_push(search_path, xstrdup(path)); +} + +static inline void +uc_search_path_free(uc_search_path_t *search_path) { + while (search_path->count > 0) + free(search_path->entries[--search_path->count]); + + uc_vector_clear(search_path); +} + /* VM definitions */ @@ -387,14 +387,13 @@ parse_define_string(char *opt, uc_value_t *globals) } static void -parse_search_path(char *pattern, uc_value_t *globals) +parse_search_path(char *pattern, uc_parse_config_t *config) { - uc_value_t *rsp = ucv_object_get(globals, "REQUIRE_SEARCH_PATH", NULL); size_t len; char *p; if (strchr(pattern, '*')) { - ucv_array_push(rsp, ucv_string_new(pattern)); + uc_search_path_add(&config->module_search_path, pattern); return; } @@ -407,11 +406,11 @@ parse_search_path(char *pattern, uc_value_t *globals) pattern[--len] = 0; xasprintf(&p, "%s/*.so", pattern); - ucv_array_push(rsp, ucv_string_new(p)); + uc_search_path_add(&config->module_search_path, p); free(p); xasprintf(&p, "%s/*.uc", pattern); - ucv_array_push(rsp, ucv_string_new(p)); + uc_search_path_add(&config->module_search_path, p); free(p); } @@ -462,6 +461,7 @@ appname(const char *argv0) int main(int argc, char **argv) { + const char *optspec = "he:tST::RD:F:U:l:L:c::o:s"; char *interp = "/usr/bin/env ucode"; uc_source_t *source = NULL; FILE *precompile = NULL; @@ -480,6 +480,8 @@ main(int argc, char **argv) .raw_mode = true }; + uc_search_path_init(&config.module_search_path); + app = appname(argv[0]); if (argc == 1) { @@ -494,6 +496,31 @@ main(int argc, char **argv) stdin_unused = stdin; + /* parse options iteration 1: parse config related options */ + while ((opt = getopt(argc, argv, optspec)) != -1) + { + switch (opt) { + case 'L': + parse_search_path(optarg, &config); + break; + + case 'S': + config.strict_declarations = true; + break; + + case 'R': + config.raw_mode = true; + break; + + case 'T': + config.raw_mode = false; + parse_template_modeflags(optarg, &config); + break; + } + } + + optind = 1; + uc_vm_init(&vm, &config); /* load std functions into global scope */ @@ -504,8 +531,8 @@ main(int argc, char **argv) ucv_object_add(uc_vm_scope_get(&vm), "ARGV", ucv_get(o)); - /* parse options */ - while ((opt = getopt(argc, argv, "he:tST::RD:F:U:l:L:c::o:s")) != -1) + /* parse options iteration 2: process remaining options */ + while ((opt = getopt(argc, argv, optspec)) != -1) { switch (opt) { case 'h': @@ -520,19 +547,6 @@ main(int argc, char **argv) uc_vm_trace_set(&vm, 1); break; - case 'S': - config.strict_declarations = true; - break; - - case 'R': - config.raw_mode = true; - break; - - case 'T': - config.raw_mode = false; - parse_template_modeflags(optarg, &config); - break; - case 'D': if (!parse_define_string(optarg, uc_vm_scope_get(&vm))) { rv = 1; @@ -553,10 +567,6 @@ main(int argc, char **argv) ucv_object_delete(uc_vm_scope_get(&vm), optarg); break; - case 'L': - parse_search_path(optarg, uc_vm_scope_get(&vm)); - break; - case 'l': if (!parse_library_load(optarg, &vm)) { rv = 1; @@ -629,6 +639,8 @@ main(int argc, char **argv) rv = compile(&vm, source, precompile, strip, interp); out: + uc_search_path_free(&config.module_search_path); + uc_source_put(source); uc_vm_free(&vm); @@ -30,6 +30,15 @@ #include "ucode/vm.h" #include "ucode/program.h" +static char *uc_default_search_path[] = { LIB_SEARCH_PATH }; + +uc_parse_config_t uc_default_parse_config = { + .module_search_path = { + .count = ARRAY_SIZE(uc_default_search_path), + .entries = uc_default_search_path + } +}; + uc_type_t ucv_type(uc_value_t *uv) { @@ -2245,3 +2254,12 @@ ucv_freeall(uc_vm_t *vm) { ucv_gc_common(vm, true); } + +void +uc_search_path_init(uc_search_path_t *search_path) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(uc_default_search_path); i++) + uc_vector_push(search_path, xstrdup(uc_default_search_path[i])); +} @@ -111,7 +111,6 @@ uc_vm_reset_callframes(uc_vm_t *vm) static uc_value_t * uc_vm_alloc_global_scope(uc_vm_t *vm) { - const char *path[] = { LIB_SEARCH_PATH }; uc_value_t *scope, *arr; size_t i; @@ -120,8 +119,8 @@ uc_vm_alloc_global_scope(uc_vm_t *vm) /* build default require() search path */ arr = ucv_array_new(vm); - for (i = 0; i < ARRAY_SIZE(path); i++) - ucv_array_push(arr, ucv_string_new(path[i])); + for (i = 0; i < vm->config->module_search_path.count; i++) + ucv_array_push(arr, ucv_string_new(vm->config->module_search_path.entries[i])); /* register module related constants */ ucv_object_add(scope, "REQUIRE_SEARCH_PATH", arr); @@ -147,7 +146,7 @@ void uc_vm_init(uc_vm_t *vm, uc_parse_config_t *config) vm->exception.type = EXCEPTION_NONE; vm->exception.message = NULL; - vm->config = config; + vm->config = config ? config : &uc_default_parse_config; vm->open_upvals = NULL; |