* Peek at the next token. */
| 223 | * Peek at the next token. |
| 224 | */ |
| 225 | static char peekToken(Parser &parser) |
| 226 | { |
| 227 | if (parser.peek != TOKEN_NONE) |
| 228 | return parser.peek; |
| 229 | |
| 230 | char c; |
| 231 | while (isspace(c = parser.getc())) |
| 232 | ; |
| 233 | switch (c) |
| 234 | { |
| 235 | case ':': case ',': case '{': case '}': case '[': case ']': case EOF: |
| 236 | return (parser.peek = c); |
| 237 | case 't': |
| 238 | if (parser.getc() != 'r' || parser.getc() != 'u' || |
| 239 | parser.getc() != 'e') |
| 240 | goto bad_token; |
| 241 | parser.b = true; |
| 242 | return (parser.peek = TOKEN_BOOL); |
| 243 | case 'f': |
| 244 | if (parser.getc() != 'a' || parser.getc() != 'l' || |
| 245 | parser.getc() != 's' || parser.getc() != 'e') |
| 246 | goto bad_token; |
| 247 | parser.b = false; |
| 248 | return (parser.peek = TOKEN_BOOL); |
| 249 | case 'n': |
| 250 | if (parser.getc() != 'u' || parser.getc() != 'l' || |
| 251 | parser.getc() != 'l') |
| 252 | goto bad_token; |
| 253 | return (parser.peek = TOKEN_NULL); |
| 254 | case '-': case '0': case '1': case '2': case '3': case '4': |
| 255 | case '5': case '6': case '7': case '8': case '9': |
| 256 | { |
| 257 | unsigned len = 0; |
| 258 | parser.s[len++] = c; |
| 259 | while (true) |
| 260 | { |
| 261 | if (len >= NUMBER_MAX) |
| 262 | parse_error(parser, "failed to read JSON number, maximum " |
| 263 | "length (%u) was exceeded", NUMBER_MAX); |
| 264 | c = parser.getc(); |
| 265 | if (!isdigit(c)) |
| 266 | { |
| 267 | parser.ungetc(c); |
| 268 | parser.s[len++] = '\0'; |
| 269 | break; |
| 270 | } |
| 271 | parser.s[len++] = c; |
| 272 | } |
| 273 | if (parser.s[0] == '-' && parser.s[1] == '\0') |
| 274 | { |
| 275 | c = '-'; |
| 276 | goto bad_token; |
| 277 | } |
| 278 | int64_t x = (int64_t)strtoll(parser.s, nullptr, 10); |
| 279 | if (x < INT32_MIN || x > INT32_MAX) |
| 280 | parse_error(parser, "failed to read JSON number, value is " |
| 281 | "out of range (%d..%d)", INT32_MIN, INT32_MAX); |
| 282 | parser.i = (int32_t)x; |