diff options
Diffstat (limited to 'json-glib')
| -rw-r--r-- | json-glib/json-parser.c | 49 | ||||
| -rw-r--r-- | json-glib/json-parser.h | 8 | ||||
| -rw-r--r-- | json-glib/tests/parser-test.c | 18 |
3 files changed, 56 insertions, 19 deletions
diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c index 4e22572..8df897e 100644 --- a/json-glib/json-parser.c +++ b/json-glib/json-parser.c @@ -1,8 +1,9 @@ /* json-parser.c - JSON streams parser * * This file is part of JSON-GLib - * Copyright (C) 2007 OpenedHand Ltd. - * Copyright (C) 2009 Intel Corp. + * + * Copyright © 2007, 2008, 2009 OpenedHand Ltd + * Copyright © 2009, 2010 Intel Corp. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -48,8 +49,7 @@ json_parser_error_quark (void) return g_quark_from_static_string ("json-parser-error"); } -#define JSON_PARSER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), JSON_TYPE_PARSER, JsonParserPrivate)) +#define JSON_PARSER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), JSON_TYPE_PARSER, JsonParserPrivate)) struct _JsonParserPrivate { @@ -58,6 +58,7 @@ struct _JsonParserPrivate JsonScanner *scanner; + JsonParserError error_code; GError *last_error; gchar *variable_name; @@ -325,6 +326,9 @@ json_parser_init (JsonParser *parser) priv->root = NULL; priv->current_node = NULL; + priv->error_code = JSON_PARSER_ERROR_PARSE; + priv->last_error = NULL; + priv->has_assignment = FALSE; priv->variable_name = NULL; @@ -338,7 +342,8 @@ json_parse_value (JsonParser *parser, guint token, JsonNode **node) { - JsonNode *current_node = parser->priv->current_node; + JsonParserPrivate *priv = parser->priv; + JsonNode *current_node = priv->current_node; gboolean is_negative = FALSE; if (token == '-') @@ -385,11 +390,14 @@ json_parse_value (JsonParser *parser, case JSON_TOKEN_TRUE: case JSON_TOKEN_FALSE: *node = json_node_new (JSON_NODE_VALUE); + JSON_NOTE (PARSER, "node: '%s'", + JSON_TOKEN_TRUE ? "<true>" : "<false>"); json_node_set_boolean (*node, token == JSON_TOKEN_TRUE ? TRUE : FALSE); break; case JSON_TOKEN_NULL: *node = json_node_new (JSON_NODE_NULL); + JSON_NOTE (PARSER, "node: <null>"); break; default: @@ -404,7 +412,10 @@ json_parse_value (JsonParser *parser, else if (cur_type == JSON_NODE_OBJECT) return G_TOKEN_RIGHT_CURLY; else - return G_TOKEN_SYMBOL; + { + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + return G_TOKEN_SYMBOL; + } } } @@ -475,7 +486,11 @@ json_parse_array (JsonParser *parser, token = json_scanner_get_next_token (scanner); if (token == G_TOKEN_RIGHT_BRACE) - return G_TOKEN_SYMBOL; + { + json_array_unref (array); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; + return G_TOKEN_SYMBOL; + } continue; } @@ -523,7 +538,11 @@ json_parse_array (JsonParser *parser, token = json_scanner_get_next_token (scanner); if (token == G_TOKEN_RIGHT_BRACE) - return G_TOKEN_SYMBOL; + { + json_array_unref (array); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; + return G_TOKEN_SYMBOL; + } continue; } @@ -557,12 +576,14 @@ json_parse_array (JsonParser *parser, if (token == G_TOKEN_RIGHT_BRACE) { json_array_unref (array); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; return G_TOKEN_SYMBOL; } } else if (token != G_TOKEN_RIGHT_BRACE) { json_array_unref (array); + priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA; return G_TOKEN_RIGHT_BRACE; } } @@ -671,6 +692,7 @@ json_parse_object (JsonParser *parser, if (token == G_TOKEN_RIGHT_CURLY) { json_object_unref (object); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; return G_TOKEN_STRING; } @@ -723,6 +745,7 @@ json_parse_object (JsonParser *parser, if (token == G_TOKEN_RIGHT_CURLY) { json_object_unref (object); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; return G_TOKEN_STRING; } @@ -760,6 +783,7 @@ json_parse_object (JsonParser *parser, { g_free (name); json_object_unref (object); + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; return G_TOKEN_STRING; } } @@ -767,6 +791,7 @@ json_parse_object (JsonParser *parser, { g_free (name); json_object_unref (object); + priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA; return G_TOKEN_RIGHT_CURLY; } @@ -814,7 +839,10 @@ json_parse_statement (JsonParser *parser, /* ... swallow the variable name... */ next_token = json_scanner_get_next_token (scanner); if (next_token != G_TOKEN_IDENTIFIER) - return G_TOKEN_IDENTIFIER; + { + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + return G_TOKEN_IDENTIFIER; + } name = g_strdup (scanner->value.v_identifier); @@ -852,6 +880,7 @@ json_parse_statement (JsonParser *parser, default: json_scanner_get_next_token (scanner); + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; return G_TOKEN_SYMBOL; } } @@ -869,7 +898,7 @@ json_scanner_msg_handler (JsonScanner *scanner, GError *error = NULL; g_set_error (&error, JSON_PARSER_ERROR, - JSON_PARSER_ERROR_PARSE, + priv->error_code, "%s:%d: Parse error: %s", priv->is_filename ? priv->filename : "<none>", scanner->line, diff --git a/json-glib/json-parser.h b/json-glib/json-parser.h index 7589464..11bfb89 100644 --- a/json-glib/json-parser.h +++ b/json-glib/json-parser.h @@ -49,12 +49,20 @@ typedef struct _JsonParserClass JsonParserClass; /** * JsonParserError: * @JSON_PARSER_ERROR_PARSE: parse error + * @JSON_PARSER_ERROR_TRAILING_COMMA: unexpected trailing comma + * @JSON_PARSER_ERROR_MISSING_COMMA: expected comma + * @JSON_PARSER_ERROR_INVALID_BAREWORD: invalid bareword * @JSON_PARSER_ERROR_UNKNOWN: unknown error * * Error enumeration for #JsonParser + * + * This enumeration can be extended at later date */ typedef enum { JSON_PARSER_ERROR_PARSE, + JSON_PARSER_ERROR_TRAILING_COMMA, + JSON_PARSER_ERROR_MISSING_COMMA, + JSON_PARSER_ERROR_INVALID_BAREWORD, JSON_PARSER_ERROR_UNKNOWN } JsonParserError; diff --git a/json-glib/tests/parser-test.c b/json-glib/tests/parser-test.c index 8f461ef..8fb11b1 100644 --- a/json-glib/tests/parser-test.c +++ b/json-glib/tests/parser-test.c @@ -131,14 +131,15 @@ static const struct static const struct { const gchar *str; + JsonParserError code; } test_invalid[] = { - { "test" }, - { "[ foo, ]" }, - { "[ true, ]" }, - { "{ \"foo\" : true \"bar\" : false }" }, - { "[ true, [ false, ] ]" }, - { "{ \"foo\" : { \"bar\" : false, } }" }, - { "[ { }, { }, { }, ]" } + { "test", JSON_PARSER_ERROR_INVALID_BAREWORD }, + { "[ foo, ]", JSON_PARSER_ERROR_INVALID_BAREWORD }, + { "[ true, ]", JSON_PARSER_ERROR_TRAILING_COMMA }, + { "{ \"foo\" : true \"bar\" : false }", JSON_PARSER_ERROR_MISSING_COMMA }, + { "[ true, [ false, ] ]", JSON_PARSER_ERROR_TRAILING_COMMA }, + { "{ \"foo\" : { \"bar\" : false, } }", JSON_PARSER_ERROR_TRAILING_COMMA }, + { "[ { }, { }, { }, ]", JSON_PARSER_ERROR_TRAILING_COMMA } }; static guint n_test_base_values = G_N_ELEMENTS (test_base_values); @@ -671,8 +672,7 @@ test_invalid_json (void) &error); g_assert (!res); - g_assert (error != NULL); - g_assert (error->domain == JSON_PARSER_ERROR); + g_assert_error (error, JSON_PARSER_ERROR, test_invalid[i].code); if (g_test_verbose ()) g_print ("Error: %s\n", error->message); |
