Software /
code /
prosody
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 |
parent | 7969:1c6a07606309 |
child | 12405: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 } |