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