1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /* 26 * This is not really json in the state it is now. 27 * Some differences: 28 * - Double quotes around the key in an object is not enforced. 29 * i.e you can write: { foo : "bar" } instead of { "foo" : "bar" }. 30 * - Comments are allowed. 31 * - The last element in an object or array can have an ending comma. 32 */ 33 34 #include "precompiled.hpp" 35 #include "utilities/json.hpp" 36 #include <math.h> 37 38 const char* strchrnul_(const char *s, int c) { 39 const char* tmp = strchr(s, c); 40 return tmp == NULL ? s + strlen(s) : tmp; 41 } 42 43 JSON::JSON(const char* text, bool silent) 44 : start(text), pos(text), mark(text), 45 level(0), line(1), column(0), silent(silent), _valid(true) 46 { 47 } 48 49 void JSON::parse() { 50 assert(start != NULL, "Need something to parse"); 51 if (start == NULL) { 52 _valid = false; 53 error(INTERNAL_ERROR, "JSON parser was called with a string that was NULL."); 54 } else { 55 _valid = parse_json_value(); 56 } 57 } 58 59 bool JSON::valid() { 60 return _valid; 61 } 62 63 bool JSON::parse_json_value() { 64 int c; 65 66 c = skip_to_token(); 67 if (c == -1) { 68 return false; 69 } 70 71 // Must start with object or array 72 if (level == 0) { 73 74 switch (c) { 75 case '{': 76 if (parse_json_object() == false) { 77 return false; 78 } 79 c = skip_to_token(); 80 if (c > 0) { 81 mark_pos(); 82 error(SYNTAX_ERROR, "Only one top level object/array is allowed."); 83 return false; 84 } else if (c < 0) { 85 return false; 86 } 87 return true; 88 89 case '[': 90 if (parse_json_array() == false) { 91 return false; 92 } 93 c = skip_to_token(); 94 if (c > 0) { 95 mark_pos(); 96 error(SYNTAX_ERROR, "Only one top level object/array is allowed."); 97 return false; 98 } else if (c < 0) { 99 return false; 100 } 101 return true; 102 103 case 0: 104 error(SYNTAX_ERROR, "EOS was encountered before any json declarations"); 105 return false; 106 107 default: 108 error(SYNTAX_ERROR, "Json must start with an object or an array."); 109 return false; 110 } 111 } else { // level > 0 112 switch (c) { 113 case '{': 114 return parse_json_object(); 115 116 case '[': 117 return parse_json_array(); 118 119 case '"': 120 return parse_json_string(); 121 122 case '-': case '0': 123 case '1': case '2': case '3': 124 case '4': case '5': case '6': 125 case '7': case '8': case '9': 126 return parse_json_number(); 127 128 case 't': 129 return parse_json_symbol("true", JSON_TRUE); 130 131 case 'f': 132 return parse_json_symbol("false", JSON_FALSE); 133 134 case 'n': 135 return parse_json_symbol("null", JSON_NULL); 136 137 case 0: 138 error(SYNTAX_ERROR, "EOS was encountered when expecting a json value."); 139 return false; 140 141 default: 142 error(SYNTAX_ERROR, "Could not parse as a json value (did you forget to quote your strings?)."); 143 return false; 144 } 145 } 146 } 147 148 // Should only be called when we actually have the start of an object 149 // Otherwise it is an internal error 150 bool JSON::parse_json_object() { 151 NOT_PRODUCT(const char* prev_pos); 152 int c; 153 154 mark_pos(); 155 // Check that we are not called in error 156 if (expect_any("{", "object start", INTERNAL_ERROR) <= 0) { 157 return false; 158 } 159 160 if (!callback(JSON_OBJECT_BEGIN, NULL, level++)) { 161 return false; 162 } 163 164 for (;;) { 165 mark_pos(); 166 c = skip_to_token(); 167 if (c == 0) { 168 error(SYNTAX_ERROR, "EOS when expecting an object key or object end"); 169 return false; 170 } else if (c < 0) { 171 return false; 172 } else if (c == '}') { 173 // We got here from either empty object "{}" or ending comma "{a:1,}" 174 next(); 175 break; 176 } 177 178 NOT_PRODUCT(prev_pos = pos); 179 if (parse_json_key() == false) { 180 return false; 181 } 182 assert(pos > prev_pos, "parsing stalled"); 183 184 skip_to_token(); 185 mark_pos(); 186 if (expect_any(":", "object key-value separator") <= 0) { 187 return false; 188 } 189 190 skip_to_token(); 191 mark_pos(); 192 NOT_PRODUCT(prev_pos = pos); 193 if (parse_json_value() == false) { 194 return false; 195 } 196 assert(pos > prev_pos, "parsing stalled"); 197 198 c = skip_to_token(); 199 mark_pos(); 200 if (expect_any(",}", "value separator or object end") <= 0) { 201 return false; 202 } 203 if (c == '}') { 204 break; 205 } 206 } 207 208 assert(c == '}', "array parsing ended without object end token ('}')"); 209 return callback(JSON_OBJECT_END, NULL, --level); 210 } 211 212 // Should only be called when we actually have the start of an array 213 // Otherwise it is an internal error 214 bool JSON::parse_json_array() { 215 NOT_PRODUCT(const char* prev_pos); 216 int c; 217 218 mark_pos(); 219 // Check that we are not called in error 220 if (expect_any("[", "array start character", INTERNAL_ERROR) <= 0) { 221 return false; 222 } 223 224 if (!callback(JSON_ARRAY_BEGIN, NULL, level++)) { 225 return false; 226 } 227 228 for (;;) { 229 mark_pos(); 230 c = skip_to_token(); 231 if (c == 0) { 232 error(SYNTAX_ERROR, "EOS when expecting a json value or array end"); 233 return false; 234 } else if (c < 0) { 235 return false; 236 } else if (c == ']') { 237 // We got here from either empty array "[]" or ending comma "[1,]" 238 next(); 239 break; 240 } 241 242 mark_pos(); 243 NOT_PRODUCT(prev_pos = pos); 244 if (parse_json_value() == false) { 245 return false; 246 } 247 assert(pos > prev_pos, "parsing stalled"); 248 249 c = skip_to_token(); 250 mark_pos(); 251 if (expect_any(",]", "value separator or array end") <= 0) { 252 return false; 253 } 254 if (c == ']') { 255 break; 256 } 257 } 258 259 assert(c == ']', "array parsing ended without array end token (']')"); 260 return callback(JSON_ARRAY_END, NULL, --level); 261 } 262 263 bool JSON::parse_json_string(bool key) { 264 const char* end; 265 JSON_VAL v; 266 267 mark_pos(); 268 if (expect_any("\"", "string start character", INTERNAL_ERROR) <= 0) { 269 return false; 270 } 271 272 end = strchr(pos, '"'); // TODO: escapes 273 if (end == NULL) { 274 error(SYNTAX_ERROR, "String started here never ended. Expected \'\"\' before EOS."); 275 return false; 276 } 277 278 v.str.start = pos; 279 v.str.length = end - pos; 280 skip(end - pos); 281 282 if (expect_any("\"", "string end character", INTERNAL_ERROR) <= 0) { 283 return false; 284 } 285 286 if (key == true) { 287 return callback(JSON_KEY, &v, level); 288 } else { 289 return callback(JSON_STRING, &v, level); 290 } 291 } 292 293 // TODO: hotspot equivalents? 294 static bool is_alpha(u_char c) { 295 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); 296 } 297 static bool is_numeric(u_char c) { 298 return (c >= '0' && c <= '9'); 299 } 300 static bool is_alnum(u_char c) { 301 return is_alpha(c) || is_numeric(c); 302 } 303 static bool is_word(u_char c) { 304 return c == '_' || is_alnum(c); 305 } 306 307 // Allow object keys to be without quotation, 308 // but then restrict to ([a-zA-Z0-9_])+ 309 bool JSON::parse_json_key() { 310 const char* begin; 311 JSON_VAL v; 312 u_char c; 313 314 mark_pos(); 315 c = peek(); 316 if (c == '"') { 317 return parse_json_string(true); 318 } 319 320 begin = pos; 321 c = peek(); 322 if (c == 0) { 323 error(SYNTAX_ERROR, "Got EOS when expecting an object key."); 324 return false; 325 } else if (is_word(c) == false) { 326 error(SYNTAX_ERROR, "Expected an object key, which can be a double-quoted (\") string or a simple string (only alphanumeric characters and underscore, separated by whitespace) that doesn't need to be quoted."); 327 return false; 328 } 329 330 for (;;) { 331 c = peek(); 332 // Allow the key to be delimited by control characters and the object key-value separator ':' 333 if (c <= ' ' || c == ':') { 334 break; 335 } else if (is_word(c) == false) { 336 error(SYNTAX_ERROR, "Object key need to be quoted, or consist entirely of alphanumeric characters and underscores."); 337 return false; 338 } 339 next(); 340 } 341 342 v.str.start = begin; 343 v.str.length = pos - begin; 344 return callback(JSON_KEY, &v, level); 345 } 346 347 bool JSON::parse_json_number() { 348 double double_value; 349 int tokens, read; 350 JSON_VAL v; 351 352 mark_pos(); 353 354 // Parsing number - for simplicity ints are limited to 2**53 355 // sscanf as a double and check if part is 0. 356 tokens = sscanf(pos, "%lf%n", &double_value, &read); 357 assert(tokens <= 1, "scanf implementation that counts %n as a token, parsing json numbers will always fail"); 358 if (tokens == 1) { 359 assert(read > 0, "sanity"); 360 361 if (floor(double_value) == double_value) { 362 // No exponent - treat as an int 363 v.int_value = (int)double_value; 364 if (!callback(JSON_NUMBER_INT, &v, level)) { 365 return false; 366 } 367 } else { 368 v.double_value = double_value; 369 if (!callback(JSON_NUMBER_FLOAT, &v, level)) { 370 return false; 371 } 372 } 373 skip(read); 374 return true; 375 } 376 377 error(SYNTAX_ERROR, "Couldn't parse json number (note that exponents are not supported)."); 378 return false; 379 } 380 381 bool JSON::parse_json_symbol(const char* name, JSON_TYPE symbol) { 382 if (expect_string(name, "maybe you forgot to quote your strings?") == false) { 383 mark_pos(); 384 return false; 385 } 386 return callback(symbol, NULL, level); 387 } 388 389 void JSON::mark_pos() { 390 assert((mark == start || *(mark - 1)) != 0, "buffer overrun"); 391 assert(mark <= pos, "mark runahead"); 392 393 u_char c; 394 395 while (mark < pos) { 396 c = *mark; 397 assert(c != 0, "pos buffer overrun?"); 398 if (c != 0) { 399 mark++; 400 column++; 401 } 402 if (c == '\n') { 403 line++; 404 column = 0; 405 } 406 } 407 408 assert(mark <= pos, "mark runahead"); 409 } 410 411 u_char JSON::next() { 412 assert((pos == start || *(pos - 1)) != 0, "buffer overrun"); 413 414 u_char c = *pos; 415 if (c != 0) { 416 pos++; 417 } 418 return c; 419 } 420 421 u_char JSON::peek() { 422 return *pos; 423 } 424 425 // Peek ahead i chars (0 is same as peek()) 426 u_char JSON::peek(size_t i) { 427 u_char c; 428 const char* p; 429 430 p = pos; 431 c = *p; 432 while (i > 0 && c != 0) { 433 i--; 434 p++; 435 c = *p; 436 } 437 return c; 438 } 439 440 /* 441 * Check that one of the expected characters is next in the stream. 442 * If not, it is an error. 443 * Returns 0 if EOS is encountered. 444 * Returns -1 if the next character was not one of the expected. 445 * Otherwise consumes and returns the expected character that was encountered. 446 */ 447 int JSON::expect_any(const char* valid_chars, const char* error_msg, JSON_ERROR e) { 448 size_t len; 449 u_char c; 450 451 len = strlen(valid_chars); 452 assert(len > 0, "need non-empty string"); 453 454 c = peek(); 455 if (c == 0) { 456 error(e, "Got EOS when expecting %s (%s\'%s\').", error_msg, len > 1 ? "one of " : "", valid_chars); 457 return 0; 458 } 459 for (size_t i = 0; i < len; i++) { 460 if (c == valid_chars[i]) { 461 return next(); 462 } 463 } 464 error(e, "Expected %s (%s\'%s\').", error_msg, len > 1 ? "one of " : "", valid_chars); 465 return -1; 466 } 467 468 /* 469 * Check that the expected string is next in the stream. 470 * If not, it is an error. 471 * Consumes the expected characters if they are present. 472 * Returns true if the expected characters were present, otherwise false. 473 */ 474 bool JSON::expect_string(const char* expected_string, const char* error_msg, JSON_ERROR e) { 475 u_char c, expected_char; 476 size_t len; 477 478 assert(expected_string != NULL, "need non-null string"); 479 len = strlen(expected_string); 480 assert(len > 0, "need non-empty string"); 481 482 for (size_t i = 0; i < len; i++) { 483 expected_char = expected_string[i]; 484 assert(expected_char > ' ', "not sane for control characters"); 485 if (expected_char <= ' ') { 486 error(INTERNAL_ERROR, "expect got a control char"); 487 } 488 c = pos[i]; 489 if (c == 0) { 490 error(e, "EOS encountered when expecting %s (\"%s\")", error_msg, expected_string); 491 return false; 492 } else if (c != expected_char) { 493 error(e, "Expected \"%s\" (%s)", expected_string, error_msg); 494 return false; 495 } 496 } 497 skip(len); 498 return true; 499 } 500 501 /* 502 * Skip i characters. 503 * Returns number of characters skipped. 504 */ 505 size_t JSON::skip(size_t i) { 506 u_char c; 507 size_t j; 508 509 c = peek(); 510 for (j = i; c != 0 && j > 0; j--) { 511 c = next(); 512 } 513 return i - j; 514 } 515 516 /* 517 * Skip whitespace and comments. 518 * Returns the first token after whitespace/comments without consuming it 519 * Returns 0 if EOS is encountered. 520 * Returns -1 if there is an error 521 */ 522 int JSON::skip_to_token() { 523 for (;;) { 524 int c = peek(0); 525 if (c == '/') { 526 u_char c2 = peek(1); 527 if (c2 == '/') { 528 c = skip_line_comment(); 529 } else if (c2 == '*') { 530 c = skip_block_comment(); 531 if (c < 0) { 532 return -1; 533 } 534 } 535 // Fall through to keep checking if there 536 // are more whitespace / comments to skip 537 } 538 if (c == 0 || c > ' ') { 539 return c; 540 } 541 next(); 542 } 543 return 0; 544 } 545 546 /* 547 * Skip to, and return the wanted char without consuming it 548 * Returns 0 if EOS is encountered. 549 */ 550 u_char JSON::skip_to(u_char want) { 551 // We want the bookkeeping done in next(). 552 // Otherwise strchr could have been used. 553 u_char c; 554 for(;;) { 555 c = peek(); 556 if (c == 0 || c == want) { 557 return c; 558 } 559 next(); 560 } 561 } 562 563 /* 564 * Should only be called when we actually have a line comment to skip. 565 * Otherwise it is an internal error. 566 * 567 * Will return the first token after the line comment without consuming it. 568 * Returns 0 if EOS is encoutered. 569 */ 570 u_char JSON::skip_line_comment() { 571 u_char c; 572 573 // Check that we are not called in error 574 expect_any("/", "line comment start", INTERNAL_ERROR); 575 expect_any("/", "line comment start", INTERNAL_ERROR); 576 577 c = skip_to('\n'); 578 if (c == 0) { 579 return 0; 580 } 581 next(); 582 return next(); 583 } 584 585 /* 586 * Should only be called when we actually have a block comment to skip. 587 * Otherwise it is an internal error. 588 * 589 * Returns the first token after the block comment without consuming it. 590 * Returns -1 if EOS is encountered in the middle of a comment. 591 */ 592 int JSON::skip_block_comment() { 593 const char* current; 594 595 // Check that we are not called in error. 596 if (peek() != '/' || peek(1) != '*') { 597 // Let expect handle EOS. 598 expect_string("/*", "block comment start", INTERNAL_ERROR); 599 return 0; 600 } 601 602 current = pos; 603 for (;;) { 604 current = strchrnul_(current, '*'); 605 606 if (current[0] == 0 || current[1] == 0) { 607 // Advance error marker to start of block comment 608 mark_pos(); 609 error(SYNTAX_ERROR, "Block comment started here never ended. Expected \"*/\" before EOS."); 610 return -1; 611 } 612 613 if (current[1] == '/') { 614 pos = current; 615 if (expect_string("*/", "block comment end", INTERNAL_ERROR) == false) { 616 return -1; 617 } 618 // Found block comment end 619 return peek(); 620 } 621 current++; 622 } 623 } 624 625 const char* JSON::strerror(JSON_ERROR e) { 626 switch (e) { 627 case SYNTAX_ERROR: 628 return "Syntax error"; 629 case INTERNAL_ERROR: 630 return "Internal error"; 631 case KEY_ERROR: 632 return "Key error"; 633 case VALUE_ERROR: 634 return "Value error"; 635 default: 636 ShouldNotReachHere(); 637 return "Unknown error"; 638 } 639 } 640 641 void JSON::error(JSON_ERROR e, const char* format, ...) { 642 _valid = false; 643 644 if (silent == false) { 645 const char* line_start; 646 const char* tmp; 647 size_t line_length; 648 va_list args; 649 u_char c; 650 651 printf("%s on line %u byte %u: ", JSON::strerror(e), line, column + 1); 652 va_start(args, format); 653 vprintf(format, args); 654 printf("\n"); 655 va_end(args); 656 657 line_start = mark - column; 658 assert(line_start >= start, "out of bounds"); 659 assert(line_start <= mark, "out of bounds"); 660 assert(line_start == start || line_start[-1] == '\n', "line counting error"); 661 662 c = *pos; 663 if (c == 0) { 664 printf(" Got "); 665 printf("EOS.\n"); 666 } 667 tmp = mark; 668 c = *tmp; 669 if (c > ' ') { 670 printf(" At "); 671 printf("'"); 672 while (c > ' ') { 673 printf("%c", c); 674 tmp++; 675 c = *tmp; 676 } 677 printf("'.\n"); 678 } 679 680 // Skip to newline or EOS 681 tmp = strchrnul_(mark, '\n'); 682 line_length = tmp - line_start; 683 684 printf("%s\n", line_start); 685 } 686 } 687 688 #ifndef PRODUCT 689 void JSONTest::test(const char* text, bool should_pass) { 690 JSONTest json(text); 691 if (should_pass) { 692 assert(json.valid() == true, "failed on a valid json string"); 693 if (VerboseInternalVMTests) { 694 printf("-- json test passed as expected --\n"); 695 } 696 } else { 697 assert(json.valid() == false, "succeeded on an invalid json string"); 698 if (VerboseInternalVMTests) { 699 printf("-- json test failed as expected --\n"); 700 } 701 } 702 } 703 704 JSONTest::JSONTest(const char* text) : JSON(text, VerboseInternalVMTests == false) { 705 prev = JSON_NONE; 706 parse(); 707 } 708 709 bool JSONTest::test() { 710 JSONTest::test("{}", true); 711 JSONTest::test("[]", true); 712 JSONTest::test(" { } ", true); 713 JSONTest::test(" [ ] ", true); 714 715 JSONTest::test("\"error\"", false); 716 JSONTest::test("error", false); 717 JSONTest::test("1", false); 718 JSONTest::test("1.2", false); 719 JSONTest::test("true", false); 720 JSONTest::test("false", false); 721 JSONTest::test("null", false); 722 723 JSONTest::test("[ 1 ]", true); 724 JSONTest::test("[ 1, ]", true); 725 JSONTest::test("[ true ]", true); 726 JSONTest::test("[ true, ]", true); 727 JSONTest::test("[ false ]", true); 728 JSONTest::test("[ false, ]", true); 729 JSONTest::test("[ null ]", true); 730 JSONTest::test("[ null, ]", true); 731 JSONTest::test("[ \"\" ]", true); 732 JSONTest::test("[ \"\", ]", true); 733 JSONTest::test("[ \"elem1\" ]", true); 734 JSONTest::test("[ \"elem1\", ]", true); 735 JSONTest::test("[ \"elem1\", ]", true); 736 JSONTest::test("[ \"elem1\" ]", true); 737 JSONTest::test("[ \"elem1\", \"elem2\" ]", true); 738 JSONTest::test("[ \"elem1\", \"elem2\", ]", true); 739 740 741 JSONTest::test("[ \"elem1\" ] { }", false); 742 JSONTest::test("[ elem1, \"elem2\" ]", false); 743 JSONTest::test("[ \"elem1\"", false); 744 JSONTest::test("[ \"elem1 ]", false); 745 JSONTest::test("[ \"elem1\", \"elem2\"", false); 746 JSONTest::test("[ truefoo ]", false); 747 JSONTest::test("[ falsefoo ]", false); 748 JSONTest::test("[ nullfoo ]", false); 749 750 JSONTest::test("{ key : 1 }", true); 751 JSONTest::test("{ key : 1, }", true); 752 JSONTest::test("{ key : 1.2 }", true); 753 JSONTest::test("{ key : true }", true); 754 JSONTest::test("{ key : true, }", true); 755 JSONTest::test("{ key : false }", true); 756 JSONTest::test("{ key : false, }", true); 757 JSONTest::test("{ key : null }", true); 758 JSONTest::test("{ key : null, }", true); 759 JSONTest::test("{ \"\" : \"\" }", true); 760 JSONTest::test("{ \"\" : \"\", }", true); 761 JSONTest::test("{ \"key1\" : \"val1\" }", true); 762 JSONTest::test("{ \"key1\" : \"val1\", }", true); 763 JSONTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); 764 JSONTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); 765 766 JSONTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); 767 JSONTest::test("{ \"key\" : \"val\" ", false); 768 769 JSONTest::test("/**/ { }", true); 770 JSONTest::test("/* */ { }", true); 771 JSONTest::test("/*foo*/ { }", true); 772 JSONTest::test("/* *foo */ { }", true); 773 JSONTest::test("/* *foo* */ { }", true); 774 JSONTest::test("/* /*foo */ { }", true); 775 JSONTest::test("{ } /* foo */", true); 776 JSONTest::test("{ } /* foo */ ", true); 777 JSONTest::test("{ } //", true); 778 JSONTest::test("{ } // ", true); 779 JSONTest::test("{ } // foo", true); 780 781 JSONTest::test("/* * / { }", false); 782 JSONTest::test("/ * */ { }", false); 783 JSONTest::test("// { }", false); 784 JSONTest::test("/* { } */", false); 785 JSONTest::test("/* { } */ ", false); 786 JSONTest::test("/* { } ", false); 787 JSONTest::test("{ } /* ", false); 788 JSONTest::test("/* { } *", false); 789 JSONTest::test("{ /* } */", false); 790 JSONTest::test("[ /* ] */", false); 791 JSONTest::test("{ key : \"val\", /* } */", false); 792 JSONTest::test("[ \"val\", /* ] */", false); 793 794 JSONTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\", { \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); 795 JSONTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\", { \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); 796 JSONTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]},\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); 797 JSONTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\", \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", false); // first key needs to be quoted since it contains a space 798 799 800 JSONTest::test("[\n]", true); 801 802 JSONTest::test( 803 "[" "\n" 804 " {" 805 " // pattern to match against class+method+signature" "\n" 806 " // leading and trailing wildcard (*) allowed" "\n" 807 " match: \"foo.bar.*\"," "\n" 808 " " "\n" 809 " // override defaults for specified compiler" "\n" 810 " // we may differentiate between levels too. TBD." "\n" 811 " c1: {" "\n" 812 " //override c1 presets " "\n" 813 " array_bounds_check_removal: false" "\n" 814 " }," "\n" 815 "" "\n" 816 " c2: {" "\n" 817 " // control inlining of method" "\n" 818 " // + force inline, - dont inline" "\n" 819 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 820 " }," "\n" 821 "" "\n" 822 " // directives outside a specific preset applies to all compilers" "\n" 823 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 824 " print_assembly: true," "\n" 825 " verify_oopmaps: true," "\n" 826 " max_loop_unrolling: 5" "\n" 827 " }," "\n" 828 " {" "\n" 829 " // matching several patterns require an array" "\n" 830 " match: [\"baz.*\",\"frob*\"]," "\n" 831 "" "\n" 832 " // only enable c1 for this directive" "\n" 833 " // all enabled by default. Command disables all not listed" "\n" 834 " enable: \"c1\"," "\n" 835 "" "\n" 836 " // applies to all compilers" "\n" 837 " // + force inline, - dont inline" "\n" 838 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 839 " print_inlining: true," "\n" 840 "" "\n" 841 " // force matching compiles to be blocking/syncronous" "\n" 842 " blocking_compile: true" "\n" 843 " }," "\n" 844 "]" "\n", true); 845 846 return true; 847 } 848 849 void JSONTest::log(uint indent, const char* format, ...) { 850 if (VerboseInternalVMTests) { 851 if (prev != JSON_KEY) { 852 for (uint i = 0; i < indent; i++) { 853 printf(" "); 854 } 855 } 856 va_list args; 857 va_start(args, format); 858 vprintf(format, args); 859 va_end(args); 860 } 861 } 862 863 bool JSONTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) { 864 switch (t) { 865 case JSON_OBJECT_BEGIN: 866 log(rlevel, "{\n"); 867 prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly 868 return true; 869 870 case JSON_OBJECT_END: 871 log(rlevel, "},\n"); 872 prev = JSON_NONE; 873 return true; 874 875 case JSON_ARRAY_BEGIN: 876 log(rlevel, "[\n"); 877 prev = JSON_NONE; 878 return true; 879 880 case JSON_ARRAY_END: 881 log(rlevel, "],\n"); 882 prev = JSON_NONE; 883 return true; 884 885 case JSON_KEY: 886 if (VerboseInternalVMTests) { 887 for (uint i = 0; i < rlevel; i++) { 888 printf(" "); 889 } 890 printf("<key>"); 891 for (size_t i = 0; i < v->str.length; i++) { 892 u_char c = v->str.start[i]; 893 assert(c != 0, "string overrun"); 894 if (c == 0) { 895 return false; 896 } 897 printf("%c", c); 898 } 899 printf(" : "); 900 } 901 prev = JSON_KEY; 902 return true; 903 904 case JSON_STRING: 905 if (VerboseInternalVMTests) { 906 if (prev != JSON_KEY) { 907 for (uint i = 0; i < rlevel; i++) { 908 printf(" "); 909 } 910 } 911 printf("<str>"); 912 for (size_t i = 0; i < v->str.length; i++) { 913 u_char c = v->str.start[i]; 914 assert(c != 0, "string overrun"); 915 if (c == 0) { 916 return false; 917 } 918 printf("%c", c); 919 } 920 printf(",\n"); 921 } 922 prev = JSON_NONE; 923 return true; 924 925 case JSON_NUMBER_INT: 926 log(rlevel, "<int>%" PRId64 ",\n", v->int_value); 927 prev = JSON_NONE; 928 return true; 929 930 case JSON_NUMBER_FLOAT: 931 log(rlevel, "<double>%lf,\n", v->double_value); 932 prev = JSON_NONE; 933 return true; 934 935 case JSON_TRUE: 936 log(rlevel, "<true>,\n"); 937 prev = JSON_NONE; 938 return true; 939 940 case JSON_FALSE: 941 log(rlevel, "<false>,\n"); 942 prev = JSON_NONE; 943 return true; 944 945 case JSON_NULL: 946 log(rlevel, "<null>,\n"); 947 prev = JSON_NONE; 948 return true; 949 950 default: 951 error(INTERNAL_ERROR, "unknown JSON type"); 952 return false; 953 } 954 } 955 #endif