diff options
-rw-r--r-- | include/BLua.h | 5 | ||||
-rw-r--r-- | lib/BLua.cc | 186 |
2 files changed, 182 insertions, 9 deletions
diff --git a/include/BLua.h b/include/BLua.h index da09ef4..baaf9db 100644 --- a/include/BLua.h +++ b/include/BLua.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.h,v 1.25 2005-10-13 16:00:37 pixel Exp $ */ +/* $Id: BLua.h,v 1.26 2005-12-01 14:29:20 pixel Exp $ */ #ifndef __BLUA_H__ #define __BLUA_H__ @@ -72,6 +72,7 @@ class Lua : public Base { void gettable(int = -2, bool raw = false); void setvar(); int gettop(); + void getglobal(const String &) throw (GeneralException); void push_lua_context(); void error(const String &); int type(int = -1); @@ -93,6 +94,7 @@ class Lua : public Base { Lua * tothread(int = -1); void load(Handle *, bool docall = true) throw (GeneralException); void dump(Handle *, bool strip = true); + void dumpvars(Handle *, const String &, int = -1); Lua * thread(); int yield(int nargs = 0); int resume(int nresults = 0); @@ -113,6 +115,7 @@ class Lua : public Base { lua_State * L; static std::map<lua_State *, Lua *> lualist; bool _protected; + void dumpvars_r(Handle *, int, int = 0) throw (GeneralException); }; class LuaObject : public Base { diff --git a/lib/BLua.cc b/lib/BLua.cc index 8aba47e..14ab466 100644 --- a/lib/BLua.cc +++ b/lib/BLua.cc @@ -17,10 +17,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.cc,v 1.32 2005-10-13 16:00:37 pixel Exp $ */ +/* $Id: BLua.cc,v 1.33 2005-12-01 14:29:20 pixel Exp $ */ #include <stdlib.h> #include "BLua.h" +#include "Buffer.h" #include <lualib.h> #ifndef BUFFERSIZE @@ -69,6 +70,9 @@ class LuaStatics : public Base { static int hex(lua_State *); static int shl(lua_State *); static int shr(lua_State *); + + static int getglobal(lua_State *); + static int dumpvars(lua_State *); }; std::map<lua_State *, Lua *> Lua::lualist; @@ -98,7 +102,7 @@ int LuaStatics::andB(lua_State * __L) { int n = L->gettop(); Uint32 a, b; - if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + if ((n != 2) || !L->isnumber(1) || !L->isnumber(2)) { L->error("Incorrect arguments to function `andB'"); } @@ -115,7 +119,7 @@ int LuaStatics::orB(lua_State * __L) { int n = L->gettop(); Uint32 a, b; - if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + if ((n != 2) || !L->isnumber(1) || !L->isnumber(2)) { L->error("Incorrect arguments to function `orB'"); } @@ -132,7 +136,7 @@ int LuaStatics::xorB(lua_State * __L) { int n = L->gettop(); Uint32 a, b; - if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) { + if ((n != 2) || !L->isnumber(1) || !L->isnumber(2)) { L->error("Incorrect arguments to function `xorB'"); } @@ -149,7 +153,7 @@ int LuaStatics::notB(lua_State * __L) { int n = L->gettop(); Uint32 x; - if ((n != 1) && !L->isnumber()) { + if ((n != 1) || !L->isnumber()) { L->error("Incorrect arguments to function `notB'"); } @@ -165,7 +169,7 @@ int LuaStatics::shl(lua_State * __L) { int n = L->gettop(); Uint32 a, b; - if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) { + if ((n > 2) || !L->isnumber(1) || ((n == 2) && !L->isnumber(2))) { L->error("Incorrect arguments to function `shl'"); } @@ -185,7 +189,7 @@ int LuaStatics::shr(lua_State * __L) { int n = L->gettop(); Uint32 a, b; - if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) { + if ((n > 2) || !L->isnumber(1) || ((n == 2) && !L->isnumber(2))) { L->error("Incorrect arguments to function `shr'"); } @@ -206,7 +210,7 @@ int LuaStatics::hex(lua_State * __L) { int x; String r; - if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) { + if (((n != 1) && (n != 2)) || !L->isnumber(1) || ((n == 2) && !L->isstring(2))) { L->error("Incorrect arguments to function `hex'"); } @@ -219,6 +223,50 @@ int LuaStatics::hex(lua_State * __L) { return 1; } +int LuaStatics::getglobal(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + + if ((n != 1) || !L->isstring(1)) { + L->error("Incorrect arguments to function `getglobal'"); + } + + Buffer b; + b << "return " + L->tostring(); + + L->load(&b, false); + L->call(0, 1); + return 1; +} + +int LuaStatics::dumpvars(lua_State * _L) { + Lua * L = Lua::find(_L); + int n = L->gettop(); + Handle * h; + String prefix; + String varname; + + if ((n > 3) || (n < 2) || !L->isobject(1) || + ((n == 2) && !L->isstring(2)) || + ((n == 3) && !L->isstring(3) && !L->istable(2) && !L->isstring(2))) { + L->error("Incorrect arguments to function `dumpvars'"); + } + + prefix = L->tostring(n); + + if (n == 3) + L->pop(); + + if (L->isstring(2)) + L->getglobal(L->tostring(2)); + + h = (Handle *) LuaObject::getme(L); + + L->dumpvars(h, prefix); + + return 0; +} + Lua::Lua() : L(lua_open()) { lualist[L] = this; lua_atpanic(L, LuaStatics::luapanic); @@ -231,6 +279,8 @@ Lua::Lua() : L(lua_open()) { declarefunc("shl", LuaStatics::shl); declarefunc("shr", LuaStatics::shr); declarefunc("hex", LuaStatics::hex); + declarefunc("getglobal", LuaStatics::getglobal); + declarefunc("dumpvars", LuaStatics::dumpvars); } Lua::Lua(lua_State * __L) : L(__L), _protected(false) { @@ -391,6 +441,19 @@ int Lua::gettop() { return lua_gettop(L); } +void Lua::getglobal(const String & name) throw (GeneralException) { + Buffer b; + b << "return " + name; + + try { + load(&b, false); + call(0, 1); + } + catch (LuaException & l) { + throw LuaException("Error finding global variable `" + name + "'"); + } +} + void Lua::push_lua_context() { String whole_msg; struct lua_Debug ar; @@ -554,6 +617,113 @@ void Lua::dump(Handle * h, bool strip) { luacmain(L, strip, LuaStatics::putF, &lf); } +void Lua::dumpvars(Handle * h, const String & prefix, int i) { + Buffer b; + + b << prefix << " = {\n"; + dumpvars_r(&b, i); + b << "}\n"; + + b.copyto(h); +} + +void Lua::dumpvars_r(Handle * h, int i, int depth) throw (GeneralException) { + int j; + String t; + bool dump_value; + + if (lua_type(L, i) != LUA_TTABLE) + throw LuaException("Error dumping variables: variable isn't a table."); + + push(); + + if (i < 0) + i--; + + depth++; + + while(lua_next(L, i) != 0) { + for (j = 0; j < depth; j++) { + (*h) << " "; + } + + dump_value = true; + + // first, let's dump the key. + switch(lua_type(L, -2)) { + case LUA_TNONE: + throw LuaException("Internal error: got invalid index for key while dumpvars."); + case LUA_TNIL: + throw LuaException("Internal error: got nil index for key while dumpvars."); + case LUA_TNUMBER: + t.set("[%.14g] = ", lua_tonumber(L, -2)); + break; + case LUA_TBOOLEAN: + t = String("[") + (lua_toboolean(L, -2) ? "true" : "false") + "] = "; + break; + case LUA_TSTRING: + t = lua_tostring(L, -2) + String(" = "); + break; + case LUA_TTABLE: + t = "-- [a table]\n"; + dump_value = false; + break; + case LUA_TFUNCTION: + t = "-- [function() ... end]\n"; + dump_value = false; + break; + default: + throw LuaException("Internal error: got unknow index for key while dumpvars."); + } + + // Seems that we can't dump that key. + if (!dump_value) { + pop(); + (*h) << t; + continue; + } + + // let's look at the value: if it's a function, we can't dump it. + if (lua_type(L, -1) == LUA_TFUNCTION) + (*h) << "-- "; + + (*h) << t; + + // Finally, let's dump the value. + switch(lua_type(L, -1)) { + case LUA_TNONE: + throw LuaException("Internal error: got invalid index for value while dumpvars."); + case LUA_TNIL: + (*h) << "nil,\n"; + case LUA_TNUMBER: + t.set("%.14g,\n", lua_tonumber(L, -1)); + (*h) << t; + break; + case LUA_TBOOLEAN: + (*h) << (lua_toboolean(L, -1) ? "true" : "false") << ",\n"; + break; + case LUA_TSTRING: + (*h) << "\"" << lua_tostring(L, -1) << "\",\n"; + break; + case LUA_TTABLE: + (*h) << "{\n"; + dumpvars_r(h, -1, depth); + for (j = 0; j < depth; j++) { + (*h) << " "; + } + (*h) << "},\n"; + break; + case LUA_TFUNCTION: + (*h) << "function() ... end\n"; + break; + default: + throw LuaException("Internal error: got unknow index for value while dumpvars."); + } + + pop(); + } +} + Lua * Lua::thread() { return new Lua(lua_newthread(L)); } |