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); }
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); }