diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2014-06-18 17:59:51 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2014-06-18 18:50:51 +0200 |
commit | afa3a10096e6d3ad50dc9d8250f40d8f23a9ad42 (patch) | |
tree | e6a84c25ea9a61e2f30b7937f504a8539b694422 /main.c | |
parent | c0e1d4495a8afe51cc1900269d6a6fcf0b51a761 (diff) | |
download | jsonpath-afa3a10096e6d3ad50dc9d8250f40d8f23a9ad42.tar.gz |
Improve error reporting
Keep track of the exact location the error occured in and switch
the internal error description from a dynamic string buffer to an
integer which either holds negative values for lexer errors or
positives values for grammer violations.
In case of grammer violations the "error_code" member will hold
a bitfield describing the expected tokens.
Also rework the error messages emitted by the cli to be more
precise.
Examples:
$ jsonfilter -s '{}' -e '@.foo bar'
Syntax error: Expecting End of file
In expression @.foo bar
Near here ----------^
$ jsonfilter -s '{}' -e '@.foo\bar'
Syntax error: Unexpected character
In expression @.foo\bar
Near here ---------^
$ jsonfilter -s '{}' -e '@.foo..bar'
Syntax error: Expecting Label or '*'
In expression @.foo..bar
Near here ----------^
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 63 |
1 files changed, 58 insertions, 5 deletions
@@ -250,6 +250,57 @@ match_cb(struct json_object *res, void *priv) } } +static void +print_error(struct jp_state *state, char *expr) +{ + int i; + bool first = true; + + fprintf(stderr, "Syntax error: "); + + switch (state->error_code) + { + case -4: + fprintf(stderr, "Unexpected character\n"); + break; + + case -3: + fprintf(stderr, "String or label literal too long\n"); + break; + + case -2: + fprintf(stderr, "Invalid escape sequence\n"); + break; + + case -1: + fprintf(stderr, "Unterminated string\n"); + break; + + default: + for (i = 0; i < sizeof(state->error_code) * 8; i++) + { + if (state->error_code & (1 << i)) + { + fprintf(stderr, + first ? "Expecting %s" : " or %s", tokennames[i]); + + first = false; + } + } + + fprintf(stderr, "\n"); + break; + } + + fprintf(stderr, "In expression %s\n", expr); + fprintf(stderr, "Near here ----"); + + for (i = 0; i < state->error_pos; i++) + fprintf(stderr, "-"); + + fprintf(stderr, "^\n"); +} + static bool filter_json(int opt, struct json_object *jsobj, char *expr) { @@ -261,12 +312,14 @@ filter_json(int opt, struct json_object *jsobj, char *expr) state = jp_parse(expr); - if (!state || state->error) + if (!state) { - fprintf(stderr, "Syntax error near {%s}: %s\n", - state ? expr + state->erroff : expr, - state ? state->error : "Out of memory"); - + fprintf(stderr, "Out of memory\n"); + goto out; + } + else if (state->error_code) + { + print_error(state, expr); goto out; } |