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>

浙公网安备 33010602011771号