diff options
author | Mark Pulford <mark@kyne.com.au> | 2011-05-01 16:34:45 +0930 |
---|---|---|
committer | Mark Pulford <mark@kyne.com.au> | 2011-05-01 16:34:45 +0930 |
commit | 667f354934627a885e9a627a3c2b93a673956ed8 (patch) | |
tree | 649f13dc8be4644199efa7d410b5ddd483fae032 | |
parent | a875deda45983379fabf07a4b60064d33dd70d57 (diff) | |
download | lua-cjson-667f354934627a885e9a627a3c2b93a673956ed8.tar.gz lua-cjson-667f354934627a885e9a627a3c2b93a673956ed8.tar.bz2 lua-cjson-667f354934627a885e9a627a3c2b93a673956ed8.zip |
Simplify generating parse error tokens
-rw-r--r-- | lua_cjson.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index e339d51..cd3b9f7 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -89,7 +89,7 @@ typedef struct { | |||
89 | json_token_type_t type; | 89 | json_token_type_t type; |
90 | int index; | 90 | int index; |
91 | union { | 91 | union { |
92 | char *string; | 92 | const char *string; |
93 | double number; | 93 | double number; |
94 | int boolean; | 94 | int boolean; |
95 | } value; | 95 | } value; |
@@ -561,7 +561,9 @@ static int codepoint_to_utf8(char *utf8, int codepoint) | |||
561 | } | 561 | } |
562 | 562 | ||
563 | 563 | ||
564 | /* Called when index pointing to beginning of UCS-2 hex code: uXXXX | 564 | /* Called when index pointing to beginning of UCS-2 hex code: \uXXXX |
565 | * \u is guaranteed to exist, but the remaining hex characters may be | ||
566 | * missing. | ||
565 | * Translate to UTF-8 and append to temporary token string. | 567 | * Translate to UTF-8 and append to temporary token string. |
566 | * Must advance index to the next character to be processed. | 568 | * Must advance index to the next character to be processed. |
567 | * Returns: 0 success | 569 | * Returns: 0 success |
@@ -574,7 +576,7 @@ static int json_append_unicode_escape(json_parse_t *json) | |||
574 | int len; | 576 | int len; |
575 | 577 | ||
576 | /* Fetch UCS-2 codepoint */ | 578 | /* Fetch UCS-2 codepoint */ |
577 | codepoint = decode_hex4(&json->data[json->index + 1]); | 579 | codepoint = decode_hex4(&json->data[json->index + 2]); |
578 | if (codepoint < 0) { | 580 | if (codepoint < 0) { |
579 | return -1; | 581 | return -1; |
580 | } | 582 | } |
@@ -587,11 +589,19 @@ static int json_append_unicode_escape(json_parse_t *json) | |||
587 | 589 | ||
588 | /* Append bytes and advance counter */ | 590 | /* Append bytes and advance counter */ |
589 | strbuf_append_mem(json->tmp, utf8, len); | 591 | strbuf_append_mem(json->tmp, utf8, len); |
590 | json->index += 5; | 592 | json->index += 6; |
591 | 593 | ||
592 | return 0; | 594 | return 0; |
593 | } | 595 | } |
594 | 596 | ||
597 | static void json_set_token_error(json_token_t *token, json_parse_t *json, | ||
598 | const char *errtype) | ||
599 | { | ||
600 | token->type = T_ERROR; | ||
601 | token->index = json->index; | ||
602 | token->value.string = errtype; | ||
603 | } | ||
604 | |||
595 | static void json_next_string_token(json_parse_t *json, json_token_t *token) | 605 | static void json_next_string_token(json_parse_t *json, json_token_t *token) |
596 | { | 606 | { |
597 | char *ch2escape = json->cfg->ch2escape; | 607 | char *ch2escape = json->cfg->ch2escape; |
@@ -609,17 +619,14 @@ static void json_next_string_token(json_parse_t *json, json_token_t *token) | |||
609 | while ((ch = json->data[json->index]) != '"') { | 619 | while ((ch = json->data[json->index]) != '"') { |
610 | if (!ch) { | 620 | if (!ch) { |
611 | /* Premature end of the string */ | 621 | /* Premature end of the string */ |
612 | token->type = T_ERROR; | 622 | json_set_token_error(token, json, "unexpected end of string"); |
613 | token->index = json->index; | ||
614 | token->value.string = "unexpected end of string"; | ||
615 | return; | 623 | return; |
616 | } | 624 | } |
617 | 625 | ||
618 | /* Handle escapes */ | 626 | /* Handle escapes */ |
619 | if (ch == '\\') { | 627 | if (ch == '\\') { |
620 | /* Skip \ and fetch escape character */ | 628 | /* Fetch escape character */ |
621 | json->index++; | 629 | ch = json->data[json->index + 1]; |
622 | ch = json->data[json->index]; | ||
623 | 630 | ||
624 | /* Translate escape code and append to tmp string */ | 631 | /* Translate escape code and append to tmp string */ |
625 | ch = ch2escape[(unsigned char)ch]; | 632 | ch = ch2escape[(unsigned char)ch]; |
@@ -627,18 +634,17 @@ static void json_next_string_token(json_parse_t *json, json_token_t *token) | |||
627 | if (json_append_unicode_escape(json) == 0) | 634 | if (json_append_unicode_escape(json) == 0) |
628 | continue; | 635 | continue; |
629 | 636 | ||
630 | token->type = T_ERROR; | 637 | json_set_token_error(token, json, |
631 | token->index = json->index - 1; /* point at '\' */ | 638 | "invalid unicode escape code"); |
632 | token->value.string = "invalid unicode escape"; | ||
633 | return; | 639 | return; |
634 | } | 640 | } |
635 | if (!ch) { | 641 | if (!ch) { |
636 | /* Invalid escape code */ | 642 | json_set_token_error(token, json, "invalid escape code"); |
637 | token->type = T_ERROR; | ||
638 | token->index = json->index - 1; | ||
639 | token->value.string = "invalid escape"; | ||
640 | return; | 643 | return; |
641 | } | 644 | } |
645 | |||
646 | /* Skip '\' */ | ||
647 | json->index++; | ||
642 | } | 648 | } |
643 | /* Append normal character or translated single character | 649 | /* Append normal character or translated single character |
644 | * Unicode escapes are handled above */ | 650 | * Unicode escapes are handled above */ |
@@ -674,13 +680,10 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token) | |||
674 | token->type = T_NUMBER; | 680 | token->type = T_NUMBER; |
675 | startptr = &json->data[json->index]; | 681 | startptr = &json->data[json->index]; |
676 | token->value.number = strtod(&json->data[json->index], &endptr); | 682 | token->value.number = strtod(&json->data[json->index], &endptr); |
677 | if (startptr == endptr) { | 683 | if (startptr == endptr) |
678 | token->type = T_ERROR; | 684 | json_set_token_error(token, json, "invalid number"); |
679 | token->index = json->index; | 685 | else |
680 | token->value.string = "invalid number"; | ||
681 | } else { | ||
682 | json->index += endptr - startptr; /* Skip the processed number */ | 686 | json->index += endptr - startptr; /* Skip the processed number */ |
683 | } | ||
684 | 687 | ||
685 | return; | 688 | return; |
686 | } | 689 | } |
@@ -703,7 +706,7 @@ static void json_next_token(json_parse_t *json, json_token_t *token) | |||
703 | 706 | ||
704 | /* Don't advance the pointer for an error or the end */ | 707 | /* Don't advance the pointer for an error or the end */ |
705 | if (token->type == T_ERROR) { | 708 | if (token->type == T_ERROR) { |
706 | token->value.string = "invalid token"; | 709 | json_set_token_error(token, json, "invalid token"); |
707 | return; | 710 | return; |
708 | } | 711 | } |
709 | 712 | ||
@@ -741,10 +744,8 @@ static void json_next_token(json_parse_t *json, json_token_t *token) | |||
741 | return; | 744 | return; |
742 | } | 745 | } |
743 | 746 | ||
744 | /* We can fall through here if a token starts with t/f/n but isn't | 747 | /* Token starts with t/f/n but isn't recognised above. */ |
745 | * recognised above */ | 748 | json_set_token_error(token, json, "invalid token"); |
746 | token->type = T_ERROR; | ||
747 | token->value.string = "invalid token"; | ||
748 | } | 749 | } |
749 | 750 | ||
750 | /* This function does not return. | 751 | /* This function does not return. |