# # patch "ChangeLog" # from [959d7976bf446520b243d3e7d174cddc58daf772] # to [d8bbdf5115be4299abe66ea7032092c2f05f25e1] # # patch "lua.cc" # from [05bd5b6c67ac30fa0ae5db7f9341699a2fa0812f] # to [40cea21efcbbbcb98eb2c502cf971b10ab76e521] # ======================================================================== --- ChangeLog 959d7976bf446520b243d3e7d174cddc58daf772 +++ ChangeLog d8bbdf5115be4299abe66ea7032092c2f05f25e1 @@ -1,5 +1,13 @@ 2005-08-17 Nathaniel Smith + * lua.cc (dump_stack): New function. + (Lua::fail): New method; use above. + (get, get_fn, get_tab, get_str, get_num, get_bool, extract_str) + (extract_int, extract_double, extract_bool, begin, next, pop): Use + it, to give better logging. + +2005-08-17 Nathaniel Smith + * Makefile.am (lib3rdparty_a_CFLAGS): Build 3rd party C code with -fexceptions. ======================================================================== --- lua.cc 05bd5b6c67ac30fa0ae5db7f9341699a2fa0812f +++ lua.cc 40cea21efcbbbcb98eb2c502cf971b10ab76e521 @@ -44,6 +44,41 @@ throw oops("lua panic"); } +// adapted from "programming in lua", section 24.2.3 +// http://www.lua.org/pil/24.2.3.html +// output is from bottom (least accessible) to top (most accessible, where +// push and pop happen). +static std::string +dump_stack(lua_State * st) +{ + std::string out; + int i; + int top = lua_gettop(st); + for (i = 1; i <= top; i++) { /* repeat for each level */ + int t = lua_type(st, i); + switch (t) { + case LUA_TSTRING: /* strings */ + out += (F("`%s'") % std::string(lua_tostring(st, i), lua_strlen(st, i))).str(); + break; + + case LUA_TBOOLEAN: /* booleans */ + out += (lua_toboolean(st, i) ? "true" : "false"); + break; + + case LUA_TNUMBER: /* numbers */ + out += (F("%g") % lua_tonumber(st, i)).str(); + break; + + default: /* other values */ + out += (F("%s") % lua_typename(st, t)).str(); + break; + + } + out += " "; /* put a separator */ + } + return out; +} + // This Lua object represents a single imperative transaction with the lua // interpreter. if it fails at any point, all further commands in the // transaction are ignored. it cleans the lua stack up when it is @@ -65,6 +100,12 @@ lua_settop(st, 0); } + void fail(std::string const & reason) + { + L(F("lua failure: %s; stack = %s\n") % reason % dump_stack(st)); + failed = true; + } + bool ok() { L(F("Lua::ok(): failed = %i") % failed); @@ -76,6 +117,7 @@ I(lua_isstring(st, -1)); string err = string(lua_tostring(st, -1), lua_strlen(st, -1)); W(F("%s\n") % err); + L(F("lua stack: %s") % dump_stack(st)); lua_pop(st, 1); failed = true; } @@ -87,14 +129,12 @@ if (failed) return *this; if (!lua_istable (st, idx)) { - L(F("lua istable() failed\n")); - failed = true; + fail("istable() in get"); return *this; } if (lua_gettop (st) < 1) { - L(F("lua stack top > 0 failed\n")); - failed = true; + fail("stack top > 0 in get"); return *this; } lua_gettable(st, idx); @@ -106,10 +146,7 @@ if (failed) return *this; get(idx); if (!lua_isfunction (st, -1)) - { - L(F("lua isfunction() failed in get_fn\n")); - failed = true; - } + fail("isfunction() in get_fn"); return *this; } @@ -118,10 +155,7 @@ if (failed) return *this; get(idx); if (!lua_istable (st, -1)) - { - L(F("lua istable() failed in get_tab\n")); - failed = true; - } + fail("istable() in get_tab"); return *this; } @@ -130,10 +164,7 @@ if (failed) return *this; get(idx); if (!lua_isstring (st, -1)) - { - L(F("lua isstring() failed in get_str\n")); - failed = true; - } + fail("isstring() in get_str"); return *this; } @@ -142,10 +173,7 @@ if (failed) return *this; get(idx); if (!lua_isnumber (st, -1)) - { - L(F("lua isnumber() failed in get_num\n")); - failed = true; - } + fail("isnumber() in get_num"); return *this; } @@ -154,10 +182,7 @@ if (failed) return *this; get(idx); if (!lua_isboolean (st, -1)) - { - L(F("lua isboolean() failed in get_bool\n")); - failed = true; - } + fail("isboolean() in get_bool"); return *this; } @@ -168,8 +193,7 @@ if (failed) return *this; if (!lua_isstring (st, -1)) { - L(F("lua isstring() failed in extract_str\n")); - failed = true; + fail("isstring() in extract_str"); return *this; } str = string(lua_tostring(st, -1), lua_strlen(st, -1)); @@ -182,8 +206,7 @@ if (failed) return *this; if (!lua_isnumber (st, -1)) { - L(F("lua isnumber() failed in extract_int\n")); - failed = true; + fail("isnumber() in extract_int"); return *this; } i = static_cast(lua_tonumber(st, -1)); @@ -196,8 +219,7 @@ if (failed) return *this; if (!lua_isnumber (st, -1)) { - L(F("lua isnumber() failed in extract_double\n")); - failed = true; + fail("isnumber() in extract_double"); return *this; } i = lua_tonumber(st, -1); @@ -211,8 +233,7 @@ if (failed) return *this; if (!lua_isboolean (st, -1)) { - L(F("lua isboolean() failed in extract_bool\n")); - failed = true; + fail("isboolean() in extract_bool"); return *this; } i = (lua_toboolean(st, -1) == 1); @@ -228,8 +249,7 @@ if (failed) return *this; if (!lua_istable(st, -1)) { - L(F("lua istable() failed in begin\n")); - failed = true; + fail("istable() in begin"); return *this; } I(lua_checkstack (st, 1)); @@ -242,8 +262,7 @@ if (failed) return false; if (!lua_istable(st, -2)) { - L(F("lua istable() failed in next\n")); - failed = true; + fail("istable() in next"); return false; } I(lua_checkstack (st, 1)); @@ -329,8 +348,7 @@ if (failed) return *this; if (lua_gettop (st) < count) { - L(F("lua stack top >= count failed\n")); - failed = true; + fail("stack top is not >= count in pop"); return *this; } lua_pop(st, count);