12b15cb3dSCy Schubert #include <stdio.h>
22b15cb3dSCy Schubert #include <stdlib.h>
32b15cb3dSCy Schubert #include <string.h>
42b15cb3dSCy Schubert
52b15cb3dSCy Schubert static int test_passed = 0;
62b15cb3dSCy Schubert static int test_failed = 0;
72b15cb3dSCy Schubert
82b15cb3dSCy Schubert /* Terminate current test with error */
92b15cb3dSCy Schubert #define fail() return __LINE__
102b15cb3dSCy Schubert
112b15cb3dSCy Schubert /* Successfull end of the test case */
122b15cb3dSCy Schubert #define done() return 0
132b15cb3dSCy Schubert
142b15cb3dSCy Schubert /* Check single condition */
152b15cb3dSCy Schubert #define check(cond) do { if (!(cond)) fail(); } while (0)
162b15cb3dSCy Schubert
172b15cb3dSCy Schubert /* Test runner */
test(int (* func)(void),const char * name)182b15cb3dSCy Schubert static void test(int (*func)(void), const char *name) {
192b15cb3dSCy Schubert int r = func();
202b15cb3dSCy Schubert if (r == 0) {
212b15cb3dSCy Schubert test_passed++;
222b15cb3dSCy Schubert } else {
232b15cb3dSCy Schubert test_failed++;
242b15cb3dSCy Schubert printf("FAILED: %s (at line %d)\n", name, r);
252b15cb3dSCy Schubert }
262b15cb3dSCy Schubert }
272b15cb3dSCy Schubert
282b15cb3dSCy Schubert #define TOKEN_EQ(t, tok_start, tok_end, tok_type) \
292b15cb3dSCy Schubert ((t).start == tok_start \
302b15cb3dSCy Schubert && (t).end == tok_end \
312b15cb3dSCy Schubert && (t).type == (tok_type))
322b15cb3dSCy Schubert
332b15cb3dSCy Schubert #define TOKEN_STRING(js, t, s) \
342b15cb3dSCy Schubert (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \
352b15cb3dSCy Schubert && strlen(s) == (t).end - (t).start)
362b15cb3dSCy Schubert
372b15cb3dSCy Schubert #define TOKEN_PRINT(t) \
382b15cb3dSCy Schubert printf("start: %d, end: %d, type: %d, size: %d\n", \
392b15cb3dSCy Schubert (t).start, (t).end, (t).type, (t).size)
402b15cb3dSCy Schubert
41*276da39aSCy Schubert #define JSMN_STRICT
42*276da39aSCy Schubert #include "jsmn.c"
43*276da39aSCy Schubert
test_empty()442b15cb3dSCy Schubert int test_empty() {
452b15cb3dSCy Schubert const char *js;
462b15cb3dSCy Schubert int r;
472b15cb3dSCy Schubert jsmn_parser p;
482b15cb3dSCy Schubert jsmntok_t t[10];
492b15cb3dSCy Schubert
502b15cb3dSCy Schubert js = "{}";
512b15cb3dSCy Schubert jsmn_init(&p);
52*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), t, 10);
53*276da39aSCy Schubert check(r >= 0);
542b15cb3dSCy Schubert check(t[0].type == JSMN_OBJECT);
552b15cb3dSCy Schubert check(t[0].start == 0 && t[0].end == 2);
562b15cb3dSCy Schubert
572b15cb3dSCy Schubert js = "[]";
582b15cb3dSCy Schubert jsmn_init(&p);
59*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), t, 10);
60*276da39aSCy Schubert check(r >= 0);
612b15cb3dSCy Schubert check(t[0].type == JSMN_ARRAY);
622b15cb3dSCy Schubert check(t[0].start == 0 && t[0].end == 2);
632b15cb3dSCy Schubert
642b15cb3dSCy Schubert js = "{\"a\":[]}";
652b15cb3dSCy Schubert jsmn_init(&p);
66*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), t, 10);
67*276da39aSCy Schubert check(r >= 0);
682b15cb3dSCy Schubert check(t[0].type == JSMN_OBJECT && t[0].start == 0 && t[0].end == 8);
692b15cb3dSCy Schubert check(t[1].type == JSMN_STRING && t[1].start == 2 && t[1].end == 3);
702b15cb3dSCy Schubert check(t[2].type == JSMN_ARRAY && t[2].start == 5 && t[2].end == 7);
712b15cb3dSCy Schubert
722b15cb3dSCy Schubert js = "[{},{}]";
732b15cb3dSCy Schubert jsmn_init(&p);
74*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), t, 10);
75*276da39aSCy Schubert check(r >= 0);
762b15cb3dSCy Schubert check(t[0].type == JSMN_ARRAY && t[0].start == 0 && t[0].end == 7);
772b15cb3dSCy Schubert check(t[1].type == JSMN_OBJECT && t[1].start == 1 && t[1].end == 3);
782b15cb3dSCy Schubert check(t[2].type == JSMN_OBJECT && t[2].start == 4 && t[2].end == 6);
792b15cb3dSCy Schubert return 0;
802b15cb3dSCy Schubert }
812b15cb3dSCy Schubert
test_simple()822b15cb3dSCy Schubert int test_simple() {
832b15cb3dSCy Schubert const char *js;
842b15cb3dSCy Schubert int r;
852b15cb3dSCy Schubert jsmn_parser p;
862b15cb3dSCy Schubert jsmntok_t tokens[10];
872b15cb3dSCy Schubert
882b15cb3dSCy Schubert js = "{\"a\": 0}";
892b15cb3dSCy Schubert
902b15cb3dSCy Schubert jsmn_init(&p);
91*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
92*276da39aSCy Schubert check(r >= 0);
932b15cb3dSCy Schubert check(TOKEN_EQ(tokens[0], 0, 8, JSMN_OBJECT));
942b15cb3dSCy Schubert check(TOKEN_EQ(tokens[1], 2, 3, JSMN_STRING));
952b15cb3dSCy Schubert check(TOKEN_EQ(tokens[2], 6, 7, JSMN_PRIMITIVE));
962b15cb3dSCy Schubert
972b15cb3dSCy Schubert check(TOKEN_STRING(js, tokens[0], js));
982b15cb3dSCy Schubert check(TOKEN_STRING(js, tokens[1], "a"));
992b15cb3dSCy Schubert check(TOKEN_STRING(js, tokens[2], "0"));
1002b15cb3dSCy Schubert
1012b15cb3dSCy Schubert jsmn_init(&p);
1022b15cb3dSCy Schubert js = "[\"a\":{},\"b\":{}]";
103*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
104*276da39aSCy Schubert check(r >= 0);
1052b15cb3dSCy Schubert
1062b15cb3dSCy Schubert jsmn_init(&p);
1072b15cb3dSCy Schubert js = "{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }";
108*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
109*276da39aSCy Schubert check(r >= 0);
1102b15cb3dSCy Schubert
1112b15cb3dSCy Schubert return 0;
1122b15cb3dSCy Schubert }
1132b15cb3dSCy Schubert
test_primitive()1142b15cb3dSCy Schubert int test_primitive() {
115*276da39aSCy Schubert #ifndef JSMN_STRICT
1162b15cb3dSCy Schubert int r;
1172b15cb3dSCy Schubert jsmn_parser p;
1182b15cb3dSCy Schubert jsmntok_t tok[10];
1192b15cb3dSCy Schubert const char *js;
1202b15cb3dSCy Schubert js = "\"boolVar\" : true";
1212b15cb3dSCy Schubert jsmn_init(&p);
122*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
123*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1242b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE);
1252b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "boolVar"));
1262b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "true"));
1272b15cb3dSCy Schubert
1282b15cb3dSCy Schubert js = "\"boolVar\" : false";
1292b15cb3dSCy Schubert jsmn_init(&p);
130*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
131*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1322b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE);
1332b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "boolVar"));
1342b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "false"));
1352b15cb3dSCy Schubert
1362b15cb3dSCy Schubert js = "\"intVar\" : 12345";
1372b15cb3dSCy Schubert jsmn_init(&p);
138*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
139*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1402b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE);
1412b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "intVar"));
1422b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "12345"));
1432b15cb3dSCy Schubert
1442b15cb3dSCy Schubert js = "\"floatVar\" : 12.345";
1452b15cb3dSCy Schubert jsmn_init(&p);
146*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
147*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1482b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE);
1492b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "floatVar"));
1502b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "12.345"));
1512b15cb3dSCy Schubert
1522b15cb3dSCy Schubert js = "\"nullVar\" : null";
1532b15cb3dSCy Schubert jsmn_init(&p);
154*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
155*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1562b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE);
1572b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "nullVar"));
1582b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "null"));
1592b15cb3dSCy Schubert #endif
1602b15cb3dSCy Schubert return 0;
1612b15cb3dSCy Schubert }
1622b15cb3dSCy Schubert
test_string()1632b15cb3dSCy Schubert int test_string() {
1642b15cb3dSCy Schubert int r;
1652b15cb3dSCy Schubert jsmn_parser p;
1662b15cb3dSCy Schubert jsmntok_t tok[10];
1672b15cb3dSCy Schubert const char *js;
1682b15cb3dSCy Schubert
1692b15cb3dSCy Schubert js = "\"strVar\" : \"hello world\"";
1702b15cb3dSCy Schubert jsmn_init(&p);
171*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
172*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1732b15cb3dSCy Schubert && tok[1].type == JSMN_STRING);
1742b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "strVar"));
1752b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "hello world"));
1762b15cb3dSCy Schubert
1772b15cb3dSCy Schubert js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"";
1782b15cb3dSCy Schubert jsmn_init(&p);
179*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
180*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1812b15cb3dSCy Schubert && tok[1].type == JSMN_STRING);
1822b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "strVar"));
1832b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\"));
1842b15cb3dSCy Schubert
1852b15cb3dSCy Schubert js = "\"strVar\" : \"\"";
1862b15cb3dSCy Schubert jsmn_init(&p);
187*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
188*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
1892b15cb3dSCy Schubert && tok[1].type == JSMN_STRING);
1902b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "strVar"));
1912b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], ""));
1922b15cb3dSCy Schubert
1932b15cb3dSCy Schubert return 0;
1942b15cb3dSCy Schubert }
1952b15cb3dSCy Schubert
test_partial_string()1962b15cb3dSCy Schubert int test_partial_string() {
1972b15cb3dSCy Schubert int r;
1982b15cb3dSCy Schubert jsmn_parser p;
1992b15cb3dSCy Schubert jsmntok_t tok[10];
2002b15cb3dSCy Schubert const char *js;
2012b15cb3dSCy Schubert
2022b15cb3dSCy Schubert jsmn_init(&p);
2032b15cb3dSCy Schubert js = "\"x\": \"va";
204*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
2052b15cb3dSCy Schubert check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING);
2062b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "x"));
2072b15cb3dSCy Schubert check(p.toknext == 1);
2082b15cb3dSCy Schubert
209*276da39aSCy Schubert jsmn_init(&p);
210*276da39aSCy Schubert char js_slash[9] = "\"x\": \"va\\";
211*276da39aSCy Schubert r = jsmn_parse(&p, js_slash, sizeof(js_slash), tok, 10);
212*276da39aSCy Schubert check(r == JSMN_ERROR_PART);
213*276da39aSCy Schubert
214*276da39aSCy Schubert jsmn_init(&p);
215*276da39aSCy Schubert char js_unicode[10] = "\"x\": \"va\\u";
216*276da39aSCy Schubert r = jsmn_parse(&p, js_unicode, sizeof(js_unicode), tok, 10);
217*276da39aSCy Schubert check(r == JSMN_ERROR_PART);
218*276da39aSCy Schubert
2192b15cb3dSCy Schubert js = "\"x\": \"valu";
220*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
2212b15cb3dSCy Schubert check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING);
2222b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "x"));
2232b15cb3dSCy Schubert check(p.toknext == 1);
2242b15cb3dSCy Schubert
2252b15cb3dSCy Schubert js = "\"x\": \"value\"";
226*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
227*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
2282b15cb3dSCy Schubert && tok[1].type == JSMN_STRING);
2292b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "x"));
2302b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "value"));
2312b15cb3dSCy Schubert
2322b15cb3dSCy Schubert js = "\"x\": \"value\", \"y\": \"value y\"";
233*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
234*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_STRING
2352b15cb3dSCy Schubert && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING
2362b15cb3dSCy Schubert && tok[3].type == JSMN_STRING);
2372b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "x"));
2382b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "value"));
2392b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[2], "y"));
2402b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[3], "value y"));
2412b15cb3dSCy Schubert
2422b15cb3dSCy Schubert return 0;
2432b15cb3dSCy Schubert }
2442b15cb3dSCy Schubert
test_unquoted_keys()2452b15cb3dSCy Schubert int test_unquoted_keys() {
2462b15cb3dSCy Schubert #ifndef JSMN_STRICT
2472b15cb3dSCy Schubert int r;
2482b15cb3dSCy Schubert jsmn_parser p;
2492b15cb3dSCy Schubert jsmntok_t tok[10];
2502b15cb3dSCy Schubert const char *js;
2512b15cb3dSCy Schubert
2522b15cb3dSCy Schubert jsmn_init(&p);
2532b15cb3dSCy Schubert js = "key1: \"value\"\nkey2 : 123";
2542b15cb3dSCy Schubert
255*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
256*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_PRIMITIVE
2572b15cb3dSCy Schubert && tok[1].type == JSMN_STRING && tok[2].type == JSMN_PRIMITIVE
2582b15cb3dSCy Schubert && tok[3].type == JSMN_PRIMITIVE);
2592b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[0], "key1"));
2602b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[1], "value"));
2612b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[2], "key2"));
2622b15cb3dSCy Schubert check(TOKEN_STRING(js, tok[3], "123"));
2632b15cb3dSCy Schubert #endif
2642b15cb3dSCy Schubert return 0;
2652b15cb3dSCy Schubert }
2662b15cb3dSCy Schubert
test_partial_array()2672b15cb3dSCy Schubert int test_partial_array() {
2682b15cb3dSCy Schubert int r;
2692b15cb3dSCy Schubert jsmn_parser p;
2702b15cb3dSCy Schubert jsmntok_t tok[10];
2712b15cb3dSCy Schubert const char *js;
2722b15cb3dSCy Schubert
2732b15cb3dSCy Schubert jsmn_init(&p);
2742b15cb3dSCy Schubert js = " [ 1, true, ";
275*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
2762b15cb3dSCy Schubert check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
2772b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE);
2782b15cb3dSCy Schubert
2792b15cb3dSCy Schubert js = " [ 1, true, [123, \"hello";
280*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
2812b15cb3dSCy Schubert check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
2822b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
2832b15cb3dSCy Schubert && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE);
2842b15cb3dSCy Schubert
2852b15cb3dSCy Schubert js = " [ 1, true, [123, \"hello\"]";
286*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
2872b15cb3dSCy Schubert check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
2882b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
2892b15cb3dSCy Schubert && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE
2902b15cb3dSCy Schubert && tok[5].type == JSMN_STRING);
2912b15cb3dSCy Schubert /* check child nodes of the 2nd array */
2922b15cb3dSCy Schubert check(tok[3].size == 2);
2932b15cb3dSCy Schubert
2942b15cb3dSCy Schubert js = " [ 1, true, [123, \"hello\"]]";
295*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tok, 10);
296*276da39aSCy Schubert check(r >= 0 && tok[0].type == JSMN_ARRAY
2972b15cb3dSCy Schubert && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
2982b15cb3dSCy Schubert && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE
2992b15cb3dSCy Schubert && tok[5].type == JSMN_STRING);
3002b15cb3dSCy Schubert check(tok[3].size == 2);
3012b15cb3dSCy Schubert check(tok[0].size == 3);
3022b15cb3dSCy Schubert return 0;
3032b15cb3dSCy Schubert }
3042b15cb3dSCy Schubert
test_array_nomem()3052b15cb3dSCy Schubert int test_array_nomem() {
3062b15cb3dSCy Schubert int i;
3072b15cb3dSCy Schubert int r;
3082b15cb3dSCy Schubert jsmn_parser p;
3092b15cb3dSCy Schubert jsmntok_t toksmall[10], toklarge[10];
3102b15cb3dSCy Schubert const char *js;
3112b15cb3dSCy Schubert
3122b15cb3dSCy Schubert js = " [ 1, true, [123, \"hello\"]]";
3132b15cb3dSCy Schubert
3142b15cb3dSCy Schubert for (i = 0; i < 6; i++) {
3152b15cb3dSCy Schubert jsmn_init(&p);
3162b15cb3dSCy Schubert memset(toksmall, 0, sizeof(toksmall));
3172b15cb3dSCy Schubert memset(toklarge, 0, sizeof(toklarge));
318*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), toksmall, i);
3192b15cb3dSCy Schubert check(r == JSMN_ERROR_NOMEM);
3202b15cb3dSCy Schubert
3212b15cb3dSCy Schubert memcpy(toklarge, toksmall, sizeof(toksmall));
3222b15cb3dSCy Schubert
323*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), toklarge, 10);
324*276da39aSCy Schubert check(r >= 0);
3252b15cb3dSCy Schubert
3262b15cb3dSCy Schubert check(toklarge[0].type == JSMN_ARRAY && toklarge[0].size == 3);
3272b15cb3dSCy Schubert check(toklarge[3].type == JSMN_ARRAY && toklarge[3].size == 2);
3282b15cb3dSCy Schubert }
3292b15cb3dSCy Schubert return 0;
3302b15cb3dSCy Schubert }
3312b15cb3dSCy Schubert
test_objects_arrays()3322b15cb3dSCy Schubert int test_objects_arrays() {
3332b15cb3dSCy Schubert int r;
3342b15cb3dSCy Schubert jsmn_parser p;
3352b15cb3dSCy Schubert jsmntok_t tokens[10];
3362b15cb3dSCy Schubert const char *js;
3372b15cb3dSCy Schubert
3382b15cb3dSCy Schubert js = "[10}";
3392b15cb3dSCy Schubert jsmn_init(&p);
340*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
3412b15cb3dSCy Schubert check(r == JSMN_ERROR_INVAL);
3422b15cb3dSCy Schubert
3432b15cb3dSCy Schubert js = "[10]";
3442b15cb3dSCy Schubert jsmn_init(&p);
345*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
346*276da39aSCy Schubert check(r >= 0);
3472b15cb3dSCy Schubert
3482b15cb3dSCy Schubert js = "{\"a\": 1]";
3492b15cb3dSCy Schubert jsmn_init(&p);
350*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
3512b15cb3dSCy Schubert check(r == JSMN_ERROR_INVAL);
3522b15cb3dSCy Schubert
3532b15cb3dSCy Schubert js = "{\"a\": 1}";
3542b15cb3dSCy Schubert jsmn_init(&p);
355*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
356*276da39aSCy Schubert check(r >= 0);
3572b15cb3dSCy Schubert
3582b15cb3dSCy Schubert return 0;
3592b15cb3dSCy Schubert }
3602b15cb3dSCy Schubert
test_issue_22()361*276da39aSCy Schubert int test_issue_22() {
362*276da39aSCy Schubert int r;
363*276da39aSCy Schubert jsmn_parser p;
364*276da39aSCy Schubert jsmntok_t tokens[128];
365*276da39aSCy Schubert const char *js;
366*276da39aSCy Schubert
367*276da39aSCy Schubert js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, "
368*276da39aSCy Schubert "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", "
369*276da39aSCy Schubert "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], "
370*276da39aSCy Schubert "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, "
371*276da39aSCy Schubert "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", "
372*276da39aSCy Schubert "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", "
373*276da39aSCy Schubert "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], "
374*276da39aSCy Schubert "\"tilewidth\":32, \"version\":1, \"width\":10 }";
375*276da39aSCy Schubert jsmn_init(&p);
376*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 128);
377*276da39aSCy Schubert check(r >= 0);
378*276da39aSCy Schubert #if 0
379*276da39aSCy Schubert for (i = 1; tokens[i].end < tokens[0].end; i++) {
380*276da39aSCy Schubert if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) {
381*276da39aSCy Schubert printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start);
382*276da39aSCy Schubert } else if (tokens[i].type == JSMN_ARRAY) {
383*276da39aSCy Schubert printf("[%d elems]\n", tokens[i].size);
384*276da39aSCy Schubert } else if (tokens[i].type == JSMN_OBJECT) {
385*276da39aSCy Schubert printf("{%d elems}\n", tokens[i].size);
386*276da39aSCy Schubert } else {
387*276da39aSCy Schubert TOKEN_PRINT(tokens[i]);
388*276da39aSCy Schubert }
389*276da39aSCy Schubert }
390*276da39aSCy Schubert #endif
391*276da39aSCy Schubert return 0;
392*276da39aSCy Schubert }
393*276da39aSCy Schubert
test_unicode_characters()3942b15cb3dSCy Schubert int test_unicode_characters() {
3952b15cb3dSCy Schubert jsmn_parser p;
3962b15cb3dSCy Schubert jsmntok_t tokens[10];
3972b15cb3dSCy Schubert const char *js;
3982b15cb3dSCy Schubert
3992b15cb3dSCy Schubert int r;
4002b15cb3dSCy Schubert js = "{\"a\":\"\\uAbcD\"}";
4012b15cb3dSCy Schubert jsmn_init(&p);
402*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
403*276da39aSCy Schubert check(r >= 0);
4042b15cb3dSCy Schubert
4052b15cb3dSCy Schubert js = "{\"a\":\"str\\u0000\"}";
4062b15cb3dSCy Schubert jsmn_init(&p);
407*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
408*276da39aSCy Schubert check(r >= 0);
4092b15cb3dSCy Schubert
4102b15cb3dSCy Schubert js = "{\"a\":\"\\uFFFFstr\"}";
4112b15cb3dSCy Schubert jsmn_init(&p);
412*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
413*276da39aSCy Schubert check(r >= 0);
4142b15cb3dSCy Schubert
4152b15cb3dSCy Schubert js = "{\"a\":\"str\\uFFGFstr\"}";
4162b15cb3dSCy Schubert jsmn_init(&p);
417*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
4182b15cb3dSCy Schubert check(r == JSMN_ERROR_INVAL);
4192b15cb3dSCy Schubert
4202b15cb3dSCy Schubert js = "{\"a\":\"str\\u@FfF\"}";
4212b15cb3dSCy Schubert jsmn_init(&p);
422*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
4232b15cb3dSCy Schubert check(r == JSMN_ERROR_INVAL);
4242b15cb3dSCy Schubert
4252b15cb3dSCy Schubert js = "{\"a\":[\"\\u028\"]}";
4262b15cb3dSCy Schubert jsmn_init(&p);
427*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
4282b15cb3dSCy Schubert check(r == JSMN_ERROR_INVAL);
4292b15cb3dSCy Schubert
4302b15cb3dSCy Schubert js = "{\"a\":[\"\\u0280\"]}";
4312b15cb3dSCy Schubert jsmn_init(&p);
432*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
433*276da39aSCy Schubert check(r >= 0);
4342b15cb3dSCy Schubert
4352b15cb3dSCy Schubert return 0;
4362b15cb3dSCy Schubert }
4372b15cb3dSCy Schubert
test_input_length()438*276da39aSCy Schubert int test_input_length() {
439*276da39aSCy Schubert const char *js;
440*276da39aSCy Schubert int r;
441*276da39aSCy Schubert jsmn_parser p;
442*276da39aSCy Schubert jsmntok_t tokens[10];
443*276da39aSCy Schubert
444*276da39aSCy Schubert js = "{\"a\": 0}garbage";
445*276da39aSCy Schubert
446*276da39aSCy Schubert jsmn_init(&p);
447*276da39aSCy Schubert r = jsmn_parse(&p, js, 8, tokens, 10);
448*276da39aSCy Schubert check(r == 3);
449*276da39aSCy Schubert check(TOKEN_STRING(js, tokens[0], "{\"a\": 0}"));
450*276da39aSCy Schubert check(TOKEN_STRING(js, tokens[1], "a"));
451*276da39aSCy Schubert check(TOKEN_STRING(js, tokens[2], "0"));
452*276da39aSCy Schubert
453*276da39aSCy Schubert return 0;
454*276da39aSCy Schubert }
455*276da39aSCy Schubert
test_count()456*276da39aSCy Schubert int test_count() {
457*276da39aSCy Schubert jsmn_parser p;
458*276da39aSCy Schubert const char *js;
459*276da39aSCy Schubert
460*276da39aSCy Schubert js = "{}";
461*276da39aSCy Schubert jsmn_init(&p);
462*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
463*276da39aSCy Schubert
464*276da39aSCy Schubert js = "[]";
465*276da39aSCy Schubert jsmn_init(&p);
466*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
467*276da39aSCy Schubert
468*276da39aSCy Schubert js = "[[]]";
469*276da39aSCy Schubert jsmn_init(&p);
470*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2);
471*276da39aSCy Schubert
472*276da39aSCy Schubert js = "[[], []]";
473*276da39aSCy Schubert jsmn_init(&p);
474*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
475*276da39aSCy Schubert
476*276da39aSCy Schubert js = "[[], []]";
477*276da39aSCy Schubert jsmn_init(&p);
478*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
479*276da39aSCy Schubert
480*276da39aSCy Schubert js = "[[], [[]], [[], []]]";
481*276da39aSCy Schubert jsmn_init(&p);
482*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
483*276da39aSCy Schubert
484*276da39aSCy Schubert js = "[\"a\", [[], []]]";
485*276da39aSCy Schubert jsmn_init(&p);
486*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
487*276da39aSCy Schubert
488*276da39aSCy Schubert js = "[[], \"[], [[]]\", [[]]]";
489*276da39aSCy Schubert jsmn_init(&p);
490*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
491*276da39aSCy Schubert
492*276da39aSCy Schubert js = "[1, 2, 3]";
493*276da39aSCy Schubert jsmn_init(&p);
494*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4);
495*276da39aSCy Schubert
496*276da39aSCy Schubert js = "[1, 2, [3, \"a\"], null]";
497*276da39aSCy Schubert jsmn_init(&p);
498*276da39aSCy Schubert check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
499*276da39aSCy Schubert
500*276da39aSCy Schubert return 0;
501*276da39aSCy Schubert }
502*276da39aSCy Schubert
test_keyvalue()503*276da39aSCy Schubert int test_keyvalue() {
504*276da39aSCy Schubert const char *js;
505*276da39aSCy Schubert int r;
506*276da39aSCy Schubert jsmn_parser p;
507*276da39aSCy Schubert jsmntok_t tokens[10];
508*276da39aSCy Schubert
509*276da39aSCy Schubert js = "{\"a\": 0, \"b\": \"c\"}";
510*276da39aSCy Schubert
511*276da39aSCy Schubert jsmn_init(&p);
512*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
513*276da39aSCy Schubert check(r == 5);
514*276da39aSCy Schubert check(tokens[0].size == 2); /* two keys */
515*276da39aSCy Schubert check(tokens[1].size == 1 && tokens[3].size == 1); /* one value per key */
516*276da39aSCy Schubert check(tokens[2].size == 0 && tokens[4].size == 0); /* values have zero size */
517*276da39aSCy Schubert
518*276da39aSCy Schubert js = "{\"a\"\n0}";
519*276da39aSCy Schubert jsmn_init(&p);
520*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
521*276da39aSCy Schubert check(r == JSMN_ERROR_INVAL);
522*276da39aSCy Schubert
523*276da39aSCy Schubert js = "{\"a\", 0}";
524*276da39aSCy Schubert jsmn_init(&p);
525*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
526*276da39aSCy Schubert check(r == JSMN_ERROR_INVAL);
527*276da39aSCy Schubert
528*276da39aSCy Schubert js = "{\"a\": {2}}";
529*276da39aSCy Schubert jsmn_init(&p);
530*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
531*276da39aSCy Schubert check(r == JSMN_ERROR_INVAL);
532*276da39aSCy Schubert
533*276da39aSCy Schubert js = "{\"a\": {2: 3}}";
534*276da39aSCy Schubert jsmn_init(&p);
535*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
536*276da39aSCy Schubert check(r == JSMN_ERROR_INVAL);
537*276da39aSCy Schubert
538*276da39aSCy Schubert
539*276da39aSCy Schubert js = "{\"a\": {\"a\": 2 3}}";
540*276da39aSCy Schubert jsmn_init(&p);
541*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
542*276da39aSCy Schubert check(r == JSMN_ERROR_INVAL);
543*276da39aSCy Schubert return 0;
544*276da39aSCy Schubert }
545*276da39aSCy Schubert
546*276da39aSCy Schubert /** A huge redefinition of everything to include jsmn in non-script mode */
547*276da39aSCy Schubert #define jsmn_init jsmn_init_nonstrict
548*276da39aSCy Schubert #define jsmn_parse jsmn_parse_nonstrict
549*276da39aSCy Schubert #define jsmn_parser jsmn_parser_nonstrict
550*276da39aSCy Schubert #define jsmn_alloc_token jsmn_alloc_token_nonstrict
551*276da39aSCy Schubert #define jsmn_fill_token jsmn_fill_token_nonstrict
552*276da39aSCy Schubert #define jsmn_parse_primitive jsmn_parse_primitive_nonstrict
553*276da39aSCy Schubert #define jsmn_parse_string jsmn_parse_string_nonstrict
554*276da39aSCy Schubert #define jsmntype_t jsmntype_nonstrict_t
555*276da39aSCy Schubert #define jsmnerr_t jsmnerr_nonstrict_t
556*276da39aSCy Schubert #define jsmntok_t jsmntok_nonstrict_t
557*276da39aSCy Schubert #define JSMN_PRIMITIVE JSMN_PRIMITIVE_NONSTRICT
558*276da39aSCy Schubert #define JSMN_OBJECT JSMN_OBJECT_NONSTRICT
559*276da39aSCy Schubert #define JSMN_ARRAY JSMN_ARRAY_NONSTRICT
560*276da39aSCy Schubert #define JSMN_STRING JSMN_STRING_NONSTRICT
561*276da39aSCy Schubert #define JSMN_ERROR_NOMEM JSMN_ERROR_NOMEM_NONSTRICT
562*276da39aSCy Schubert #define JSMN_ERROR_INVAL JSMN_ERROR_INVAL_NONSTRICT
563*276da39aSCy Schubert #define JSMN_ERROR_PART JSMN_ERROR_PART_NONSTRICT
564*276da39aSCy Schubert #undef __JSMN_H_
565*276da39aSCy Schubert #undef JSMN_STRICT
566*276da39aSCy Schubert #include "jsmn.c"
567*276da39aSCy Schubert
test_nonstrict()568*276da39aSCy Schubert int test_nonstrict() {
569*276da39aSCy Schubert const char *js;
570*276da39aSCy Schubert int r;
571*276da39aSCy Schubert jsmn_parser p;
572*276da39aSCy Schubert jsmntok_t tokens[10];
573*276da39aSCy Schubert
574*276da39aSCy Schubert js = "a: 0garbage";
575*276da39aSCy Schubert
576*276da39aSCy Schubert jsmn_init(&p);
577*276da39aSCy Schubert r = jsmn_parse(&p, js, 4, tokens, 10);
578*276da39aSCy Schubert check(r == 2);
579*276da39aSCy Schubert check(TOKEN_STRING(js, tokens[0], "a"));
580*276da39aSCy Schubert check(TOKEN_STRING(js, tokens[1], "0"));
581*276da39aSCy Schubert
582*276da39aSCy Schubert js = "Day : 26\nMonth : Sep\n\nYear: 12";
583*276da39aSCy Schubert jsmn_init(&p);
584*276da39aSCy Schubert r = jsmn_parse(&p, js, strlen(js), tokens, 10);
585*276da39aSCy Schubert check(r == 6);
586*276da39aSCy Schubert return 0;
587*276da39aSCy Schubert }
588*276da39aSCy Schubert
main()5892b15cb3dSCy Schubert int main() {
5902b15cb3dSCy Schubert test(test_empty, "general test for a empty JSON objects/arrays");
5912b15cb3dSCy Schubert test(test_simple, "general test for a simple JSON string");
5922b15cb3dSCy Schubert test(test_primitive, "test primitive JSON data types");
5932b15cb3dSCy Schubert test(test_string, "test string JSON data types");
5942b15cb3dSCy Schubert test(test_partial_string, "test partial JSON string parsing");
5952b15cb3dSCy Schubert test(test_partial_array, "test partial array reading");
5962b15cb3dSCy Schubert test(test_array_nomem, "test array reading with a smaller number of tokens");
5972b15cb3dSCy Schubert test(test_unquoted_keys, "test unquoted keys (like in JavaScript)");
5982b15cb3dSCy Schubert test(test_objects_arrays, "test objects and arrays");
5992b15cb3dSCy Schubert test(test_unicode_characters, "test unicode characters");
600*276da39aSCy Schubert test(test_input_length, "test strings that are not null-terminated");
601*276da39aSCy Schubert test(test_issue_22, "test issue #22");
602*276da39aSCy Schubert test(test_count, "test tokens count estimation");
603*276da39aSCy Schubert test(test_nonstrict, "test for non-strict mode");
604*276da39aSCy Schubert test(test_keyvalue, "test for keys/values");
6052b15cb3dSCy Schubert printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed);
6062b15cb3dSCy Schubert return 0;
6072b15cb3dSCy Schubert }
6082b15cb3dSCy Schubert
609