diff --git a/Makefile b/Makefile index f897581..0afdef4 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ test: jsmn_test jsmn_test: jsmn_test.o $(CC) -L. -ljsmn $< -o $@ +jsmn_test.o: jsmn_test.c libjsmn.a + clean: rm -f jsmn.o jsmn_test.o rm -f jsmn_test diff --git a/jsmn.c b/jsmn.c index 22757b2..1bf5614 100644 --- a/jsmn.c +++ b/jsmn.c @@ -8,9 +8,9 @@ static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, size_t num_tokens) { unsigned int i; - for (i = parser->curtoken; i < num_tokens; i++) { + for (i = parser->toknext; i < num_tokens; i++) { if (tokens[i].start == -1 && tokens[i].end == -1) { - parser->curtoken = i; + parser->toknext = i + 1; tokens[i].size = 0; return &tokens[i]; } @@ -121,7 +121,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, jsmntok_t *token; /* initialize the rest of tokens (they could be reallocated) */ - for (i = parser->curtoken; i < num_tokens; i++) { + for (i = parser->toknext; i < num_tokens; i++) { jsmn_fill_token(&tokens[i], JSMN_PRIMITIVE, -1, -1); } @@ -143,7 +143,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, break; case '}': case ']': type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); - for (i = parser->curtoken; i >= 0; i--) { + for (i = parser->toknext - 1; i >= 0; i--) { token = &tokens[i]; if (token->start != -1 && token->end == -1) { if (token->type != type) { @@ -191,7 +191,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, */ void jsmn_init(jsmn_parser *parser) { parser->pos = 0; - parser->curtoken = 0; + parser->toknext = 0; parser->cursize = NULL; } diff --git a/jsmn.h b/jsmn.h index 3d1f9ec..72040bc 100644 --- a/jsmn.h +++ b/jsmn.h @@ -45,7 +45,7 @@ typedef struct { */ typedef struct { unsigned int pos; - int curtoken; + int toknext; int *cursize; } jsmn_parser; diff --git a/jsmn_test.c b/jsmn_test.c index 6a0b340..b01e6c2 100644 --- a/jsmn_test.c +++ b/jsmn_test.c @@ -109,6 +109,15 @@ int test_primitive() { check(TOKEN_STIRNG(js, tok[0], "nullVar")); check(TOKEN_STIRNG(js, tok[1], "null")); + return 0; +} + +int test_string() { + int r; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js; + js = "\"strVar\" : \"hello world\""; jsmn_init(&p); r = jsmn_parse(&p, js, tok, 10); @@ -117,12 +126,61 @@ int test_primitive() { check(TOKEN_STIRNG(js, tok[0], "strVar")); check(TOKEN_STIRNG(js, tok[1], "hello world")); + js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\""; + jsmn_init(&p); + r = jsmn_parse(&p, js, tok, 10); + check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING + && tok[1].type == JSMN_STRING); + check(TOKEN_STIRNG(js, tok[0], "strVar")); + check(TOKEN_STIRNG(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\")); + + js = "\"strVar\" : \"\""; + jsmn_init(&p); + r = jsmn_parse(&p, js, tok, 10); + check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING + && tok[1].type == JSMN_STRING); + check(TOKEN_STIRNG(js, tok[0], "strVar")); + check(TOKEN_STIRNG(js, tok[1], "")); + + return 0; +} + +int test_partial_string() { + int r; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js; + + jsmn_init(&p); + js = "\"x\": \"va"; + r = jsmn_parse(&p, js, tok, 10); + check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); + check(TOKEN_STIRNG(js, tok[0], "x")); + check(TOKEN_EQ(tok[1], -1, -1, 0)); + + js = "\"x\": \"valu"; + r = jsmn_parse(&p, js, tok, 10); + check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); + check(TOKEN_STIRNG(js, tok[0], "x")); + check(TOKEN_EQ(tok[1], -1, -1, 0)); + + js = "\"x\": \"value\""; + r = jsmn_parse(&p, js, tok, 10); + check(r == JSMN_SUCCESS && tok[0].type == JSMN_STRING + && tok[1].type == JSMN_STRING); + check(TOKEN_STIRNG(js, tok[0], "x")); + check(TOKEN_STIRNG(js, tok[1], "value")); + return 0; } int main() { +#if 0 test(test_simple, "general test for a simple JSON string"); test(test_primitive, "test primitive JSON data types"); + test(test_string, "test string JSON data types"); +#endif + test(test_partial_string, "test partial JSON string parsing"); printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); return 0; }