diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | lib.c | 67 | ||||
-rw-r--r-- | tests/custom/03_stdlib/05_getenv | 7 | ||||
-rw-r--r-- | tests/custom/03_stdlib/18_split | 4 |
4 files changed, 66 insertions, 17 deletions
@@ -736,9 +736,10 @@ a = filter(["foo", 1, true, null, 2.2], function(v) { // a = [1, 2.2] ``` -#### 6.10. `getenv(name)` +#### 6.10. `getenv([name])` -Return the value of the given environment variable. +Return the value of the given environment variable. If the variable name is +omitted, returns a dictionary containing all environment variables. #### 6.11. `hex(x)` @@ -560,11 +560,34 @@ uc_exit(uc_vm_t *vm, size_t nargs) static uc_value_t * uc_getenv(uc_vm_t *vm, size_t nargs) { - uc_value_t *key = uc_fn_arg(0); - char *k = ucv_string_get(key); - char *val = k ? getenv(k) : NULL; + uc_value_t *key = uc_fn_arg(0), *rv = NULL; + extern char **environ; + char *k, *v; - return val ? ucv_string_new(val) : NULL; + if (!key) { + rv = ucv_object_new(vm); + + while (*environ) { + v = strchr(*environ, '='); + + if (v) { + xasprintf(&k, "%.*s", (int)(v - *environ), *environ); + ucv_object_add(rv, k, ucv_string_new(v + 1)); + free(k); + } + + environ++; + } + } + else if (ucv_type(key) == UC_STRING) { + k = ucv_string_get(key); + v = getenv(k); + + if (v) + rv = ucv_string_new(v); + } + + return rv; } static uc_value_t * @@ -1002,16 +1025,17 @@ uc_split(uc_vm_t *vm, size_t nargs) uc_value_t *sep = uc_fn_arg(1); uc_value_t *arr = NULL; const char *p, *sepstr, *splitstr; + size_t seplen, splitlen; int eflags = 0, res; regmatch_t pmatch; uc_regexp_t *re; - size_t seplen; if (!sep || ucv_type(str) != UC_STRING) return NULL; arr = ucv_array_new(vm); - splitstr = ucv_string_get(str); + splitlen = ucv_string_length(str); + p = splitstr = ucv_string_get(str); if (ucv_type(sep) == UC_REGEXP) { re = (uc_regexp_t *)sep; @@ -1041,18 +1065,35 @@ uc_split(uc_vm_t *vm, size_t nargs) } else if (ucv_type(sep) == UC_STRING) { sepstr = ucv_string_get(sep); + seplen = ucv_string_length(sep); - for (p = splitstr, seplen = strlen(sepstr); *p; p++) { - if (!strncmp(p, sepstr, seplen)) { - if (*sepstr || p > splitstr) - ucv_array_push(arr, ucv_string_new_length(splitstr, p - splitstr)); + if (splitlen == 0) { + ucv_array_push(arr, ucv_string_new_length("", 0)); + } + else if (seplen == 0) { + while (splitlen > 0) { + ucv_array_push(arr, ucv_string_new_length(p, 1)); - splitstr = p + seplen; - p = splitstr - (*sepstr ? 1 : 0); + splitlen--; + p++; } } + else { + while (splitlen >= seplen) { + if (!memcmp(p, sepstr, seplen)) { + ucv_array_push(arr, ucv_string_new_length(splitstr, p - splitstr)); - ucv_array_push(arr, ucv_string_new_length(splitstr, p - splitstr)); + p = splitstr = p + seplen; + splitlen -= seplen; + continue; + } + + splitlen--; + p++; + } + + ucv_array_push(arr, ucv_string_new_length(splitstr, p - splitstr + splitlen)); + } } else { ucv_put(arr); diff --git a/tests/custom/03_stdlib/05_getenv b/tests/custom/03_stdlib/05_getenv index 350e952..064add0 100644 --- a/tests/custom/03_stdlib/05_getenv +++ b/tests/custom/03_stdlib/05_getenv @@ -2,6 +2,9 @@ The `getenv()` function returns the value of the given environment variable or `null` if either the given variable does not exist or if the given name argument is not a string. +If the variable name argument is omitted, getenv() returns a dictionary +containing all environment variables. + -- Testcase -- {% printf("%.J\n", [ @@ -9,7 +12,7 @@ argument is not a string. getenv("EMPTY_VARIABLE"), getenv("THIS_LIKELY_DOES_NOT_EXIST"), getenv(123), - getenv(null) + type(getenv()) ]); %} -- End -- @@ -25,6 +28,6 @@ EMPTY_VARIABLE= "", null, null, - null + "object" ] -- End -- diff --git a/tests/custom/03_stdlib/18_split b/tests/custom/03_stdlib/18_split index e31ce78..5ee35a2 100644 --- a/tests/custom/03_stdlib/18_split +++ b/tests/custom/03_stdlib/18_split @@ -40,6 +40,9 @@ argument is neither a string nor a regular expression. // leading and trailing empty substrings are retained split("|abc|def|", "|"), split(",foo;bar:", /[,;:]/), + + // subject and split strings handle embedded \0 + split("foo=1\0bar=2\0baz=3", "\0"), ]), "\n"); %} -- End -- @@ -58,6 +61,7 @@ argument is neither a string nor a regular expression. [ "foo", "bar", "", "baz" ] [ "", "abc", "def", "" ] [ "", "foo", "bar", "" ] +[ "foo=1", "bar=2", "baz=3" ] -- End -- |