Beispiel #1
0
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;
		}
	}
}
Beispiel #2
0
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;
}
Beispiel #3
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++;
}
Beispiel #4
0
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;
		}
	}
}
Beispiel #5
0
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;
}
Beispiel #6
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++;
			}
		}
	}
}
Beispiel #7
0
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;
		}
	}
}
Beispiel #8
0
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;
}
Beispiel #9
0
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");
}
Beispiel #10
0
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;
}
Beispiel #11
0
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));
}