]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-lua: Implement a Lua 5.1 & 5.2 compatibility wrapper for lua_isinteger
authorJosef 'Jeff' Sipek <jeff.sipek@open-xchange.com>
Thu, 4 Mar 2021 21:21:07 +0000 (16:21 -0500)
committerjeff.sipek <jeff.sipek@open-xchange.com>
Wed, 10 Mar 2021 19:12:41 +0000 (19:12 +0000)
src/lib-lua/dlua-compat.c
src/lib-lua/dlua-compat.h
src/lib-lua/test-lua.c

index f057b09c31eac97d2d9e3bbbc13a79310dbf1500..d50d2d53f99284845a294d9f445328aa98de245d 100644 (file)
@@ -25,6 +25,27 @@ void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
 }
 #endif
 
+#ifndef HAVE_LUA_ISINTEGER
+#  if LUA_VERSION_NUM >= 503
+#    error "Lua 5.3+ should have lua_isinteger()"
+#  endif
+/*
+ * Lua 5.3 added lua_isinteger() which tells us whether or not the input is
+ * an integer.  In Lua 5.1 and 5.2, we have to emulate it.
+ */
+int lua_isinteger(lua_State *L, int idx)
+{
+       int isnum;
+
+       if (lua_type(L, idx) != LUA_TNUMBER)
+               return 0;
+
+       (void) lua_tointegerx(L, idx, &isnum);
+
+       return isnum;
+}
+#endif
+
 #ifndef HAVE_LUA_TOINTEGERX
 #  if LUA_VERSION_NUM >= 502
 #    error "Lua 5.2+ should have lua_tointegerx()"
index d35f47459714beff124404f13ff98d7c6a314209..f1e564d5d0c6823129fe7a669fb826a117c99d5a 100644 (file)
@@ -5,6 +5,18 @@
  * In general, make whatever Lua version we have behave more like Lua 5.3.
  */
 
+#ifndef HAVE_LUA_ISINTEGER
+/*
+ * Lua 5.3 can actually keep track of intergers vs. numbers.  As a
+ * consequence, lua_isinteger() tells us if the internal representation of
+ * the number is an integer (vs. a number).  In previous versions, there was
+ * no way to check for this and our compatibility wrapper is not quite
+ * capable of matching the 5.3 behavior exactly.  Therefore, it returns 1
+ * when the number is representable as an integer instead.
+ */
+int lua_isinteger(lua_State *L, int idx);
+#endif
+
 #ifndef HAVE_LUA_TOINTEGERX
 /*
  * Lua 5.2 and 5.3 both have lua_tointegerx(), but their behavior is subtly
index 607f275d93d80253633b38f4f822b818d5cf0810..5e7e8e5346eaaf670393b33d14ca9654c9140892 100644 (file)
@@ -66,6 +66,7 @@ static void test_lua(void)
 
 /* check lua_tointegerx against top-of-stack item */
 static void check_tointegerx_compat(lua_State *L, int expected_isnum,
+                                   int expected_isint,
                                    lua_Integer expected_value)
 {
        lua_Integer value;
@@ -77,10 +78,12 @@ static void check_tointegerx_compat(lua_State *L, int expected_isnum,
        if (isnum == 1)
                test_assert(value == expected_value);
 
+       test_assert(lua_isinteger(L, -1) == expected_isint);
+
        lua_pop(L, 1);
 }
 
-static void test_compat_tointegerx(void)
+static void test_compat_tointegerx_and_isinteger(void)
 {
        static const struct {
                const char *input;
@@ -155,25 +158,35 @@ static void test_compat_tointegerx(void)
        const char *error;
        size_t i;
 
-       test_begin("lua compat tostringx");
+       test_begin("lua compat tostringx/isinteger");
 
        test_assert(dlua_script_create_string("", &script, NULL, &error) == 0);
 
        for (i = 0; i < N_ELEMENTS(str_tests); i++) {
                lua_pushstring(script->L, str_tests[i].input);
-               check_tointegerx_compat(script->L, str_tests[i].isnum,
+               check_tointegerx_compat(script->L, str_tests[i].isnum, 0,
                                        str_tests[i].output);
        }
 
        for (i = 0; i < N_ELEMENTS(num_tests); i++) {
+               int isint;
+
+               /* See lua_isinteger() comment in dlua-compat.h */
+#if LUA_VERSION_NUM == 503
+               isint = 0;
+#else
+               isint = num_tests[i].isnum;
+#endif
+
                lua_pushnumber(script->L, num_tests[i].input);
                check_tointegerx_compat(script->L, num_tests[i].isnum,
+                                       isint,
                                        num_tests[i].output);
        }
 
        for (i = 0; i < N_ELEMENTS(int_tests); i++) {
                lua_pushinteger(script->L, int_tests[i].input);
-               check_tointegerx_compat(script->L, 1,
+               check_tointegerx_compat(script->L, 1, 1,
                                        int_tests[i].output);
        }
 
@@ -185,7 +198,7 @@ static void test_compat_tointegerx(void)
 int main(void) {
        void (*tests[])(void) = {
                test_lua,
-               test_compat_tointegerx,
+               test_compat_tointegerx_and_isinteger,
                NULL
        };