void fx_Error_toString(txMachine* the) { txInteger aLength; mxPushSlot(mxThis); fxGetID(the, mxID(_name)); if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, "Error"); else fxToString(the, the->stack); mxPushSlot(mxThis); fxGetID(the, mxID(_message)); if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, ""); else fxToString(the, the->stack); aLength = c_strlen(the->stack->value.string); if (aLength) { aLength += c_strlen((the->stack + 1)->value.string) + 2; mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, (the->stack + 1)->value.string); c_strcat(mxResult->value.string, ": "); c_strcat(mxResult->value.string, the->stack->value.string); the->stack++; the->stack++; } else { the->stack++; mxPullSlot(mxResult); } }
void fxCatenate(txMachine* the) { txInteger aCount, anIndex; aCount = the->stack->value.integer; the->stack++; fxToString(the, the->stack); for (anIndex = 1; anIndex < aCount; anIndex++) { fxToString(the, the->stack + anIndex); fxConcatString(the, the->stack, the->stack + anIndex); } aCount--; (the->stack + aCount)->value = (the->stack)->value; the->stack += aCount; }
void fxSlotToID(txMachine* the, txSlot* slot, txInteger* id) { txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, id)) return; if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, id)) return; if (slot->kind == XS_SYMBOL_KIND) { *id = slot->value.ID; return; } if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (!fxStringToIndex(the->dtoa, string, id)) { if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); *id = key->ID; } }
void fx_JSON_parse(txMachine* the) { txSlot* aSlot; txStringCStream aCStream; txStringStream aStream; aSlot = fxGetInstance(the, mxThis); if (aSlot->flag & XS_SANDBOX_FLAG) the->frame->flag |= XS_SANDBOX_FLAG; else the->frame->flag |= the->frame->next->flag & XS_SANDBOX_FLAG; if (mxArgc < 1) mxDebug0(the, XS_SYNTAX_ERROR, "JSON.parse: no buffer"); aSlot = fxGetInstance(the, mxArgv(0)); if (mxIsChunk(aSlot)) { aSlot = aSlot->next; aCStream.buffer = aSlot->value.host.data; aCStream.size = aSlot->next->value.integer; aCStream.offset = 0; fxParseJSON(the, &aCStream, fxStringCGetter); } else { fxToString(the, mxArgv(0)); aStream.slot = mxArgv(0); aStream.size = c_strlen(aStream.slot->value.string); aStream.offset = 0; fxParseJSON(the, &aStream, fxStringGetter); } *mxResult = *(the->stack++); }
void fx_decodeURI(txMachine* the) { if (mxArgc < 1) mxSyntaxError("no URI parameter"); fxToString(the, mxArgv(0)); fxDecodeURI(the, (txString)gxURIReservedSet); }
void fx_decodeURIComponent(txMachine* the) { if (mxArgc < 1) mxSyntaxError("no URI Component parameter"); fxToString(the, mxArgv(0)); fxDecodeURI(the, (txString)gxURIEmptySet); }
void fxLoadModuleXML(txMachine* the, txString path, txID moduleID) { FskFileMapping map = NULL; txFileMapStream fileMapStream; txStringStream stringStream; txScript* script = NULL; mxTry(the) { fxBeginHost(the); xsThrowIfFskErr(FskFileMap(path, &fileMapStream.buffer, &fileMapStream.size, 0, &map)); fileMapStream.offset = 0; mxPushInteger(0); mxPushInteger(0); mxPushInteger(0); mxPushInteger(0); mxPushInteger(3); fxParse(the, &fileMapStream, fxFileMapGetter, path, 1, xsSourceFlag | xsDebugFlag); fxCallID(the, fxID(the, "generate")); fxToString(the, the->stack); stringStream.slot = the->stack; stringStream.size = c_strlen(stringStream.slot->value.string); stringStream.offset = 0; script = fxParseScript(the, &stringStream, fxStringGetter, mxDebugFlag); fxEndHost(the); } mxCatch(the) { break; } FskFileDisposeMap(map); fxResolveModule(the, moduleID, script, NULL, NULL); }
void fx_xs_execute(txMachine* the) { if (mxArgc > 0) { txStringStream stream; txString path; txInteger line; fxToString(the, mxArgv(0)); stream.slot = mxArgv(0); stream.size = c_strlen(stream.slot->value.string); stream.offset = 0; path = (mxArgc > 1) ? fxToString(the, mxArgv(1)) : NULL; line = (mxArgc > 2) ? fxToInteger(the, mxArgv(2)) : 0; fxExecute(the, &stream, fxStringGetter, path, line); *mxResult = *the->stack; } }
void fx_Boolean_prototype_toString(txMachine* the) { txSlot* slot = fxCheckBoolean(the, mxThis); if (!slot) mxTypeError("this is no boolean"); mxResult->kind = slot->kind; mxResult->value = slot->value; fxToString(the, mxResult); }
void fx_Number_prototype_toString(txMachine* the) { char buffer[256]; txInteger radix; txSlot* slot = fxCheckNumber(the, mxThis); if (!slot) mxTypeError("this is no number"); if (mxArgc > 0) { radix = fxToInteger(the, mxArgv(0)); if (radix) { if ((radix < 2) || (36 < radix)) mxRangeError("invalid radix"); } else radix = 10; } else radix = 10; mxResult->kind = slot->kind; mxResult->value = slot->value; if (radix == 10) fxToString(the, mxResult); else { static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; txString string = buffer + sizeof(buffer); txNumber value; txBoolean minus; value = mxResult->value.number; switch (c_fpclassify(value)) { case C_FP_INFINITE: if (value < 0) fxCopyStringC(the, mxResult, "-Infinity"); else fxCopyStringC(the, mxResult, "Infinity"); break; case C_FP_NAN: fxCopyStringC(the, mxResult, "NaN"); break; case C_FP_ZERO: fxCopyStringC(the, mxResult, "0"); break; default: *(--string) = 0; if (value < 0) { minus = 1; value = -value; } else minus = 0; do { *(--string) = gxDigits[(txInteger)c_fmod(value, radix)]; value = value / radix; } while (value >= 1); if (minus) *(--string) = '-'; fxCopyStringC(the, mxResult, string); } } }
txID fxToID(txMachine* the) { txSlot* aSymbol; fxToString(the, the->stack); aSymbol = fxNewSymbol(the, the->stack); the->stack++; return aSymbol->ID; }
int fxCompareArrayItem(txMachine* the, txSlot* function, txSlot* array, txInteger i) { txSlot* address = array->value.array.address; txSlot* a = address + i; txSlot* b = the->stack; int result; if (!(a->ID)) result = (!(b->ID)) ? 0 : 1; else if (!(b->ID)) result = -1; else if (a->kind == XS_UNDEFINED_KIND) result = (b->kind == XS_UNDEFINED_KIND) ? 0 : 1; else if (b->kind == XS_UNDEFINED_KIND) result = -1; else { mxPushSlot(a); mxPushSlot(b); if (function) { /* ARGC */ mxPushInteger(2); /* THIS */ mxPushSlot(mxThis); /* FUNCTION */ mxPushReference(function); fxCall(the); if (the->stack->kind == XS_INTEGER_KIND) result = the->stack->value.integer; else { txNumber number = fxToNumber(the, the->stack); result = (number < 0) ? -1 : (number > 0) ? 1 : 0; } the->stack++; } else { fxToString(the, the->stack + 1); fxToString(the, the->stack); result = c_strcmp((the->stack + 1)->value.string, the->stack->value.string); the->stack += 2; } } return result; }
void fx_Error_aux(txMachine* the) { txSlot* aProperty; if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) { aProperty = fxSetProperty(the, fxGetInstance(the, mxResult), mxID(_message), C_NULL); aProperty->value.string = fxToString(the, mxArgv(0)); aProperty->kind = mxArgv(0)->kind; } }
void fx_Function(txMachine* the) { txInteger c, i; txStringStream stream; c = mxArgc; i = 0; mxPushStringC("(function anonymous("); while (c > 1) { fxToString(the, mxArgv(i)); fxConcatString(the, the->stack, mxArgv(i)); if (c > 2) fxConcatStringC(the, the->stack, ", "); c--; i++; } fxConcatStringC(the, the->stack, "){"); if (c > 0) { fxToString(the, mxArgv(i)); fxConcatString(the, the->stack, mxArgv(i)); } fxConcatStringC(the, the->stack, "})"); stream.slot = the->stack; stream.offset = 0; stream.size = c_strlen(the->stack->value.string); fxRunScript(the, fxParseScript(the, &stream, fxStringGetter, mxProgramFlag), C_NULL, C_NULL, C_NULL, C_NULL); if (mxTarget->kind == XS_UNDEFINED_KIND) mxPullSlot(mxResult); else { txSlot* from = fxGetInstance(the, the->stack++); txSlot* to = fxGetInstance(the, mxThis); txSlot* fromProperty; txSlot* toProperty; to->next->value.code = from->next->value.code; fromProperty = mxFunctionInstancePrototype(from); toProperty = mxFunctionInstancePrototype(to); *toProperty = *fromProperty; fromProperty = mxFunctionInstanceInfo(from); toProperty = mxFunctionInstanceInfo(to); *toProperty = *fromProperty; } }
void fx_parseFloat(txMachine* the) { if (mxArgc < 1) { mxResult->value.number = C_NAN; mxResult->kind = XS_NUMBER_KIND; return; } fxToString(the, mxArgv(0)); mxResult->kind = XS_NUMBER_KIND; mxResult->value.number = fxStringToNumber(the->dtoa, mxArgv(0)->value.string, 0); }
void fx_Boolean_toString(txMachine* the) { txSlot* aBoolean; txSlot* aProperty; aBoolean = fxGetInstance(the, mxThis); mxCheckBoolean(aBoolean); aProperty = aBoolean->next; mxResult->kind = aProperty->kind; mxResult->value = aProperty->value; fxToString(the, mxResult); }
txString fxToStringBuffer(txMachine* the, txSlot* theSlot, txString theBuffer, txSize theSize) { char* aString; txSize aSize; aString = fxToString(the, theSlot); aSize = c_strlen(aString) + 1; if (aSize > theSize) mxRangeError("Cannot buffer string"); c_memcpy(theBuffer, aString, aSize); return theBuffer; }
void fx_Error_toString(txMachine* the) { txSlot* anError; txSlot* aProperty; txInteger aLength; anError = fxGetInstance(the, mxThis); aProperty = fxGetProperty(the, anError, fxID(the, "name")); --the->stack; the->stack->kind = aProperty->kind; the->stack->value = aProperty->value; if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, "Error"); else fxToString(the, the->stack); aProperty = fxGetProperty(the, anError, fxID(the, "message")); --the->stack; the->stack->kind = aProperty->kind; the->stack->value = aProperty->value; if (the->stack->kind == XS_UNDEFINED_KIND) fxCopyStringC(the, the->stack, ""); else fxToString(the, the->stack); aLength = c_strlen(the->stack->value.string); if (aLength) { aLength += c_strlen((the->stack + 1)->value.string) + 2; mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, (the->stack + 1)->value.string); c_strcat(mxResult->value.string, ": "); c_strcat(mxResult->value.string, the->stack->value.string); the->stack++; the->stack++; } else { the->stack++; *mxResult = *(the->stack++); } }
void fx_Number_toString(txMachine* the) { txSlot* aNumber; txSlot* aProperty; txInteger aRadix; aNumber = fxGetInstance(the, mxThis); mxCheckNumber(aNumber); aProperty = aNumber->next; if (mxArgc > 0) { aRadix = fxToInteger(the, mxArgv(0)); if (aRadix) { if ((aRadix < 2) || (36 < aRadix)) mxDebug0(the, XS_RANGE_ERROR, "invalid radix"); } else aRadix = 10; } else aRadix = 10; mxResult->kind = aProperty->kind; mxResult->value = aProperty->value; if (aRadix == 10) fxToString(the, mxResult); else { static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char aBuffer[256]; txString aString; txNumber aValue; txBoolean aMinus; fxToNumber(the, mxResult); aString = aBuffer + sizeof(aBuffer); *(--aString) = 0; aValue = mxResult->value.number; if (aValue < 0) { aMinus = 1; aValue = -aValue; } else aMinus = 0; do { *(--aString) = gxDigits[(txInteger)c_fmod(aValue, aRadix)]; aValue = aValue / aRadix; } while (aValue >= 1); if (aMinus) *(--aString) = '-'; fxCopyStringC(the, mxResult, aString); } }
void fx_String(txMachine* the) { if ((mxThis->kind == XS_REFERENCE_KIND) && ((mxThis->value.reference->flag & XS_SHARED_FLAG) == 0)) { txSlot* anInstance = mxThis->value.reference; if (mxIsString(anInstance)) { if (mxArgc > 0) { txString aString = fxToString(the, mxArgv(0)); anInstance->next->value.string = aString; anInstance->next->next->value.integer = fxUnicodeLength(aString); } *mxResult = *mxThis; } return; } if (mxArgc > 0) { *mxResult = *mxArgv(0); fxToString(the, mxResult); } else { mxResult->value.string = mxEmptyString.value.string; mxResult->kind = mxEmptyString.kind; } }
void fx_String_compare(txMachine* the) { txString aString; aString = fxCoerceToString(the, mxThis); if (!aString) mxDebug0(the, XS_TYPE_ERROR, "String.prototype.compare: this is null or undefined"); if (mxArgc < 1) mxResult->value.integer = c_strcmp(aString, "undefined"); else { fxToString(the, mxArgv(0)); mxResult->value.integer = c_strcmp(aString, mxArgv(0)->value.string); } mxResult->kind = XS_INTEGER_KIND; }
void fx_JSON_parse(txMachine* the) { volatile txJSONParser* aParser = C_NULL; txSlot* slot; mxTry(the) { if (mxArgc < 1) mxSyntaxError("no buffer"); aParser = c_malloc(sizeof(txJSONParser)); if (NULL == aParser) mxUnknownError("out of memory"); c_memset((txJSONParser*)aParser, 0, sizeof(txJSONParser)); if (mxArgc > 1) { slot = mxArgv(1); if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference; if (slot->next && ((slot->next->kind == XS_CODE_KIND) || (slot->next->kind == XS_CODE_X_KIND) || (slot->next->kind == XS_CALLBACK_KIND))) aParser->reviver = slot; } } slot = mxArgv(0); if (slot->kind == XS_REFERENCE_KIND) { slot = slot->value.reference->next; if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_HOST_KIND)) { aParser->data = slot->value.host.data; aParser->offset = 0; mxPushSlot(mxArgv(0)); fxGetID(the, mxID(_length)); aParser->size = fxToInteger(the, the->stack++); } } if (!aParser->data) { fxToString(the, mxArgv(0)); aParser->slot = mxArgv(0); aParser->offset = 0; aParser->size = c_strlen(aParser->slot->value.string); } fxParseJSON(the, (txJSONParser*)aParser); mxPullSlot(mxResult); c_free((txJSONParser*)aParser); // @@ reviver } mxCatch(the) { if (aParser) c_free((txJSONParser*)aParser); fxJump(the); } }
void fx_xs_setProfilingDirectory(txMachine* the) { if (the->profileDirectory) { c_free(the->profileDirectory); the->profileDirectory = C_NULL; } if (mxArgc > 0) { mxPushSlot(mxArgv(0)); if (fxRunTest(the)) { txString aString = fxToString(the, mxArgv(0)); txInteger aLength = c_strlen(aString) + 1; the->profileDirectory = c_malloc(aLength); if (!the->profileDirectory) fxJump(the); c_memcpy(the->profileDirectory, aString, aLength); } } }
void fx_Symbol_for(txMachine* the) { txString string; txU1* p; txU4 sum; txU4 modulo; txSlot* result; txID index; if (mxArgc < 1) mxSyntaxError("no key parameter"); string = fxToString(the, mxArgv(0)); p = (txU1*)string; sum = 0; while(*p != 0) { sum = (sum << 1) + *p++; } sum &= 0x7FFFFFFF; modulo = sum % the->symbolModulo; result = the->symbolTable[modulo]; while (result != C_NULL) { if (result->value.key.sum == sum) if (c_strcmp(result->value.key.string, string) == 0) break; result = result->next; } if (result == C_NULL) { index = the->keyIndex; if (index == the->keyCount) mxUnknownError("not enough IDs"); result = fxNewSlot(the); result->next = the->symbolTable[modulo]; result->kind = XS_KEY_KIND; result->ID = 0x8000 | index; result->value.key.string = mxArgv(0)->value.string; result->value.key.sum = sum; the->keyArray[index] = result; the->keyIndex++; the->symbolTable[modulo] = result; } mxResult->kind = XS_SYMBOL_KIND; mxResult->value.ID = result->ID; }
void fx_String_concat(txMachine* the) { txString aString; txInteger aCount; txInteger aLength; txInteger anIndex; aString = fxCoerceToString(the, mxThis); if (!aString) mxDebug0(the, XS_TYPE_ERROR, "String.prototype.concat: this is null or undefined"); aCount = mxArgc; aLength = c_strlen(mxThis->value.string); for (anIndex = 0; anIndex < aCount; anIndex++) aLength += c_strlen(fxToString(the, mxArgv(anIndex))); mxResult->value.string = (txString)fxNewChunk(the, aLength + 1); mxResult->kind = XS_STRING_KIND; c_strcpy(mxResult->value.string, mxThis->value.string); for (anIndex = 0; anIndex < aCount; anIndex++) c_strcat(mxResult->value.string, mxArgv(anIndex)->value.string); }
void fx_Date_prototype_toPrimitive(txMachine* the) { if (mxThis->kind == XS_REFERENCE_KIND) { txInteger hint = ((mxArgc > 0) && (c_strcmp(fxToString(the, mxArgv(0)), "number") == 0)) ? XS_NUMBER_HINT : XS_STRING_HINT; if (hint == XS_STRING_HINT) { mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_toString)); if (mxIsReference(the->stack)) { the->stack++; mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_valueOf)); } } else { mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_valueOf)); if (mxIsReference(the->stack)) { the->stack++; mxPushInteger(0); mxPushSlot(mxThis); fxCallID(the, mxID(_toString)); } } if (mxIsReference(the->stack)) { if (hint == XS_STRING_HINT) mxTypeError("Cannot coerce object to string"); else mxTypeError("Cannot coerce object to number"); } mxResult->kind = the->stack->kind; mxResult->value = the->stack->value; the->stack++; } else { mxResult->kind = mxThis->kind; mxResult->value = mxThis->value; } }
void fx_Symbol(txMachine* the) { txID id = the->keyIndex; txSlot* description; if (mxTarget->kind != XS_UNDEFINED_KIND) mxTypeError("new Symbol"); if (id == the->keyCount) mxUnknownError("not enough IDs"); if (mxArgc > 0) { fxToString(the, mxArgv(0)); description = fxNewSlot(the); description->kind = XS_STRING_KIND; description->value.string = mxArgv(0)->value.string; } else description = C_NULL; the->keyArray[id] = description; the->keyIndex++; mxResult->kind = XS_SYMBOL_KIND; mxResult->value.ID = 0x8000 | id; }
txSlot* fxAt(txMachine* the, txSlot* slot) { txIndex index; txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else if (slot->kind == XS_SYMBOL_KIND) { slot->value.at.id = slot->value.symbol; slot->value.at.index = XS_NO_ID; } else { if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (fxStringToIndex(the->dtoa, string, &index)) { slot->value.at.id = 0; slot->value.at.index = index; } else { if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); slot->value.at.id = key->ID; slot->value.at.index = XS_NO_ID; } } slot->kind = XS_AT_KIND; return slot; }
txInteger fxSlotToIndex(txMachine* the, txSlot* slot, txIndex* index) { txString string; txSlot* key; again: if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the->dtoa, slot->value.integer, index)) return 0; if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the->dtoa, slot->value.number, index)) return 0; if (slot->kind == XS_SYMBOL_KIND) return slot->value.symbol; if (slot->kind == XS_REFERENCE_KIND) { fxToPrimitive(the, slot, XS_STRING_HINT); goto again; } string = fxToString(the, slot); if (fxStringToIndex(the->dtoa, string, index)) return 0; if (slot->kind == XS_STRING_X_KIND) key = fxNewNameX(the, string); else key = fxNewName(the, slot); return key->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"); }