summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/ltablib.c
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/ltablib.c
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz
rockbox-36378988ad4059982742f05f5eb50580b456840a.zip
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change reduces the number of modifications in the Lua source using some new defines and because the upstream source is now more flexible. Unless otherwise stated, l*.[ch] files are taken unmodified from the upstream lua-5.2.3. fscanf.c: file descriptors in rockbox are just ints, they are hidden behind a void* now so liolib requires less modifications. fscanf is updated to use void* too. getc.c: this is a new file required for getc implementation in lauxlib.c lauxlib.c: LoadF replaced FILE* with int, the rockbox file descriptor int are cast to FILE* (actually void* due to typedef). getc uses the PREFIX version. stdin is not used, as per 5.1.4. lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now rather than being commented out. lbitlib.c: use the built-in version from 5.2.3 rather than Reuben Thomas's external library. Backwards compatible and adds some new bit operations. ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have been removed from rockconf.h liolib.c: here the implementation has changed to use the LStream from the original source, and cast the FILE* pointers to int. This has reduced the number of modifications from the upstream version. llex.c: the only change from upstream is to remove the locale include. lmathlib.c: updated from the 5.2.3 version and re-applied the changes that were made vs 5.1.4 for random numbers and to remove unsupported float functions. loadlib.c: upstream version, with the 5.1.4 changes for missing functions. lobject.c: upstream version, with ctype.h added and sprintf changed to snprintf. loslib.c: upstream version with locale.h removed and 5.1.4 changes for unsupportable functions. lstrlib.c: sprintf changed to snprintf. ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp in luai_hashnum. luaconf.h: updated to 5.2.3 version, restored relevant parts from the original 5.1.4 configuration. The COMPAT defines that are no longer available are not included. lundump.c: VERSION macro conflicts with the core Rockbox equivalent. rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg equivalent. Moved checkboolean/optboolean functions to this file and out of core lua files. luaL_getn is no longer available, replaced by luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs replacements. rli_init has to be called before setting up the newlib to avoid overwriting the rb table. rocklib_aux.pl: use rli_checkboolean from rocklib.c. rocklua.c: new default bits library used, update the library loading code with idiomatic 5.2 code. strcspn.c: no longer needed, but strspn.c is required for strspn in lbaselib.c Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651 Reviewed-on: http://gerrit.rockbox.org/774 Tested: Richard Quirk <richard.quirk@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
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