diff options
-rw-r--r-- | src/builtin.c | 6 | ||||
-rw-r--r-- | src/execute.c | 15 | ||||
-rw-r--r-- | src/jq.h | 3 | ||||
-rw-r--r-- | src/main.c | 15 | ||||
-rwxr-xr-x | tests/shtest | 10 |
5 files changed, 47 insertions, 2 deletions
diff --git a/src/builtin.c b/src/builtin.c index c71272f8..fb7513ce 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -1245,7 +1245,11 @@ static jv f_debug(jq_state *jq, jv input) { } static jv f_stderr(jq_state *jq, jv input) { - jv_dumpf(jv_copy(input), stderr, 0); + jq_msg_cb cb; + void *data; + jq_get_stderr_cb(jq, &cb, &data); + if (cb != NULL) + cb(data, jv_copy(input)); return input; } diff --git a/src/execute.c b/src/execute.c index adf37737..34bb63dc 100644 --- a/src/execute.c +++ b/src/execute.c @@ -49,6 +49,8 @@ struct jq_state { void *input_cb_data; jq_msg_cb debug_cb; void *debug_cb_data; + jq_msg_cb stderr_cb; + void *stderr_cb_data; }; struct closure { @@ -1018,6 +1020,9 @@ jq_state *jq_init(void) { jq->debug_cb = NULL; jq->debug_cb_data = NULL; + jq->stderr_cb = NULL; + jq->stderr_cb_data = NULL; + jq->err_cb = default_err_cb; jq->err_cb_data = stderr; @@ -1249,6 +1254,16 @@ void jq_get_debug_cb(jq_state *jq, jq_msg_cb *cb, void **data) { *data = jq->debug_cb_data; } +void jq_set_stderr_cb(jq_state *jq, jq_msg_cb cb, void *data) { + jq->stderr_cb = cb; + jq->stderr_cb_data = data; +} + +void jq_get_stderr_cb(jq_state *jq, jq_msg_cb *cb, void **data) { + *cb = jq->stderr_cb; + *data = jq->stderr_cb_data; +} + void jq_halt(jq_state *jq, jv exit_code, jv error_message) { @@ -34,9 +34,10 @@ jv jq_get_error_message(jq_state *); typedef jv (*jq_input_cb)(jq_state *, void *); void jq_set_input_cb(jq_state *, jq_input_cb, void *); void jq_get_input_cb(jq_state *, jq_input_cb *, void **); - void jq_set_debug_cb(jq_state *, jq_msg_cb, void *); void jq_get_debug_cb(jq_state *, jq_msg_cb *, void **); +void jq_set_stderr_cb(jq_state *, jq_msg_cb, void *); +void jq_get_stderr_cb(jq_state *, jq_msg_cb *, void **); void jq_set_attrs(jq_state *, jv); jv jq_get_attrs(jq_state *); @@ -263,6 +263,18 @@ static void debug_cb(void *data, jv input) { fprintf(stderr, "\n"); } +static void stderr_cb(void *data, jv input) { + if (jv_get_kind(input) == JV_KIND_STRING) { + int dumpopts = *(int *)data; + priv_fwrite(jv_string_value(input), jv_string_length_bytes(jv_copy(input)), + stderr, dumpopts & JV_PRINT_ISATTY); + } else { + input = jv_dump_string(input, 0); + fprintf(stderr, "%s", jv_string_value(input)); + } + jv_free(input); +} + #ifdef WIN32 int umain(int argc, char* argv[]); @@ -694,6 +706,9 @@ int main(int argc, char* argv[]) { // Let jq program call `debug` builtin and have that go somewhere jq_set_debug_cb(jq, debug_cb, &dumpopts); + // Let jq program call `stderr` builtin and have that go somewhere + jq_set_stderr_cb(jq, stderr_cb, &dumpopts); + if (nfiles == 0) jq_util_input_add_input(input_state, "-"); diff --git a/tests/shtest b/tests/shtest index 1ee84d3a..6cc428ca 100755 --- a/tests/shtest +++ b/tests/shtest @@ -237,6 +237,16 @@ grep "Expected string key after '{', not '\\['" $d/err > /dev/null echo '{"x":"y",["a","b"]}' | $JQ --stream > /dev/null 2> $d/err || true grep "Expected string key after ',' in object, not '\\['" $d/err > /dev/null +# debug, stderr +$VALGRIND $Q $JQ -n '"test", {} | debug, stderr' >/dev/null +$JQ -n -c -j '"hello\nworld", null, [false, 0], {"foo":["bar"]}, "\n" | stderr' >$d/out 2>$d/err +cat > $d/expected <<'EOF' +hello +worldnull[false,0]{"foo":["bar"]} +EOF +cmp $d/out $d/expected +cmp $d/err $d/expected + # --arg, --argjson, $ARGS.named $VALGRIND $JQ -n -c --arg foo 1 --argjson bar 2 '{$foo, $bar} | ., . == $ARGS.named' > $d/out printf '{"foo":"1","bar":2}\ntrue\n' > $d/expected |