summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/ltablib.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/ltablib.c')
-rw-r--r--apps/plugins/lua/ltablib.c140
1 files changed, 68 insertions, 72 deletions
diff --git a/apps/plugins/lua/ltablib.c b/apps/plugins/lua/ltablib.c
index b6d9cb4ac7..6001224e39 100644
--- a/apps/plugins/lua/ltablib.c
+++ b/apps/plugins/lua/ltablib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ 2** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,43 +16,11 @@
16#include "lualib.h" 16#include "lualib.h"
17 17
18 18
19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
20 20
21 21
22static int foreachi (lua_State *L) {
23 int i;
24 int n = aux_getn(L, 1);
25 luaL_checktype(L, 2, LUA_TFUNCTION);
26 for (i=1; i <= n; i++) {
27 lua_pushvalue(L, 2); /* function */
28 lua_pushinteger(L, i); /* 1st argument */
29 lua_rawgeti(L, 1, i); /* 2nd argument */
30 lua_call(L, 2, 1);
31 if (!lua_isnil(L, -1))
32 return 1;
33 lua_pop(L, 1); /* remove nil result */
34 }
35 return 0;
36}
37
38
39static int foreach (lua_State *L) {
40 luaL_checktype(L, 1, LUA_TTABLE);
41 luaL_checktype(L, 2, LUA_TFUNCTION);
42 lua_pushnil(L); /* first key */
43 while (lua_next(L, 1)) {
44 lua_pushvalue(L, 2); /* function */
45 lua_pushvalue(L, -3); /* key */
46 lua_pushvalue(L, -3); /* value */
47 lua_call(L, 2, 1);
48 if (!lua_isnil(L, -1))
49 return 1;
50 lua_pop(L, 2); /* remove value and result */
51 }
52 return 0;
53}
54
55 22
23#if defined(LUA_COMPAT_MAXN)
56static int maxn (lua_State *L) { 24static int maxn (lua_State *L) {
57 lua_Number max = 0; 25 lua_Number max = 0;
58 luaL_checktype(L, 1, LUA_TTABLE); 26 luaL_checktype(L, 1, LUA_TTABLE);
@@ -67,24 +35,7 @@ static int maxn (lua_State *L) {
67 lua_pushnumber(L, max); 35 lua_pushnumber(L, max);
68 return 1; 36 return 1;
69} 37}
70
71
72static int getn (lua_State *L) {
73 lua_pushinteger(L, aux_getn(L, 1));
74 return 1;
75}
76
77
78static int setn (lua_State *L) {
79 luaL_checktype(L, 1, LUA_TTABLE);
80#ifndef luaL_setn
81 luaL_setn(L, 1, luaL_checkint(L, 2));
82#else
83 luaL_error(L, LUA_QL("setn") " is obsolete");
84#endif 38#endif
85 lua_pushvalue(L, 1);
86 return 1;
87}
88 39
89 40
90static int tinsert (lua_State *L) { 41static int tinsert (lua_State *L) {
@@ -98,7 +49,7 @@ static int tinsert (lua_State *L) {
98 case 3: { 49 case 3: {
99 int i; 50 int i;
100 pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 51 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
101 if (pos > e) e = pos; /* `grow' array if necessary */ 52 luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
102 for (i = e; i > pos; i--) { /* move up elements */ 53 for (i = e; i > pos; i--) { /* move up elements */
103 lua_rawgeti(L, 1, i-1); 54 lua_rawgeti(L, 1, i-1);
104 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ 55 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
@@ -109,25 +60,23 @@ static int tinsert (lua_State *L) {
109 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); 60 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
110 } 61 }
111 } 62 }
112 luaL_setn(L, 1, e); /* new size */
113 lua_rawseti(L, 1, pos); /* t[pos] = v */ 63 lua_rawseti(L, 1, pos); /* t[pos] = v */
114 return 0; 64 return 0;
115} 65}
116 66
117 67
118static int tremove (lua_State *L) { 68static int tremove (lua_State *L) {
119 int e = aux_getn(L, 1); 69 int size = aux_getn(L, 1);
120 int pos = luaL_optint(L, 2, e); 70 int pos = luaL_optint(L, 2, size);
121 if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ 71 if (pos != size) /* validate 'pos' if given */
122 return 0; /* nothing to remove */ 72 luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
123 luaL_setn(L, 1, e - 1); /* t.n = n-1 */
124 lua_rawgeti(L, 1, pos); /* result = t[pos] */ 73 lua_rawgeti(L, 1, pos); /* result = t[pos] */
125 for ( ;pos<e; pos++) { 74 for ( ; pos < size; pos++) {
126 lua_rawgeti(L, 1, pos+1); 75 lua_rawgeti(L, 1, pos+1);
127 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ 76 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
128 } 77 }
129 lua_pushnil(L); 78 lua_pushnil(L);
130 lua_rawseti(L, 1, e); /* t[e] = nil */ 79 lua_rawseti(L, 1, pos); /* t[pos] = nil */
131 return 1; 80 return 1;
132} 81}
133 82
@@ -137,7 +86,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
137 if (!lua_isstring(L, -1)) 86 if (!lua_isstring(L, -1))
138 luaL_error(L, "invalid value (%s) at index %d in table for " 87 luaL_error(L, "invalid value (%s) at index %d in table for "
139 LUA_QL("concat"), luaL_typename(L, -1), i); 88 LUA_QL("concat"), luaL_typename(L, -1), i);
140 luaL_addvalue(b); 89 luaL_addvalue(b);
141} 90}
142 91
143 92
@@ -148,7 +97,7 @@ static int tconcat (lua_State *L) {
148 const char *sep = luaL_optlstring(L, 2, "", &lsep); 97 const char *sep = luaL_optlstring(L, 2, "", &lsep);
149 luaL_checktype(L, 1, LUA_TTABLE); 98 luaL_checktype(L, 1, LUA_TTABLE);
150 i = luaL_optint(L, 3, 1); 99 i = luaL_optint(L, 3, 1);
151 last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); 100 last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1));
152 luaL_buffinit(L, &b); 101 luaL_buffinit(L, &b);
153 for (; i < last; i++) { 102 for (; i < last; i++) {
154 addfield(L, &b, i); 103 addfield(L, &b, i);
@@ -161,12 +110,54 @@ static int tconcat (lua_State *L) {
161} 110}
162 111
163 112
113/*
114** {======================================================
115** Pack/unpack
116** =======================================================
117*/
118
119static int pack (lua_State *L) {
120 int n = lua_gettop(L); /* number of elements to pack */
121 lua_createtable(L, n, 1); /* create result table */
122 lua_pushinteger(L, n);
123 lua_setfield(L, -2, "n"); /* t.n = number of elements */
124 if (n > 0) { /* at least one element? */
125 int i;
126 lua_pushvalue(L, 1);
127 lua_rawseti(L, -2, 1); /* insert first element */
128 lua_replace(L, 1); /* move table into index 1 */
129 for (i = n; i >= 2; i--) /* assign other elements */
130 lua_rawseti(L, 1, i);
131 }
132 return 1; /* return table */
133}
134
135
136static int unpack (lua_State *L) {
137 int i, e, n;
138 luaL_checktype(L, 1, LUA_TTABLE);
139 i = luaL_optint(L, 2, 1);
140 e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
141 if (i > e) return 0; /* empty range */
142 n = e - i + 1; /* number of elements */
143 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
144 return luaL_error(L, "too many results to unpack");
145 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
146 while (i++ < e) /* push arg[i + 1...e] */
147 lua_rawgeti(L, 1, i);
148 return n;
149}
150
151/* }====================================================== */
152
153
164 154
165/* 155/*
166** {====================================================== 156** {======================================================
167** Quicksort 157** Quicksort
168** (based on `Algorithms in MODULA-3', Robert Sedgewick; 158** (based on `Algorithms in MODULA-3', Robert Sedgewick;
169** Addison-Wesley, 1993.) 159** Addison-Wesley, 1993.)
160** =======================================================
170*/ 161*/
171 162
172 163
@@ -187,7 +178,7 @@ static int sort_comp (lua_State *L, int a, int b) {
187 return res; 178 return res;
188 } 179 }
189 else /* a < b? */ 180 else /* a < b? */
190 return lua_lessthan(L, a, b); 181 return lua_compare(L, a, b, LUA_OPLT);
191} 182}
192 183
193static void auxsort (lua_State *L, int l, int u) { 184static void auxsort (lua_State *L, int l, int u) {
@@ -224,12 +215,12 @@ static void auxsort (lua_State *L, int l, int u) {
224 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 215 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
225 /* repeat ++i until a[i] >= P */ 216 /* repeat ++i until a[i] >= P */
226 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { 217 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
227 if (i>u) luaL_error(L, "invalid order function for sorting"); 218 if (i>=u) luaL_error(L, "invalid order function for sorting");
228 lua_pop(L, 1); /* remove a[i] */ 219 lua_pop(L, 1); /* remove a[i] */
229 } 220 }
230 /* repeat --j until a[j] <= P */ 221 /* repeat --j until a[j] <= P */
231 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { 222 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
232 if (j<l) luaL_error(L, "invalid order function for sorting"); 223 if (j<=l) luaL_error(L, "invalid order function for sorting");
233 lua_pop(L, 1); /* remove a[j] */ 224 lua_pop(L, 1); /* remove a[j] */
234 } 225 }
235 if (j<i) { 226 if (j<i) {
@@ -268,20 +259,25 @@ static int sort (lua_State *L) {
268 259
269static const luaL_Reg tab_funcs[] = { 260static const luaL_Reg tab_funcs[] = {
270 {"concat", tconcat}, 261 {"concat", tconcat},
271 {"foreach", foreach}, 262#if defined(LUA_COMPAT_MAXN)
272 {"foreachi", foreachi},
273 {"getn", getn},
274 {"maxn", maxn}, 263 {"maxn", maxn},
264#endif
275 {"insert", tinsert}, 265 {"insert", tinsert},
266 {"pack", pack},
267 {"unpack", unpack},
276 {"remove", tremove}, 268 {"remove", tremove},
277 {"setn", setn},
278 {"sort", sort}, 269 {"sort", sort},
279 {NULL, NULL} 270 {NULL, NULL}
280}; 271};
281 272
282 273
283LUALIB_API int luaopen_table (lua_State *L) { 274LUAMOD_API int luaopen_table (lua_State *L) {
284 luaL_register(L, LUA_TABLIBNAME, tab_funcs); 275 luaL_newlib(L, tab_funcs);
276#if defined(LUA_COMPAT_UNPACK)
277 /* _G.unpack = table.unpack */
278 lua_getfield(L, -1, "unpack");
279 lua_setglobal(L, "unpack");
280#endif
285 return 1; 281 return 1;
286} 282}
287 283