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>

 

posted @ 2016-01-20 09:44  SillyFlame  阅读(245)  评论(0编辑  收藏  举报