}
#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()"
* 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
/* 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;
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;
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);
}
int main(void) {
void (*tests[])(void) = {
test_lua,
- test_compat_tointegerx,
+ test_compat_tointegerx_and_isinteger,
NULL
};