diff options
Diffstat (limited to 'apps/plugins/lua/ltablib.c')
-rw-r--r-- | apps/plugins/lua/ltablib.c | 140 |
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 | ||
22 | static 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 | |||
39 | static 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) | ||
56 | static int maxn (lua_State *L) { | 24 | static 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 | |||
72 | static int getn (lua_State *L) { | ||
73 | lua_pushinteger(L, aux_getn(L, 1)); | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | |||
78 | static 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 | ||
90 | static int tinsert (lua_State *L) { | 41 | static 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 | ||
118 | static int tremove (lua_State *L) { | 68 | static 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 | |||
119 | static 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 | |||
136 | static 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 | ||
193 | static void auxsort (lua_State *L, int l, int u) { | 184 | static 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 | ||
269 | static const luaL_Reg tab_funcs[] = { | 260 | static 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 | ||
283 | LUALIB_API int luaopen_table (lua_State *L) { | 274 | LUAMOD_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 | ||