aboutsummaryrefslogtreecommitdiffstats
path: root/util-src
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2022-03-18 15:21:25 +0000
committerMatthew Wild <mwild1@gmail.com>2022-03-18 15:21:25 +0000
commit26605b51971d2f899ce55214a86d799a310fd010 (patch)
tree76505deaf80816d3d448e6f1a55885bc49e8e4f7 /util-src
parentd26811f5e570192b2dd5fb66d3d789b66362508c (diff)
downloadprosody-26605b51971d2f899ce55214a86d799a310fd010.tar.gz
prosody-26605b51971d2f899ce55214a86d799a310fd010.zip
util.table: Backport table.move() from Lua 5.4
One difference is that 5.4 accepts "table-like" values (for this and other table.*() functions), but that would require additional backporting work.
Diffstat (limited to 'util-src')
-rw-r--r--util-src/table.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/util-src/table.c b/util-src/table.c
index 9a9553fc..0756a256 100644
--- a/util-src/table.c
+++ b/util-src/table.c
@@ -1,11 +1,17 @@
#include <lua.h>
#include <lauxlib.h>
+#ifndef LUA_MAXINTEGER
+#include <stdint.h>
+#define LUA_MAXINTEGER PTRDIFF_MAX
+#endif
+
static int Lcreate_table(lua_State *L) {
lua_createtable(L, luaL_checkinteger(L, 1), luaL_checkinteger(L, 2));
return 1;
}
+/* COMPAT: w/ Lua pre-5.4 */
static int Lpack(lua_State *L) {
unsigned int n_args = lua_gettop(L);
lua_createtable(L, n_args, 1);
@@ -20,6 +26,40 @@ static int Lpack(lua_State *L) {
return 1;
}
+/* COMPAT: w/ Lua pre-5.4 */
+static int Lmove (lua_State *L) {
+ lua_Integer f = luaL_checkinteger(L, 2);
+ lua_Integer e = luaL_checkinteger(L, 3);
+ lua_Integer t = luaL_checkinteger(L, 4);
+
+ int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checktype(L, tt, LUA_TTABLE);
+
+ if (e >= f) { /* otherwise, nothing to move */
+ lua_Integer n, i;
+ luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
+ "too many elements to move");
+ n = e - f + 1; /* number of elements to move */
+ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
+ "destination wrap around");
+ if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
+ for (i = 0; i < n; i++) {
+ lua_rawgeti(L, 1, f + i);
+ lua_rawseti(L, tt, t + i);
+ }
+ } else {
+ for (i = n - 1; i >= 0; i--) {
+ lua_rawgeti(L, 1, f + i);
+ lua_rawseti(L, tt, t + i);
+ }
+ }
+ }
+
+ lua_pushvalue(L, tt); /* return destination table */
+ return 1;
+}
+
int luaopen_util_table(lua_State *L) {
#if (LUA_VERSION_NUM > 501)
luaL_checkversion(L);
@@ -29,5 +69,7 @@ int luaopen_util_table(lua_State *L) {
lua_setfield(L, -2, "create");
lua_pushcfunction(L, Lpack);
lua_setfield(L, -2, "pack");
+ lua_pushcfunction(L, Lmove);
+ lua_setfield(L, -2, "move");
return 1;
}