From: Markus Armbruster <armbru@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [PATCH v3 7/7] json-parser: add location to JSON parsing errors
Date: Mon, 15 Jun 2026 13:35:36 +0200 [thread overview]
Message-ID: <8733yoqbnb.fsf@pond.sub.org> (raw)
In-Reply-To: <20260525150503.393743-8-pbonzini@redhat.com> (Paolo Bonzini's message of "Mon, 25 May 2026 17:05:03 +0200")
Paolo Bonzini <pbonzini@redhat.com> writes:
> Now that all calls to parse_error have a token, add the line and column
> to the message. As far as I can see the two important TODOs (better
> errors and better EOI handling) are done, and the others (token range
> information and "parsed size"?) do not really matter or are handled
> better by json-streamer.c. So remove the list, which had sat unchanged
> since 2009.
>
> This needs some adjustments to provide a good x and y for error messages.
> First of all, they switch from zero-based to one-based, which is safe
> because they were both sitting unused. Second, right now the x and y
> are those of the *last* character in the token. Modify json-lexer.c to
> freeze tok->x and tok->y at the first character added to the GString.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
QMP errors become obviously better, e.g.
-> {"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
<- {"return": {}}
-> {"execute": "query-commands"]
<- {"error": {"class": "GenericError", "desc": "JSON parse error, expected ',' or '}'"}}
improves to
<- {"error": {"class": "GenericError", "desc": "JSON parse error at line 2, column 29, expected ',' or '}'"}}
The change to CLI errors is a mixed bag, e.g.
$ qemu-system-x86_64 -S -blockdev '{"driver": "host_cdrom", "node-name": "blk0", "filename": "/dev/sr0"'
qemu-system-x86_64: -blockdev {"driver": "host_cdrom", "node-name": "blk0", "filename": "/dev/sr0": JSON parse error, premature end of input
becomes
qemu-system-x86_64: -blockdev {"driver": "host_cdrom", "node-name": "blk0", "filename": "/dev/sr0": JSON parse error at line 1, column 69, premature end of input
I fear this is confusing. If you understand what's happening here, the
"column 69" part has value. The "line 1" part is mostly noise.
Might be less of an issue with more compact location information. See
below.
> ---
> include/qobject/json-parser.h | 1 +
> qobject/json-lexer.c | 11 +++++++----
> qobject/json-parser.c | 12 ++----------
> 3 files changed, 10 insertions(+), 14 deletions(-)
>
> diff --git a/include/qobject/json-parser.h b/include/qobject/json-parser.h
> index 3479e637588..e078b36b2d5 100644
> --- a/include/qobject/json-parser.h
> +++ b/include/qobject/json-parser.h
> @@ -17,6 +17,7 @@
> typedef struct JSONLexer {
> int start_state, state;
> GString *token;
> + int cur_x, cur_y;
> int x, y;
> } JSONLexer;
>
> diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
> index 51341d96e49..7753ba6c092 100644
> --- a/qobject/json-lexer.c
> +++ b/qobject/json-lexer.c
> @@ -277,7 +277,8 @@ void json_lexer_init(JSONLexer *lexer, bool enable_interpolation)
> lexer->start_state = lexer->state = enable_interpolation
> ? IN_START_INTERP : IN_START;
> lexer->token = g_string_sized_new(3);
> - lexer->x = lexer->y = 0;
> + lexer->cur_x = lexer->cur_y = 1;
> + lexer->x = lexer->y = 1;
> }
>
> static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
> @@ -285,10 +286,10 @@ static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
> int new_state;
> bool char_consumed = false;
>
> - lexer->x++;
> + lexer->cur_x++;
> if (ch == '\n') {
> - lexer->x = 0;
> - lexer->y++;
> + lexer->cur_x = 1;
> + lexer->cur_y++;
> }
>
> while (flush ? lexer->state != lexer->start_state : !char_consumed) {
> @@ -316,6 +317,8 @@ static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
> case IN_START:
> g_string_truncate(lexer->token, 0);
> new_state = lexer->start_state;
> + lexer->x = lexer->cur_x;
> + lexer->y = lexer->cur_y;
> break;
> case JSON_ERROR:
> json_message_process_token(lexer, lexer->token, JSON_ERROR,
> diff --git a/qobject/json-parser.c b/qobject/json-parser.c
> index faf3a9142bd..8c58ae0349a 100644
> --- a/qobject/json-parser.c
> +++ b/qobject/json-parser.c
> @@ -126,15 +126,6 @@ typedef struct JSONParserStackEntry {
>
> #define BUG_ON(cond) assert(!(cond))
>
> -/**
> - * TODO
> - *
> - * 0) make errors meaningful again
> - * 1) add geometry information to tokens
> - * 3) should we return a parsed size?
> - * 4) deal with premature EOI
> - */
> -
> static inline JSONParserStackEntry *current_entry(JSONParserContext *ctxt)
> {
> return g_queue_peek_tail(ctxt->stack);
> @@ -172,7 +163,8 @@ static void G_GNUC_PRINTF(3, 4) parse_error(JSONParserContext *ctxt,
> va_start(ap, msg);
> vsnprintf(message, sizeof(message), msg, ap);
> va_end(ap);
> - error_setg(&ctxt->err, "JSON parse error, %s", message);
> + error_setg(&ctxt->err, "JSON parse error at line %d, column %d, %s",
The usual format used by code parsing tools such as compilers is like
"%d:%d: JSON parse error: %s, token->x, token->y, message
Should we use it?
> + token->y, token->x, message);
> }
>
> static int cvt4hex(const char *s)
next prev parent reply other threads:[~2026-06-15 11:36 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 15:04 [PATCH v3 0/7] qobject: switch JSON parser to push Paolo Bonzini
2026-05-25 15:04 ` [PATCH v3 1/7] json-parser: constify JSONToken Paolo Bonzini
2026-05-25 15:04 ` [PATCH v3 2/7] json-parser: replace with a push parser Paolo Bonzini
2026-06-12 14:21 ` Markus Armbruster
2026-06-12 15:08 ` Paolo Bonzini
2026-06-15 7:48 ` Markus Armbruster
2026-06-15 11:06 ` Markus Armbruster
2026-06-15 12:23 ` Markus Armbruster
2026-05-25 15:04 ` [PATCH v3 3/7] json-streamer: reuse parser Paolo Bonzini
2026-06-15 7:56 ` Markus Armbruster
2026-05-25 15:05 ` [PATCH v3 4/7] json-streamer: make brace/bracket count unsigned Paolo Bonzini
2026-06-15 8:11 ` Markus Armbruster
2026-05-25 15:05 ` [PATCH v3 5/7] json-streamer: remove token queue Paolo Bonzini
2026-06-15 10:58 ` Markus Armbruster
2026-06-15 13:33 ` Paolo Bonzini
2026-06-15 12:29 ` Markus Armbruster
2026-06-15 13:22 ` Paolo Bonzini
2026-05-25 15:05 ` [PATCH v3 6/7] json-streamer: do not heap-allocate JSONToken Paolo Bonzini
2026-05-25 15:05 ` [PATCH v3 7/7] json-parser: add location to JSON parsing errors Paolo Bonzini
2026-06-15 11:35 ` Markus Armbruster [this message]
2026-06-15 13:22 ` Paolo Bonzini
2026-06-02 8:58 ` [PATCH v3 0/7] qobject: switch JSON parser to push Paolo Bonzini
2026-06-15 17:01 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8733yoqbnb.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.