Skip to content

Commit

Permalink
Fix stderr to output string with no decoration (fix #2063)
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Jul 23, 2023
1 parent 34629ed commit 16cd5e7
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,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;
}

Expand Down
15 changes: 15 additions & 0 deletions src/execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
{
Expand Down
3 changes: 2 additions & 1 deletion src/jq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
16 changes: 16 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,19 @@ static void debug_cb(void *data, jv input) {
int dumpopts = *(int *)data;
jv_dumpf(JV_ARRAY(jv_string("DEBUG:"), input), stderr, dumpopts & ~(JV_PRINT_PRETTY));
fprintf(stderr, "\n");
jv_free(input);
}

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
Expand Down Expand Up @@ -684,6 +697,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, "-");

Expand Down
10 changes: 10 additions & 0 deletions tests/shtest
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,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 2>&1
$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
Expand Down

0 comments on commit 16cd5e7

Please sign in to comment.