summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2014-06-18 17:59:51 +0200
committerJo-Philipp Wich <jow@openwrt.org>2014-06-18 18:50:51 +0200
commitafa3a10096e6d3ad50dc9d8250f40d8f23a9ad42 (patch)
treee6a84c25ea9a61e2f30b7937f504a8539b694422 /main.c
parentc0e1d4495a8afe51cc1900269d6a6fcf0b51a761 (diff)
downloadjsonpath-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.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/main.c b/main.c
index 3166746..62e38e9 100644
--- a/main.c
+++ b/main.c
@@ -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;
}