Пример #1
0
int Xml_eval(lua_State *L) {
	char* str = 0;
	size_t str_size=0;
	if(lua_isuserdata(L,1)) str = (char*)lua_touserdata(L,1);
	else {
		const char * sTmp = luaL_checklstring(L,1,&str_size);
		str = (char*)malloc(str_size+1);
		memcpy(str, sTmp, str_size);
		str[str_size]=0;
	}
	Tokenizer* tok = Tokenizer_new(str, str_size ? str_size : strlen(str));
	lua_settop(L,0);
	const char* token=0;
	int firstStatement = 1;
	while((token=Tokenizer_next(tok))!=0) if(token[0]==OPN) { // new tag found
		if(lua_gettop(L)) {
			int newIndex=lua_objlen(L,-1)+1;
			lua_pushnumber(L,newIndex);
			lua_newtable(L);
			lua_settable(L, -3);
			lua_pushnumber(L,newIndex);
			lua_gettable(L,-2);
		}
		else {
			if (firstStatement) {
				lua_newtable(L); 
				firstStatement = 0;
			}
			else return lua_gettop(L);
		}
		// set metatable:    
		lua_newtable(L);
		lua_pushliteral(L, "__index");
		lua_getglobal(L, "xml");
		lua_settable(L, -3);
			
		lua_pushliteral(L, "__tostring"); // set __tostring metamethod
		lua_getglobal(L, "xml");
		lua_pushliteral(L,"str");
		lua_gettable(L, -2);
		lua_remove(L, -2);
		lua_settable(L, -3);			
		lua_setmetatable(L, -2);
		
		// parse tag and content:
		lua_pushnumber(L,0); // use index 0 for storing the tag
		lua_pushstring(L, Tokenizer_next(tok));
		lua_settable(L, -3);
		
		while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header
			size_t sepPos=find(token, "=", 0);
			if(token[sepPos]) { // regular attribute
				const char* aVal =token+sepPos+2;
				lua_pushlstring(L, token, sepPos);
				Xml_pushDecode(L, aVal, strlen(aVal)-1);
				lua_settable(L, -3);
			}
		}            
		if(!token||(token[0]==ESC)) {
			if(lua_gettop(L)>1) lua_settop(L,-2); // this tag has no content, only attributes
			else break;
		}
	}
	else if(token[0]==ESC) { // previous tag is over
		if(lua_gettop(L)>1) lua_settop(L,-2); // pop current table
		else break;
	}
	else { // read elements
		lua_pushnumber(L,lua_objlen(L,-1)+1);
		Xml_pushDecode(L, token, 0);
		lua_settable(L, -3);
	}
	Tokenizer_delete(tok);
	free(str);
	return lua_gettop(L);
}
Пример #2
0
int Xml_eval(HSQUIRRELVM v) {
    SQ_FUNC_VARS_NO_TOP(v);
	SQChar* str = 0;
	size_t str_size=0;
	if(sq_gettype(v,2) == OT_USERPOINTER) sq_getuserpointer(v, 2, &str);
	else {
	    SQ_GET_STRING(v, 2, sTmp);
		str = (SQChar*)sq_malloc(sTmp_size+(sizeof(SQChar)));
		memcpy(str, sTmp, sTmp_size);
		str[sTmp_size]=0;
		str_size = sTmp_size;
	}
	Tokenizer* tok = Tokenizer_new(str, str_size ? str_size : scstrlen(str));
	sq_settop(v,0);
	const SQChar* token=0;
	int firstStatement = 1;
	while((token=Tokenizer_next(tok))!=0) if(token[0]==OPN) { // new tag found
		if(sq_gettop(v)) {
			int newIndex=sq_size(v,-1)+1;
			sq_pushinteger(v,newIndex);
			sq_newtable(v);
			sq_set(v, -3);
			sq_pushinteger(v,newIndex);
			sq_get(v,-2);
		}
		else {
			if (firstStatement) {
				sq_newtable(v);
				firstStatement = 0;
			}
			else return lua_gettop(L);
		}
		// set metatable:
		sq_newtable(v);
		sq_pushliteral(v, _SC("__index"));
		sq_getglobal(v, "xml");
		lua_settable(v, -3);

		sq_pushliteral(v, _SC("__tostring")); // set __tostring metamethod
		lua_getglobal(L, "xml");
		lua_pushliteral(L,"str");
		lua_gettable(v, -2);
		sq_remove(v, -2);
		sq_set(v, -3);
		lua_setmetatable(L, -2);

		// parse tag and content:
		sq_pushinteger(v,0); // use index 0 for storing the tag
		sq_pushstring(v, Tokenizer_next(tok), -1);
		sq_set(v, -3);

		while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header
			size_t sepPos=find(token, "=", 0);
			if(token[sepPos]) { // regular attribute
				const SQChar* aVal =token+sepPos+2;
				sq_pushstring(v, token, sepPos);
				size_t lenVal = strlen(aVal)-1;
				if(!lenVal) Xml_pushDecode(v, _SC(""), 0);
				else Xml_pushDecode(v, aVal, lenVal);
				sq_set(v, -3);
			}
		}
		if(!token||(token[0]==ESC)) {
			if(sq_gettop(v)>1) sq_settop(v,-2); // this tag has no content, only attributes
			else break;
		}
	}
	else if(token[0]==ESC) { // previous tag is over
		if(sq_gettop(v)>1) sq_settop(v,-2); // pop current table
		else break;
	}
	else { // read elements
		sq_pushinteger(v,sq_size(v,-1)+1);
		Xml_pushDecode(v, token, 0);
		sq_rawset(v, -3);
	}
	Tokenizer_delete(tok);
	sq_free(str);
	return sq_gettop(v);
}