Mercurial > prosody-hg
comparison util-src/table.c @ 12402:8deb401a21f6
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.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 18 Mar 2022 15:21:25 +0000 |
| parents | 1c6a07606309 |
| children | 308ed64dc69b |
comparison
equal
deleted
inserted
replaced
| 12401:c029ddcad258 | 12402:8deb401a21f6 |
|---|---|
| 1 #include <lua.h> | 1 #include <lua.h> |
| 2 #include <lauxlib.h> | 2 #include <lauxlib.h> |
| 3 | |
| 4 #ifndef LUA_MAXINTEGER | |
| 5 #include <stdint.h> | |
| 6 #define LUA_MAXINTEGER PTRDIFF_MAX | |
| 7 #endif | |
| 3 | 8 |
| 4 static int Lcreate_table(lua_State *L) { | 9 static int Lcreate_table(lua_State *L) { |
| 5 lua_createtable(L, luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)); | 10 lua_createtable(L, luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)); |
| 6 return 1; | 11 return 1; |
| 7 } | 12 } |
| 8 | 13 |
| 14 /* COMPAT: w/ Lua pre-5.4 */ | |
| 9 static int Lpack(lua_State *L) { | 15 static int Lpack(lua_State *L) { |
| 10 unsigned int n_args = lua_gettop(L); | 16 unsigned int n_args = lua_gettop(L); |
| 11 lua_createtable(L, n_args, 1); | 17 lua_createtable(L, n_args, 1); |
| 12 lua_insert(L, 1); | 18 lua_insert(L, 1); |
| 13 | 19 |
| 18 lua_pushinteger(L, n_args); | 24 lua_pushinteger(L, n_args); |
| 19 lua_setfield(L, -2, "n"); | 25 lua_setfield(L, -2, "n"); |
| 20 return 1; | 26 return 1; |
| 21 } | 27 } |
| 22 | 28 |
| 29 /* COMPAT: w/ Lua pre-5.4 */ | |
| 30 static int Lmove (lua_State *L) { | |
| 31 lua_Integer f = luaL_checkinteger(L, 2); | |
| 32 lua_Integer e = luaL_checkinteger(L, 3); | |
| 33 lua_Integer t = luaL_checkinteger(L, 4); | |
| 34 | |
| 35 int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ | |
| 36 luaL_checktype(L, 1, LUA_TTABLE); | |
| 37 luaL_checktype(L, tt, LUA_TTABLE); | |
| 38 | |
| 39 if (e >= f) { /* otherwise, nothing to move */ | |
| 40 lua_Integer n, i; | |
| 41 luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, | |
| 42 "too many elements to move"); | |
| 43 n = e - f + 1; /* number of elements to move */ | |
| 44 luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, | |
| 45 "destination wrap around"); | |
| 46 if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { | |
| 47 for (i = 0; i < n; i++) { | |
| 48 lua_rawgeti(L, 1, f + i); | |
| 49 lua_rawseti(L, tt, t + i); | |
| 50 } | |
| 51 } else { | |
| 52 for (i = n - 1; i >= 0; i--) { | |
| 53 lua_rawgeti(L, 1, f + i); | |
| 54 lua_rawseti(L, tt, t + i); | |
| 55 } | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 lua_pushvalue(L, tt); /* return destination table */ | |
| 60 return 1; | |
| 61 } | |
| 62 | |
| 23 int luaopen_util_table(lua_State *L) { | 63 int luaopen_util_table(lua_State *L) { |
| 24 #if (LUA_VERSION_NUM > 501) | 64 #if (LUA_VERSION_NUM > 501) |
| 25 luaL_checkversion(L); | 65 luaL_checkversion(L); |
| 26 #endif | 66 #endif |
| 27 lua_createtable(L, 0, 2); | 67 lua_createtable(L, 0, 2); |
| 28 lua_pushcfunction(L, Lcreate_table); | 68 lua_pushcfunction(L, Lcreate_table); |
| 29 lua_setfield(L, -2, "create"); | 69 lua_setfield(L, -2, "create"); |
| 30 lua_pushcfunction(L, Lpack); | 70 lua_pushcfunction(L, Lpack); |
| 31 lua_setfield(L, -2, "pack"); | 71 lua_setfield(L, -2, "pack"); |
| 72 lua_pushcfunction(L, Lmove); | |
| 73 lua_setfield(L, -2, "move"); | |
| 32 return 1; | 74 return 1; |
| 33 } | 75 } |
