void fxGetNextJSONToken(txScriptParser* theParser) { txMachine* the = theParser->the; int c; txString p; txString q; txString r; txString s; txU4 t = 0; txNumber aNumber; theParser->line = theParser->line2; theParser->crlf = theParser->crlf2; theParser->escaped = theParser->escaped2; theParser->flags->value.string = theParser->flags2->value.string; theParser->integer = theParser->integer2; theParser->number = theParser->number2; theParser->string->value.string = theParser->string2->value.string; theParser->symbol = theParser->symbol2; theParser->token = theParser->token2; theParser->crlf2 = 0; theParser->escaped2 = 0; theParser->flags2->value.string = mxEmptyString.value.string; theParser->integer2 = 0; theParser->number2 = 0; theParser->string2->value.string = mxEmptyString.value.string; theParser->symbol2 = C_NULL; theParser->token2 = XS_NO_TOKEN; while (theParser->token2 == XS_NO_TOKEN) { switch (theParser->character) { case C_EOF: theParser->token2 = XS_TOKEN_EOF; break; case 10: theParser->line2++; fxGetNextCharacter(theParser); theParser->crlf2 = 1; break; case 13: theParser->line2++; fxGetNextCharacter(theParser); if (theParser->character == 10) fxGetNextCharacter(theParser); theParser->crlf2 = 1; break; case '\t': case ' ': fxGetNextCharacter(theParser); break; case '0': fxGetNextCharacter(theParser); c = theParser->character; if (c == '.') { fxGetNextCharacter(theParser); c = theParser->character; if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E')) fxGetNextNumber(theParser, 0); else { theParser->number2 = 0; theParser->token2 = XS_TOKEN_NUMBER; } } else if ((c == 'e') || (c == 'E')) { fxGetNextNumber(theParser, 0); } else if ((c == 'x') || (c == 'X')) { p = theParser->buffer; *p++ = '0'; *p++ = 'x'; for (;;) { fxGetNextCharacter(theParser); c = theParser->character; if (('0' <= c) && (c <= '9')) *p++ = c; else if (('A' <= c) && (c <= 'Z')) *p++ = c; else if (('a' <= c) && (c <= 'z')) *p++ = c; else break; } *p = 0; theParser->number2 = fxStringToNumber(theParser->the, theParser->buffer, 1); theParser->integer2 = (txInteger)theParser->number2; aNumber = theParser->integer2; if (theParser->number2 == aNumber) theParser->token2 = XS_TOKEN_INTEGER; else theParser->token2 = XS_TOKEN_NUMBER; } else { theParser->integer2 = 0; theParser->token2 = XS_TOKEN_INTEGER; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': fxGetNextNumber(theParser, 1); break; case ',': theParser->token2 = XS_TOKEN_COMMA; fxGetNextCharacter(theParser); break; case ':': theParser->token2 = XS_TOKEN_COLON; fxGetNextCharacter(theParser); break; case '[': theParser->token2 = XS_TOKEN_LEFT_BRACKET; fxGetNextCharacter(theParser); break; case ']': theParser->token2 = XS_TOKEN_RIGHT_BRACKET; fxGetNextCharacter(theParser); break; case '{': theParser->token2 = XS_TOKEN_LEFT_BRACE; fxGetNextCharacter(theParser); break; case '}': theParser->token2 = XS_TOKEN_RIGHT_BRACE; fxGetNextCharacter(theParser); break; case '"': p = theParser->buffer; q = p + sizeof(theParser->buffer) - 1; r = C_NULL; fxGetNextCharacter(theParser); for (;;) { if (theParser->character == C_EOF) { fxReportParserError(theParser, "end of file in string"); break; } else if ((theParser->character == 10) || (theParser->character == 13)) { fxReportParserError(theParser, "end of line in string"); break; } else if ((0 <= theParser->character) && (theParser->character < 32)) { fxReportParserError(theParser, "invalid character in string"); break; } else if (theParser->character == '"') { fxGetNextCharacter(theParser); break; } else if (theParser->character == '"') { fxGetNextCharacter(theParser); break; } else if (theParser->character == '\\') { theParser->escaped2 = 1; r = C_NULL; fxGetNextCharacter(theParser); switch (theParser->character) { case 10: theParser->line2++; fxGetNextCharacter(theParser); break; case 13: theParser->line2++; fxGetNextCharacter(theParser); if (theParser->character == 10) fxGetNextCharacter(theParser); break; case '\'': if (p < q) *p++ = '\''; fxGetNextCharacter(theParser); break; case '"': if (p < q) *p++ = '"'; fxGetNextCharacter(theParser); break; case '\\': if (p < q) *p++ = '\\'; fxGetNextCharacter(theParser); break; case '0': if (p < q) *p++ = 0; fxGetNextCharacter(theParser); break; case 'b': if (p < q) *p++ = '\b'; fxGetNextCharacter(theParser); break; case 'f': if (p < q) *p++ = '\f'; fxGetNextCharacter(theParser); break; case 'n': if (p < q) *p++ = '\n'; fxGetNextCharacter(theParser); break; case 'r': if (p < q) *p++ = '\r'; fxGetNextCharacter(theParser); break; case 't': if (p < q) *p++ = '\t'; fxGetNextCharacter(theParser); break; case 'u': r = p; t = 5; if (p < q) *p++ = 'u'; fxGetNextCharacter(theParser); break; case 'v': if (p < q) *p++ = '\v'; fxGetNextCharacter(theParser); break; case 'x': r = p; t = 3; if (p < q) *p++ = 'x'; fxGetNextCharacter(theParser); break; default: p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p); fxGetNextCharacter(theParser); break; } } else { p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p); if (r) { if ((txU4)(p - r) > t) r = C_NULL; else if (((txU4)(p - r) == t) && (p < q)) { *p = 0; t = c_strtoul(r + 1, &s, 16); if (!*s) p = (txString)fsX2UTF8(theParser, t, (txU1*)r, q - r); r = C_NULL; } } fxGetNextCharacter(theParser); } } *p = 0; if (p == q) fxReportParserError(theParser, "string overflow"); fxCopyStringC(theParser->the, theParser->string2, theParser->buffer); theParser->token2 = XS_TOKEN_STRING; break; default: if (fxIsIdentifierFirst(theParser->character)) { p = theParser->buffer; q = p + sizeof(theParser->buffer) - 1; for (;;) { if (p == q) { fxReportParserError(theParser, "identifier overflow"); break; } *p++ = theParser->character; fxGetNextCharacter(theParser); if (!fxIsIdentifierNext(theParser->character)) break; } *p = 0; fxGetNextJSONKeyword(theParser); } else { mxDebug1(theParser->the, XS_SYNTAX_ERROR, "invalid character %d", theParser->character); fxGetNextCharacter(theParser); } break; } } }
void fxGetNextString(txParser* parser, int c) { txString p = parser->buffer; txString q = p + parser->bufferSize - 1; txString r, s; char character; txU4 t; for (;;) { if (parser->character == (txU4)C_EOF) { fxReportParserError(parser, "end of file in string"); break; } else if (parser->character == 10) { parser->line2++; if (c == '`') { p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); } else { fxReportParserError(parser, "end of line in string"); break; } } else if (parser->character == 13) { parser->line2++; if (c == '`') { p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); } else { fxReportParserError(parser, "end of line in string"); break; } } else if (parser->character == (txU4)c) { break; } else if (parser->character == '$') { fxGetNextCharacter(parser); if ((c == '`') && (parser->character == '{')) break; p = (txString)fsX2UTF8('$', (txU1*)p, q - p); } else if (parser->character == '\\') { parser->escaped2 = 1; p = (txString)fsX2UTF8('\\', (txU1*)p, q - p); fxGetNextCharacter(parser); switch (parser->character) { case 10: parser->line2++; p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); break; case 13: parser->line2++; p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); break; default: p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); fxGetNextCharacter(parser); break; } } else { p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); fxGetNextCharacter(parser); } } *p = 0; if (p == q) fxReportParserWarning(parser, "string overflow"); parser->rawLength2 = p - parser->buffer; parser->raw2 = fxNewParserString(parser, parser->buffer, parser->rawLength2); if (parser->escaped2) { p = parser->buffer; q = p + parser->bufferSize - 1; s = parser->raw2; character = *s++; while (character) { if (character == '\\') { character = *s++; switch (character) { case 10: if (c == '`') *p++ = 10; character = *s++; break; case 'b': *p++ = '\b'; character = *s++; break; case 'f': *p++ = '\f'; character = *s++; break; case 'n': *p++ = '\n'; character = *s++; break; case 'r': *p++ = '\r'; character = *s++; break; case 't': *p++ = '\t'; character = *s++; break; case 'u': r = p; t = 0; *p++ = 'u'; character = *s++; if (character == '{') { *p++ = character; character = *s++; while (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; } if (character == '}') { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } else { if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } } } } break; case 'v': *p++ = '\v'; character = *s++; break; case 'x': r = p; t = 0; *p++ = 'x'; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': r = p; t = character - '0'; *p++ = character; character = *s++; while (fxGetNextString0(parser, character, &t)) { *p++ = character; character = *s++; } p = (txString)fsX2UTF8(t, (txU1*)r, q - r); if ((parser->flags & mxStrictFlag)) fxReportParserError(parser, "octal escape sequence (strict mode)"); break; default: *p++ = character; character = *s++; break; } } else { *p++ = character; character = *s++; } } *p = 0; parser->stringLength2 = p - parser->buffer; parser->string2 = fxNewParserString(parser, parser->buffer, parser->stringLength2); } else { parser->stringLength2 = parser->rawLength2; parser->string2 = parser->raw2; } }
void fxGetNextTokenAux(txParser* parser) { int c; txString p; txString q; txU4 t = 0; parser->crlf2 = 0; parser->escaped2 = 0; parser->integer2 = 0; parser->modifierLength2 = 0; parser->modifier2 = parser->emptyString; parser->number2 = 0; parser->rawLength2 = 0; parser->raw2 = parser->emptyString; parser->stringLength2 = 0; parser->string2 = parser->emptyString; parser->symbol2 = C_NULL; parser->token2 = XS_NO_TOKEN; while (parser->token2 == XS_NO_TOKEN) { switch (parser->character) { case C_EOF: parser->token2 = XS_TOKEN_EOF; break; case 10: parser->line2++; fxGetNextCharacter(parser); parser->crlf2 = 1; #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case 13: parser->line2++; fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); parser->crlf2 = 1; #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case 11: case 12: case 160: case ' ': case '\t': fxGetNextCharacter(parser); #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case '0': fxGetNextCharacter(parser); c = parser->character; if (c == '.') { fxGetNextCharacter(parser); c = parser->character; if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E')) fxGetNextNumberE(parser, 0); else { parser->number2 = 0; parser->token2 = XS_TOKEN_NUMBER; } } else if ((c == 'b') || (c == 'B')) { fxGetNextNumberB(parser); } else if ((c == 'e') || (c == 'E')) { fxGetNextNumberE(parser, 0); } else if ((c == 'o') || (c == 'O')) { fxGetNextNumberO(parser, '0'); } else if ((c == 'x') || (c == 'X')) { fxGetNextNumberX(parser); } else if (('0' <= c) && (c <= '7')) { if ((parser->flags & mxStrictFlag)) fxReportParserError(parser, "octal number (strict mode)"); fxGetNextNumberO(parser, c); } else { parser->integer2 = 0; parser->token2 = XS_TOKEN_INTEGER; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': fxGetNextNumberE(parser, 1); break; case '.': fxGetNextCharacter(parser); if (parser->character == '.') { fxGetNextCharacter(parser); if (parser->character == '.') { parser->token2 = XS_TOKEN_SPREAD; fxGetNextCharacter(parser); } else { fxReportParserError(parser, "invalid character %d", parser->character); } } else if (('0' <= parser->character) && (parser->character <= '9')) fxGetNextNumberE(parser, 0); else parser->token2 = XS_TOKEN_DOT; break; case ',': parser->token2 = XS_TOKEN_COMMA; fxGetNextCharacter(parser); break; case ';': parser->token2 = XS_TOKEN_SEMICOLON; fxGetNextCharacter(parser); break; case ':': parser->token2 = XS_TOKEN_COLON; fxGetNextCharacter(parser); break; case '?': parser->token2 = XS_TOKEN_QUESTION_MARK; fxGetNextCharacter(parser); break; case '(': parser->token2 = XS_TOKEN_LEFT_PARENTHESIS; fxGetNextCharacter(parser); break; case ')': parser->token2 = XS_TOKEN_RIGHT_PARENTHESIS; fxGetNextCharacter(parser); break; case '[': parser->token2 = XS_TOKEN_LEFT_BRACKET; fxGetNextCharacter(parser); break; case ']': parser->token2 = XS_TOKEN_RIGHT_BRACKET; fxGetNextCharacter(parser); break; case '{': parser->token2 = XS_TOKEN_LEFT_BRACE; fxGetNextCharacter(parser); break; case '}': parser->token2 = XS_TOKEN_RIGHT_BRACE; fxGetNextCharacter(parser); break; case '=': fxGetNextCharacter(parser); if (parser->character == '=') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_STRICT_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_EQUAL; } else if (parser->character == '>') { parser->token2 = XS_TOKEN_ARROW; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_ASSIGN; break; case '<': fxGetNextCharacter(parser); if (parser->character == '<') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_LEFT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_LEFT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_LESS_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_LESS; break; case '>': fxGetNextCharacter(parser); if (parser->character == '>') { fxGetNextCharacter(parser); if (parser->character == '>') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_UNSIGNED_RIGHT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_UNSIGNED_RIGHT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_SIGNED_RIGHT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_SIGNED_RIGHT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_MORE_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MORE; break; case '!': fxGetNextCharacter(parser); if (parser->character == '=') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_STRICT_NOT_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_NOT_EQUAL; } else parser->token2 = XS_TOKEN_NOT; break; case '~': parser->token2 = XS_TOKEN_BIT_NOT; fxGetNextCharacter(parser); break; case '&': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_AND_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '&') { parser->token2 = XS_TOKEN_AND; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_AND; break; case '|': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_OR_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '|') { parser->token2 = XS_TOKEN_OR; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_OR; break; case '^': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_XOR_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_XOR; break; case '+': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_ADD_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '+') { parser->token2 = XS_TOKEN_INCREMENT; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_ADD; break; case '-': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_SUBTRACT_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '-') { parser->token2 = XS_TOKEN_DECREMENT; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_SUBTRACT; break; case '*': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_MULTIPLY_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MULTIPLY; break; case '/': fxGetNextCharacter(parser); if (parser->character == '*') { fxGetNextCharacter(parser); for (;;) { if (parser->character == (txU4)C_EOF) break; else if (parser->character == 10) { parser->line2++; fxGetNextCharacter(parser); } else if (parser->character == 13) { parser->line2++; fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); } else if (parser->character == '*') { fxGetNextCharacter(parser); if (parser->character == '/') { fxGetNextCharacter(parser); break; } } else fxGetNextCharacter(parser); } } else if (parser->character == '/') { fxGetNextCharacter(parser); p = parser->buffer; q = p + parser->bufferSize - 1; while ((parser->character != (txU4)C_EOF) && (parser->character != 10) && (parser->character != 13)) { if (p < q) *p++ = (char)parser->character; fxGetNextCharacter(parser); } *p = 0; p = parser->buffer; if (!c_strcmp(p, "@module")) { if (parser->token2 == XS_NO_TOKEN) parser->flags |= mxCommonModuleFlag; } else if (!c_strcmp(p, "@program")) { if (parser->token2 == XS_NO_TOKEN) parser->flags |= mxCommonProgramFlag; } else if (parser->flags & mxDebugFlag) { if (!c_strncmp(p, "@line ", 6)) { p += 6; t = 0; c = *p++; while (('0' <= c) && (c <= '9')) { t = (t * 10) + (c - '0'); c = *p++; } if (!t) goto bail; if (c == ' ') { c = *p++; if (c != '"') goto bail; q = p; c = *q++; while ((c != 0) && (c != 10) && (c != 13) && (c != '"')) c = *q++; if (c != '"') goto bail; *(--q) = 0; parser->path = fxNewParserSymbol(parser, p); } parser->line2 = t - 1; } else if (!c_strncmp(p, "# sourceMappingURL=", 19) || !c_strncmp(p, "@ sourceMappingURL=", 19)) { p += 19; q = p; c = *q++; while ((c != 0) && (c != 10) && (c != 13)) c = *q++; *q = 0; parser->name = fxNewParserString(parser, p, q - p); } } bail: ; } else if ((parser->crlf2) || (fxAcceptRegExp(parser))) { parser->token2 = XS_TOKEN_NULL; p = parser->buffer; q = p + parser->bufferSize - 1; for (;;) { if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } else if (parser->character == (txU4)C_EOF) { fxReportParserWarning(parser, "end of file in regular expression"); break; } else if ((parser->character == 10) || (parser->character == 13)) { fxReportParserWarning(parser, "end of line in regular expression"); break; } else if (parser->character == '/') { *p = 0; parser->stringLength2 = p - parser->buffer; parser->string2 = fxNewParserString(parser, parser->buffer, parser->stringLength2); parser->token2 = XS_TOKEN_REGEXP; p = parser->buffer; q = p + parser->bufferSize - 1; for (;;) { fxGetNextCharacter(parser); if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } else if (fxIsIdentifierNext((char)parser->character)) *p++ = (char)parser->character; else { if (p != parser->buffer) { *p = 0; parser->modifierLength2 = p - parser->buffer; parser->modifier2 = fxNewParserString(parser, parser->buffer, parser->modifierLength2); } break; } } break; } else if (parser->character == '\\') { *p++ = (char)parser->character; fxGetNextCharacter(parser); if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } } p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); //*p++ = parser->character; fxGetNextCharacter(parser); } } else if (parser->character == '=') { parser->token2 = XS_TOKEN_DIVIDE_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_DIVIDE; break; case '%': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_MODULO_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MODULO; break; case '"': case '\'': c = parser->character; fxGetNextCharacter(parser); fxGetNextString(parser, c); parser->token2 = XS_TOKEN_STRING; fxGetNextCharacter(parser); break; case '`': fxGetNextCharacter(parser); fxGetNextString(parser, '`'); if (parser->character == '{') parser->token2 = XS_TOKEN_TEMPLATE_HEAD; else parser->token2 = XS_TOKEN_TEMPLATE; fxGetNextCharacter(parser); break; case '@': if (parser->flags & mxCFlag) parser->token2 = XS_TOKEN_HOST; else fxReportParserError(parser, "invalid character @"); fxGetNextCharacter(parser); break; default: p = parser->buffer; q = p + parser->bufferSize - 1; if (fxIsIdentifierFirst((char)parser->character)) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } else if (parser->character == '\\') { t = 0; if (fxGetNextIdentiferX(parser, &t)) p = (txString)fsX2UTF8(t, (txU1*)p, q - p); else p = C_NULL; } else p = C_NULL; if (p) { for (;;) { if (p == q) { fxReportParserWarning(parser, "identifier overflow"); break; } if (fxIsIdentifierNext((char)parser->character)) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } else if (parser->character == '\\') { t = 0; if (fxGetNextIdentiferX(parser, &t)) p = (txString)fsX2UTF8(t, (txU1*)p, q - p); else { p = C_NULL; break; } } else { *p = 0; fxGetNextKeyword(parser); break; } } } if (!p) { fxReportParserWarning(parser, "invalid character %d", parser->character); fxGetNextCharacter(parser); } break; } } }
void fxGetNextJSONToken(txMachine* the, txJSONParser* theParser) { txString p; txString q; txString r; txString s; char c; txInteger i; txBoolean escaped; txNumber number; txU4 size; txU4 value; const txUTF8Sequence* sequence; txString string; theParser->integer = 0; theParser->number = 0; theParser->string->value.string = mxEmptyString.value.string; theParser->token = XS_NO_JSON_TOKEN; r = (theParser->data) ? theParser->data : theParser->slot->value.string; p = r + theParser->offset; q = r + theParser->size; c = (p < q) ? *p : 0; while (theParser->token == XS_NO_JSON_TOKEN) { switch (c) { case 0: theParser->token = XS_JSON_TOKEN_EOF; break; case '\n': case '\r': case '\t': case ' ': c = (++p < q) ? *p : 0; break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': s = p; if (c == '-') c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) { if (c == '0') { c = (++p < q) ? *p : 0; } else { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } if (c == '.') { c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } else mxSyntaxError("invalid character in number"); } if ((c == 'e') || (c == 'E')) { c = (++p < q) ? *p : 0; if ((c== '+') || (c == '-')) { c = (++p < q) ? *p : 0; } if (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; while (('0' <= c) && (c <= '9')) { c = (++p < q) ? *p : 0; } } else mxSyntaxError("invalid character in number"); } size = p - s; if ((size + 1) > sizeof(the->nameBuffer)) mxSyntaxError("number overflow"); c_memcpy(the->nameBuffer, s, size); the->nameBuffer[size] = 0; theParser->number = fxStringToNumber(the->dtoa, the->nameBuffer, 0); theParser->integer = (txInteger)theParser->number; number = theParser->integer; if (theParser->number == number) theParser->token = XS_JSON_TOKEN_INTEGER; else theParser->token = XS_JSON_TOKEN_NUMBER; } else mxSyntaxError("invalid character in number"); break; case ',': p++; theParser->token = XS_JSON_TOKEN_COMMA; break; case ':': p++; theParser->token = XS_JSON_TOKEN_COLON; break; case '[': p++; theParser->token = XS_JSON_TOKEN_LEFT_BRACKET; break; case ']': p++; theParser->token = XS_JSON_TOKEN_RIGHT_BRACKET; break; case '{': p++; theParser->token = XS_JSON_TOKEN_LEFT_BRACE; break; case '}': p++; theParser->token = XS_JSON_TOKEN_RIGHT_BRACE; break; case '"': c = (++p < q) ? *p : 0; s = p; escaped = 0; size = 0; for (;;) { if ((0 <= c) && (c < 32)) { mxSyntaxError("invalid character in string"); break; } else if (c == '"') { break; } else if (c == '\\') { escaped = 1; c = (++p < q) ? *p : 0; switch (c) { case '"': case '/': case '\\': case 'b': case 'f': case 'n': case 'r': case 't': size++; c = (++p < q) ? *p : 0; break; case 'u': value = 0; for (i = 0; i < 4; i++) { c = (++p < q) ? *p : 0; if (('0' <= c) && (c <= '9')) value = (value * 16) + (c - '0'); else if (('a' <= c) && (c <= 'f')) value = (value * 16) + (10 + c - 'a'); else if (('A' <= c) && (c <= 'F')) value = (value * 16) + (10 + c - 'A'); else mxSyntaxError("invalid character in string"); } // surrogate pair? for (sequence = gxUTF8Sequences; sequence->size; sequence++) if (value <= sequence->lmask) break; size += sequence->size; c = (++p < q) ? *p : 0; break; default: mxSyntaxError("invalid character in string"); break; } } else { size++; c = (++p < q) ? *p : 0; } } { txSize after = p - r; txSize before = s - r; string = theParser->string->value.string = (txString)fxNewChunk(the, size + 1); r = (theParser->data) ? theParser->data : theParser->slot->value.string; p = r + after; q = r + theParser->size; s = r + before; } if (escaped) { p = s; c = *p; for (;;) { if (c == '"') { break; } else if (c == '\\') { p++; c = *p; switch (c) { case '"': case '/': case '\\': *string++ = c; p++; c = *p; break; case 'b': *string++ = '\b'; p++; c = *p; break; case 'f': *string++ = '\f'; p++; c = *p; break; case 'n': *string++ = '\n'; p++; c = *p; break; case 'r': *string++ = '\r'; p++; c = *p; break; case 't': *string++ = '\t'; p++; c = *p; break; case 'u': value = 0; for (i = 0; i < 4; i++) { p++; c = *p; if (('0' <= c) && (c <= '9')) value = (value * 16) + (c - '0'); else if (('a' <= c) && (c <= 'f')) value = (value * 16) + (10 + c - 'a'); else value = (value * 16) + (10 + c - 'A'); } // surrogate pair? string = (txString)fsX2UTF8(value, (txU1*)string, 0x7FFFFFFF); p++; c = *p; break; } } else { *string++ = c; p++; c = *p; } } *string = 0; } else { c_memcpy(string, s, size); string[size] = 0; } p++; theParser->token = XS_JSON_TOKEN_STRING; break; default: if ((q - p >= 5) && (!c_strncmp(p, "false", 5))) { p += 5; theParser->token = XS_JSON_TOKEN_FALSE; } else if ((q - p >= 4) && (!c_strncmp(p, "null", 4))) { p += 4; theParser->token = XS_JSON_TOKEN_NULL; } else if ((q - p >= 4) && (!c_strncmp(p, "true", 4))) { p += 4; theParser->token = XS_JSON_TOKEN_TRUE; } else mxSyntaxError("invalid character"); break; } } theParser->offset = p - r; }