From 42e43b044ffc49e3128ae59e75ce5ffd84c371be Mon Sep 17 00:00:00 2001 From: deva Date: Fri, 1 Jul 2011 10:02:42 +0000 Subject: Fixed bug in field check/creation with depth greater than 1. --- server/src/luautil.cc | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) (limited to 'server/src/luautil.cc') diff --git a/server/src/luautil.cc b/server/src/luautil.cc index 116d219..1042d8f 100644 --- a/server/src/luautil.cc +++ b/server/src/luautil.cc @@ -217,6 +217,129 @@ int Pracro::checkParameters(lua_State *L, ...) return 0; } +void Pracro::stack(lua_State* l, const char *fmt, ...) +{ + int i; + int top = lua_gettop(l); + + va_list va; + va_start(va, fmt); + + printf("---Stack: "); + vprintf(fmt, va); + printf("---\nSize: %d\n", top); + + for (i = 1; i <= top; i++) { + int t = lua_type(l, i); + switch (t) { + case LUA_TSTRING: + printf("string: '%s'\n", lua_tostring(l, i)); + break; + case LUA_TBOOLEAN: + printf("boolean %s\n",lua_toboolean(l, i) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf("number: %g\n", lua_tonumber(l, i)); + break; + default: + printf("%s\n", lua_typename(l, t)); + break; + } + printf(" "); + } + printf("\n"); + fflush(stdout); +} + +bool Pracro::hasField(lua_State *L, int i, std::string name) +{ + // stack [] + lua_getfield(L, i, name.c_str()); // stack [field|nil] + bool ret = !lua_isnil(L, lua_gettop(L)); // stack [field|nil] + lua_pop(L, 1); // stack [] + + return ret; +} + +bool Pracro::testField(lua_State *L, std::vector groups, + std::string field) +{ + int top = lua_gettop(L); + + groups.push_back(field); + + int grp = LUA_GLOBALSINDEX; + std::vector::iterator gi = groups.begin(); + while(gi != groups.end()) { + const char *name = gi->c_str(); + + if(!hasField(L, grp, name)) { + while(lua_gettop(L) > top) lua_pop(L, 1); + return false; + } + lua_getfield(L, grp, name); + + grp = lua_gettop(L); + gi++; + } + + while(lua_gettop(L) > top) lua_pop(L, 1); + + return true; +} + +bool Pracro::getField(lua_State *L, std::vector groups, + std::string field) +{ + int top = lua_gettop(L); + groups.push_back(field); + + int grp = LUA_GLOBALSINDEX; + std::vector::iterator gi = groups.begin(); + while(gi != groups.end()) { + const char *name = gi->c_str(); + + if(!hasField(L, grp, name)) { + while(lua_gettop(L) > top) lua_pop(L, 1); + return false; + } + lua_getfield(L, grp, name); + + grp = lua_gettop(L); + gi++; + } + + return true; +} + +bool Pracro::createField(lua_State *L, std::vector groups, + std::string field) +{ + int top = lua_gettop(L); + + int grp = LUA_GLOBALSINDEX; + std::vector::iterator gi = groups.begin(); + while(gi != groups.end()) { + const char *name = gi->c_str(); + + if(!hasField(L, grp, name)) { + while(lua_gettop(L) > top) lua_pop(L, 1); + return false; + } + lua_getfield(L, grp, name); + + grp = lua_gettop(L); + gi++; + } + + lua_newtable(L); + lua_setfield(L, grp, field.c_str()); + + while(lua_gettop(L) > top) lua_pop(L, 1); + + return true; +} + #ifdef TEST_LUAUTIL //deps: //cflags: $(LUA_CFLAGS) -I.. @@ -305,6 +428,26 @@ if(luaL_loadstring(L, LUAPROG_MISSING_END)) { } TEST_NOTEQUAL_INT(lua_pcall(L, 0, LUA_MULTRET, 0), 0, "Missing T_END"); +std::string src = + "foo = {}" + "foo.bar = {}" + "foo.bar.bas = {}" + "foo.bar.bas.value = 'hello'" + "print('done')"; + +luaL_loadbuffer(L, src.c_str(), src.size(), "src"); +lua_pcall(L, 0, LUA_MULTRET, 0); + +std::vector g; +g.push_back("foo"); +g.push_back("bar"); +g.push_back("bas"); +TEST_TRUE(Pracro::testField(L, g, "value"), "?"); + +TEST_TRUE(Pracro::createField(L, g, "abe"), "?"); + +TEST_TRUE(Pracro::testField(L, g, "abe"), "?"); + lua_close(L); TEST_END; -- cgit v1.2.3