mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Better error handling and messages for invalid index/assign operations.
This commit is contained in:
34
c/execute.c
34
c/execute.c
@ -133,7 +133,14 @@ static struct closure make_closure(struct forkable_stack* stk, frame_ptr fr, uin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_error(jv value) {
|
||||
assert(!jv_is_valid(value));
|
||||
jv msg = jv_invalid_get_msg(value);
|
||||
if (jv_get_kind(msg) == JV_KIND_STRING) {
|
||||
fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
|
||||
}
|
||||
jv_free(msg);
|
||||
}
|
||||
#define ON_BACKTRACK(op) ((op)+NUM_OPCODES)
|
||||
|
||||
jv jq_next() {
|
||||
@ -273,7 +280,13 @@ jv jq_next() {
|
||||
uint16_t v = *pc++;
|
||||
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
||||
jv* var = frame_local_var(fp, v);
|
||||
*var = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
||||
jv result = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
||||
if (jv_is_valid(result)) {
|
||||
*var = result;
|
||||
} else {
|
||||
print_error(result);
|
||||
*var = jv_null();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -282,13 +295,14 @@ jv jq_next() {
|
||||
jv k = stack_pop().value;
|
||||
int pathidx = path_push(t, jv_copy(k));
|
||||
jv v = jv_lookup(t.value, k);
|
||||
if (1 /* fixme invalid lookups */) {
|
||||
if (jv_is_valid(v)) {
|
||||
stackval sv;
|
||||
sv.value = v;
|
||||
sv.pathidx = pathidx;
|
||||
stack_push(sv);
|
||||
} else {
|
||||
assert(0 && "bad lookup");
|
||||
print_error(v);
|
||||
goto do_backtrack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -379,11 +393,7 @@ jv jq_next() {
|
||||
if (jv_is_valid(top.value)) {
|
||||
stack_push(top);
|
||||
} else {
|
||||
jv msg = jv_invalid_get_msg(top.value);
|
||||
if (jv_get_kind(msg) == JV_KIND_STRING) {
|
||||
fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
|
||||
}
|
||||
jv_free(msg);
|
||||
print_error(top.value);
|
||||
goto do_backtrack;
|
||||
}
|
||||
break;
|
||||
@ -405,11 +415,7 @@ jv jq_next() {
|
||||
if (jv_is_valid(top.value)) {
|
||||
stack_push(top);
|
||||
} else {
|
||||
jv msg = jv_invalid_get_msg(top.value);
|
||||
if (jv_get_kind(msg) == JV_KIND_STRING) {
|
||||
fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
|
||||
}
|
||||
jv_free(msg);
|
||||
print_error(top.value);
|
||||
goto do_backtrack;
|
||||
}
|
||||
break;
|
||||
|
2
c/jv.c
2
c/jv.c
@ -49,7 +49,7 @@ const char* jv_kind_name(jv_kind k) {
|
||||
case JV_KIND_ARRAY: return "array";
|
||||
case JV_KIND_OBJECT: return "object";
|
||||
}
|
||||
assert(0);
|
||||
assert(0 && "invalid kind");
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
|
44
c/jv.h
44
c/jv.h
@ -126,39 +126,33 @@ static jv jv_lookup(jv t, jv k) {
|
||||
jv_free(k);
|
||||
v = jv_null();
|
||||
} else {
|
||||
assert(0&&"bad lookup");
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s",
|
||||
jv_kind_name(jv_get_kind(t)),
|
||||
jv_kind_name(jv_get_kind(k))));
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
}
|
||||
return v;
|
||||
// FIXME: invalid indexes, JV_KIND_INVALID
|
||||
/*
|
||||
if (v)
|
||||
return v;
|
||||
else
|
||||
return jv_null();
|
||||
*/
|
||||
}
|
||||
|
||||
static jv jv_modify(jv t, jv k, jv 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) {
|
||||
int isnull = jv_get_kind(t) == JV_KIND_NULL;
|
||||
if (jv_get_kind(k) == JV_KIND_STRING &&
|
||||
(jv_get_kind(t) == JV_KIND_OBJECT || isnull)) {
|
||||
if (isnull) t = jv_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) {
|
||||
} else if (jv_get_kind(k) == JV_KIND_NUMBER &&
|
||||
(jv_get_kind(t) == JV_KIND_ARRAY || isnull)) {
|
||||
if (isnull) t = jv_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 - seriously, wtf");
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("Cannot update field at %s index of %s",
|
||||
jv_kind_name(jv_get_kind(t)),
|
||||
jv_kind_name(jv_get_kind(v))));
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
jv_free(v);
|
||||
t = err;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
Reference in New Issue
Block a user