1275970Scy#include <stdio.h> 2275970Scy#include <stdlib.h> 3275970Scy#include <string.h> 4275970Scy 5275970Scystatic int test_passed = 0; 6275970Scystatic int test_failed = 0; 7275970Scy 8275970Scy/* Terminate current test with error */ 9275970Scy#define fail() return __LINE__ 10275970Scy 11275970Scy/* Successfull end of the test case */ 12275970Scy#define done() return 0 13275970Scy 14275970Scy/* Check single condition */ 15275970Scy#define check(cond) do { if (!(cond)) fail(); } while (0) 16275970Scy 17275970Scy/* Test runner */ 18275970Scystatic void test(int (*func)(void), const char *name) { 19275970Scy int r = func(); 20275970Scy if (r == 0) { 21275970Scy test_passed++; 22275970Scy } else { 23275970Scy test_failed++; 24275970Scy printf("FAILED: %s (at line %d)\n", name, r); 25275970Scy } 26275970Scy} 27275970Scy 28275970Scy#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ 29275970Scy ((t).start == tok_start \ 30275970Scy && (t).end == tok_end \ 31275970Scy && (t).type == (tok_type)) 32275970Scy 33275970Scy#define TOKEN_STRING(js, t, s) \ 34275970Scy (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ 35275970Scy && strlen(s) == (t).end - (t).start) 36275970Scy 37275970Scy#define TOKEN_PRINT(t) \ 38275970Scy printf("start: %d, end: %d, type: %d, size: %d\n", \ 39275970Scy (t).start, (t).end, (t).type, (t).size) 40275970Scy 41285169Scy#define JSMN_STRICT 42285169Scy#include "jsmn.c" 43285169Scy 44275970Scyint test_empty() { 45275970Scy const char *js; 46275970Scy int r; 47275970Scy jsmn_parser p; 48275970Scy jsmntok_t t[10]; 49275970Scy 50275970Scy js = "{}"; 51275970Scy jsmn_init(&p); 52285169Scy r = jsmn_parse(&p, js, strlen(js), t, 10); 53285169Scy check(r >= 0); 54275970Scy check(t[0].type == JSMN_OBJECT); 55275970Scy check(t[0].start == 0 && t[0].end == 2); 56275970Scy 57275970Scy js = "[]"; 58275970Scy jsmn_init(&p); 59285169Scy r = jsmn_parse(&p, js, strlen(js), t, 10); 60285169Scy check(r >= 0); 61275970Scy check(t[0].type == JSMN_ARRAY); 62275970Scy check(t[0].start == 0 && t[0].end == 2); 63275970Scy 64275970Scy js = "{\"a\":[]}"; 65275970Scy jsmn_init(&p); 66285169Scy r = jsmn_parse(&p, js, strlen(js), t, 10); 67285169Scy check(r >= 0); 68275970Scy check(t[0].type == JSMN_OBJECT && t[0].start == 0 && t[0].end == 8); 69275970Scy check(t[1].type == JSMN_STRING && t[1].start == 2 && t[1].end == 3); 70275970Scy check(t[2].type == JSMN_ARRAY && t[2].start == 5 && t[2].end == 7); 71275970Scy 72275970Scy js = "[{},{}]"; 73275970Scy jsmn_init(&p); 74285169Scy r = jsmn_parse(&p, js, strlen(js), t, 10); 75285169Scy check(r >= 0); 76275970Scy check(t[0].type == JSMN_ARRAY && t[0].start == 0 && t[0].end == 7); 77275970Scy check(t[1].type == JSMN_OBJECT && t[1].start == 1 && t[1].end == 3); 78275970Scy check(t[2].type == JSMN_OBJECT && t[2].start == 4 && t[2].end == 6); 79275970Scy return 0; 80275970Scy} 81275970Scy 82275970Scyint test_simple() { 83275970Scy const char *js; 84275970Scy int r; 85275970Scy jsmn_parser p; 86275970Scy jsmntok_t tokens[10]; 87275970Scy 88275970Scy js = "{\"a\": 0}"; 89275970Scy 90275970Scy jsmn_init(&p); 91285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 92285169Scy check(r >= 0); 93275970Scy check(TOKEN_EQ(tokens[0], 0, 8, JSMN_OBJECT)); 94275970Scy check(TOKEN_EQ(tokens[1], 2, 3, JSMN_STRING)); 95275970Scy check(TOKEN_EQ(tokens[2], 6, 7, JSMN_PRIMITIVE)); 96275970Scy 97275970Scy check(TOKEN_STRING(js, tokens[0], js)); 98275970Scy check(TOKEN_STRING(js, tokens[1], "a")); 99275970Scy check(TOKEN_STRING(js, tokens[2], "0")); 100275970Scy 101275970Scy jsmn_init(&p); 102275970Scy js = "[\"a\":{},\"b\":{}]"; 103285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 104285169Scy check(r >= 0); 105275970Scy 106275970Scy jsmn_init(&p); 107275970Scy js = "{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }"; 108285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 109285169Scy check(r >= 0); 110275970Scy 111275970Scy return 0; 112275970Scy} 113275970Scy 114275970Scyint test_primitive() { 115285169Scy#ifndef JSMN_STRICT 116275970Scy int r; 117275970Scy jsmn_parser p; 118275970Scy jsmntok_t tok[10]; 119275970Scy const char *js; 120275970Scy js = "\"boolVar\" : true"; 121275970Scy jsmn_init(&p); 122285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 123285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 124275970Scy && tok[1].type == JSMN_PRIMITIVE); 125275970Scy check(TOKEN_STRING(js, tok[0], "boolVar")); 126275970Scy check(TOKEN_STRING(js, tok[1], "true")); 127275970Scy 128275970Scy js = "\"boolVar\" : false"; 129275970Scy jsmn_init(&p); 130285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 131285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 132275970Scy && tok[1].type == JSMN_PRIMITIVE); 133275970Scy check(TOKEN_STRING(js, tok[0], "boolVar")); 134275970Scy check(TOKEN_STRING(js, tok[1], "false")); 135275970Scy 136275970Scy js = "\"intVar\" : 12345"; 137275970Scy jsmn_init(&p); 138285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 139285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 140275970Scy && tok[1].type == JSMN_PRIMITIVE); 141275970Scy check(TOKEN_STRING(js, tok[0], "intVar")); 142275970Scy check(TOKEN_STRING(js, tok[1], "12345")); 143275970Scy 144275970Scy js = "\"floatVar\" : 12.345"; 145275970Scy jsmn_init(&p); 146285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 147285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 148275970Scy && tok[1].type == JSMN_PRIMITIVE); 149275970Scy check(TOKEN_STRING(js, tok[0], "floatVar")); 150275970Scy check(TOKEN_STRING(js, tok[1], "12.345")); 151275970Scy 152275970Scy js = "\"nullVar\" : null"; 153275970Scy jsmn_init(&p); 154285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 155285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 156275970Scy && tok[1].type == JSMN_PRIMITIVE); 157275970Scy check(TOKEN_STRING(js, tok[0], "nullVar")); 158275970Scy check(TOKEN_STRING(js, tok[1], "null")); 159275970Scy#endif 160275970Scy return 0; 161275970Scy} 162275970Scy 163275970Scyint test_string() { 164275970Scy int r; 165275970Scy jsmn_parser p; 166275970Scy jsmntok_t tok[10]; 167275970Scy const char *js; 168275970Scy 169275970Scy js = "\"strVar\" : \"hello world\""; 170275970Scy jsmn_init(&p); 171285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 172285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 173275970Scy && tok[1].type == JSMN_STRING); 174275970Scy check(TOKEN_STRING(js, tok[0], "strVar")); 175275970Scy check(TOKEN_STRING(js, tok[1], "hello world")); 176275970Scy 177275970Scy js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\""; 178275970Scy jsmn_init(&p); 179285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 180285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 181275970Scy && tok[1].type == JSMN_STRING); 182275970Scy check(TOKEN_STRING(js, tok[0], "strVar")); 183275970Scy check(TOKEN_STRING(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\")); 184275970Scy 185275970Scy js = "\"strVar\" : \"\""; 186275970Scy jsmn_init(&p); 187285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 188285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 189275970Scy && tok[1].type == JSMN_STRING); 190275970Scy check(TOKEN_STRING(js, tok[0], "strVar")); 191275970Scy check(TOKEN_STRING(js, tok[1], "")); 192275970Scy 193275970Scy return 0; 194275970Scy} 195275970Scy 196275970Scyint test_partial_string() { 197275970Scy int r; 198275970Scy jsmn_parser p; 199275970Scy jsmntok_t tok[10]; 200275970Scy const char *js; 201275970Scy 202275970Scy jsmn_init(&p); 203275970Scy js = "\"x\": \"va"; 204285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 205275970Scy check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); 206275970Scy check(TOKEN_STRING(js, tok[0], "x")); 207275970Scy check(p.toknext == 1); 208275970Scy 209285169Scy jsmn_init(&p); 210285169Scy char js_slash[9] = "\"x\": \"va\\"; 211285169Scy r = jsmn_parse(&p, js_slash, sizeof(js_slash), tok, 10); 212285169Scy check(r == JSMN_ERROR_PART); 213285169Scy 214285169Scy jsmn_init(&p); 215285169Scy char js_unicode[10] = "\"x\": \"va\\u"; 216285169Scy r = jsmn_parse(&p, js_unicode, sizeof(js_unicode), tok, 10); 217285169Scy check(r == JSMN_ERROR_PART); 218285169Scy 219275970Scy js = "\"x\": \"valu"; 220285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 221275970Scy check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); 222275970Scy check(TOKEN_STRING(js, tok[0], "x")); 223275970Scy check(p.toknext == 1); 224275970Scy 225275970Scy js = "\"x\": \"value\""; 226285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 227285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 228275970Scy && tok[1].type == JSMN_STRING); 229275970Scy check(TOKEN_STRING(js, tok[0], "x")); 230275970Scy check(TOKEN_STRING(js, tok[1], "value")); 231275970Scy 232275970Scy js = "\"x\": \"value\", \"y\": \"value y\""; 233285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 234285169Scy check(r >= 0 && tok[0].type == JSMN_STRING 235275970Scy && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING 236275970Scy && tok[3].type == JSMN_STRING); 237275970Scy check(TOKEN_STRING(js, tok[0], "x")); 238275970Scy check(TOKEN_STRING(js, tok[1], "value")); 239275970Scy check(TOKEN_STRING(js, tok[2], "y")); 240275970Scy check(TOKEN_STRING(js, tok[3], "value y")); 241275970Scy 242275970Scy return 0; 243275970Scy} 244275970Scy 245275970Scyint test_unquoted_keys() { 246275970Scy#ifndef JSMN_STRICT 247275970Scy int r; 248275970Scy jsmn_parser p; 249275970Scy jsmntok_t tok[10]; 250275970Scy const char *js; 251275970Scy 252275970Scy jsmn_init(&p); 253275970Scy js = "key1: \"value\"\nkey2 : 123"; 254275970Scy 255285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 256285169Scy check(r >= 0 && tok[0].type == JSMN_PRIMITIVE 257275970Scy && tok[1].type == JSMN_STRING && tok[2].type == JSMN_PRIMITIVE 258275970Scy && tok[3].type == JSMN_PRIMITIVE); 259275970Scy check(TOKEN_STRING(js, tok[0], "key1")); 260275970Scy check(TOKEN_STRING(js, tok[1], "value")); 261275970Scy check(TOKEN_STRING(js, tok[2], "key2")); 262275970Scy check(TOKEN_STRING(js, tok[3], "123")); 263275970Scy#endif 264275970Scy return 0; 265275970Scy} 266275970Scy 267275970Scyint test_partial_array() { 268275970Scy int r; 269275970Scy jsmn_parser p; 270275970Scy jsmntok_t tok[10]; 271275970Scy const char *js; 272275970Scy 273275970Scy jsmn_init(&p); 274275970Scy js = " [ 1, true, "; 275285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 276285169Scy check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 277275970Scy && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE); 278275970Scy 279275970Scy js = " [ 1, true, [123, \"hello"; 280285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 281285169Scy check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 282275970Scy && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 283275970Scy && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE); 284275970Scy 285275970Scy js = " [ 1, true, [123, \"hello\"]"; 286285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 287285169Scy check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 288275970Scy && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 289275970Scy && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE 290275970Scy && tok[5].type == JSMN_STRING); 291275970Scy /* check child nodes of the 2nd array */ 292275970Scy check(tok[3].size == 2); 293275970Scy 294275970Scy js = " [ 1, true, [123, \"hello\"]]"; 295285169Scy r = jsmn_parse(&p, js, strlen(js), tok, 10); 296285169Scy check(r >= 0 && tok[0].type == JSMN_ARRAY 297275970Scy && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 298275970Scy && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE 299275970Scy && tok[5].type == JSMN_STRING); 300275970Scy check(tok[3].size == 2); 301275970Scy check(tok[0].size == 3); 302275970Scy return 0; 303275970Scy} 304275970Scy 305275970Scyint test_array_nomem() { 306275970Scy int i; 307275970Scy int r; 308275970Scy jsmn_parser p; 309275970Scy jsmntok_t toksmall[10], toklarge[10]; 310275970Scy const char *js; 311275970Scy 312275970Scy js = " [ 1, true, [123, \"hello\"]]"; 313275970Scy 314275970Scy for (i = 0; i < 6; i++) { 315275970Scy jsmn_init(&p); 316275970Scy memset(toksmall, 0, sizeof(toksmall)); 317275970Scy memset(toklarge, 0, sizeof(toklarge)); 318285169Scy r = jsmn_parse(&p, js, strlen(js), toksmall, i); 319275970Scy check(r == JSMN_ERROR_NOMEM); 320275970Scy 321275970Scy memcpy(toklarge, toksmall, sizeof(toksmall)); 322275970Scy 323285169Scy r = jsmn_parse(&p, js, strlen(js), toklarge, 10); 324285169Scy check(r >= 0); 325275970Scy 326275970Scy check(toklarge[0].type == JSMN_ARRAY && toklarge[0].size == 3); 327275970Scy check(toklarge[3].type == JSMN_ARRAY && toklarge[3].size == 2); 328275970Scy } 329275970Scy return 0; 330275970Scy} 331275970Scy 332275970Scyint test_objects_arrays() { 333275970Scy int r; 334275970Scy jsmn_parser p; 335275970Scy jsmntok_t tokens[10]; 336275970Scy const char *js; 337275970Scy 338275970Scy js = "[10}"; 339275970Scy jsmn_init(&p); 340285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 341275970Scy check(r == JSMN_ERROR_INVAL); 342275970Scy 343275970Scy js = "[10]"; 344275970Scy jsmn_init(&p); 345285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 346285169Scy check(r >= 0); 347275970Scy 348275970Scy js = "{\"a\": 1]"; 349275970Scy jsmn_init(&p); 350285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 351275970Scy check(r == JSMN_ERROR_INVAL); 352275970Scy 353275970Scy js = "{\"a\": 1}"; 354275970Scy jsmn_init(&p); 355285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 356285169Scy check(r >= 0); 357275970Scy 358275970Scy return 0; 359275970Scy} 360275970Scy 361285169Scyint test_issue_22() { 362285169Scy int r; 363285169Scy jsmn_parser p; 364285169Scy jsmntok_t tokens[128]; 365285169Scy const char *js; 366285169Scy 367285169Scy js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, " 368285169Scy "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", " 369285169Scy "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], " 370285169Scy "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, " 371285169Scy "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", " 372285169Scy "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", " 373285169Scy "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], " 374285169Scy "\"tilewidth\":32, \"version\":1, \"width\":10 }"; 375285169Scy jsmn_init(&p); 376285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 128); 377285169Scy check(r >= 0); 378285169Scy#if 0 379285169Scy for (i = 1; tokens[i].end < tokens[0].end; i++) { 380285169Scy if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { 381285169Scy printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); 382285169Scy } else if (tokens[i].type == JSMN_ARRAY) { 383285169Scy printf("[%d elems]\n", tokens[i].size); 384285169Scy } else if (tokens[i].type == JSMN_OBJECT) { 385285169Scy printf("{%d elems}\n", tokens[i].size); 386285169Scy } else { 387285169Scy TOKEN_PRINT(tokens[i]); 388285169Scy } 389285169Scy } 390285169Scy#endif 391285169Scy return 0; 392285169Scy} 393285169Scy 394275970Scyint test_unicode_characters() { 395275970Scy jsmn_parser p; 396275970Scy jsmntok_t tokens[10]; 397275970Scy const char *js; 398275970Scy 399275970Scy int r; 400275970Scy js = "{\"a\":\"\\uAbcD\"}"; 401275970Scy jsmn_init(&p); 402285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 403285169Scy check(r >= 0); 404275970Scy 405275970Scy js = "{\"a\":\"str\\u0000\"}"; 406275970Scy jsmn_init(&p); 407285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 408285169Scy check(r >= 0); 409275970Scy 410275970Scy js = "{\"a\":\"\\uFFFFstr\"}"; 411275970Scy jsmn_init(&p); 412285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 413285169Scy check(r >= 0); 414275970Scy 415275970Scy js = "{\"a\":\"str\\uFFGFstr\"}"; 416275970Scy jsmn_init(&p); 417285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 418275970Scy check(r == JSMN_ERROR_INVAL); 419275970Scy 420275970Scy js = "{\"a\":\"str\\u@FfF\"}"; 421275970Scy jsmn_init(&p); 422285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 423275970Scy check(r == JSMN_ERROR_INVAL); 424275970Scy 425275970Scy js = "{\"a\":[\"\\u028\"]}"; 426275970Scy jsmn_init(&p); 427285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 428275970Scy check(r == JSMN_ERROR_INVAL); 429275970Scy 430275970Scy js = "{\"a\":[\"\\u0280\"]}"; 431275970Scy jsmn_init(&p); 432285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 433285169Scy check(r >= 0); 434275970Scy 435275970Scy return 0; 436275970Scy} 437275970Scy 438285169Scyint test_input_length() { 439285169Scy const char *js; 440285169Scy int r; 441285169Scy jsmn_parser p; 442285169Scy jsmntok_t tokens[10]; 443285169Scy 444285169Scy js = "{\"a\": 0}garbage"; 445285169Scy 446285169Scy jsmn_init(&p); 447285169Scy r = jsmn_parse(&p, js, 8, tokens, 10); 448285169Scy check(r == 3); 449285169Scy check(TOKEN_STRING(js, tokens[0], "{\"a\": 0}")); 450285169Scy check(TOKEN_STRING(js, tokens[1], "a")); 451285169Scy check(TOKEN_STRING(js, tokens[2], "0")); 452285169Scy 453285169Scy return 0; 454285169Scy} 455285169Scy 456285169Scyint test_count() { 457285169Scy jsmn_parser p; 458285169Scy const char *js; 459285169Scy 460285169Scy js = "{}"; 461285169Scy jsmn_init(&p); 462285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); 463285169Scy 464285169Scy js = "[]"; 465285169Scy jsmn_init(&p); 466285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); 467285169Scy 468285169Scy js = "[[]]"; 469285169Scy jsmn_init(&p); 470285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2); 471285169Scy 472285169Scy js = "[[], []]"; 473285169Scy jsmn_init(&p); 474285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); 475285169Scy 476285169Scy js = "[[], []]"; 477285169Scy jsmn_init(&p); 478285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); 479285169Scy 480285169Scy js = "[[], [[]], [[], []]]"; 481285169Scy jsmn_init(&p); 482285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); 483285169Scy 484285169Scy js = "[\"a\", [[], []]]"; 485285169Scy jsmn_init(&p); 486285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); 487285169Scy 488285169Scy js = "[[], \"[], [[]]\", [[]]]"; 489285169Scy jsmn_init(&p); 490285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); 491285169Scy 492285169Scy js = "[1, 2, 3]"; 493285169Scy jsmn_init(&p); 494285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4); 495285169Scy 496285169Scy js = "[1, 2, [3, \"a\"], null]"; 497285169Scy jsmn_init(&p); 498285169Scy check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); 499285169Scy 500285169Scy return 0; 501285169Scy} 502285169Scy 503285169Scyint test_keyvalue() { 504285169Scy const char *js; 505285169Scy int r; 506285169Scy jsmn_parser p; 507285169Scy jsmntok_t tokens[10]; 508285169Scy 509285169Scy js = "{\"a\": 0, \"b\": \"c\"}"; 510285169Scy 511285169Scy jsmn_init(&p); 512285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 513285169Scy check(r == 5); 514285169Scy check(tokens[0].size == 2); /* two keys */ 515285169Scy check(tokens[1].size == 1 && tokens[3].size == 1); /* one value per key */ 516285169Scy check(tokens[2].size == 0 && tokens[4].size == 0); /* values have zero size */ 517285169Scy 518285169Scy js = "{\"a\"\n0}"; 519285169Scy jsmn_init(&p); 520285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 521285169Scy check(r == JSMN_ERROR_INVAL); 522285169Scy 523285169Scy js = "{\"a\", 0}"; 524285169Scy jsmn_init(&p); 525285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 526285169Scy check(r == JSMN_ERROR_INVAL); 527285169Scy 528285169Scy js = "{\"a\": {2}}"; 529285169Scy jsmn_init(&p); 530285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 531285169Scy check(r == JSMN_ERROR_INVAL); 532285169Scy 533285169Scy js = "{\"a\": {2: 3}}"; 534285169Scy jsmn_init(&p); 535285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 536285169Scy check(r == JSMN_ERROR_INVAL); 537285169Scy 538285169Scy 539285169Scy js = "{\"a\": {\"a\": 2 3}}"; 540285169Scy jsmn_init(&p); 541285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 542285169Scy check(r == JSMN_ERROR_INVAL); 543285169Scy return 0; 544285169Scy} 545285169Scy 546285169Scy/** A huge redefinition of everything to include jsmn in non-script mode */ 547285169Scy#define jsmn_init jsmn_init_nonstrict 548285169Scy#define jsmn_parse jsmn_parse_nonstrict 549285169Scy#define jsmn_parser jsmn_parser_nonstrict 550285169Scy#define jsmn_alloc_token jsmn_alloc_token_nonstrict 551285169Scy#define jsmn_fill_token jsmn_fill_token_nonstrict 552285169Scy#define jsmn_parse_primitive jsmn_parse_primitive_nonstrict 553285169Scy#define jsmn_parse_string jsmn_parse_string_nonstrict 554285169Scy#define jsmntype_t jsmntype_nonstrict_t 555285169Scy#define jsmnerr_t jsmnerr_nonstrict_t 556285169Scy#define jsmntok_t jsmntok_nonstrict_t 557285169Scy#define JSMN_PRIMITIVE JSMN_PRIMITIVE_NONSTRICT 558285169Scy#define JSMN_OBJECT JSMN_OBJECT_NONSTRICT 559285169Scy#define JSMN_ARRAY JSMN_ARRAY_NONSTRICT 560285169Scy#define JSMN_STRING JSMN_STRING_NONSTRICT 561285169Scy#define JSMN_ERROR_NOMEM JSMN_ERROR_NOMEM_NONSTRICT 562285169Scy#define JSMN_ERROR_INVAL JSMN_ERROR_INVAL_NONSTRICT 563285169Scy#define JSMN_ERROR_PART JSMN_ERROR_PART_NONSTRICT 564285169Scy#undef __JSMN_H_ 565285169Scy#undef JSMN_STRICT 566285169Scy#include "jsmn.c" 567285169Scy 568285169Scyint test_nonstrict() { 569285169Scy const char *js; 570285169Scy int r; 571285169Scy jsmn_parser p; 572285169Scy jsmntok_t tokens[10]; 573285169Scy 574285169Scy js = "a: 0garbage"; 575285169Scy 576285169Scy jsmn_init(&p); 577285169Scy r = jsmn_parse(&p, js, 4, tokens, 10); 578285169Scy check(r == 2); 579285169Scy check(TOKEN_STRING(js, tokens[0], "a")); 580285169Scy check(TOKEN_STRING(js, tokens[1], "0")); 581285169Scy 582285169Scy js = "Day : 26\nMonth : Sep\n\nYear: 12"; 583285169Scy jsmn_init(&p); 584285169Scy r = jsmn_parse(&p, js, strlen(js), tokens, 10); 585285169Scy check(r == 6); 586285169Scy return 0; 587285169Scy} 588285169Scy 589275970Scyint main() { 590275970Scy test(test_empty, "general test for a empty JSON objects/arrays"); 591275970Scy test(test_simple, "general test for a simple JSON string"); 592275970Scy test(test_primitive, "test primitive JSON data types"); 593275970Scy test(test_string, "test string JSON data types"); 594275970Scy test(test_partial_string, "test partial JSON string parsing"); 595275970Scy test(test_partial_array, "test partial array reading"); 596275970Scy test(test_array_nomem, "test array reading with a smaller number of tokens"); 597275970Scy test(test_unquoted_keys, "test unquoted keys (like in JavaScript)"); 598275970Scy test(test_objects_arrays, "test objects and arrays"); 599275970Scy test(test_unicode_characters, "test unicode characters"); 600285169Scy test(test_input_length, "test strings that are not null-terminated"); 601285169Scy test(test_issue_22, "test issue #22"); 602285169Scy test(test_count, "test tokens count estimation"); 603285169Scy test(test_nonstrict, "test for non-strict mode"); 604285169Scy test(test_keyvalue, "test for keys/values"); 605275970Scy printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); 606275970Scy return 0; 607275970Scy} 608275970Scy 609