From b5acec0a3c5701c53854ff7afdf4008863e6e8df Mon Sep 17 00:00:00 2001 From: sapier Date: Tue, 29 Apr 2014 17:47:34 +0200 Subject: [PATCH] Add proper lua api deprecated handling --- builtin/misc.lua | 1 + minetest.conf.example | 5 ++++ src/defaultsettings.cpp | 5 ++++ src/guiFormSpecMenu.cpp | 9 ++++++- src/script/common/c_internal.cpp | 39 ++++++++++++++++++++++++++++++ src/script/common/c_internal.h | 4 +-- src/script/lua_api/l_object.cpp | 1 + src/script/lua_api/l_particles.cpp | 2 ++ src/script/lua_api/l_util.cpp | 5 ++++ src/script/scripting_game.cpp | 5 ++++ src/script/scripting_game.h | 2 ++ 11 files changed, 75 insertions(+), 3 deletions(-) diff --git a/builtin/misc.lua b/builtin/misc.lua index f91f5e095..82cc527cd 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -85,6 +85,7 @@ function minetest.get_item_group(name, group) end function minetest.get_node_group(name, group) + minetest.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead") return minetest.get_item_group(name, group) end diff --git a/minetest.conf.example b/minetest.conf.example index dfebe0102..c13444657 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -285,6 +285,11 @@ #disable_anticheat = false # If true, actions are recorded for rollback #enable_rollback_recording = false +# handling for deprecated lua api calls +# "legacy" = (try to) mimic old behaviour (default for release) +# "log" = mimic and log backtrace of deprecated call (default for debug) +# "error" = abort on usage of deprecated call (suggested for mod developers) +#deprecated_lua_api_handling = legacy # Profiler data print interval. #0 = disable. #profiler_print_interval = 0 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index ff0da4b2c..3c17e650e 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -201,6 +201,11 @@ void set_default_settings(Settings *settings) settings->setDefault("disallow_empty_password", "false"); settings->setDefault("disable_anticheat", "false"); settings->setDefault("enable_rollback_recording", "false"); +#ifdef NDEBUG + settings->setDefault("deprecated_lua_api_handling", "legacy"); +#else + settings->setDefault("deprecated_lua_api_handling", "log"); +#endif settings->setDefault("profiler_print_interval", "0"); settings->setDefault("enable_mapgen_debug_info", "false"); diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 962d15188..129ab0259 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -45,6 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "gettime.h" #include "gettext.h" +#include "scripting_game.h" #define MY_CHECKPOS(a,b) \ if (v_pos.size() != 2) { \ @@ -1478,7 +1479,13 @@ void GUIFormSpecMenu::parseElement(parserData* data,std::string element) std::string type = trim(parts[0]); std::string description = trim(parts[1]); - if ((type == "size") || (type == "invsize")){ + if (type == "size") { + parseSize(data,description); + return; + } + + if (type == "invsize") { + log_deprecated("Deprecated formspec element \"invsize\" is used"); parseSize(data,description); return; } diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 4263dec90..4c6604f65 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -19,6 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_internal.h" #include "debug.h" +#include "log.h" +#include "main.h" +#include "settings.h" std::string script_get_backtrace(lua_State *L) { @@ -109,4 +112,40 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) lua_remove(L, -2); // Remove error handler } +void log_deprecated(lua_State *L, std::string message) +{ + static bool configured = false; + static bool dolog = false; + static bool doerror = false; + + // performance optimization to not have to read and compare setting for every logline + if (!configured) { + std::string value = g_settings->get("deprecated_lua_api_handling"); + if (value == "log") { + dolog = true; + } + if (value == "error") { + dolog = true; + doerror = true; + } + } + + if (doerror) { + if (L != NULL) { + script_error(L); + } else { + /* As of april 2014 assert is not optimized to nop in release builds + * therefore this is correct. */ + assert("Can't do a scripterror for this deprecated message, so exit completely!"); + } + } + + if (dolog) { + /* abusing actionstream because of lack of file-only-logged loglevel */ + actionstream << message << std::endl; + if (L != NULL) { + actionstream << script_get_backtrace(L) << std::endl; + } + } +} diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h index f3ef18d70..eb9181b09 100644 --- a/src/script/common/c_internal.h +++ b/src/script/common/c_internal.h @@ -68,7 +68,7 @@ std::string script_get_backtrace(lua_State *L); int script_error_handler(lua_State *L); int script_exception_wrapper(lua_State *L, lua_CFunction f); void script_error(lua_State *L); -void script_run_callbacks(lua_State *L, int nargs, - RunCallbacksMode mode); +void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode); +void log_deprecated(lua_State *L, std::string message); #endif /* C_INTERNAL_H_ */ diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 5e3ddd235..30d423e6a 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -659,6 +659,7 @@ int ObjectRef::l_get_entity_name(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); LuaEntitySAO *co = getluaobject(ref); + log_deprecated(L,"Deprecated call to \"get_entity_name"); if(co == NULL) return 0; // Do it std::string name = co->getName(); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 088eba06e..6769f5c23 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -44,6 +44,7 @@ int ModApiParticles::l_add_particle(lua_State *L) if (lua_gettop(L) > 1) // deprecated { + log_deprecated(L,"Deprecated add_particle call with individual parameters instead of definition"); pos = check_v3f(L, 1); vel = check_v3f(L, 2); acc = check_v3f(L, 3); @@ -128,6 +129,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) if (lua_gettop(L) > 1) //deprecated { + log_deprecated(L,"Deprecated add_particlespawner call with individual parameters instead of definition"); amount = luaL_checknumber(L, 1); time = luaL_checknumber(L, 2); minpos = check_v3f(L, 3); diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 90a1d77ab..7babaaf71 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -78,6 +78,11 @@ int ModApiUtil::l_log(lua_State *L) level = LMT_ACTION; else if(levelname == "verbose") level = LMT_VERBOSE; + else if (levelname == "deprecated") { + log_deprecated(L,text); + return 0; + } + } log_printline(level, text); return 0; diff --git a/src/script/scripting_game.cpp b/src/script/scripting_game.cpp index 12baac032..b2c2150c6 100644 --- a/src/script/scripting_game.cpp +++ b/src/script/scripting_game.cpp @@ -98,3 +98,8 @@ void GameScripting::InitializeModApi(lua_State *L, int top) ObjectRef::Register(L); LuaSettings::Register(L); } + +void log_deprecated(std::string message) +{ + log_deprecated(NULL,message); +} diff --git a/src/script/scripting_game.h b/src/script/scripting_game.h index ed6567922..14dbd9170 100644 --- a/src/script/scripting_game.h +++ b/src/script/scripting_game.h @@ -50,4 +50,6 @@ private: void InitializeModApi(lua_State *L, int top); }; +void log_deprecated(std::string message); + #endif /* SCRIPTING_GAME_H_ */