Home | History | Annotate | Download | only in jsmn
      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 */
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 }