diff options
Diffstat (limited to 'src/script/common/c_converter.cpp')
-rw-r--r-- | src/script/common/c_converter.cpp | 99 |
1 files changed, 39 insertions, 60 deletions
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index 7898b197d..69da35b73 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -18,8 +18,8 @@ with this program; if not, write to the Free Software Foundation, Inc., */ extern "C" { -#include "lua.h" -#include "lauxlib.h" +#include <lua.h> +#include <lauxlib.h> } #include "util/numeric.h" @@ -29,55 +29,52 @@ extern "C" { #include "common/c_internal.h" #include "constants.h" #include <set> +#include <cmath> -#define CHECK_TYPE(index, name, type) { \ +#define CHECK_TYPE(index, name, type) do { \ int t = lua_type(L, (index)); \ if (t != (type)) { \ throw LuaError(std::string("Invalid ") + (name) + \ " (expected " + lua_typename(L, (type)) + \ " got " + lua_typename(L, t) + ")."); \ } \ - } -#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER) -#define CHECK_FLOAT_RANGE(value, name) \ -if (value < F1000_MIN || value > F1000_MAX) { \ - std::ostringstream error_text; \ - error_text << "Invalid float vector dimension range '" name "' " << \ - "(expected " << F1000_MIN << " < " name " < " << F1000_MAX << \ - " got " << value << ")." << std::endl; \ - throw LuaError(error_text.str()); \ -} -#define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE) + } while(0) + +#define CHECK_FLOAT(value, name) do {\ + if (std::isnan(value) || std::isinf(value)) { \ + throw LuaError("Invalid float value for '" name \ + "' (NaN or infinity)"); \ + } \ + } while (0) + +#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "vector coordinate " name, LUA_TNUMBER) +#define CHECK_POS_TAB(index) CHECK_TYPE(index, "vector", LUA_TTABLE) /** - * A helper which sets (if available) the vector metatable from builtin as metatable - * for the table on top of the stack + * A helper which sets the vector metatable for the table on top of the stack */ static void set_vector_metatable(lua_State *L) { - // get vector.metatable - lua_getglobal(L, "vector"); - if (!lua_istable(L, -1)) { - // there is no global vector table - lua_pop(L, 1); - errorstream << "set_vector_metatable in c_converter.cpp: " << - "missing global vector table" << std::endl; - return; - } - lua_getfield(L, -1, "metatable"); - // set the metatable - lua_setmetatable(L, -3); - // pop vector global - lua_pop(L, 1); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); + lua_setmetatable(L, -2); } - -void push_float_string(lua_State *L, float value) +// Retrieve an integer vector where all components are optional +template<class T> +static bool getv3intfield(lua_State *L, int index, + const char *fieldname, T &result) { - auto str = ftos(value); - lua_pushstring(L, str.c_str()); + lua_getfield(L, index, fieldname); + bool got = false; + if (lua_istable(L, -1)) { + got |= getintfield(L, -1, "x", result.X); + got |= getintfield(L, -1, "y", result.Y); + got |= getintfield(L, -1, "z", result.Z); + } + lua_pop(L, 1); + return got; } void push_v3f(lua_State *L, v3f p) @@ -101,26 +98,6 @@ void push_v2f(lua_State *L, v2f p) lua_setfield(L, -2, "y"); } -void push_v3_float_string(lua_State *L, v3f p) -{ - lua_createtable(L, 0, 3); - push_float_string(L, p.X); - lua_setfield(L, -2, "x"); - push_float_string(L, p.Y); - lua_setfield(L, -2, "y"); - push_float_string(L, p.Z); - lua_setfield(L, -2, "z"); -} - -void push_v2_float_string(lua_State *L, v2f p) -{ - lua_createtable(L, 0, 2); - push_float_string(L, p.X); - lua_setfield(L, -2, "x"); - push_float_string(L, p.Y); - lua_setfield(L, -2, "y"); -} - v2s16 read_v2s16(lua_State *L, int index) { v2s16 p; @@ -185,10 +162,12 @@ v2f check_v2f(lua_State *L, int index) lua_getfield(L, index, "x"); CHECK_POS_COORD("x"); p.X = lua_tonumber(L, -1); + CHECK_FLOAT(p.X, "x"); lua_pop(L, 1); lua_getfield(L, index, "y"); CHECK_POS_COORD("y"); p.Y = lua_tonumber(L, -1); + CHECK_FLOAT(p.Y, "y"); lua_pop(L, 1); return p; } @@ -216,17 +195,17 @@ v3f check_v3f(lua_State *L, int index) lua_getfield(L, index, "x"); CHECK_POS_COORD("x"); pos.X = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.X, "x") + CHECK_FLOAT(pos.X, "x"); lua_pop(L, 1); lua_getfield(L, index, "y"); CHECK_POS_COORD("y"); pos.Y = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.Y, "y") + CHECK_FLOAT(pos.Y, "y"); lua_pop(L, 1); lua_getfield(L, index, "z"); CHECK_POS_COORD("z"); pos.Z = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.Z, "z") + CHECK_FLOAT(pos.Z, "z"); lua_pop(L, 1); return pos; } @@ -254,17 +233,17 @@ v3d check_v3d(lua_State *L, int index) lua_getfield(L, index, "x"); CHECK_POS_COORD("x"); pos.X = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.X, "x") + CHECK_FLOAT(pos.X, "x"); lua_pop(L, 1); lua_getfield(L, index, "y"); CHECK_POS_COORD("y"); pos.Y = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.Y, "y") + CHECK_FLOAT(pos.Y, "y"); lua_pop(L, 1); lua_getfield(L, index, "z"); CHECK_POS_COORD("z"); pos.Z = lua_tonumber(L, -1); - CHECK_FLOAT_RANGE(pos.Z, "z") + CHECK_FLOAT(pos.Z, "z"); lua_pop(L, 1); return pos; } |