diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-12-29 16:50:58 +0000 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-12-29 16:52:26 +0000 |
commit | e0cda536f331b0fc53b493069dce70bb32de9a8b (patch) | |
tree | 1b0a0abe8e20417c71f1cd0ce2ac822294eee7cf | |
parent | d5fdf70434a243e6f3bd6967dbc2d28c9144cb29 (diff) |
Make null + foo return foo, rather than an error.
This also allows 'add' to be implemented in jq rather than C.
-rw-r--r-- | builtin.c | 26 | ||||
-rw-r--r-- | docs/content/3.manual/manual.yml | 9 | ||||
-rw-r--r-- | testdata | 12 |
3 files changed, 29 insertions, 18 deletions
@@ -45,7 +45,13 @@ static jv type_error2(jv bad1, jv bad2, const char* msg) { static jv f_plus(jv input, jv a, jv b) { jv_free(input); - if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { + if (jv_get_kind(a) == JV_KIND_NULL) { + jv_free(a); + return b; + } else if (jv_get_kind(b) == JV_KIND_NULL) { + jv_free(b); + return a; + } else if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { return jv_number(jv_number_value(a) + jv_number_value(b)); } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { @@ -104,22 +110,6 @@ static jv f_divide(jv input, jv a, jv b) { } } -static jv f_add(jv array) { - if (jv_get_kind(array) != JV_KIND_ARRAY) { - return type_error(array, "cannot have its elements added"); - } else if (jv_array_length(jv_copy(array)) == 0) { - jv_free(array); - return jv_null(); - } else { - jv sum = jv_array_get(jv_copy(array), 0); - for (int i = 1; i < jv_array_length(jv_copy(array)); i++) { - sum = f_plus(jv_null(), sum, jv_array_get(jv_copy(array), i)); - } - jv_free(array); - return sum; - } -} - static jv f_equal(jv input, jv a, jv b) { jv_free(input); return jv_bool(jv_equal(a, b)); @@ -495,7 +485,6 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_contains, "contains", 2}, {(cfunction_ptr)f_length, "length", 1}, {(cfunction_ptr)f_type, "type", 1}, - {(cfunction_ptr)f_add, "add", 1}, {(cfunction_ptr)f_sort, "sort", 1}, {(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2}, {(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2}, @@ -551,6 +540,7 @@ static const char* jq_builtins[] = { "def unique: group_by(.) | map(.[0]);", "def max_by(f): _max_by_impl(map([f]));", "def min_by(f): _min_by_impl(map([f]));", + "def add: fold null as $sum (.[] | $sum + .);", "def del(f): delpaths([path(f)]);", "def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));", "def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));", diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 1de1a387..fba7e4a7 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -356,6 +356,9 @@ sections: the key-value pairs from both objects into a single combined object. If both objects contain a value for the same key, the object on the right of the `+` wins. + + `null` can be added to any value, and returns the other + value unchanged. examples: - program: '.a + 1' @@ -364,6 +367,12 @@ sections: - program: '.a + .b' input: '{"a": [1,2], "b": [3,4]}' output: ['[1,2,3,4]'] + - program: '.a + null' + input: '{"a": 1}' + output: ['1'] + - program: '.a + 1' + input: '{}' + output: ['1'] - program: '{a: 1} + {b: 2} + {c: 3} + {a: 42}' input: 'null' output: ['{"a": 42, "b": 2, "c": 3}'] @@ -205,6 +205,18 @@ null 15 19.0 +.+null +{"a":42} +{"a":42} + +null+. +null +null + +.a+.b +{"a":42} +42 + [1,2,3] + [.] null [1,2,3,null] |