summaryrefslogtreecommitdiffhomepage
path: root/lib.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-08-29 12:02:43 +0200
committerJo-Philipp Wich <jo@mein.io>2022-08-29 12:02:43 +0200
commit89452b20e5073feb28b294a707342ef144f4b5f0 (patch)
tree13b7a042cd7acb0dd0019b5ebab628bfcf5226d9 /lib.c
parentbcdd2cb33797412cce1f1014d265a71461676cff (diff)
lib: improve getenv() and split() implementations
- getenv(): Allow querying the entire environment by omiting variable name - split(): Properly handle null bytes in subject and separator strings Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/lib.c b/lib.c
index 37563c2..d5e02a5 100644
--- a/lib.c
+++ b/lib.c
@@ -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);