summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2014-12-30 11:17:58 -0600
committerNicolas Williams <nico@cryptonector.com>2014-12-30 11:31:52 -0600
commitcbfc0d6130b784799256f29bb515727df9d894f4 (patch)
treefed8c9f451c06b15b1c5fb206a682e64685f4563
parentc308b2881fce6ce53a66ae600a8b2803214f0b89 (diff)
Remove string indexing by string (fix #454)
This turns out to have been a bad idea: "foo"|.["o"] it interacts badly with `path()`. See #454 for the gory details.
-rw-r--r--builtin.c14
-rw-r--r--jv_aux.c2
-rw-r--r--tests/all.test12
3 files changed, 11 insertions, 17 deletions
diff --git a/builtin.c b/builtin.c
index 25879e3f..6399aff1 100644
--- a/builtin.c
+++ b/builtin.c
@@ -841,6 +841,10 @@ static jv f_string_explode(jq_state *jq, jv a) {
return jv_string_explode(a);
}
+static jv f_string_indexes(jq_state *jq, jv a, jv b) {
+ return jv_string_indexes(a, b);
+}
+
static jv f_string_implode(jq_state *jq, jv a) {
if (jv_get_kind(a) != JV_KIND_ARRAY) {
jv_free(a);
@@ -909,6 +913,7 @@ static const struct cfunction function_list[] = {
{(cfunction_ptr)f_string_split, "split", 2},
{(cfunction_ptr)f_string_explode, "explode", 1},
{(cfunction_ptr)f_string_implode, "implode", 1},
+ {(cfunction_ptr)f_string_indexes, "_strindices", 2},
{(cfunction_ptr)f_setpath, "setpath", 3}, // FIXME typechecking
{(cfunction_ptr)f_getpath, "getpath", 2},
{(cfunction_ptr)f_delpaths, "delpaths", 2},
@@ -1010,9 +1015,12 @@ static const char* const jq_builtins[] = {
"def from_entries: map({(.key // .Key): (.value // .Value)}) | add | .//={};",
"def with_entries(f): to_entries | map(f) | from_entries;",
"def reverse: [.[length - 1 - range(0;length)]];",
- "def indices($i): if type == \"array\" and ($i|type) == \"array\" then .[$i] elif type == \"array\" then .[[$i]] else .[$i] end;",
- "def index($i): if type == \"array\" and ($i|type) == \"array\" then .[$i] elif type == \"array\" then .[[$i]] else .[$i] end | .[0];",
- "def rindex($i): if type == \"array\" and ($i|type) == \"array\" then .[$i] elif type == \"array\" then .[[$i]] else .[$i] end | .[-1:][0];",
+ "def indices($i): if type == \"array\" and ($i|type) == \"array\" then .[$i]"
+ " elif type == \"array\" then .[[$i]]"
+ " elif type == \"string\" and ($i|type) == \"string\" then _strindices($i)"
+ " else .[$i] end;",
+ "def index($i): indices($i) | .[0];", // TODO: optimize
+ "def rindex($i): indices($i) | .[-1:][0];", // TODO: optimize
"def paths: path(recurse(if (type|. == \"array\" or . == \"object\") then .[] else empty end))|select(length > 0);",
"def paths(node_filter): . as $dot|paths|select(. as $p|$dot|getpath($p)|node_filter);",
"def any(generator; condition):"
diff --git a/jv_aux.c b/jv_aux.c
index d859dc49..7bc35cb7 100644
--- a/jv_aux.c
+++ b/jv_aux.c
@@ -86,8 +86,6 @@ jv jv_get(jv t, jv k) {
v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an string slice must be numbers"));
jv_free(t);
}
- } else if (jv_get_kind(t) == JV_KIND_STRING && jv_get_kind(k) == JV_KIND_STRING) {
- v = jv_string_indexes(t, k);
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_ARRAY) {
v = jv_array_indexes(t, k);
} else if (jv_get_kind(t) == JV_KIND_NULL &&
diff --git a/tests/all.test b/tests/all.test
index 0246d6fd..4477ec25 100644
--- a/tests/all.test
+++ b/tests/all.test
@@ -902,18 +902,6 @@ gsub("(?<x>.)[^a]*"; "+\(.x)-")
["fo", "foo", "barfoo", "foobar", "foob"]
["fo","","bar","foobar","foob"]
-.[","]
-"a,bc,def,ghij,klmno"
-[1,4,8,13]
-
-.[", "]
-"a,bc,def,ghij,klmno"
-[]
-
-.[", "]
-"a,b,, c, d,ef, , ghi, jklmn, o"
-[4,7,13,15,20,27]
-
[(index(","), rindex(",")), indices(",")]
"a,bc,def,ghij,klmno"
[1,13,[1,4,8,13]]