void fxLoadModule(txMachine* the, txID moduleID) { txArchive* archive = the->archive; txSlot* key = fxGetKey(the, moduleID); char buffer[PATH_MAX]; txString path = buffer; txString dot; txString* extension; txLoader* loader; c_strcpy(path, key->value.key.string); if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount, i; txScript* script = archive->scripts; path += archive->baseLength; for (i = 0; i < c; i++) { if (!c_strcmp(path, script->path)) { fxResolveModule(the, moduleID, script, fxLoadLibrary(the, key->value.key.string, C_NULL), fxUnloadLibrary); return; } script++; } } } dot = c_strrchr(path, '.'); for (extension = gxExtensions, loader = gxLoaders; *extension; extension++, loader++) { if (!c_strcmp(dot, *extension)) { (**loader)(the, buffer, moduleID); return; } } }
txBoolean fxFindArchive(txMachine* the, txString path) { txArchive* archive = the->archive; if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount; txScript* script = archive->scripts; char name[PATH_MAX]; c_strcpy(name, path + archive->baseLength); #if mxWindows { char* separator = name; while (*separator) { if (*separator == '/') *separator = mxSeparator; separator++; } } #endif while (c > 0) { if (!c_strcmp(name, script->path)) return 1; c--; script++; } } } return 0; }
void fxBaseScript(txLinker* linker, txLinkerScript* script, txString base, txInteger baseLength) { if (c_strncmp(script->path, base, baseLength)) fxReportError(linker, "'%s': not relative to '%s'", script->path, base); script->path += baseLength; script->pathSize = c_strlen(script->path) + 1; script->scriptIndex = linker->scriptCount; linker->codeSize += script->codeSize; linker->pathsSize += script->pathSize; linker->scriptCount++; }
void fxLoadModule(txMachine* the, txID moduleID) { txArchive* archive = the->archive; txSlot* key = fxGetKey(the, moduleID); txString path = NULL; char buffer[PATH_MAX]; txString dot = NULL; txString* extension; txLoader* loader; KprURLToPath(key->value.key.string, &path); c_strcpy(buffer, path); c_free(path); path = buffer; if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount, i; txScript* script = archive->scripts; path += archive->baseLength; #if mxWindows { char* separator = path; while (*separator) { if (*separator == '/') *separator = mxSeparator; separator++; } } #endif for (i = 0; i < c; i++) { if (!c_strcmp(path, script->path)) { fxResolveModule(the, moduleID, script, C_NULL, C_NULL); return; } script++; } } } dot = FskStrRChr(path, '.'); for (extension = gxExtensions, loader = gxLoaders; *extension; extension++, loader++) { if (!FskStrCompare(dot, *extension)) { (**loader)(the, buffer, moduleID); break; } } }
txBoolean fxFindArchive(txMachine* the, txString path) { txArchive* archive = the->archive; if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount; txScript* script = archive->scripts; path += archive->baseLength; while (c > 0) { if (!c_strcmp(path, script->path)) return 1; c--; script++; } } } return 0; }
void fxRunProgram(txMachine* the, txString path) { txArchive* archive = the->archive; if (archive) { if (!c_strncmp(path, archive->base, archive->baseLength)) { txInteger c = archive->scriptCount, i; txScript* script = archive->scripts; path += archive->baseLength; for (i = 0; i < c; i++) { if (!c_strcmp(path, script->path)) { fxRunScript(the, script, &mxGlobal, C_NULL, C_NULL, C_NULL); return; } script++; } } } }
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; } } }
txID fxFindModule(txMachine* the, txID moduleID, txSlot* slot) { char name[PATH_MAX]; char base[PATH_MAX]; txBoolean absolute, relative, search; txSlot *key, *iterator, *result; txString dot, slash; txID id; fxToStringBuffer(the, slot, name, sizeof(name)); if ((!c_strncmp(name, "./", 2)) || (!c_strncmp(name, "../", 3))) { absolute = 0; relative = (moduleID == XS_NO_ID) ? 0 : 1; search = 0; } else if ((!c_strncmp(name, "/", 1))) { absolute = 1; relative = 0; search = 0; } else { absolute = 0; relative = (moduleID == XS_NO_ID) ? 0 : 1; search = 1; } slash = c_strrchr(name, '/'); if (!slash) slash = name; dot = c_strrchr(slash, '.'); if (!dot) dot = name + c_strlen(name); if (absolute) { if (fxFindURI(the, "", name, dot, &id)) return id; } if (relative) { key = fxGetKey(the, moduleID); c_strcpy(base, key->value.key.string); if (fxFindURI(the, base, name, dot, &id)) return id; } if (search) { mxCallID(&mxModulePaths, mxID(_Symbol_iterator), 0); iterator = the->stack; for (;;) { mxCallID(iterator, mxID(_next), 0); result = the->stack; mxGetID(result, mxID(_done)); if (fxToBoolean(the, the->stack)) break; the->stack++; mxGetID(result, mxID(_value)); fxToStringBuffer(the, the->stack++, base, sizeof(base)); if (fxFindURI(the, base, name, dot, &id)) return id; } } mxReferenceError("module \"%s\" not found", name); return XS_NO_ID; }
void fx_Date_parse(txMachine* the) { #define mxDayCount 7 static char* gxDays[mxDayCount] = { "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" }; #define mxMonthCount 12 static char* gxMonths[mxMonthCount] = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" }; #define mxZoneCount 11 static char* gxZones[mxZoneCount] = { "gmt", "ut", "utc", "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt" }; static int gxDeltas[mxZoneCount] = { 0, 0, 0, -5, -4, -6, -5, -7, -6, -8, -7 }; txString aString; txTimeDescription td; txString p; txString q; txByte c; char buffer[10]; /* base type should be the same as txString */ txInteger aComment; txInteger aDelta; txInteger aValue; txInteger aLength; txInteger i; c_time_t time; txNumber number; txInteger hasSlash = 0; if (mxArgc < 1) goto fail; aString = fxToString(the, mxArgv(0)); td.tm.tm_sec = -1; td.tm.tm_min = -1; td.tm.tm_hour = -1; td.tm.tm_mday = -1; td.tm.tm_mon = -1; td.tm.tm_year = -1; td.ms = 0; aComment = 0; aDelta = -1; c = *aString++; while (c) { if (c == '(') { aComment++; c = *aString++; continue; } else if (c == ')') { if (aComment) { aComment--; c = *aString++; continue; } else goto fail; } else if (aComment) { c = *aString++; continue; } if ((c <= ' ') || (c == ',')) { c = *aString++; continue; } else if ((c == '-') | (c == '+')) { txInteger aSign; if ((aDelta != 0) && (aDelta != -1)) goto fail; if (c == '-') aSign = -1; else aSign = 1; c = *aString++; if (('0' <= c) && (c <= '9')) { aValue = fx_Date_parse_number(&c, &aString); if (c == ':') { aDelta = 60 * aValue; c = *aString++; if (('0' <= c) && (c <= '9')) { aDelta += fx_Date_parse_number(&c, &aString); } } else { if (aValue < 24) aDelta = aValue * 60; else aDelta = (aValue % 100) + ((aValue / 100) * 60); } } else goto fail; aDelta *= aSign; } else if (('0' <= c) && (c <= '9')) { aValue = fx_Date_parse_number(&c, &aString); if (c == ':') { if (td.tm.tm_hour >= 0) goto fail; td.tm.tm_hour = aValue; c = *aString++; if (('0' <= c) && (c <= '9')) { td.tm.tm_min = fx_Date_parse_number(&c, &aString); if (c == ':') { c = *aString++; if (('0' <= c) && (c <= '9')) { td.tm.tm_sec = fx_Date_parse_number(&c, &aString); if (c == '.') { c = *aString++; if (('0' <= c) && (c <= '9')) { td.ms = fx_Date_parse_fraction(&c, &aString); } } } else td.tm.tm_sec = 0; } } else td.tm.tm_sec = 0; } else if (c == '/') { if (td.tm.tm_year >= 0) goto fail; td.tm.tm_year = (aValue < 100) ? aValue : aValue - 1900; c = *aString++; if (('0' <= c) && (c <= '9')) { td.tm.tm_mon = fx_Date_parse_number(&c, &aString) - 1; if (c == '/') { c = *aString++; if (('0' <= c) && (c <= '9')) { td.tm.tm_mday = fx_Date_parse_number(&c, &aString); hasSlash = 1; } else td.tm.tm_mday = 1; } } else td.tm.tm_mon = 0; } else if (c == '-') { if (td.tm.tm_year >= 0) goto fail; td.tm.tm_year = (aValue < 100) ? aValue : aValue - 1900; c = *aString++; if (('0' <= c) && (c <= '9')) { td.tm.tm_mon = fx_Date_parse_number(&c, &aString) - 1; if (c == '-') { c = *aString++; if (('0' <= c) && (c <= '9')) td.tm.tm_mday = fx_Date_parse_number(&c, &aString); else td.tm.tm_mday = 1; } } else td.tm.tm_mon = 0; } else { if (aValue < 70) { if (td.tm.tm_mday < 0) td.tm.tm_mday = aValue; else goto fail; } else { if (td.tm.tm_year < 0) td.tm.tm_year = (aValue < 100) ? aValue : aValue - 1900; else goto fail; } } } else if ((('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'))) { txInteger cmpLength; p = buffer; q = p + sizeof(buffer) - 1; do { if (p == q) goto fail; *p++ = c_tolower(c); c = *aString++; } while ((('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'))); *p = 0; aLength = p - (txString)buffer; cmpLength = (aLength >=3)? aLength: 3; if (c_strcmp("am", buffer) == 0) { if ((td.tm.tm_hour < 0) || (12 < td.tm.tm_hour)) goto fail; if (td.tm.tm_hour == 12) td.tm.tm_hour = 0; continue; } if (c_strcmp("pm", buffer) == 0) { if ((td.tm.tm_hour < 0) || (12 < td.tm.tm_hour)) goto fail; if (td.tm.tm_hour != 12) td.tm.tm_hour += 12; continue; } for (i = 0; i < mxDayCount; i++) if (c_strncmp(gxDays[i], buffer, cmpLength) == 0) break; if (i < mxDayCount) continue; for (i = 0; i < mxMonthCount; i++) if (c_strncmp(gxMonths[i], buffer, cmpLength) == 0) break; if (i < mxMonthCount) { if (td.tm.tm_mon < 0) { td.tm.tm_mon = i; continue; } else goto fail; } for (i = 0; i < mxZoneCount; i++) if (c_strcmp(gxZones[i], buffer) == 0) break; if (i < mxZoneCount) { if (aDelta == -1) { aDelta = gxDeltas[i] * 60; continue; } else goto fail; } if (c_strcmp("t", buffer) == 0) { if (td.tm.tm_year < 0) goto fail; continue; } if (c_strcmp("z", buffer) == 0) { if (td.tm.tm_hour < 0) goto fail; aDelta = 0; continue; } goto fail; } else goto fail; } if (td.tm.tm_year < 0) goto fail; if (td.tm.tm_mon < 0) goto fail; if (td.tm.tm_mday < 0) td.tm.tm_mday = 1; if (td.tm.tm_hour < 0) td.tm.tm_hour = 0; if (td.tm.tm_min < 0) td.tm.tm_min = 0; if (td.tm.tm_sec < 0) td.tm.tm_sec = 0; if (aDelta != -1) td.tm.tm_isdst = 0; else td.tm.tm_isdst = -1; // Check "30/3/1999" format if (hasSlash) { if ((td.tm.tm_year < 32) && (td.tm.tm_mday >= 32)) { hasSlash = td.tm.tm_year; td.tm.tm_year = (td.tm.tm_mday < 100) ? td.tm.tm_mday : td.tm.tm_mday - 1900; td.tm.tm_mday = hasSlash; } } time = c_mktime(&(td.tm)); if (time == -1) { // Check again for real NaN : 1969-12-31T23:59:59:999 (ecma/Date/15.9.4.2.js) td.tm.tm_sec = 0; time = c_mktime(&(td.tm)); if(-60 == time) { number = -1000.0; if (aDelta != -1) { number -= gxDeltaTime; number -= (txNumber)aDelta * 60000.0; } } else number = NAN; } else { number = (time * 1000.0); if (aDelta != -1) { number -= gxDeltaTime; number -= (txNumber)aDelta * 60000.0; } } number += td.ms; mxResult->value.number = number; mxResult->kind = XS_NUMBER_KIND; return; fail: mxResult->value.number = C_NAN; mxResult->kind = XS_NUMBER_KIND; //mxSyntaxError("invalid parameter"); }
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; }
void scanStartTag(void *data, const char *tag, const char **attributes) { Scanner* self = data; xsMachine* the = self->the; const char **attribute; char* name; char* value; char* colon; scanText(data); xsVar(LINE) = xsInteger(XML_GetCurrentLineNumber(self->expat)); xsVar(CHILD) = xsNewInstanceOf(xsVar(ELEMENT_PROTOTYPE)); xsSet(xsVar(CHILD), xsID_path, xsVar(PATH)); xsSet(xsVar(CHILD), xsID_line, xsVar(LINE)); xsSet(xsVar(CHILD), xsID_parent, xsResult); if (!self->root) { self->root = 1; xsSet(xsResult, xsID_element, xsVar(CHILD)); } xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD)); xsResult = xsVar(CHILD); xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype); xsArrayCacheBegin(xsVar(CHILDREN)); attribute = attributes; while (*attribute) { name = (char*)*attribute; attribute++; value = (char*)*attribute; attribute++; if (c_strncmp(name, "xmlns", 5) == 0) { colon = name + 5; if (*colon == ':') { *colon = 0; xsVar(NAME) = xsString(colon + 1); *colon = ':'; xsVar(PREFIX) = xsVar(XML_PREFIX); } else { xsVar(NAME) = xsVar(XML_PREFIX); xsVar(PREFIX) = xsUndefined; } xsVar(NAMESPACE) = xsVar(XML_NAMESPACE); xsVar(VALUE) = xsString(value); xsVar(CHILD) = xsNewInstanceOf(xsVar(ATTRIBUTE_PROTOTYPE)); xsSet(xsVar(CHILD), xsID_parent, xsResult); xsSet(xsVar(CHILD), xsID_path, xsVar(PATH)); xsSet(xsVar(CHILD), xsID_line, xsVar(LINE)); xsSet(xsVar(CHILD), xsID_name, xsVar(NAME)); xsSet(xsVar(CHILD), xsID_namespace, xsVar(NAMESPACE)); xsSet(xsVar(CHILD), xsID_prefix, xsVar(PREFIX)); xsSet(xsVar(CHILD), xsID_value, xsVar(VALUE)); xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD)); } } xsArrayCacheEnd(xsVar(CHILDREN)); xsSet(xsResult, xsID_xmlnsAttributes, xsVar(CHILDREN)); xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype); xsArrayCacheBegin(xsVar(CHILDREN)); attribute = attributes; while (*attribute) { name = (char*)*attribute; attribute++; value = (char*)*attribute; attribute++; if (c_strncmp(name, "xmlns", 5) != 0) { scanName(the, name, 0); xsVar(VALUE) = xsString(value); xsVar(CHILD) = xsNewInstanceOf(xsVar(ATTRIBUTE_PROTOTYPE)); xsSet(xsVar(CHILD), xsID_parent, xsResult); xsSet(xsVar(CHILD), xsID_path, xsVar(PATH)); xsSet(xsVar(CHILD), xsID_line, xsVar(LINE)); xsSet(xsVar(CHILD), xsID_name, xsVar(NAME)); xsSet(xsVar(CHILD), xsID_namespace, xsVar(NAMESPACE)); xsSet(xsVar(CHILD), xsID_prefix, xsVar(PREFIX)); xsSet(xsVar(CHILD), xsID_value, xsVar(VALUE)); xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD)); } } xsArrayCacheEnd(xsVar(CHILDREN)); xsSet(xsResult, xsID__attributes, xsVar(CHILDREN)); scanName(the, tag, 1); xsSet(xsResult, xsID_name, xsVar(NAME)); xsSet(xsResult, xsID_namespace, xsVar(NAMESPACE)); xsSet(xsResult, xsID_prefix, xsVar(PREFIX)); xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype); xsArrayCacheBegin(xsVar(CHILDREN)); xsSet(xsResult, xsID_children, xsVar(CHILDREN)); }