diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-10-20 00:26:37 +0100 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-10-20 00:26:37 +0100 |
commit | 32e1b114df3067b000b26d11030fd265d2fee17a (patch) | |
tree | 562c9cccd053bb7e717afc2e43d544fdb1bfe18c | |
parent | afec2544f1793d11c47356c32ef74ce8c4035263 (diff) |
Add a 'keys' function. Fixes #4.
-rw-r--r-- | builtin.c | 34 | ||||
-rw-r--r-- | testdata | 4 |
2 files changed, 38 insertions, 0 deletions
@@ -202,6 +202,39 @@ static void f_tostring(jv input[], jv output[]) { } } +static int string_cmp(const void* pa, const void* pb){ + const jv* a = pa; + const jv* b = pb; + int lena = jv_string_length(jv_copy(*a)); + int lenb = jv_string_length(jv_copy(*b)); + int minlen = lena < lenb ? lena : lenb; + int r = memcmp(jv_string_value(*a), jv_string_value(*b), minlen); + if (r == 0) r = lena - lenb; + return r; +} + +static void f_keys(jv input[], jv output[]) { + if (jv_get_kind(input[0]) == JV_KIND_OBJECT) { + int nkeys = jv_object_length(jv_copy(input[0])); + jv* keys = malloc(sizeof(jv) * nkeys); + int kidx = 0; + jv_object_foreach(i, input[0]) { + keys[kidx++] = jv_object_iter_key(input[0], i); + } + qsort(keys, nkeys, sizeof(jv), string_cmp); + output[0] = jv_array_sized(nkeys); + for (int i = 0; i<nkeys; i++) { + output[0] = jv_array_append(output[0], keys[i]); + } + free(keys); + jv_free(input[0]); + } else { + output[0] = jv_invalid_with_msg(jv_string_fmt("'keys' only supports object, not %s", + jv_kind_name(jv_get_kind(input[0])))); + jv_free(input[0]); + } +} + static void f_type(jv input[], jv output[]) { output[0] = jv_string(jv_kind_name(jv_get_kind(input[0]))); jv_free(input[0]); @@ -243,6 +276,7 @@ static struct cfunction function_list[] = { {f_divide, "_divide", CALL_BUILTIN_3_1}, {f_tonumber, "tonumber", CALL_BUILTIN_1_1}, {f_tostring, "tostring", CALL_BUILTIN_1_1}, + {f_keys, "keys", CALL_BUILTIN_1_1}, {f_equal, "_equal", CALL_BUILTIN_3_1}, {f_less, "_less", CALL_BUILTIN_3_1}, {f_greater, "_greater", CALL_BUILTIN_3_1}, @@ -223,6 +223,10 @@ null [[], {}, [1,2], {"a":42}, "asdf"] [0, 0, 2, 1, 4] +map(keys) +[{}, {"abcd":1,"abc":2,"abcde":3}, {"x":1, "z": 3, "y":2}] +[[], ["abc","abcd","abcde"], ["x","y","z"]] + [1,2,empty,3,empty,4] null [1,2,3,4] |