mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Perl-style autovivification.
.foo.bar = 1 will cause objects to be created if they don't exist.
This commit is contained in:
19
c/jv.c
19
c/jv.c
@ -125,10 +125,13 @@ static int jvp_array_length(jv_complex* a) {
|
||||
}
|
||||
|
||||
static jv* jvp_array_read(jv_complex* a, int i) {
|
||||
assert(i >= 0 && i < jvp_array_length(a));
|
||||
jvp_array* array = jvp_array_ptr(a);
|
||||
assert(i + a->i[0] < array->length);
|
||||
return &array->elements[i + a->i[0]];
|
||||
if (i >= 0 && i < jvp_array_length(a)) {
|
||||
jvp_array* array = jvp_array_ptr(a);
|
||||
assert(i + a->i[0] < array->length);
|
||||
return &array->elements[i + a->i[0]];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static jv* jvp_array_write(jv_complex* a, int i) {
|
||||
@ -223,7 +226,13 @@ int jv_array_length(jv j) {
|
||||
|
||||
jv jv_array_get(jv j, int idx) {
|
||||
assert(jv_get_kind(j) == JV_KIND_ARRAY);
|
||||
jv val = jv_copy(*jvp_array_read(&j.val.complex, idx));
|
||||
jv* slot = jvp_array_read(&j.val.complex, idx);
|
||||
jv val;
|
||||
if (slot) {
|
||||
val = jv_copy(*slot);
|
||||
} else {
|
||||
val = jv_invalid();
|
||||
}
|
||||
jv_free(j);
|
||||
return val;
|
||||
}
|
||||
|
32
c/jv.h
32
c/jv.h
@ -104,6 +104,14 @@ static jv jv_lookup(jv t, jv k) {
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
|
||||
// FIXME: don't do lookup for noninteger index
|
||||
v = jv_array_get(t, (int)jv_number_value(k));
|
||||
if (!jv_is_valid(v)) {
|
||||
v = jv_null();
|
||||
}
|
||||
} else if (jv_get_kind(t) == JV_KIND_NULL &&
|
||||
(jv_get_kind(k) == JV_KIND_STRING || jv_get_kind(k) == JV_KIND_NUMBER)) {
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
v = jv_null();
|
||||
} else {
|
||||
assert(0&&"bad lookup");
|
||||
}
|
||||
@ -118,12 +126,26 @@ static jv jv_lookup(jv t, jv k) {
|
||||
}
|
||||
|
||||
static jv jv_modify(jv t, jv k, jv v) {
|
||||
if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) {
|
||||
t = jv_object_set(t, k, v);
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
|
||||
t = jv_array_set(t, (int)jv_number_value(k), v);
|
||||
if (jv_get_kind(k) == JV_KIND_STRING) {
|
||||
if (jv_get_kind(t) == JV_KIND_NULL) {
|
||||
t = jv_object();
|
||||
}
|
||||
if (jv_get_kind(t) == JV_KIND_OBJECT) {
|
||||
t = jv_object_set(t, k, v);
|
||||
} else {
|
||||
assert(0 && "bad mod - not an object");
|
||||
}
|
||||
} else if (jv_get_kind(k) == JV_KIND_NUMBER) {
|
||||
if (jv_get_kind(t) == JV_KIND_NULL) {
|
||||
t = jv_array();
|
||||
}
|
||||
if (jv_get_kind(t) == JV_KIND_ARRAY) {
|
||||
t = jv_array_set(t, (int)jv_number_value(k), v);
|
||||
} else {
|
||||
assert(0 && "bad mod - not an array");
|
||||
}
|
||||
} else {
|
||||
assert(0 && "bad mod");
|
||||
assert(0 && "bad mod - seriously, wtf");
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
18
c/testdata
18
c/testdata
@ -133,12 +133,18 @@ null
|
||||
# Builtin functions
|
||||
#
|
||||
|
||||
# FIXME: floats vs. integer
|
||||
|
||||
1+1
|
||||
null
|
||||
2
|
||||
|
||||
1+1
|
||||
"wtasdf"
|
||||
2.0
|
||||
|
||||
1e+0+0.001e3
|
||||
"I wonder what this will be?"
|
||||
20e-1
|
||||
|
||||
.+4
|
||||
15
|
||||
19.0
|
||||
@ -212,3 +218,11 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x
|
||||
def inc(x): x |= .+1; inc(.[].a)
|
||||
[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
|
||||
[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]
|
||||
|
||||
.[2][3] = 1
|
||||
[4]
|
||||
[4, null, [null, null, null, 1]]
|
||||
|
||||
.foo[2].bar = 1
|
||||
{"foo":[11], "bar":42}
|
||||
{"foo":[11,null,{"bar":1}], "bar":42}
|
||||
|
Reference in New Issue
Block a user