summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lobject.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/lobject.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/lobject.c')
-rw-r--r--apps/plugins/lua/lobject.c250
1 files changed, 162 insertions, 88 deletions
diff --git a/apps/plugins/lua/lobject.c b/apps/plugins/lua/lobject.c
index 62ad8e9359..34bbb25c9a 100644
--- a/apps/plugins/lua/lobject.c
+++ b/apps/plugins/lua/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,6 +15,8 @@
15 15
16#include "lua.h" 16#include "lua.h"
17 17
18#include "lctype.h"
19#include "ldebug.h"
18#include "ldo.h" 20#include "ldo.h"
19#include "lmem.h" 21#include "lmem.h"
20#include "lobject.h" 22#include "lobject.h"
@@ -24,7 +26,7 @@
24 26
25 27
26 28
27const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 29LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
28 30
29 31
30/* 32/*
@@ -33,25 +35,25 @@ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
33** eeeee != 0 and (xxx) otherwise. 35** eeeee != 0 and (xxx) otherwise.
34*/ 36*/
35int luaO_int2fb (unsigned int x) { 37int luaO_int2fb (unsigned int x) {
36 int e = 0; /* expoent */ 38 int e = 0; /* exponent */
37 while (x >= 16) { 39 if (x < 8) return x;
40 while (x >= 0x10) {
38 x = (x+1) >> 1; 41 x = (x+1) >> 1;
39 e++; 42 e++;
40 } 43 }
41 if (x < 8) return x; 44 return ((e+1) << 3) | (cast_int(x) - 8);
42 else return ((e+1) << 3) | (cast_int(x) - 8);
43} 45}
44 46
45 47
46/* converts back */ 48/* converts back */
47int luaO_fb2int (int x) { 49int luaO_fb2int (int x) {
48 int e = (x >> 3) & 31; 50 int e = (x >> 3) & 0x1f;
49 if (e == 0) return x; 51 if (e == 0) return x;
50 else return ((x & 7)+8) << (e - 1); 52 else return ((x & 7) + 8) << (e - 1);
51} 53}
52 54
53 55
54int luaO_log2 (unsigned int x) { 56int luaO_ceillog2 (unsigned int x) {
55 static const lu_byte log_2[256] = { 57 static const lu_byte log_2[256] = {
56 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 58 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
57 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 59 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
@@ -62,109 +64,169 @@ int luaO_log2 (unsigned int x) {
62 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 64 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
63 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 65 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
64 }; 66 };
65 int l = -1; 67 int l = 0;
68 x--;
66 while (x >= 256) { l += 8; x >>= 8; } 69 while (x >= 256) { l += 8; x >>= 8; }
67 return l + log_2[x]; 70 return l + log_2[x];
71}
72
73
74lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
75 switch (op) {
76 case LUA_OPADD: return luai_numadd(NULL, v1, v2);
77 case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
78 case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
79 case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
80 case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
81 case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
82 case LUA_OPUNM: return luai_numunm(NULL, v1);
83 default: lua_assert(0); return 0;
84 }
85}
86
87
88int luaO_hexavalue (int c) {
89 if (lisdigit(c)) return c - '0';
90 else return ltolower(c) - 'a' + 10;
91}
92
93
94#if !defined(lua_strx2number)
95
96#include <math.h>
97
98
99static int isneg (const char **s) {
100 if (**s == '-') { (*s)++; return 1; }
101 else if (**s == '+') (*s)++;
102 return 0;
103}
68 104
105
106static lua_Number readhexa (const char **s, lua_Number r, int *count) {
107 for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
108 r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
109 (*count)++;
110 }
111 return r;
69} 112}
70 113
71 114
72int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 115/*
73 if (ttype(t1) != ttype(t2)) return 0; 116** convert an hexadecimal numeric string to a number, following
74 else switch (ttype(t1)) { 117** C99 specification for 'strtod'
75 case LUA_TNIL: 118*/
76 return 1; 119static lua_Number lua_strx2number (const char *s, char **endptr) {
77 case LUA_TNUMBER: 120 lua_Number r = 0.0;
78 return luai_numeq(nvalue(t1), nvalue(t2)); 121 int e = 0, i = 0;
79 case LUA_TBOOLEAN: 122 int neg = 0; /* 1 if number is negative */
80 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 123 *endptr = cast(char *, s); /* nothing is valid yet */
81 case LUA_TLIGHTUSERDATA: 124 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
82 return pvalue(t1) == pvalue(t2); 125 neg = isneg(&s); /* check signal */
83 default: 126 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
84 lua_assert(iscollectable(t1)); 127 return 0.0; /* invalid format (no '0x') */
85 return gcvalue(t1) == gcvalue(t2); 128 s += 2; /* skip '0x' */
129 r = readhexa(&s, r, &i); /* read integer part */
130 if (*s == '.') {
131 s++; /* skip dot */
132 r = readhexa(&s, r, &e); /* read fractional part */
86 } 133 }
134 if (i == 0 && e == 0)
135 return 0.0; /* invalid format (no digit) */
136 e *= -4; /* each fractional digit divides value by 2^-4 */
137 *endptr = cast(char *, s); /* valid up to here */
138 if (*s == 'p' || *s == 'P') { /* exponent part? */
139 int exp1 = 0;
140 int neg1;
141 s++; /* skip 'p' */
142 neg1 = isneg(&s); /* signal */
143 if (!lisdigit(cast_uchar(*s)))
144 goto ret; /* must have at least one digit */
145 while (lisdigit(cast_uchar(*s))) /* read exponent */
146 exp1 = exp1 * 10 + *(s++) - '0';
147 if (neg1) exp1 = -exp1;
148 e += exp1;
149 }
150 *endptr = cast(char *, s); /* valid up to here */
151 ret:
152 if (neg) r = -r;
153 return l_mathop(ldexp)(r, e);
87} 154}
88 155
156#endif
157
89 158
90int luaO_str2d (const char *s, lua_Number *result) { 159int luaO_str2d (const char *s, size_t len, lua_Number *result) {
91 char *endptr; 160 char *endptr;
92 *result = lua_str2number(s, &endptr); 161 if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
93 if (endptr == s) return 0; /* conversion failed */ 162 return 0;
94 if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 163 else if (strpbrk(s, "xX")) /* hexa? */
95 *result = cast_num(strtoul(s, &endptr, 16)); 164 *result = lua_strx2number(s, &endptr);
96 if (*endptr == '\0') return 1; /* most common case */ 165 else
97 while (isspace(cast(unsigned char, *endptr))) endptr++; 166 *result = lua_str2number(s, &endptr);
98 if (*endptr != '\0') return 0; /* invalid trailing characters? */ 167 if (endptr == s) return 0; /* nothing recognized */
99 return 1; 168 while (lisspace(cast_uchar(*endptr))) endptr++;
169 return (endptr == s + len); /* OK if no trailing characters */
100} 170}
101 171
102 172
103 173
104static void pushstr (lua_State *L, const char *str) { 174static void pushstr (lua_State *L, const char *str, size_t l) {
105 setsvalue2s(L, L->top, luaS_new(L, str)); 175 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
106 incr_top(L);
107} 176}
108 177
109 178
110/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 179/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
111const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 180const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112 int n = 1; 181 int n = 0;
113 pushstr(L, "");
114 for (;;) { 182 for (;;) {
115 const char *e = strchr(fmt, '%'); 183 const char *e = strchr(fmt, '%');
116 if (e == NULL) break; 184 if (e == NULL) break;
117 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 185 luaD_checkstack(L, 2); /* fmt + item */
118 incr_top(L); 186 pushstr(L, fmt, e - fmt);
119 switch (*(e+1)) { 187 switch (*(e+1)) {
120 case 's': { 188 case 's': {
121 const char *s = va_arg(argp, char *); 189 const char *s = va_arg(argp, char *);
122 if (s == NULL) s = "(null)"; 190 if (s == NULL) s = "(null)";
123 pushstr(L, s); 191 pushstr(L, s, strlen(s));
124 break; 192 break;
125 } 193 }
126 case 'c': { 194 case 'c': {
127 char buff[2]; 195 char buff;
128 buff[0] = cast(char, va_arg(argp, int)); 196 buff = cast(char, va_arg(argp, int));
129 buff[1] = '\0'; 197 pushstr(L, &buff, 1);
130 pushstr(L, buff);
131 break; 198 break;
132 } 199 }
133 case 'd': { 200 case 'd': {
134 setnvalue(L->top, cast_num(va_arg(argp, int))); 201 setnvalue(L->top++, cast_num(va_arg(argp, int)));
135 incr_top(L);
136 break; 202 break;
137 } 203 }
138 case 'f': { 204 case 'f': {
139 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 205 setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
140 incr_top(L);
141 break; 206 break;
142 } 207 }
143 case 'p': { 208 case 'p': {
144 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 209 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
145 snprintf(buff, 4*sizeof(void *) + 8, "%p", va_arg(argp, void *)); 210 int l = snprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
146 pushstr(L, buff); 211 pushstr(L, buff, l);
147 break; 212 break;
148 } 213 }
149 case '%': { 214 case '%': {
150 pushstr(L, "%"); 215 pushstr(L, "%", 1);
151 break; 216 break;
152 } 217 }
153 default: { 218 default: {
154 char buff[3]; 219 luaG_runerror(L,
155 buff[0] = '%'; 220 "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
156 buff[1] = *(e+1); 221 *(e + 1));
157 buff[2] = '\0';
158 pushstr(L, buff);
159 break;
160 } 222 }
161 } 223 }
162 n += 2; 224 n += 2;
163 fmt = e+2; 225 fmt = e+2;
164 } 226 }
165 pushstr(L, fmt); 227 luaD_checkstack(L, 1);
166 luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 228 pushstr(L, fmt, strlen(fmt));
167 L->top -= n; 229 if (n > 0) luaV_concat(L, n + 1);
168 return svalue(L->top - 1); 230 return svalue(L->top - 1);
169} 231}
170 232
@@ -179,36 +241,48 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
179} 241}
180 242
181 243
244/* number of chars of a literal string without the ending \0 */
245#define LL(x) (sizeof(x)/sizeof(char) - 1)
246
247#define RETS "..."
248#define PRE "[string \""
249#define POS "\"]"
250
251#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
252
182void luaO_chunkid (char *out, const char *source, size_t bufflen) { 253void luaO_chunkid (char *out, const char *source, size_t bufflen) {
183 if (*source == '=') { 254 size_t l = strlen(source);
184 strncpy(out, source+1, bufflen); /* remove first char */ 255 if (*source == '=') { /* 'literal' source */
185 out[bufflen-1] = '\0'; /* ensures null termination */ 256 if (l <= bufflen) /* small enough? */
257 memcpy(out, source + 1, l * sizeof(char));
258 else { /* truncate it */
259 addstr(out, source + 1, bufflen - 1);
260 *out = '\0';
261 }
186 } 262 }
187 else { /* out = "source", or "...source" */ 263 else if (*source == '@') { /* file name */
188 if (*source == '@') { 264 if (l <= bufflen) /* small enough? */
189 size_t l; 265 memcpy(out, source + 1, l * sizeof(char));
190 source++; /* skip the `@' */ 266 else { /* add '...' before rest of name */
191 bufflen -= sizeof(" '...' "); 267 addstr(out, RETS, LL(RETS));
192 l = strlen(source); 268 bufflen -= LL(RETS);
193 strcpy(out, ""); 269 memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
194 if (l > bufflen) {
195 source += (l-bufflen); /* get last part of file name */
196 strcat(out, "...");
197 }
198 strcat(out, source);
199 } 270 }
200 else { /* out = [string "string"] */ 271 }
201 size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 272 else { /* string; format as [string "source"] */
202 bufflen -= sizeof(" [string \"...\"] "); 273 const char *nl = strchr(source, '\n'); /* find first new line (if any) */
203 if (len > bufflen) len = bufflen; 274 addstr(out, PRE, LL(PRE)); /* add prefix */
204 strcpy(out, "[string \""); 275 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
205 if (source[len] != '\0') { /* must truncate? */ 276 if (l < bufflen && nl == NULL) { /* small one-line source? */
206 strncat(out, source, len); 277 addstr(out, source, l); /* keep it */
207 strcat(out, "...");
208 }
209 else
210 strcat(out, source);
211 strcat(out, "\"]");
212 } 278 }
279 else {
280 if (nl != NULL) l = nl - source; /* stop at first newline */
281 if (l > bufflen) l = bufflen;
282 addstr(out, source, l);
283 addstr(out, RETS, LL(RETS));
284 }
285 memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
213 } 286 }
214} 287}
288