Programing in lua code sample,shit I don't get a chinese input method in ubuntu
This is the sample code of the last chapcher of the book.
the xml parse
test.cpp:
#include <stdio.h> #include <iostream> #include <lua.hpp> #include <math.h> #include <string> #include <assert.h> #include <sstream> #include <string.h> #include <vector> #include <dirent.h> #include <errno.h> //for libexpat #include "expat.h" #if defined(__amigaos__) && defined(__USE_INLINE__) #include <proto/expat.h> #endif #ifdef XML_LARGE_SIZE #if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 #define XML_FMT_INT_MOD "I64" #else #define XML_FMT_INT_MOD "ll" #endif #else #define XML_FMT_INT_MOD "l" #endif //end libexpat using namespace std; /********************************************/ //lib Person /********************************************/ class Person{ public: std::string * mName; std::string * mId; std::string * mPhone; short mAge; short mGender; }; static Person * checkPerson(lua_State *L){ void *ud = luaL_checkudata(L, 1, "LuaBook.Person"); luaL_argcheck(L, ud != NULL, 1, "`Person` expected"); return (Person*)ud; } static int newPerson(lua_State *L){ size_t nbytes = sizeof(Person); Person *p = (Person*)lua_newuserdata(L, nbytes); luaL_getmetatable(L, "LuaBook.Person"); lua_setmetatable(L, -2); p->mName = new std::string("wangxiaoyun"); p->mId = new std::string("f232-fadf-1231-dfafd"); p->mPhone = new std::string("0472-6165500"); p->mAge = 28; p->mGender = 1; return 1; } static int Person_setName(lua_State *L){ Person *p = checkPerson(L); size_t len = 0; const char * newName = luaL_checklstring(L,2,&len); luaL_argcheck(L, len <= 256, 2, "name is too long"); *(p->mName) = newName; return 0; } static int deletePerson(lua_State *L){ Person *p = checkPerson(L); delete p->mName; delete p->mId; delete p->mPhone; p->mName = NULL; p->mId = NULL; p->mPhone = NULL; } static int tostringPerson(lua_State *L){ Person *p = checkPerson(L); /* std::cout << "name:" << *p->mName << endl <<"id:" << *p->mId << endl <<"mPhone:" << *p->mPhone <<endl <<"mAge:" << p->mAge <<endl <<"mGender:" << p->mGender << endl; */ stringstream ss; ss << "name:" << *p->mName << endl <<"id:" << *p->mId << endl <<"mPhone:" << *p->mPhone <<endl <<"mAge:" << p->mAge <<endl <<"mGender:" << p->mGender << endl; lua_pushstring(L, ss.str().c_str()); return 1; } static struct luaL_Reg person_lib_f[] = { {"new", newPerson}, {NULL, NULL} }; static struct luaL_Reg person_lib_m[] = { {"delete", deletePerson}, {"__tostring", tostringPerson}, {"setName", Person_setName}, {NULL, NULL} }; void luaopen_Person(lua_State *L){ luaL_newmetatable(L, "LuaBook.Person"); lua_pushstring(L, "__index"); lua_pushvalue(L, -2); //pushes the metatable lua_settable(L, -3); //metatable.__index = metatable luaL_setfuncs(L, person_lib_m, 0); luaL_newlib(L, person_lib_f); lua_setglobal(L, "Person"); } /********************************************/ //lib Room /********************************************/ class Room{ public: std::string mId; std::string mName; std::vector<int> mPlayerId; int mState; void addPlayer(int player_id){ mPlayerId.push_back(player_id); } int getState(){ return mState; } void setState(int newState){ mState = newState; } int getPlayerSize(){ return mPlayerId.size(); } }; static int Room_new(lua_State *L){ Room * room = new Room(); room->mId = "001"; room->mName = "myRoom"; room->mState = 0; lua_pushlightuserdata(L,(void*)room); return 1; } static int Room_delete(lua_State *L){ Room *room = (Room*)lua_touserdata(L, 1); delete room; return 0; } static int Room_toString(lua_State *L){ Room *room = (Room*)lua_touserdata(L, 1); stringstream ss; ss << room->mId << endl << room->mName << endl << room->mState << endl; lua_pushstring(L, ss.str().c_str()); return 1; } static struct luaL_Reg Room_lib[] = { {"new", Room_new}, {"delete", Room_delete}, {"__tostring", Room_toString}, {NULL, NULL} }; void luaopen_Room(lua_State *L){ luaL_newlib(L, Room_lib); lua_setglobal(L, "Room"); } /********************************************/ //lib mylib /********************************************/ static int l_sin(lua_State *L){ double d = lua_tonumber(L, 1); lua_pushnumber(L, sin(d)); return 1; } static struct luaL_Reg mylib[] = { {"sin", l_sin}, {NULL, NULL} }; void luaopen_mylib(lua_State *L){ luaL_newlib(L, mylib); lua_setglobal(L, "mylib"); } /********************************************/ //lib dir /********************************************/ static int dir_iter(lua_State *L); static int l_dir(lua_State *L){ const char * path = luaL_checkstring(L, 1); DIR ** d = (DIR **)lua_newuserdata(L, sizeof(DIR*)); luaL_getmetatable(L, "LuaBook.dir"); lua_setmetatable(L, -2); *d = opendir(path); if(*d == NULL) luaL_error(L, "cannot open %s: %s", path, strerror(errno)); lua_pushcclosure(L, dir_iter, 1); return 1; } static int dir_iter(lua_State *L){ DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex(1)); struct dirent *entry; if((entry = readdir(d)) != NULL){ lua_pushstring(L, entry->d_name); return 1; } else{ return 0; } } static int dir_gc (lua_State *L){ DIR *d = *(DIR **)lua_touserdata(L, 1); if(d) closedir(d); return 0; } int luaopen_dir(lua_State *L){ luaL_newmetatable(L,"LuaBook.dir"); lua_pushstring(L, "__gc"); lua_pushcfunction(L,dir_gc); lua_settable(L, -3); lua_pushcfunction(L, l_dir); lua_setglobal(L, "dir"); return 0; } /********************************************/ //test xml /********************************************/ typedef struct lxp_userdata { lua_State *L; XML_Parser parser; int tableref; }lxp_userdata; static int lxp_parse(lua_State *L){ int status; size_t len; const char *s; lxp_userdata *xpu; xpu = (lxp_userdata*)luaL_checkudata(L, 1, "Expat"); luaL_argcheck(L,xpu, 1, "expat parser expected"); s = luaL_optlstring(L, 2, NULL, &len); lua_settop(L, 2); lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); xpu->L = L; status = XML_Parse(xpu->parser, s, (int)len, s == NULL); lua_pushboolean(L, status); return 1; } static void f_CharData(void *ud, const char *s, int len){ lxp_userdata *xpu = (lxp_userdata *)ud; lua_State *L = xpu->L; lua_pushstring(L, "CharacterData"); lua_gettable(L, 3); if(lua_isnil(L, -1)){ lua_pop(L, 1); return; } lua_pushvalue(L, 1); lua_pushlstring(L, s, len); lua_call(L, 2, 0); } static void f_EndElement(void *ud, const char *name){ lxp_userdata *xpu = (lxp_userdata *)ud; lua_State *L = xpu->L; lua_pushstring(L, "EndElement"); lua_gettable(L, 3); if(lua_isnil(L, -1)){ lua_pop(L,1); return; } lua_pushvalue(L, 1); lua_pushstring(L, name); lua_call(L, 2, 0); } static void f_StartElement(void *ud, const char *name, const char **atts){ lxp_userdata *xpu = (lxp_userdata*)ud; lua_State *L = xpu->L; lua_pushstring(L, "StartElement"); lua_gettable(L, 3); if(lua_isnil(L, -1)){ lua_pop(L,1); return; } lua_pushvalue(L, 1); lua_pushstring(L, name); lua_newtable(L); while(*atts){ lua_pushstring(L, *atts++); lua_pushstring(L, *atts++); lua_settable(L, -3); } lua_call(L, 3, 0); } static int lxp_make_parser(lua_State *L){ XML_Parser p; lxp_userdata *xpu; xpu = (lxp_userdata *)lua_newuserdata(L, sizeof(lxp_userdata)); xpu->tableref = LUA_REFNIL; xpu->parser = NULL; luaL_getmetatable(L, "Expat"); lua_setmetatable(L, -2); p = xpu->parser = XML_ParserCreate(NULL); if(!p){ luaL_error(L, "XML_ParserCreate failed"); } luaL_checktype(L, 1, LUA_TTABLE); lua_pushvalue(L, 1); xpu->tableref = luaL_ref(L, LUA_REGISTRYINDEX); XML_SetUserData(p, xpu); XML_SetElementHandler(p, f_StartElement, f_EndElement); XML_SetCharacterDataHandler(p, f_CharData); return 1; } static int lxp_close(lua_State *L){ lxp_userdata *xpu; xpu = (lxp_userdata*)luaL_checkudata(L, 1, "Expat"); luaL_argcheck(L, xpu, 1, "expat parser expected"); luaL_unref(L, LUA_REGISTRYINDEX, xpu->tableref); xpu->tableref = LUA_REFNIL; if(xpu->parser) XML_ParserFree(xpu->parser); xpu->parser = NULL; return 0; } static const struct luaL_Reg lxp_meths[] = { {"parse", lxp_parse}, {"close", lxp_close}, {"__gc", lxp_close}, {NULL, NULL} }; static const struct luaL_Reg lxp_funcs[] = { {"new", lxp_make_parser}, {NULL, NULL} }; int luaopen_lxp(lua_State *L){ luaL_newmetatable(L, "Expat"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_setfuncs(L, lxp_meths, 0); luaL_newlib(L, lxp_funcs); lua_setglobal(L, "lxp"); return 1; } void test_xml(lua_State *L){ luaopen_lxp(L); } /********************************************/ //test function /********************************************/ void run_lua_file(lua_State *L, char * filename){ assert(filename != NULL); if(luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)){ std::cout << ("cannot run lua file: %s", lua_tostring(L, -1)); } } typedef void (*test_func)(lua_State *L); void run_test( test_func func){ assert(func != NULL); lua_State *L = luaL_newstate(); luaL_openlibs(L); func(L); run_lua_file(L,"test.lua"); lua_close(L); } void test_mylib(lua_State *L){ luaopen_mylib(L); } void test_Person(lua_State *L){ luaopen_Person(L); } void test_Room(lua_State *L){ luaopen_Room(L); } void test_dir(lua_State *L){ luaopen_dir(L); } int main(){ test_func theTestFunc = test_xml; run_test( theTestFunc); //test_xml(NULL); }
test.lua:
--print("test person") --person = Person.new() --person:setName("newName") --print(person) --person:delete(); --[[print("test Room") room = Room.new() print(Room.__tostring(room)) Room.delete(room) room = nil ]]-- --print("test dir") --for fname in dir(".") do print(fname) end print("test expat") local count = 0 callbacks = { StartElement = function (parser, tagname) io.write("+ ", string.rep(" ", count), tagname, "\n") count = count + 1; end, EndElement = function(parser, tagname) count = count - 1 io.write("- ", string.rep(" ", count), tagname, "\n") end, } p = lxp.new(callbacks) for l in io.lines("test.xml") do assert(p:parse(l)) assert(p:parse("\n")) end assert(p:parse()) p:close()
test.xml:
<Person id="10000" name="sillyFlame" phone="00000000" age="30"> <Weapons> <Gun>sufGun</Gun> <Knife>smallKnife</Knife> </Weapons> <Player></Player> <Health/> <Bag/> </Person>