diff options
author | ShadowNinja <shadowninja@minetest.net> | 2013-11-05 12:06:15 -0500 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2013-11-15 14:13:31 -0500 |
commit | 371b39a09a0bf248d674fae718f5ff369e895b66 (patch) | |
tree | da8bb27e27a9c89eac895d211721de11a3781533 /src/script | |
parent | 3f519eb72922607329e1e6a48768d84d1f443efc (diff) | |
download | minetest-371b39a09a0bf248d674fae718f5ff369e895b66.tar.gz minetest-371b39a09a0bf248d674fae718f5ff369e895b66.tar.bz2 minetest-371b39a09a0bf248d674fae718f5ff369e895b66.zip |
Pass a errfunc to lua_pcall to get a traceback
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/common/c_content.cpp | 9 | ||||
-rw-r--r-- | src/script/common/c_internal.cpp | 56 | ||||
-rw-r--r-- | src/script/common/c_internal.h | 9 | ||||
-rw-r--r-- | src/script/common/c_types.cpp | 5 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.cpp | 33 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.h | 3 | ||||
-rw-r--r-- | src/script/cpp_api/s_entity.cpp | 60 | ||||
-rw-r--r-- | src/script/cpp_api/s_inventory.cpp | 147 | ||||
-rw-r--r-- | src/script/cpp_api/s_item.cpp | 70 | ||||
-rw-r--r-- | src/script/cpp_api/s_mainmenu.cpp | 28 | ||||
-rw-r--r-- | src/script/cpp_api/s_node.cpp | 92 | ||||
-rw-r--r-- | src/script/cpp_api/s_nodemeta.cpp | 162 | ||||
-rw-r--r-- | src/script/cpp_api/s_server.cpp | 31 | ||||
-rw-r--r-- | src/script/lua_api/l_base.h | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_craft.cpp | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_env.cpp | 28 | ||||
-rw-r--r-- | src/script/lua_api/l_noise.cpp | 5 | ||||
-rw-r--r-- | src/script/lua_api/l_rollback.cpp | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_server.cpp | 3 |
19 files changed, 423 insertions, 323 deletions
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index a035b32a2..2ad4c9565 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -871,6 +871,8 @@ void read_groups(lua_State *L, int index, /******************************************************************************/ void push_items(lua_State *L, const std::vector<ItemStack> &items) { + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); // Get the table insert function lua_getglobal(L, "table"); lua_getfield(L, -1, "insert"); @@ -883,11 +885,12 @@ void push_items(lua_State *L, const std::vector<ItemStack> &items) lua_pushvalue(L, table_insert); lua_pushvalue(L, table); LuaItemStack::create(L, item); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + script_error(L); } - lua_remove(L, -2); // Remove table lua_remove(L, -2); // Remove insert + lua_remove(L, -2); // Remove table + lua_remove(L, -2); // Remove error handler } /******************************************************************************/ diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 5c16b88d9..7415aecb8 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -23,32 +23,41 @@ with this program; if not, write to the Free Software Foundation, Inc., std::string script_get_backtrace(lua_State *L) { std::string s; - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + lua_getglobal(L, "debug"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "traceback"); - if(lua_isfunction(L, -1)){ + if(lua_isfunction(L, -1)) { lua_call(L, 0, 1); if(lua_isstring(L, -1)){ - s += lua_tostring(L, -1); + s = lua_tostring(L, -1); } - lua_pop(L, 1); - } - else{ - lua_pop(L, 1); } + lua_pop(L, 1); } lua_pop(L, 1); return s; } -void script_error(lua_State *L, const char *fmt, ...) +int script_error_handler(lua_State *L) { + lua_getglobal(L, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); + lua_pushinteger(L, 2); + lua_call(L, 2, 1); + return 1; +} + +void script_error(lua_State *L) { - va_list argp; - va_start(argp, fmt); - char buf[10000]; - vsnprintf(buf, 10000, fmt, argp); - va_end(argp); - throw LuaError(L, buf); + throw LuaError(NULL, lua_tostring(L, -1)); } // Push the list of callbacks (a lua table). @@ -61,13 +70,20 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) { // Insert the return value into the lua stack, below the table assert(lua_gettop(L) >= nargs + 1); + lua_pushnil(L); - lua_insert(L, -(nargs + 1) - 1); + int rv = lua_gettop(L) - nargs - 1; + lua_insert(L, rv); + + // Insert error handler after return value + lua_pushcfunction(L, script_error_handler); + int errorhandler = rv + 1; + lua_insert(L, errorhandler); + // Stack now looks like this: - // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n> + // ... <return value = nil> <error handler> <table> <arg#1> <arg#2> ... <arg#n> - int rv = lua_gettop(L) - nargs - 1; - int table = rv + 1; + int table = errorhandler + 1; int arg = table + 1; luaL_checktype(L, table, LUA_TTABLE); @@ -81,8 +97,8 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) // Call function for(int i = 0; i < nargs; i++) lua_pushvalue(L, arg+i); - if(lua_pcall(L, nargs, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, nargs, 1, errorhandler)) + script_error(L); // Move return value to designated space in stack // Or pop it diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h index 9a50b8e96..eb6aa06e8 100644 --- a/src/script/common/c_internal.h +++ b/src/script/common/c_internal.h @@ -64,9 +64,10 @@ enum RunCallbacksMode // are converted by lua_toboolean to true or false, respectively. }; -std::string script_get_backtrace (lua_State *L); -void script_error (lua_State *L, const char *fmt, ...); -void script_run_callbacks (lua_State *L, int nargs, - RunCallbacksMode mode); +std::string script_get_backtrace(lua_State *L); +int script_error_handler(lua_State *L); +void script_error(lua_State *L); +void script_run_callbacks(lua_State *L, int nargs, + RunCallbacksMode mode); #endif /* C_INTERNAL_H_ */ diff --git a/src/script/common/c_types.cpp b/src/script/common/c_types.cpp index ac724c42c..a6faf9819 100644 --- a/src/script/common/c_types.cpp +++ b/src/script/common/c_types.cpp @@ -25,9 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc., LuaError::LuaError(lua_State *L, const std::string &s) { - m_s = "LuaError: "; - m_s += s + "\n"; - m_s += script_get_backtrace(L); + m_s = "LuaError: " + s; + if (L) m_s += '\n' + script_get_backtrace(L); } struct EnumString es_ItemType[] = diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e26d54ba7..b1272b64e 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -55,23 +55,6 @@ public: } }; -static int loadScript_ErrorHandler(lua_State *L) { - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - return 1; - } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 2); - return 1; - } - lua_pushvalue(L, 1); - lua_pushinteger(L, 2); - lua_call(L, 2, 1); - return 1; -} - /* ScriptApiBase @@ -133,7 +116,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath) lua_State *L = getStack(); - lua_pushcfunction(L, loadScript_ErrorHandler); + lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler); @@ -144,7 +127,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath) errorstream<<std::endl; errorstream<<lua_tostring(L, -1)<<std::endl; errorstream<<std::endl; - errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl; + errorstream<<"======= END OF ERROR FROM LUA ========"<<std::endl; lua_pop(L, 1); // Pop error message from stack lua_pop(L, 1); // Pop the error handler from stack return false; @@ -159,19 +142,13 @@ void ScriptApiBase::realityCheck() if(top >= 30){ dstream<<"Stack is over 30:"<<std::endl; stackDump(dstream); - scriptError("Stack is over 30 (reality check)"); + throw LuaError(m_luastack, "Stack is over 30 (reality check)"); } } -void ScriptApiBase::scriptError(const char *fmt, ...) +void ScriptApiBase::scriptError() { - va_list argp; - va_start(argp, fmt); - char buf[10000]; - vsnprintf(buf, 10000, fmt, argp); - va_end(argp); - //errorstream<<"SCRIPT ERROR: "<<buf; - throw LuaError(m_luastack, buf); + throw LuaError(NULL, lua_tostring(m_luastack, -1)); } void ScriptApiBase::stackDump(std::ostream &o) diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 63f7e423f..75552cc34 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -31,6 +31,7 @@ extern "C" { #include "jthread/jmutex.h" #include "jthread/jmutexautolock.h" #include "common/c_types.h" +#include "common/c_internal.h" #define SCRIPTAPI_LOCK_DEBUG @@ -65,7 +66,7 @@ protected: { return m_luastack; } void realityCheck(); - void scriptError(const char *fmt, ...); + void scriptError(); void stackDump(std::ostream &o); Server* getServer() { return m_server; } diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index cefa27cb1..c9d1bd8e0 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -78,25 +78,29 @@ void ScriptApiEntity::luaentity_Activate(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // Get on_activate function - lua_pushvalue(L, object); lua_getfield(L, -1, "on_activate"); - if(!lua_isnil(L, -1)){ + if(!lua_isnil(L, -1)) { luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self lua_pushlstring(L, staticdata.c_str(), staticdata.size()); lua_pushinteger(L, dtime_s); // Call with 3 arguments, 0 results - if(lua_pcall(L, 3, 0, 0)) - scriptError("error running function on_activate: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + } else { + lua_pop(L, 1); } + lua_pop(L, 2); // Pop object and error handler } void ScriptApiEntity::luaentity_Remove(u16 id) @@ -123,14 +127,16 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // Get get_staticdata function - lua_pushvalue(L, object); lua_getfield(L, -1, "get_staticdata"); if(lua_isnil(L, -1)) return ""; @@ -138,11 +144,12 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self // Call with 1 arguments, 1 results - if(lua_pcall(L, 1, 1, 0)) - scriptError("error running function get_staticdata: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 1, 1, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler - size_t len=0; + size_t len = 0; const char *s = lua_tolstring(L, -1, &len); return std::string(s, len); } @@ -192,10 +199,13 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // State: object is at top of stack // Get step function @@ -206,8 +216,10 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime) lua_pushvalue(L, object); // self lua_pushnumber(L, dtime); // dtime // Call with 2 arguments, 0 results - if(lua_pcall(L, 2, 0, 0)) - scriptError("error running function 'on_step': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, @@ -218,6 +230,9 @@ void ScriptApiEntity::luaentity_Punch(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] @@ -235,8 +250,10 @@ void ScriptApiEntity::luaentity_Punch(u16 id, push_tool_capabilities(L, *toolcap); push_v3f(L, dir); // Call with 5 arguments, 0 results - if(lua_pcall(L, 5, 0, 0)) - scriptError("error running function 'on_punch': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } // Calls entity:on_rightclick(ObjectRef clicker) @@ -245,6 +262,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] @@ -259,7 +279,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id, lua_pushvalue(L, object); // self objectrefGetOrCreate(clicker); // Clicker reference // Call with 2 arguments, 0 results - if(lua_pcall(L, 2, 0, 0)) - scriptError("error running function 'on_rightclick': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index 09f26d80c..4ee6e4be0 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -33,6 +33,9 @@ int ScriptApiDetached::detached_inventory_AllowMove( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_move")) return count; @@ -42,23 +45,19 @@ int ScriptApiDetached::detached_inventory_AllowMove( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_move should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Return number of accepted items to be put @@ -69,28 +68,28 @@ int ScriptApiDetached::detached_inventory_AllowPut( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_put")) return stack.count; // All will be accepted // Call function(inv, listname, index, stack, player) - // inv InventoryLocation loc; loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + InvRef::create(L, loc); // inv + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_put should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Return number of accepted items to be taken @@ -101,28 +100,28 @@ int ScriptApiDetached::detached_inventory_AllowTake( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_take")) return stack.count; // All will be accepted // Call function(inv, listname, index, stack, player) - // inv InventoryLocation loc; loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + InvRef::create(L, loc); // inv + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_take should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Report moved items @@ -134,6 +133,9 @@ void ScriptApiDetached::detached_inventory_OnMove( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_move")) return; @@ -143,20 +145,15 @@ void ScriptApiDetached::detached_inventory_OnMove( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report put items @@ -167,6 +164,9 @@ void ScriptApiDetached::detached_inventory_OnPut( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_put")) return; @@ -176,16 +176,13 @@ void ScriptApiDetached::detached_inventory_OnPut( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report taken items @@ -196,6 +193,9 @@ void ScriptApiDetached::detached_inventory_OnTake( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_take")) return; @@ -205,16 +205,13 @@ void ScriptApiDetached::detached_inventory_OnTake( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Retrieves minetest.detached_inventories[name][callbackname] diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 1d5f218cf..49729e57b 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -34,6 +34,9 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_drop")) return false; @@ -42,10 +45,11 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(dropper); pushFloatPos(L, pos); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -54,6 +58,9 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_place")) return false; @@ -62,10 +69,11 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(placer); pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -74,6 +82,9 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_use")) return false; @@ -82,10 +93,11 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(user); pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -94,6 +106,9 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "minetest"); lua_getfield(L, -1, "on_craft"); LuaItemStack::create(L, item); @@ -106,10 +121,11 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, push_items(L, items); InvRef::create(L, craft_inv); - if(lua_pcall(L, 4, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 4, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -118,11 +134,14 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "minetest"); lua_getfield(L, -1, "craft_predict"); LuaItemStack::create(L, item); objectrefGetOrCreate(user); - + //Push inventory list std::vector<ItemStack> items; for(u32 i=0; i<old_craft_grid->getSize(); i++) @@ -130,10 +149,11 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, push_items(L, items); InvRef::create(L, craft_inv); - if(lua_pcall(L, 4, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 4, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -149,15 +169,15 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname) lua_getglobal(L, "minetest"); lua_getfield(L, -1, "registered_items"); - lua_remove(L, -2); + lua_remove(L, -2); // Remove minetest luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, name); - lua_remove(L, -2); + lua_remove(L, -2); // Remove registered_items // Should be a table if(lua_type(L, -1) != LUA_TTABLE) { // Report error and clean up - errorstream<<"Item \""<<name<<"\" not defined"<<std::endl; + errorstream << "Item \"" << name << "\" not defined" << std::endl; lua_pop(L, 1); // Try minetest.nodedef_default instead @@ -167,24 +187,16 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname) luaL_checktype(L, -1, LUA_TTABLE); } lua_getfield(L, -1, callbackname); - lua_remove(L, -2); + lua_remove(L, -2); // Remove item def // Should be a function or nil - if(lua_type(L, -1) == LUA_TFUNCTION) - { + if (lua_type(L, -1) == LUA_TFUNCTION) { return true; + } else if (!lua_isnil(L, -1)) { + errorstream << "Item \"" << name << "\" callback \"" + << callbackname << "\" is not a function" << std::endl; } - else if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - return false; - } - else - { - errorstream<<"Item \""<<name<<"\" callback \"" - <<callbackname<<" is not a function"<<std::endl; - lua_pop(L, 1); - return false; - } + lua_pop(L, 1); + return false; } void ScriptApiItem::pushPointedThing(const PointedThing& pointed) diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp index af92c59a9..5c54f7368 100644 --- a/src/script/cpp_api/s_mainmenu.cpp +++ b/src/script/cpp_api/s_mainmenu.cpp @@ -37,29 +37,41 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Get handler function lua_getglobal(L, "engine"); lua_getfield(L, -1, "event_handler"); - if(lua_isnil(L, -1)) + lua_remove(L, -2); // Remove engine + if(lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop event_handler return; + } luaL_checktype(L, -1, LUA_TFUNCTION); // Call it lua_pushstring(L, text.c_str()); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error running function engine.event_handler: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Get handler function lua_getglobal(L, "engine"); lua_getfield(L, -1, "button_handler"); - if(lua_isnil(L, -1)) + lua_remove(L, -2); // Remove engine + if(lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop button handler return; + } luaL_checktype(L, -1, LUA_TFUNCTION); // Convert fields to lua table @@ -74,7 +86,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> } // Call it - if(lua_pcall(L, 1, 0, 0)) - scriptError("error running function engine.button_handler: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 92fd00a74..cd8451cf0 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -91,6 +91,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -101,8 +104,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(puncher); - if(lua_pcall(L, 3, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler return true; } @@ -111,6 +115,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -121,8 +128,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(digger); - if(lua_pcall(L, 3, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler return true; } @@ -130,6 +138,9 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -138,14 +149,18 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -154,14 +169,18 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -171,14 +190,18 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); pushnode(L, node, ndef); - if(lua_pcall(L, 2, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -188,12 +211,10 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) // Call function push_v3s16(L, p); lua_pushnumber(L,dtime); - if(lua_pcall(L, 2, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true) - return true; - - return false; + if(lua_pcall(L, 2, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler + return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true; } void ScriptApiNode::node_on_receive_fields(v3s16 p, @@ -203,6 +224,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -215,12 +239,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, return; // Call function - // param 1 - push_v3s16(L, p); - // param 2 - lua_pushstring(L, formname.c_str()); - // param 3 - lua_newtable(L); + push_v3s16(L, p); // pos + lua_pushstring(L, formname.c_str()); // formname + lua_newtable(L); // fields for(std::map<std::string, std::string>::const_iterator i = fields.begin(); i != fields.end(); i++){ const std::string &name = i->first; @@ -229,26 +250,37 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } - // param 4 - objectrefGetOrCreate(sender); - if(lua_pcall(L, 4, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + objectrefGetOrCreate(sender); // player + if(lua_pcall(L, 4, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_falling_update(v3s16 p) { SCRIPTAPI_PRECHECKHEADER + + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "nodeupdate"); push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_falling_update_single(v3s16 p) { SCRIPTAPI_PRECHECKHEADER + + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "nodeupdate_single"); push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } + diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp index e87464c61..1f04383f1 100644 --- a/src/script/cpp_api/s_nodemeta.cpp +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -34,6 +34,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -47,25 +50,21 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, return count; // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_move should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Return number of accepted items to be put @@ -75,6 +74,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -88,21 +90,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, return stack.count; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_put should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Return number of accepted items to be taken @@ -112,6 +112,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -125,21 +128,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, return stack.count; // Call function(pos, listname, index, count, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_take should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Report moved items @@ -150,6 +151,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -163,22 +167,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, return; // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report put items @@ -188,6 +186,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -201,18 +202,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p, return; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report taken items @@ -222,6 +219,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -235,18 +235,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, return; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } ScriptApiNodemeta::ScriptApiNodemeta() { diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp index d41805b7b..4baf90636 100644 --- a/src/script/cpp_api/s_server.cpp +++ b/src/script/cpp_api/s_server.cpp @@ -27,13 +27,18 @@ bool ScriptApiServer::getAuth(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + getAuthHandler(); lua_getfield(L, -1, "get_auth"); if(lua_type(L, -1) != LUA_TFUNCTION) throw LuaError(L, "Authentication handler missing get_auth"); lua_pushstring(L, playername.c_str()); - if(lua_pcall(L, 1, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 1, errorhandler)) + scriptError(); + lua_remove(L, -2); // Remove auth handler + lua_remove(L, errorhandler); // Remove error handler // nil = login not allowed if(lua_isnil(L, -1)) @@ -49,8 +54,7 @@ bool ScriptApiServer::getAuth(const std::string &playername, lua_getfield(L, -1, "privileges"); if(!lua_istable(L, -1)) - throw LuaError(L, - "Authentication handler didn't return privilege table"); + throw LuaError(L, "Authentication handler didn't return privilege table"); if(dst_privs) readPrivileges(-1, *dst_privs); lua_pop(L, 1); @@ -68,6 +72,7 @@ void ScriptApiServer::getAuthHandler() lua_pop(L, 1); lua_getfield(L, -1, "builtin_auth_handler"); } + lua_remove(L, -2); // Remove minetest if(lua_type(L, -1) != LUA_TTABLE) throw LuaError(L, "Authentication handler table not valid"); } @@ -96,14 +101,19 @@ void ScriptApiServer::createAuth(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + getAuthHandler(); lua_getfield(L, -1, "create_auth"); + lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) throw LuaError(L, "Authentication handler missing create_auth"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } bool ScriptApiServer::setPassword(const std::string &playername, @@ -111,14 +121,19 @@ bool ScriptApiServer::setPassword(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + getAuthHandler(); lua_getfield(L, -1, "set_password"); + lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) throw LuaError(L, "Authentication handler missing set_password"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 1, errorhandler)) + scriptError(); + lua_remove(L, -2); // Remove error handler return lua_toboolean(L, -1); } diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h index 71ebd215c..808043bd4 100644 --- a/src/script/lua_api/l_base.h +++ b/src/script/lua_api/l_base.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define L_BASE_H_ #include "common/c_types.h" +#include "common/c_internal.h" extern "C" { #include <lua.h> diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index b0a47bfc1..c5732bad2 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -449,7 +449,7 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L) lua_pushstring(L, &tmpout.item[0]); lua_setfield(L, -2, "output"); if (lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + script_error(L); } } return 1; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 436eb014d..9bed23d47 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -53,28 +53,34 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Get minetest.registered_abms lua_getglobal(L, "minetest"); lua_getfield(L, -1, "registered_abms"); luaL_checktype(L, -1, LUA_TTABLE); - int registered_abms = lua_gettop(L); + lua_remove(L, -2); // Remove "minetest" // Get minetest.registered_abms[m_id] lua_pushnumber(L, m_id); - lua_gettable(L, registered_abms); + lua_gettable(L, -2); if(lua_isnil(L, -1)) assert(0); + lua_remove(L, -2); // Remove "registered_abms" // Call action luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, "action"); luaL_checktype(L, -1, LUA_TFUNCTION); + lua_remove(L, -2); // Remove "registered_abms[m_id]" push_v3s16(L, p); pushnode(L, n, env->getGameDef()->ndef()); lua_pushnumber(L, active_object_count); lua_pushnumber(L, active_object_count_wider); - if(lua_pcall(L, 4, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 4, 0, errorhandler)) + script_error(L); + lua_pop(L, 1); // Pop error handler } // Exported functions @@ -370,15 +376,21 @@ int ModApiEnvMod::l_add_item(lua_State *L) ItemStack item = read_item(L, 2,getServer(L)); if(item.empty() || !item.isKnown(getServer(L)->idef())) return 0; + + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Use minetest.spawn_item to spawn a __builtin:item lua_getglobal(L, "minetest"); lua_getfield(L, -1, "spawn_item"); + lua_remove(L, -2); // Remove minetest if(lua_isnil(L, -1)) return 0; lua_pushvalue(L, 1); lua_pushstring(L, item.getItemString().c_str()); - if(lua_pcall(L, 2, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 1, errorhandler)) + script_error(L); + lua_remove(L, errorhandler); // Remove error handler return 1; /*lua_pushvalue(L, 1); lua_pushstring(L, "__builtin:item"); @@ -441,7 +453,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) lua_pushvalue(L, table); getScriptApiBase(L)->objectrefGetOrCreate(obj); if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + script_error(L); } return 1; } @@ -569,7 +581,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L) lua_pushvalue(L, table); push_v3s16(L, p); if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + script_error(L); } } return 1; diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index ecbda9fad..4b0c7932d 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -333,7 +333,10 @@ int LuaPseudoRandom::l_next(lua_State *L) throw LuaError(L, "PseudoRandom.next(): max < min"); } if(max - min != 32767 && max - min > 32767/5) - throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make."); + throw LuaError(L, "PseudoRandom.next() max-min is not 32767" + " and is > 32768/5. This is disallowed due to" + " the bad random distribution the" + " implementation would otherwise make."); PseudoRandom &pseudo = o->m_pseudo; int val = pseudo.next(); val = (val % (max-min+1)) + min; diff --git a/src/script/lua_api/l_rollback.cpp b/src/script/lua_api/l_rollback.cpp index 6076399ae..d5abe176e 100644 --- a/src/script/lua_api/l_rollback.cpp +++ b/src/script/lua_api/l_rollback.cpp @@ -66,7 +66,7 @@ int ModApiRollback::l_rollback_revert_actions_by(lua_State *L) lua_pushvalue(L, table); lua_pushstring(L, i->c_str()); if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + script_error(L); } lua_remove(L, -2); // Remove table lua_remove(L, -2); // Remove insert diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 8e809c36a..19e2f1bcb 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -220,6 +220,7 @@ int ModApiServer::l_get_modpath(lua_State *L) int ModApiServer::l_get_modnames(lua_State *L) { NO_MAP_LOCK_REQUIRED; + // Get a list of mods std::list<std::string> mods_unsorted, mods_sorted; getServer(L)->getModNames(mods_unsorted); @@ -263,7 +264,7 @@ int ModApiServer::l_get_modnames(lua_State *L) lua_pushstring(L, (*i).c_str()); if(lua_pcall(L, 2, 0, 0) != 0) { - script_error(L, "error: %s", lua_tostring(L, -1)); + script_error(L); } ++i; } |