1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 static int test_passed = 0;
6 static int test_failed = 0;
7 
8 /* Terminate current test with error */
9 #define fail()  return __LINE__
10 
11 /* Successfull end of the test case */
12 #define done() return 0
13 
14 /* Check single condition */
15 #define check(cond) do { if (!(cond)) fail(); } while (0)
16 
17 /* Test runner */
test(int (* func)(void),const char * name)18 static void test(int (*func)(void), const char *name) {
19   int r = func();
20   if (r == 0) {
21     test_passed++;
22   } else {
23     test_failed++;
24     printf("FAILED: %s (at line %d)\n", name, r);
25   }
26 }
27 
28 #define TOKEN_EQ(t, tok_start, tok_end, tok_type) \
29   ((t).start == tok_start \
30    && (t).end == tok_end  \
31    && (t).type == (tok_type))
32 
33 #define TOKEN_STRING(js, t, s) \
34   (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \
35    && strlen(s) == (t).end - (t).start)
36 
37 #define TOKEN_PRINT(t) \
38   printf("start: %d, end: %d, type: %d, size: %d\n", \
39       (t).start, (t).end, (t).type, (t).size)
40 
41 #define JSMN_STRICT
42 #include "jsmn.c"
43 
test_empty()44 int test_empty() {
45   const char *js;
46   int r;
47   jsmn_parser p;
48   jsmntok_t t[10];
49 
50   js = "{}";
51   jsmn_init(&p);
52   r = jsmn_parse(&p, js, strlen(js), t, 10);
53   check(r >= 0);
54   check(t[0].type == JSMN_OBJECT);
55   check(t[0].start == 0 && t[0].end == 2);
56 
57   js = "[]";
58   jsmn_init(&p);
59   r = jsmn_parse(&p, js, strlen(js), t, 10);
60   check(r >= 0);
61   check(t[0].type == JSMN_ARRAY);
62   check(t[0].start == 0 && t[0].end == 2);
63 
64   js = "{\"a\":[]}";
65   jsmn_init(&p);
66   r = jsmn_parse(&p, js, strlen(js), t, 10);
67   check(r >= 0);
68   check(t[0].type == JSMN_OBJECT && t[0].start == 0 && t[0].end == 8);
69   check(t[1].type == JSMN_STRING && t[1].start == 2 && t[1].end == 3);
70   check(t[2].type == JSMN_ARRAY && t[2].start == 5 && t[2].end == 7);
71 
72   js = "[{},{}]";
73   jsmn_init(&p);
74   r = jsmn_parse(&p, js, strlen(js), t, 10);
75   check(r >= 0);
76   check(t[0].type == JSMN_ARRAY && t[0].start == 0 && t[0].end == 7);
77   check(t[1].type == JSMN_OBJECT && t[1].start == 1 && t[1].end == 3);
78   check(t[2].type == JSMN_OBJECT && t[2].start == 4 && t[2].end == 6);
79   return 0;
80 }
81 
test_simple()82 int test_simple() {
83   const char *js;
84   int r;
85   jsmn_parser p;
86   jsmntok_t tokens[10];
87 
88   js = "{\"a\": 0}";
89 
90   jsmn_init(&p);
91   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
92   check(r >= 0);
93   check(TOKEN_EQ(tokens[0], 0, 8, JSMN_OBJECT));
94   check(TOKEN_EQ(tokens[1], 2, 3, JSMN_STRING));
95   check(TOKEN_EQ(tokens[2], 6, 7, JSMN_PRIMITIVE));
96 
97   check(TOKEN_STRING(js, tokens[0], js));
98   check(TOKEN_STRING(js, tokens[1], "a"));
99   check(TOKEN_STRING(js, tokens[2], "0"));
100 
101   jsmn_init(&p);
102   js = "[\"a\":{},\"b\":{}]";
103   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
104   check(r >= 0);
105 
106   jsmn_init(&p);
107   js = "{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }";
108   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
109   check(r >= 0);
110 
111   return 0;
112 }
113 
test_primitive()114 int test_primitive() {
115   int r;
116   jsmn_parser p;
117   jsmntok_t tok[10];
118   const char *js;
119 #ifndef JSMN_STRICT
120   js = "\"boolVar\" : true";
121   jsmn_init(&p);
122   r = jsmn_parse(&p, js, strlen(js), tok, 10);
123   check(r >= 0 && tok[0].type == JSMN_STRING
124       && tok[1].type == JSMN_PRIMITIVE);
125   check(TOKEN_STRING(js, tok[0], "boolVar"));
126   check(TOKEN_STRING(js, tok[1], "true"));
127 
128   js = "\"boolVar\" : false";
129   jsmn_init(&p);
130   r = jsmn_parse(&p, js, strlen(js), tok, 10);
131   check(r >= 0 && tok[0].type == JSMN_STRING
132       && tok[1].type == JSMN_PRIMITIVE);
133   check(TOKEN_STRING(js, tok[0], "boolVar"));
134   check(TOKEN_STRING(js, tok[1], "false"));
135 
136   js = "\"intVar\" : 12345";
137   jsmn_init(&p);
138   r = jsmn_parse(&p, js, strlen(js), tok, 10);
139   check(r >= 0 && tok[0].type == JSMN_STRING
140       && tok[1].type == JSMN_PRIMITIVE);
141   check(TOKEN_STRING(js, tok[0], "intVar"));
142   check(TOKEN_STRING(js, tok[1], "12345"));
143 
144   js = "\"floatVar\" : 12.345";
145   jsmn_init(&p);
146   r = jsmn_parse(&p, js, strlen(js), tok, 10);
147   check(r >= 0 && tok[0].type == JSMN_STRING
148       && tok[1].type == JSMN_PRIMITIVE);
149   check(TOKEN_STRING(js, tok[0], "floatVar"));
150   check(TOKEN_STRING(js, tok[1], "12.345"));
151 
152   js = "\"nullVar\" : null";
153   jsmn_init(&p);
154   r = jsmn_parse(&p, js, strlen(js), tok, 10);
155   check(r >= 0 && tok[0].type == JSMN_STRING
156       && tok[1].type == JSMN_PRIMITIVE);
157   check(TOKEN_STRING(js, tok[0], "nullVar"));
158   check(TOKEN_STRING(js, tok[1], "null"));
159 #endif
160   return 0;
161 }
162 
test_string()163 int test_string() {
164   int r;
165   jsmn_parser p;
166   jsmntok_t tok[10];
167   const char *js;
168 
169   js = "\"strVar\" : \"hello world\"";
170   jsmn_init(&p);
171   r = jsmn_parse(&p, js, strlen(js), tok, 10);
172   check(r >= 0 && tok[0].type == JSMN_STRING
173       && tok[1].type == JSMN_STRING);
174   check(TOKEN_STRING(js, tok[0], "strVar"));
175   check(TOKEN_STRING(js, tok[1], "hello world"));
176 
177   js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"";
178   jsmn_init(&p);
179   r = jsmn_parse(&p, js, strlen(js), tok, 10);
180   check(r >= 0 && tok[0].type == JSMN_STRING
181       && tok[1].type == JSMN_STRING);
182   check(TOKEN_STRING(js, tok[0], "strVar"));
183   check(TOKEN_STRING(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\"));
184 
185   js = "\"strVar\" : \"\"";
186   jsmn_init(&p);
187   r = jsmn_parse(&p, js, strlen(js), tok, 10);
188   check(r >= 0 && tok[0].type == JSMN_STRING
189       && tok[1].type == JSMN_STRING);
190   check(TOKEN_STRING(js, tok[0], "strVar"));
191   check(TOKEN_STRING(js, tok[1], ""));
192 
193   return 0;
194 }
195 
test_partial_string()196 int test_partial_string() {
197   int r;
198   jsmn_parser p;
199   jsmntok_t tok[10];
200   const char *js;
201 
202   jsmn_init(&p);
203   js = "\"x\": \"va";
204   r = jsmn_parse(&p, js, strlen(js), tok, 10);
205   check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING);
206   check(TOKEN_STRING(js, tok[0], "x"));
207   check(p.toknext == 1);
208 
209   js = "\"x\": \"valu";
210   r = jsmn_parse(&p, js, strlen(js), tok, 10);
211   check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING);
212   check(TOKEN_STRING(js, tok[0], "x"));
213   check(p.toknext == 1);
214 
215   js = "\"x\": \"value\"";
216   r = jsmn_parse(&p, js, strlen(js), tok, 10);
217   check(r >= 0 && tok[0].type == JSMN_STRING
218       && tok[1].type == JSMN_STRING);
219   check(TOKEN_STRING(js, tok[0], "x"));
220   check(TOKEN_STRING(js, tok[1], "value"));
221 
222   js = "\"x\": \"value\", \"y\": \"value y\"";
223   r = jsmn_parse(&p, js, strlen(js), tok, 10);
224   check(r >= 0 && tok[0].type == JSMN_STRING
225       && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING
226       && tok[3].type == JSMN_STRING);
227   check(TOKEN_STRING(js, tok[0], "x"));
228   check(TOKEN_STRING(js, tok[1], "value"));
229   check(TOKEN_STRING(js, tok[2], "y"));
230   check(TOKEN_STRING(js, tok[3], "value y"));
231 
232   return 0;
233 }
234 
test_unquoted_keys()235 int test_unquoted_keys() {
236 #ifndef JSMN_STRICT
237   int r;
238   jsmn_parser p;
239   jsmntok_t tok[10];
240   const char *js;
241 
242   jsmn_init(&p);
243   js = "key1: \"value\"\nkey2 : 123";
244 
245   r = jsmn_parse(&p, js, strlen(js), tok, 10);
246   check(r >= 0 && tok[0].type == JSMN_PRIMITIVE
247       && tok[1].type == JSMN_STRING && tok[2].type == JSMN_PRIMITIVE
248       && tok[3].type == JSMN_PRIMITIVE);
249   check(TOKEN_STRING(js, tok[0], "key1"));
250   check(TOKEN_STRING(js, tok[1], "value"));
251   check(TOKEN_STRING(js, tok[2], "key2"));
252   check(TOKEN_STRING(js, tok[3], "123"));
253 #endif
254   return 0;
255 }
256 
test_partial_array()257 int test_partial_array() {
258   int r;
259   jsmn_parser p;
260   jsmntok_t tok[10];
261   const char *js;
262 
263   jsmn_init(&p);
264   js = "  [ 1, true, ";
265   r = jsmn_parse(&p, js, strlen(js), tok, 10);
266   check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
267       && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE);
268 
269   js = "  [ 1, true, [123, \"hello";
270   r = jsmn_parse(&p, js, strlen(js), tok, 10);
271   check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
272       && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
273       && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE);
274 
275   js = "  [ 1, true, [123, \"hello\"]";
276   r = jsmn_parse(&p, js, strlen(js), tok, 10);
277   check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY
278       && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
279       && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE
280       && tok[5].type == JSMN_STRING);
281   /* check child nodes of the 2nd array */
282   check(tok[3].size == 2);
283 
284   js = "  [ 1, true, [123, \"hello\"]]";
285   r = jsmn_parse(&p, js, strlen(js), tok, 10);
286   check(r >= 0 && tok[0].type == JSMN_ARRAY
287       && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE
288       && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE
289       && tok[5].type == JSMN_STRING);
290   check(tok[3].size == 2);
291   check(tok[0].size == 3);
292   return 0;
293 }
294 
test_array_nomem()295 int test_array_nomem() {
296   int i;
297   int r;
298   jsmn_parser p;
299   jsmntok_t toksmall[10], toklarge[10];
300   const char *js;
301 
302   js = "  [ 1, true, [123, \"hello\"]]";
303 
304   for (i = 0; i < 6; i++) {
305     jsmn_init(&p);
306     memset(toksmall, 0, sizeof(toksmall));
307     memset(toklarge, 0, sizeof(toklarge));
308     r = jsmn_parse(&p, js, strlen(js), toksmall, i);
309     check(r == JSMN_ERROR_NOMEM);
310 
311     memcpy(toklarge, toksmall, sizeof(toksmall));
312 
313     r = jsmn_parse(&p, js, strlen(js), toklarge, 10);
314     check(r >= 0);
315 
316     check(toklarge[0].type == JSMN_ARRAY && toklarge[0].size == 3);
317     check(toklarge[3].type == JSMN_ARRAY && toklarge[3].size == 2);
318   }
319   return 0;
320 }
321 
test_objects_arrays()322 int test_objects_arrays() {
323   int i;
324   int r;
325   jsmn_parser p;
326   jsmntok_t tokens[10];
327   const char *js;
328 
329   js = "[10}";
330   jsmn_init(&p);
331   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
332   check(r == JSMN_ERROR_INVAL);
333 
334   js = "[10]";
335   jsmn_init(&p);
336   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
337   check(r >= 0);
338 
339   js = "{\"a\": 1]";
340   jsmn_init(&p);
341   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
342   check(r == JSMN_ERROR_INVAL);
343 
344   js = "{\"a\": 1}";
345   jsmn_init(&p);
346   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
347   check(r >= 0);
348 
349   return 0;
350 }
351 
test_issue_22()352 int test_issue_22() {
353   int i;
354   int r;
355   jsmn_parser p;
356   jsmntok_t tokens[128];
357   const char *js;
358 
359   js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, "
360     "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", "
361     "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], "
362     "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, "
363     "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", "
364     "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", "
365     "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], "
366     "\"tilewidth\":32, \"version\":1, \"width\":10 }";
367   jsmn_init(&p);
368   r = jsmn_parse(&p, js, strlen(js), tokens, 128);
369   check(r >= 0);
370 #if 0
371   for (i = 1; tokens[i].end < tokens[0].end; i++) {
372     if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) {
373       printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start);
374     } else if (tokens[i].type == JSMN_ARRAY) {
375       printf("[%d elems]\n", tokens[i].size);
376     } else if (tokens[i].type == JSMN_OBJECT) {
377       printf("{%d elems}\n", tokens[i].size);
378     } else {
379       TOKEN_PRINT(tokens[i]);
380     }
381   }
382 #endif
383   return 0;
384 }
385 
test_unicode_characters()386 int test_unicode_characters() {
387   jsmn_parser p;
388   jsmntok_t tokens[10];
389   const char *js;
390 
391   int r;
392   js = "{\"a\":\"\\uAbcD\"}";
393   jsmn_init(&p);
394   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
395   check(r >= 0);
396 
397   js = "{\"a\":\"str\\u0000\"}";
398   jsmn_init(&p);
399   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
400   check(r >= 0);
401 
402   js = "{\"a\":\"\\uFFFFstr\"}";
403   jsmn_init(&p);
404   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
405   check(r >= 0);
406 
407   js = "{\"a\":\"str\\uFFGFstr\"}";
408   jsmn_init(&p);
409   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
410   check(r == JSMN_ERROR_INVAL);
411 
412   js = "{\"a\":\"str\\u@FfF\"}";
413   jsmn_init(&p);
414   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
415   check(r == JSMN_ERROR_INVAL);
416 
417   js = "{\"a\":[\"\\u028\"]}";
418   jsmn_init(&p);
419   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
420   check(r == JSMN_ERROR_INVAL);
421 
422   js = "{\"a\":[\"\\u0280\"]}";
423   jsmn_init(&p);
424   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
425   check(r >= 0);
426 
427   return 0;
428 }
429 
test_input_length()430 int test_input_length() {
431   const char *js;
432   int r;
433   jsmn_parser p;
434   jsmntok_t tokens[10];
435 
436   js = "{\"a\": 0}garbage";
437 
438   jsmn_init(&p);
439   r = jsmn_parse(&p, js, 8, tokens, 10);
440   check(r == 3);
441   check(TOKEN_STRING(js, tokens[0], "{\"a\": 0}"));
442   check(TOKEN_STRING(js, tokens[1], "a"));
443   check(TOKEN_STRING(js, tokens[2], "0"));
444 
445   return 0;
446 }
447 
test_jwk()448 int test_jwk() {
449   const char *js;
450   int i, r, num_tokens;
451   jsmn_parser p;
452   jsmntok_t* tokens;
453 
454   js = "{\"keys\":"
455           "[{ \"kty\":\"oct\""
456           "\"alg\":\"A128KW1\""
457           "\"kid\":\"1-67ef0gd8pvfd0=\""
458           "\"k\":\"1-GawgguFyGrWKav7AX4VKUg\""
459           "}"
460           "{ \"kty\":\"oct\""
461           "\"alg\":\"A128KW2\""
462           "\"kid\":\"2-67ef0gd8pvfd0=\""
463           "\"k\":\"2-GawgguFyGrWKav7AX4VKUg\""
464           "}" \
465           "{ \"kty\":\"oct\""
466           "\"alg\":\"A128KW3\""
467           "\"kid\""
468           "\"k\":\"3-GawgguFyGrWKav7AX4VKUg\""
469           "}]"
470   "}";
471 
472   jsmn_init(&p);
473   num_tokens = jsmn_parse(&p, js, strlen(js), NULL, 0);
474   printf("num_tokens=%d, len=%lu\n", num_tokens, strlen(js));
475 
476   unsigned int tokens_size = num_tokens * sizeof(jsmntok_t);
477   tokens = malloc(tokens_size);
478   if (tokens == NULL) {
479     printf("!!! failed to alloc for %d tokens, size=%u\n", num_tokens,
480         tokens_size);
481     return -1;
482   }
483   jsmn_init(&p);
484   memset(tokens, 0, tokens_size);
485   r = jsmn_parse(&p, js, strlen(js), tokens, num_tokens);
486 
487   for (i = 0; i < num_tokens; ++i) {
488     int j;
489     const char *pjs = js + tokens[i].start;
490     if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) {
491       for (j = 0; j < tokens[i].end - tokens[i].start; ++j) {
492         printf("%c", *pjs++);
493       }
494       printf("\n");
495     }
496   }
497 
498   free(tokens);
499   return 0;
500 }
501 
test_count()502 int test_count() {
503   jsmn_parser p;
504   const char *js;
505   int r;
506 
507   js = "{}";
508   jsmn_init(&p);
509   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
510   check(r == 1);
511 
512   js = "[]";
513   jsmn_init(&p);
514   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
515   check(r == 1);
516 
517   js = "[[]]";
518   jsmn_init(&p);
519   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
520   check(r == 2);
521 
522   js = "[[], []]";
523   jsmn_init(&p);
524   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
525   check(r == 3);
526 
527   js = "[[], []]";
528   jsmn_init(&p);
529   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
530   check(r == 3);
531 
532   js = "[[], [[]], [[], []]]";
533   jsmn_init(&p);
534   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
535   check(r == 7);
536 
537   js = "[\"a\", [[], []]]";
538   jsmn_init(&p);
539   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
540   check(r == 5);
541 
542   js = "[[], \"[], [[]]\", [[]]]";
543   jsmn_init(&p);
544   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
545   check(r == 5);
546 
547   js = "[1, 2, 3]";
548   jsmn_init(&p);
549   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
550   check(r == 4);
551 
552   js = "[1, 2, [3, \"a\"], null]";
553   jsmn_init(&p);
554   r = jsmn_parse(&p, js, strlen(js), NULL, 0);
555   check(r == 7);
556 
557   return 0;
558 }
559 
560 /** A huge redefinition of everything to include jsmn in non-script mode */
561 #define jsmn_init jsmn_init_nonstrict
562 #define jsmn_parse jsmn_parse_nonstrict
563 #define jsmn_parser jsmn_parser_nonstrict
564 #define jsmn_alloc_token jsmn_alloc_token_nonstrict
565 #define jsmn_fill_token jsmn_fill_token_nonstrict
566 #define jsmn_parse_primitive jsmn_parse_primitive_nonstrict
567 #define jsmn_parse_string jsmn_parse_string_nonstrict
568 #define jsmntype_t jsmntype_nonstrict_t
569 #define jsmnerr_t jsmnerr_nonstrict_t
570 #define jsmntok_t jsmntok_nonstrict_t
571 #define JSMN_PRIMITIVE JSMN_PRIMITIVE_NONSTRICT
572 #define JSMN_OBJECT JSMN_OBJECT_NONSTRICT
573 #define JSMN_ARRAY JSMN_ARRAY_NONSTRICT
574 #define JSMN_STRING JSMN_STRING_NONSTRICT
575 #define JSMN_ERROR_NOMEM JSMN_ERROR_NOMEM_NONSTRICT
576 #define JSMN_ERROR_INVAL JSMN_ERROR_INVAL_NONSTRICT
577 #define JSMN_ERROR_PART JSMN_ERROR_PART_NONSTRICT
578 #undef __JSMN_H_
579 #undef JSMN_STRICT
580 #include "jsmn.c"
581 
test_nonstrict()582 int test_nonstrict() {
583   const char *js;
584   int r;
585   jsmn_parser p;
586   jsmntok_t tokens[10];
587 
588   js = "a: 0garbage";
589 
590   jsmn_init(&p);
591   r = jsmn_parse(&p, js, 4, tokens, 10);
592   check(r == 2);
593   check(TOKEN_STRING(js, tokens[0], "a"));
594   check(TOKEN_STRING(js, tokens[1], "0"));
595 
596   js = "Day : 26\nMonth : Sep\n\nYear: 12";
597   jsmn_init(&p);
598   r = jsmn_parse(&p, js, strlen(js), tokens, 10);
599   check(r == 6);
600   return 0;
601 }
602 
main()603 int main() {
604 
605   test(test_empty, "general test for a empty JSON objects/arrays");
606   test(test_simple, "general test for a simple JSON string");
607   test(test_primitive, "test primitive JSON data types");
608   test(test_string, "test string JSON data types");
609   test(test_partial_string, "test partial JSON string parsing");
610   test(test_partial_array, "test partial array reading");
611   test(test_array_nomem, "test array reading with a smaller number of tokens");
612   test(test_unquoted_keys, "test unquoted keys (like in JavaScript)");
613   test(test_objects_arrays, "test objects and arrays");
614   test(test_unicode_characters, "test unicode characters");
615   test(test_input_length, "test strings that are not null-terminated");
616   test(test_issue_22, "test issue #22");
617   test(test_count, "test tokens count estimation");
618   test(test_nonstrict, "test for non-strict mode");
619 
620   test(test_jwk, "test jwk");
621   printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed);
622   return 0;
623 }