| 847 | } |
| 848 | |
| 849 | bool parse_string(const char **sp, char **out) |
| 850 | { |
| 851 | const char *s = *sp; |
| 852 | SB sb; |
| 853 | char throwaway_buffer[4]; |
| 854 | /* enough space for a UTF-8 character */ |
| 855 | char *b; |
| 856 | |
| 857 | if (*s++ != '"') |
| 858 | return false; |
| 859 | |
| 860 | if (out) |
| 861 | { |
| 862 | sb_init(&sb); |
| 863 | sb_need(&sb, 4); |
| 864 | b = sb.cur; |
| 865 | } |
| 866 | else |
| 867 | b = throwaway_buffer; |
| 868 | |
| 869 | while (*s != '"') |
| 870 | { |
| 871 | unsigned char c = *s++; |
| 872 | |
| 873 | /* Parse next character, and write it to b. */ |
| 874 | if (c == '\\') |
| 875 | { |
| 876 | c = *s++; |
| 877 | switch (c) |
| 878 | { |
| 879 | case '"': |
| 880 | case '\\': |
| 881 | case '/': |
| 882 | *b++ = c; |
| 883 | break; |
| 884 | case 'b': |
| 885 | *b++ = '\b'; |
| 886 | break; |
| 887 | case 'f': |
| 888 | *b++ = '\f'; |
| 889 | break; |
| 890 | case 'n': |
| 891 | *b++ = '\n'; |
| 892 | break; |
| 893 | case 'r': |
| 894 | *b++ = '\r'; |
| 895 | break; |
| 896 | case 't': |
| 897 | *b++ = '\t'; |
| 898 | break; |
| 899 | case 'u': |
| 900 | { |
| 901 | uint16_t uc, lc; |
| 902 | uchar_t unicode; |
| 903 | |
| 904 | if (!parse_hex16(&s, &uc)) |
| 905 | goto failed; |
| 906 |
no test coverage detected