Skip to content

Commit d030ead

Browse files
committed
Fix stderr to output string with no decoration (fix #2063)
1 parent 34629ed commit d030ead

File tree

5 files changed

+47
-2
lines changed

5 files changed

+47
-2
lines changed

src/builtin.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,11 @@ static jv f_debug(jq_state *jq, jv input) {
12461246
}
12471247

12481248
static jv f_stderr(jq_state *jq, jv input) {
1249-
jv_dumpf(jv_copy(input), stderr, 0);
1249+
jq_msg_cb cb;
1250+
void *data;
1251+
jq_get_stderr_cb(jq, &cb, &data);
1252+
if (cb != NULL)
1253+
cb(data, jv_copy(input));
12501254
return input;
12511255
}
12521256

src/execute.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct jq_state {
4949
void *input_cb_data;
5050
jq_msg_cb debug_cb;
5151
void *debug_cb_data;
52+
jq_msg_cb stderr_cb;
53+
void *stderr_cb_data;
5254
};
5355

5456
struct closure {
@@ -1018,6 +1020,9 @@ jq_state *jq_init(void) {
10181020
jq->debug_cb = NULL;
10191021
jq->debug_cb_data = NULL;
10201022

1023+
jq->stderr_cb = NULL;
1024+
jq->stderr_cb_data = NULL;
1025+
10211026
jq->err_cb = default_err_cb;
10221027
jq->err_cb_data = stderr;
10231028

@@ -1249,6 +1254,16 @@ void jq_get_debug_cb(jq_state *jq, jq_msg_cb *cb, void **data) {
12491254
*data = jq->debug_cb_data;
12501255
}
12511256

1257+
void jq_set_stderr_cb(jq_state *jq, jq_msg_cb cb, void *data) {
1258+
jq->stderr_cb = cb;
1259+
jq->stderr_cb_data = data;
1260+
}
1261+
1262+
void jq_get_stderr_cb(jq_state *jq, jq_msg_cb *cb, void **data) {
1263+
*cb = jq->stderr_cb;
1264+
*data = jq->stderr_cb_data;
1265+
}
1266+
12521267
void
12531268
jq_halt(jq_state *jq, jv exit_code, jv error_message)
12541269
{

src/jq.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ jv jq_get_error_message(jq_state *);
3434
typedef jv (*jq_input_cb)(jq_state *, void *);
3535
void jq_set_input_cb(jq_state *, jq_input_cb, void *);
3636
void jq_get_input_cb(jq_state *, jq_input_cb *, void **);
37-
3837
void jq_set_debug_cb(jq_state *, jq_msg_cb, void *);
3938
void jq_get_debug_cb(jq_state *, jq_msg_cb *, void **);
39+
void jq_set_stderr_cb(jq_state *, jq_msg_cb, void *);
40+
void jq_get_stderr_cb(jq_state *, jq_msg_cb *, void **);
4041

4142
void jq_set_attrs(jq_state *, jv);
4243
jv jq_get_attrs(jq_state *);

src/main.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,18 @@ static void debug_cb(void *data, jv input) {
253253
fprintf(stderr, "\n");
254254
}
255255

256+
static void stderr_cb(void *data, jv input) {
257+
if (jv_get_kind(input) == JV_KIND_STRING) {
258+
int dumpopts = *(int *)data;
259+
priv_fwrite(jv_string_value(input), jv_string_length_bytes(jv_copy(input)),
260+
stderr, dumpopts & JV_PRINT_ISATTY);
261+
} else {
262+
input = jv_dump_string(input, 0);
263+
fprintf(stderr, "%s", jv_string_value(input));
264+
}
265+
jv_free(input);
266+
}
267+
256268
#ifdef WIN32
257269
int umain(int argc, char* argv[]);
258270

@@ -684,6 +696,9 @@ int main(int argc, char* argv[]) {
684696
// Let jq program call `debug` builtin and have that go somewhere
685697
jq_set_debug_cb(jq, debug_cb, &dumpopts);
686698

699+
// Let jq program call `stderr` builtin and have that go somewhere
700+
jq_set_stderr_cb(jq, stderr_cb, &dumpopts);
701+
687702
if (nfiles == 0)
688703
jq_util_input_add_input(input_state, "-");
689704

tests/shtest

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ grep "Expected string key after '{', not '\\['" $d/err > /dev/null
232232
echo '{"x":"y",["a","b"]}' | $JQ --stream > /dev/null 2> $d/err || true
233233
grep "Expected string key after ',' in object, not '\\['" $d/err > /dev/null
234234

235+
# debug, stderr
236+
$VALGRIND $Q $JQ -n '"test", {} | debug, stderr' >/dev/null
237+
$JQ -n -c -j '"hello\nworld", null, [false, 0], {"foo":["bar"]}, "\n" | stderr' >$d/out 2>$d/err
238+
cat > $d/expected <<'EOF'
239+
hello
240+
worldnull[false,0]{"foo":["bar"]}
241+
EOF
242+
cmp $d/out $d/expected
243+
cmp $d/err $d/expected
244+
235245
# --arg, --argjson, $ARGS.named
236246
$VALGRIND $JQ -n -c --arg foo 1 --argjson bar 2 '{$foo, $bar} | ., . == $ARGS.named' > $d/out
237247
printf '{"foo":"1","bar":2}\ntrue\n' > $d/expected

0 commit comments

Comments
 (0)