Fri Mar 25 08:15:20 2016 UTC ()
Apply second and third patch from http://lua.org/bugs.html.


(mbalmer)
diff -r1.4 -r1.5 src/external/mit/lua/dist/src/lparser.c
diff -r1.11 -r1.12 src/external/mit/lua/dist/src/lstrlib.c

cvs diff -r1.4 -r1.5 src/external/mit/lua/dist/src/lparser.c (switch to unified diff)

--- src/external/mit/lua/dist/src/lparser.c 2016/01/28 14:41:39 1.4
+++ src/external/mit/lua/dist/src/lparser.c 2016/03/25 08:15:20 1.5
@@ -1,1662 +1,1662 @@ @@ -1,1662 +1,1662 @@
1/* $NetBSD: lparser.c,v 1.4 2016/01/28 14:41:39 lneto Exp $ */ 1/* $NetBSD: lparser.c,v 1.5 2016/03/25 08:15:20 mbalmer Exp $ */
2 2
3/* 3/*
4** Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp  4** Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp
5** Lua Parser 5** Lua Parser
6** See Copyright Notice in lua.h 6** See Copyright Notice in lua.h
7*/ 7*/
8 8
9#define lparser_c 9#define lparser_c
10#define LUA_CORE 10#define LUA_CORE
11 11
12#include "lprefix.h" 12#include "lprefix.h"
13 13
14 14
15#ifndef _KERNEL 15#ifndef _KERNEL
16#include <string.h> 16#include <string.h>
17#endif /* _KERNEL */ 17#endif /* _KERNEL */
18 18
19#include "lua.h" 19#include "lua.h"
20 20
21#include "lcode.h" 21#include "lcode.h"
22#include "ldebug.h" 22#include "ldebug.h"
23#include "ldo.h" 23#include "ldo.h"
24#include "lfunc.h" 24#include "lfunc.h"
25#include "llex.h" 25#include "llex.h"
26#include "lmem.h" 26#include "lmem.h"
27#include "lobject.h" 27#include "lobject.h"
28#include "lopcodes.h" 28#include "lopcodes.h"
29#include "lparser.h" 29#include "lparser.h"
30#include "lstate.h" 30#include "lstate.h"
31#include "lstring.h" 31#include "lstring.h"
32#include "ltable.h" 32#include "ltable.h"
33 33
34 34
35 35
36/* maximum number of local variables per function (must be smaller 36/* maximum number of local variables per function (must be smaller
37 than 250, due to the bytecode format) */ 37 than 250, due to the bytecode format) */
38#define MAXVARS 200 38#define MAXVARS 200
39 39
40 40
41#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 41#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
42 42
43 43
44/* because all strings are unified by the scanner, the parser 44/* because all strings are unified by the scanner, the parser
45 can use pointer equality for string equality */ 45 can use pointer equality for string equality */
46#define eqstr(a,b) ((a) == (b)) 46#define eqstr(a,b) ((a) == (b))
47 47
48 48
49/* 49/*
50** nodes for block list (list of active blocks) 50** nodes for block list (list of active blocks)
51*/ 51*/
52typedef struct BlockCnt { 52typedef struct BlockCnt {
53 struct BlockCnt *previous; /* chain */ 53 struct BlockCnt *previous; /* chain */
54 int firstlabel; /* index of first label in this block */ 54 int firstlabel; /* index of first label in this block */
55 int firstgoto; /* index of first pending goto in this block */ 55 int firstgoto; /* index of first pending goto in this block */
56 lu_byte nactvar; /* # active locals outside the block */ 56 lu_byte nactvar; /* # active locals outside the block */
57 lu_byte upval; /* true if some variable in the block is an upvalue */ 57 lu_byte upval; /* true if some variable in the block is an upvalue */
58 lu_byte isloop; /* true if 'block' is a loop */ 58 lu_byte isloop; /* true if 'block' is a loop */
59} BlockCnt; 59} BlockCnt;
60 60
61 61
62 62
63/* 63/*
64** prototypes for recursive non-terminal functions 64** prototypes for recursive non-terminal functions
65*/ 65*/
66static void statement (LexState *ls); 66static void statement (LexState *ls);
67static void expr (LexState *ls, expdesc *v); 67static void expr (LexState *ls, expdesc *v);
68 68
69 69
70/* semantic error */ 70/* semantic error */
71static l_noret semerror (LexState *ls, const char *msg) { 71static l_noret semerror (LexState *ls, const char *msg) {
72 ls->t.token = 0; /* remove "near <token>" from final message */ 72 ls->t.token = 0; /* remove "near <token>" from final message */
73 luaX_syntaxerror(ls, msg); 73 luaX_syntaxerror(ls, msg);
74} 74}
75 75
76 76
77static l_noret error_expected (LexState *ls, int token) { 77static l_noret error_expected (LexState *ls, int token) {
78 luaX_syntaxerror(ls, 78 luaX_syntaxerror(ls,
79 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); 79 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
80} 80}
81 81
82 82
83static l_noret errorlimit (FuncState *fs, int limit, const char *what) { 83static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
84 lua_State *L = fs->ls->L; 84 lua_State *L = fs->ls->L;
85 const char *msg; 85 const char *msg;
86 int line = fs->f->linedefined; 86 int line = fs->f->linedefined;
87 const char *where = (line == 0) 87 const char *where = (line == 0)
88 ? "main function" 88 ? "main function"
89 : luaO_pushfstring(L, "function at line %d", line); 89 : luaO_pushfstring(L, "function at line %d", line);
90 msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", 90 msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
91 what, limit, where); 91 what, limit, where);
92 luaX_syntaxerror(fs->ls, msg); 92 luaX_syntaxerror(fs->ls, msg);
93} 93}
94 94
95 95
96static void checklimit (FuncState *fs, int v, int l, const char *what) { 96static void checklimit (FuncState *fs, int v, int l, const char *what) {
97 if (v > l) errorlimit(fs, l, what); 97 if (v > l) errorlimit(fs, l, what);
98} 98}
99 99
100 100
101static int testnext (LexState *ls, int c) { 101static int testnext (LexState *ls, int c) {
102 if (ls->t.token == c) { 102 if (ls->t.token == c) {
103 luaX_next(ls); 103 luaX_next(ls);
104 return 1; 104 return 1;
105 } 105 }
106 else return 0; 106 else return 0;
107} 107}
108 108
109 109
110static void check (LexState *ls, int c) { 110static void check (LexState *ls, int c) {
111 if (ls->t.token != c) 111 if (ls->t.token != c)
112 error_expected(ls, c); 112 error_expected(ls, c);
113} 113}
114 114
115 115
116static void checknext (LexState *ls, int c) { 116static void checknext (LexState *ls, int c) {
117 check(ls, c); 117 check(ls, c);
118 luaX_next(ls); 118 luaX_next(ls);
119} 119}
120 120
121 121
122#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } 122#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
123 123
124 124
125 125
126static void check_match (LexState *ls, int what, int who, int where) { 126static void check_match (LexState *ls, int what, int who, int where) {
127 if (!testnext(ls, what)) { 127 if (!testnext(ls, what)) {
128 if (where == ls->linenumber) 128 if (where == ls->linenumber)
129 error_expected(ls, what); 129 error_expected(ls, what);
130 else { 130 else {
131 luaX_syntaxerror(ls, luaO_pushfstring(ls->L, 131 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
132 "%s expected (to close %s at line %d)", 132 "%s expected (to close %s at line %d)",
133 luaX_token2str(ls, what), luaX_token2str(ls, who), where)); 133 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
134 } 134 }
135 } 135 }
136} 136}
137 137
138 138
139static TString *str_checkname (LexState *ls) { 139static TString *str_checkname (LexState *ls) {
140 TString *ts; 140 TString *ts;
141 check(ls, TK_NAME); 141 check(ls, TK_NAME);
142 ts = ls->t.seminfo.ts; 142 ts = ls->t.seminfo.ts;
143 luaX_next(ls); 143 luaX_next(ls);
144 return ts; 144 return ts;
145} 145}
146 146
147 147
148static void init_exp (expdesc *e, expkind k, int i) { 148static void init_exp (expdesc *e, expkind k, int i) {
149 e->f = e->t = NO_JUMP; 149 e->f = e->t = NO_JUMP;
150 e->k = k; 150 e->k = k;
151 e->u.info = i; 151 e->u.info = i;
152} 152}
153 153
154 154
155static void codestring (LexState *ls, expdesc *e, TString *s) { 155static void codestring (LexState *ls, expdesc *e, TString *s) {
156 init_exp(e, VK, luaK_stringK(ls->fs, s)); 156 init_exp(e, VK, luaK_stringK(ls->fs, s));
157} 157}
158 158
159 159
160static void checkname (LexState *ls, expdesc *e) { 160static void checkname (LexState *ls, expdesc *e) {
161 codestring(ls, e, str_checkname(ls)); 161 codestring(ls, e, str_checkname(ls));
162} 162}
163 163
164 164
165static int registerlocalvar (LexState *ls, TString *varname) { 165static int registerlocalvar (LexState *ls, TString *varname) {
166 FuncState *fs = ls->fs; 166 FuncState *fs = ls->fs;
167 Proto *f = fs->f; 167 Proto *f = fs->f;
168 int oldsize = f->sizelocvars; 168 int oldsize = f->sizelocvars;
169 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 169 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
170 LocVar, SHRT_MAX, "local variables"); 170 LocVar, SHRT_MAX, "local variables");
171 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; 171 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
172 f->locvars[fs->nlocvars].varname = varname; 172 f->locvars[fs->nlocvars].varname = varname;
173 luaC_objbarrier(ls->L, f, varname); 173 luaC_objbarrier(ls->L, f, varname);
174 return fs->nlocvars++; 174 return fs->nlocvars++;
175} 175}
176 176
177 177
178static void new_localvar (LexState *ls, TString *name) { 178static void new_localvar (LexState *ls, TString *name) {
179 FuncState *fs = ls->fs; 179 FuncState *fs = ls->fs;
180 Dyndata *dyd = ls->dyd; 180 Dyndata *dyd = ls->dyd;
181 int reg = registerlocalvar(ls, name); 181 int reg = registerlocalvar(ls, name);
182 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, 182 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
183 MAXVARS, "local variables"); 183 MAXVARS, "local variables");
184 luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, 184 luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
185 dyd->actvar.size, Vardesc, MAX_INT, "local variables"); 185 dyd->actvar.size, Vardesc, MAX_INT, "local variables");
186 dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); 186 dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
187} 187}
188 188
189 189
190static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { 190static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
191 new_localvar(ls, luaX_newstring(ls, name, sz)); 191 new_localvar(ls, luaX_newstring(ls, name, sz));
192} 192}
193 193
194#define new_localvarliteral(ls,v) \ 194#define new_localvarliteral(ls,v) \
195 new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) 195 new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
196 196
197 197
198static LocVar *getlocvar (FuncState *fs, int i) { 198static LocVar *getlocvar (FuncState *fs, int i) {
199 int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; 199 int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
200 lua_assert(idx < fs->nlocvars); 200 lua_assert(idx < fs->nlocvars);
201 return &fs->f->locvars[idx]; 201 return &fs->f->locvars[idx];
202} 202}
203 203
204 204
205static void adjustlocalvars (LexState *ls, int nvars) { 205static void adjustlocalvars (LexState *ls, int nvars) {
206 FuncState *fs = ls->fs; 206 FuncState *fs = ls->fs;
207 fs->nactvar = cast_byte(fs->nactvar + nvars); 207 fs->nactvar = cast_byte(fs->nactvar + nvars);
208 for (; nvars; nvars--) { 208 for (; nvars; nvars--) {
209 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; 209 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
210 } 210 }
211} 211}
212 212
213 213
214static void removevars (FuncState *fs, int tolevel) { 214static void removevars (FuncState *fs, int tolevel) {
215 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); 215 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
216 while (fs->nactvar > tolevel) 216 while (fs->nactvar > tolevel)
217 getlocvar(fs, --fs->nactvar)->endpc = fs->pc; 217 getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
218} 218}
219 219
220 220
221static int searchupvalue (FuncState *fs, TString *name) { 221static int searchupvalue (FuncState *fs, TString *name) {
222 int i; 222 int i;
223 Upvaldesc *up = fs->f->upvalues; 223 Upvaldesc *up = fs->f->upvalues;
224 for (i = 0; i < fs->nups; i++) { 224 for (i = 0; i < fs->nups; i++) {
225 if (eqstr(up[i].name, name)) return i; 225 if (eqstr(up[i].name, name)) return i;
226 } 226 }
227 return -1; /* not found */ 227 return -1; /* not found */
228} 228}
229 229
230 230
231static int newupvalue (FuncState *fs, TString *name, expdesc *v) { 231static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
232 Proto *f = fs->f; 232 Proto *f = fs->f;
233 int oldsize = f->sizeupvalues; 233 int oldsize = f->sizeupvalues;
234 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); 234 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
235 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, 235 luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
236 Upvaldesc, MAXUPVAL, "upvalues"); 236 Upvaldesc, MAXUPVAL, "upvalues");
237 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; 237 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
238 f->upvalues[fs->nups].instack = (v->k == VLOCAL); 238 f->upvalues[fs->nups].instack = (v->k == VLOCAL);
239 f->upvalues[fs->nups].idx = cast_byte(v->u.info); 239 f->upvalues[fs->nups].idx = cast_byte(v->u.info);
240 f->upvalues[fs->nups].name = name; 240 f->upvalues[fs->nups].name = name;
241 luaC_objbarrier(fs->ls->L, f, name); 241 luaC_objbarrier(fs->ls->L, f, name);
242 return fs->nups++; 242 return fs->nups++;
243} 243}
244 244
245 245
246static int searchvar (FuncState *fs, TString *n) { 246static int searchvar (FuncState *fs, TString *n) {
247 int i; 247 int i;
248 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 248 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
249 if (eqstr(n, getlocvar(fs, i)->varname)) 249 if (eqstr(n, getlocvar(fs, i)->varname))
250 return i; 250 return i;
251 } 251 }
252 return -1; /* not found */ 252 return -1; /* not found */
253} 253}
254 254
255 255
256/* 256/*
257 Mark block where variable at given level was defined 257 Mark block where variable at given level was defined
258 (to emit close instructions later). 258 (to emit close instructions later).
259*/ 259*/
260static void markupval (FuncState *fs, int level) { 260static void markupval (FuncState *fs, int level) {
261 BlockCnt *bl = fs->bl; 261 BlockCnt *bl = fs->bl;
262 while (bl->nactvar > level) bl = bl->previous; 262 while (bl->nactvar > level) bl = bl->previous;
263 bl->upval = 1; 263 bl->upval = 1;
264} 264}
265 265
266 266
267/* 267/*
268 Find variable with given name 'n'. If it is an upvalue, add this 268 Find variable with given name 'n'. If it is an upvalue, add this
269 upvalue into all intermediate functions. 269 upvalue into all intermediate functions.
270*/ 270*/
271static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 271static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
272 if (fs == NULL) /* no more levels? */ 272 if (fs == NULL) /* no more levels? */
273 return VVOID; /* default is global */ 273 return VVOID; /* default is global */
274 else { 274 else {
275 int v = searchvar(fs, n); /* look up locals at current level */ 275 int v = searchvar(fs, n); /* look up locals at current level */
276 if (v >= 0) { /* found? */ 276 if (v >= 0) { /* found? */
277 init_exp(var, VLOCAL, v); /* variable is local */ 277 init_exp(var, VLOCAL, v); /* variable is local */
278 if (!base) 278 if (!base)
279 markupval(fs, v); /* local will be used as an upval */ 279 markupval(fs, v); /* local will be used as an upval */
280 return VLOCAL; 280 return VLOCAL;
281 } 281 }
282 else { /* not found as local at current level; try upvalues */ 282 else { /* not found as local at current level; try upvalues */
283 int idx = searchupvalue(fs, n); /* try existing upvalues */ 283 int idx = searchupvalue(fs, n); /* try existing upvalues */
284 if (idx < 0) { /* not found? */ 284 if (idx < 0) { /* not found? */
285 if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ 285 if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
286 return VVOID; /* not found; is a global */ 286 return VVOID; /* not found; is a global */
287 /* else was LOCAL or UPVAL */ 287 /* else was LOCAL or UPVAL */
288 idx = newupvalue(fs, n, var); /* will be a new upvalue */ 288 idx = newupvalue(fs, n, var); /* will be a new upvalue */
289 } 289 }
290 init_exp(var, VUPVAL, idx); 290 init_exp(var, VUPVAL, idx);
291 return VUPVAL; 291 return VUPVAL;
292 } 292 }
293 } 293 }
294} 294}
295 295
296 296
297static void singlevar (LexState *ls, expdesc *var) { 297static void singlevar (LexState *ls, expdesc *var) {
298 TString *varname = str_checkname(ls); 298 TString *varname = str_checkname(ls);
299 FuncState *fs = ls->fs; 299 FuncState *fs = ls->fs;
300 if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ 300 if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
301 expdesc key; 301 expdesc key;
302 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ 302 singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
303 lua_assert(var->k == VLOCAL || var->k == VUPVAL); 303 lua_assert(var->k == VLOCAL || var->k == VUPVAL);
304 codestring(ls, &key, varname); /* key is variable name */ 304 codestring(ls, &key, varname); /* key is variable name */
305 luaK_indexed(fs, var, &key); /* env[varname] */ 305 luaK_indexed(fs, var, &key); /* env[varname] */
306 } 306 }
307} 307}
308 308
309 309
310static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 310static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
311 FuncState *fs = ls->fs; 311 FuncState *fs = ls->fs;
312 int extra = nvars - nexps; 312 int extra = nvars - nexps;
313 if (hasmultret(e->k)) { 313 if (hasmultret(e->k)) {
314 extra++; /* includes call itself */ 314 extra++; /* includes call itself */
315 if (extra < 0) extra = 0; 315 if (extra < 0) extra = 0;
316 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ 316 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
317 if (extra > 1) luaK_reserveregs(fs, extra-1); 317 if (extra > 1) luaK_reserveregs(fs, extra-1);
318 } 318 }
319 else { 319 else {
320 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ 320 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
321 if (extra > 0) { 321 if (extra > 0) {
322 int reg = fs->freereg; 322 int reg = fs->freereg;
323 luaK_reserveregs(fs, extra); 323 luaK_reserveregs(fs, extra);
324 luaK_nil(fs, reg, extra); 324 luaK_nil(fs, reg, extra);
325 } 325 }
326 } 326 }
327} 327}
328 328
329 329
330static void enterlevel (LexState *ls) { 330static void enterlevel (LexState *ls) {
331 lua_State *L = ls->L; 331 lua_State *L = ls->L;
332 ++L->nCcalls; 332 ++L->nCcalls;
333 checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); 333 checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
334} 334}
335 335
336 336
337#define leavelevel(ls) ((ls)->L->nCcalls--) 337#define leavelevel(ls) ((ls)->L->nCcalls--)
338 338
339 339
340static void closegoto (LexState *ls, int g, Labeldesc *label) { 340static void closegoto (LexState *ls, int g, Labeldesc *label) {
341 int i; 341 int i;
342 FuncState *fs = ls->fs; 342 FuncState *fs = ls->fs;
343 Labellist *gl = &ls->dyd->gt; 343 Labellist *gl = &ls->dyd->gt;
344 Labeldesc *gt = &gl->arr[g]; 344 Labeldesc *gt = &gl->arr[g];
345 lua_assert(eqstr(gt->name, label->name)); 345 lua_assert(eqstr(gt->name, label->name));
346 if (gt->nactvar < label->nactvar) { 346 if (gt->nactvar < label->nactvar) {
347 TString *vname = getlocvar(fs, gt->nactvar)->varname; 347 TString *vname = getlocvar(fs, gt->nactvar)->varname;
348 const char *msg = luaO_pushfstring(ls->L, 348 const char *msg = luaO_pushfstring(ls->L,
349 "<goto %s> at line %d jumps into the scope of local '%s'", 349 "<goto %s> at line %d jumps into the scope of local '%s'",
350 getstr(gt->name), gt->line, getstr(vname)); 350 getstr(gt->name), gt->line, getstr(vname));
351 semerror(ls, msg); 351 semerror(ls, msg);
352 } 352 }
353 luaK_patchlist(fs, gt->pc, label->pc); 353 luaK_patchlist(fs, gt->pc, label->pc);
354 /* remove goto from pending list */ 354 /* remove goto from pending list */
355 for (i = g; i < gl->n - 1; i++) 355 for (i = g; i < gl->n - 1; i++)
356 gl->arr[i] = gl->arr[i + 1]; 356 gl->arr[i] = gl->arr[i + 1];
357 gl->n--; 357 gl->n--;
358} 358}
359 359
360 360
361/* 361/*
362** try to close a goto with existing labels; this solves backward jumps 362** try to close a goto with existing labels; this solves backward jumps
363*/ 363*/
364static int findlabel (LexState *ls, int g) { 364static int findlabel (LexState *ls, int g) {
365 int i; 365 int i;
366 BlockCnt *bl = ls->fs->bl; 366 BlockCnt *bl = ls->fs->bl;
367 Dyndata *dyd = ls->dyd; 367 Dyndata *dyd = ls->dyd;
368 Labeldesc *gt = &dyd->gt.arr[g]; 368 Labeldesc *gt = &dyd->gt.arr[g];
369 /* check labels in current block for a match */ 369 /* check labels in current block for a match */
370 for (i = bl->firstlabel; i < dyd->label.n; i++) { 370 for (i = bl->firstlabel; i < dyd->label.n; i++) {
371 Labeldesc *lb = &dyd->label.arr[i]; 371 Labeldesc *lb = &dyd->label.arr[i];
372 if (eqstr(lb->name, gt->name)) { /* correct label? */ 372 if (eqstr(lb->name, gt->name)) { /* correct label? */
373 if (gt->nactvar > lb->nactvar && 373 if (gt->nactvar > lb->nactvar &&
374 (bl->upval || dyd->label.n > bl->firstlabel)) 374 (bl->upval || dyd->label.n > bl->firstlabel))
375 luaK_patchclose(ls->fs, gt->pc, lb->nactvar); 375 luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
376 closegoto(ls, g, lb); /* close it */ 376 closegoto(ls, g, lb); /* close it */
377 return 1; 377 return 1;
378 } 378 }
379 } 379 }
380 return 0; /* label not found; cannot close goto */ 380 return 0; /* label not found; cannot close goto */
381} 381}
382 382
383 383
384static int newlabelentry (LexState *ls, Labellist *l, TString *name, 384static int newlabelentry (LexState *ls, Labellist *l, TString *name,
385 int line, int pc) { 385 int line, int pc) {
386 int n = l->n; 386 int n = l->n;
387 luaM_growvector(ls->L, l->arr, n, l->size, 387 luaM_growvector(ls->L, l->arr, n, l->size,
388 Labeldesc, SHRT_MAX, "labels/gotos"); 388 Labeldesc, SHRT_MAX, "labels/gotos");
389 l->arr[n].name = name; 389 l->arr[n].name = name;
390 l->arr[n].line = line; 390 l->arr[n].line = line;
391 l->arr[n].nactvar = ls->fs->nactvar; 391 l->arr[n].nactvar = ls->fs->nactvar;
392 l->arr[n].pc = pc; 392 l->arr[n].pc = pc;
393 l->n = n + 1; 393 l->n = n + 1;
394 return n; 394 return n;
395} 395}
396 396
397 397
398/* 398/*
399** check whether new label 'lb' matches any pending gotos in current 399** check whether new label 'lb' matches any pending gotos in current
400** block; solves forward jumps 400** block; solves forward jumps
401*/ 401*/
402static void findgotos (LexState *ls, Labeldesc *lb) { 402static void findgotos (LexState *ls, Labeldesc *lb) {
403 Labellist *gl = &ls->dyd->gt; 403 Labellist *gl = &ls->dyd->gt;
404 int i = ls->fs->bl->firstgoto; 404 int i = ls->fs->bl->firstgoto;
405 while (i < gl->n) { 405 while (i < gl->n) {
406 if (eqstr(gl->arr[i].name, lb->name)) 406 if (eqstr(gl->arr[i].name, lb->name))
407 closegoto(ls, i, lb); 407 closegoto(ls, i, lb);
408 else 408 else
409 i++; 409 i++;
410 } 410 }
411} 411}
412 412
413 413
414/* 414/*
415** export pending gotos to outer level, to check them against 415** export pending gotos to outer level, to check them against
416** outer labels; if the block being exited has upvalues, and 416** outer labels; if the block being exited has upvalues, and
417** the goto exits the scope of any variable (which can be the 417** the goto exits the scope of any variable (which can be the
418** upvalue), close those variables being exited. 418** upvalue), close those variables being exited.
419*/ 419*/
420static void movegotosout (FuncState *fs, BlockCnt *bl) { 420static void movegotosout (FuncState *fs, BlockCnt *bl) {
421 int i = bl->firstgoto; 421 int i = bl->firstgoto;
422 Labellist *gl = &fs->ls->dyd->gt; 422 Labellist *gl = &fs->ls->dyd->gt;
423 /* correct pending gotos to current block and try to close it 423 /* correct pending gotos to current block and try to close it
424 with visible labels */ 424 with visible labels */
425 while (i < gl->n) { 425 while (i < gl->n) {
426 Labeldesc *gt = &gl->arr[i]; 426 Labeldesc *gt = &gl->arr[i];
427 if (gt->nactvar > bl->nactvar) { 427 if (gt->nactvar > bl->nactvar) {
428 if (bl->upval) 428 if (bl->upval)
429 luaK_patchclose(fs, gt->pc, bl->nactvar); 429 luaK_patchclose(fs, gt->pc, bl->nactvar);
430 gt->nactvar = bl->nactvar; 430 gt->nactvar = bl->nactvar;
431 } 431 }
432 if (!findlabel(fs->ls, i)) 432 if (!findlabel(fs->ls, i))
433 i++; /* move to next one */ 433 i++; /* move to next one */
434 } 434 }
435} 435}
436 436
437 437
438static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { 438static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
439 bl->isloop = isloop; 439 bl->isloop = isloop;
440 bl->nactvar = fs->nactvar; 440 bl->nactvar = fs->nactvar;
441 bl->firstlabel = fs->ls->dyd->label.n; 441 bl->firstlabel = fs->ls->dyd->label.n;
442 bl->firstgoto = fs->ls->dyd->gt.n; 442 bl->firstgoto = fs->ls->dyd->gt.n;
443 bl->upval = 0; 443 bl->upval = 0;
444 bl->previous = fs->bl; 444 bl->previous = fs->bl;
445 fs->bl = bl; 445 fs->bl = bl;
446 lua_assert(fs->freereg == fs->nactvar); 446 lua_assert(fs->freereg == fs->nactvar);
447} 447}
448 448
449 449
450/* 450/*
451** create a label named 'break' to resolve break statements 451** create a label named 'break' to resolve break statements
452*/ 452*/
453static void breaklabel (LexState *ls) { 453static void breaklabel (LexState *ls) {
454 TString *n = luaS_new(ls->L, "break"); 454 TString *n = luaS_new(ls->L, "break");
455 int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); 455 int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
456 findgotos(ls, &ls->dyd->label.arr[l]); 456 findgotos(ls, &ls->dyd->label.arr[l]);
457} 457}
458 458
459/* 459/*
460** generates an error for an undefined 'goto'; choose appropriate 460** generates an error for an undefined 'goto'; choose appropriate
461** message when label name is a reserved word (which can only be 'break') 461** message when label name is a reserved word (which can only be 'break')
462*/ 462*/
463static l_noret undefgoto (LexState *ls, Labeldesc *gt) { 463static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
464 const char *msg = isreserved(gt->name) 464 const char *msg = isreserved(gt->name)
465 ? "<%s> at line %d not inside a loop" 465 ? "<%s> at line %d not inside a loop"
466 : "no visible label '%s' for <goto> at line %d"; 466 : "no visible label '%s' for <goto> at line %d";
467 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); 467 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
468 semerror(ls, msg); 468 semerror(ls, msg);
469} 469}
470 470
471 471
472static void leaveblock (FuncState *fs) { 472static void leaveblock (FuncState *fs) {
473 BlockCnt *bl = fs->bl; 473 BlockCnt *bl = fs->bl;
474 LexState *ls = fs->ls; 474 LexState *ls = fs->ls;
475 if (bl->previous && bl->upval) { 475 if (bl->previous && bl->upval) {
476 /* create a 'jump to here' to close upvalues */ 476 /* create a 'jump to here' to close upvalues */
477 int j = luaK_jump(fs); 477 int j = luaK_jump(fs);
478 luaK_patchclose(fs, j, bl->nactvar); 478 luaK_patchclose(fs, j, bl->nactvar);
479 luaK_patchtohere(fs, j); 479 luaK_patchtohere(fs, j);
480 } 480 }
481 if (bl->isloop) 481 if (bl->isloop)
482 breaklabel(ls); /* close pending breaks */ 482 breaklabel(ls); /* close pending breaks */
483 fs->bl = bl->previous; 483 fs->bl = bl->previous;
484 removevars(fs, bl->nactvar); 484 removevars(fs, bl->nactvar);
485 lua_assert(bl->nactvar == fs->nactvar); 485 lua_assert(bl->nactvar == fs->nactvar);
486 fs->freereg = fs->nactvar; /* free registers */ 486 fs->freereg = fs->nactvar; /* free registers */
487 ls->dyd->label.n = bl->firstlabel; /* remove local labels */ 487 ls->dyd->label.n = bl->firstlabel; /* remove local labels */
488 if (bl->previous) /* inner block? */ 488 if (bl->previous) /* inner block? */
489 movegotosout(fs, bl); /* update pending gotos to outer block */ 489 movegotosout(fs, bl); /* update pending gotos to outer block */
490 else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ 490 else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
491 undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ 491 undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
492} 492}
493 493
494 494
495/* 495/*
496** adds a new prototype into list of prototypes 496** adds a new prototype into list of prototypes
497*/ 497*/
498static Proto *addprototype (LexState *ls) { 498static Proto *addprototype (LexState *ls) {
499 Proto *clp; 499 Proto *clp;
500 lua_State *L = ls->L; 500 lua_State *L = ls->L;
501 FuncState *fs = ls->fs; 501 FuncState *fs = ls->fs;
502 Proto *f = fs->f; /* prototype of current function */ 502 Proto *f = fs->f; /* prototype of current function */
503 if (fs->np >= f->sizep) { 503 if (fs->np >= f->sizep) {
504 int oldsize = f->sizep; 504 int oldsize = f->sizep;
505 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); 505 luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
506 while (oldsize < f->sizep) f->p[oldsize++] = NULL; 506 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
507 } 507 }
508 f->p[fs->np++] = clp = luaF_newproto(L); 508 f->p[fs->np++] = clp = luaF_newproto(L);
509 luaC_objbarrier(L, f, clp); 509 luaC_objbarrier(L, f, clp);
510 return clp; 510 return clp;
511} 511}
512 512
513 513
514/* 514/*
515** codes instruction to create new closure in parent function. 515** codes instruction to create new closure in parent function.
516** The OP_CLOSURE instruction must use the last available register, 516** The OP_CLOSURE instruction must use the last available register,
517** so that, if it invokes the GC, the GC knows which registers 517** so that, if it invokes the GC, the GC knows which registers
518** are in use at that time. 518** are in use at that time.
519*/ 519*/
520static void codeclosure (LexState *ls, expdesc *v) { 520static void codeclosure (LexState *ls, expdesc *v) {
521 FuncState *fs = ls->fs->prev; 521 FuncState *fs = ls->fs->prev;
522 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); 522 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
523 luaK_exp2nextreg(fs, v); /* fix it at the last register */ 523 luaK_exp2nextreg(fs, v); /* fix it at the last register */
524} 524}
525 525
526 526
527static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { 527static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
528 Proto *f; 528 Proto *f;
529 fs->prev = ls->fs; /* linked list of funcstates */ 529 fs->prev = ls->fs; /* linked list of funcstates */
530 fs->ls = ls; 530 fs->ls = ls;
531 ls->fs = fs; 531 ls->fs = fs;
532 fs->pc = 0; 532 fs->pc = 0;
533 fs->lasttarget = 0; 533 fs->lasttarget = 0;
534 fs->jpc = NO_JUMP; 534 fs->jpc = NO_JUMP;
535 fs->freereg = 0; 535 fs->freereg = 0;
536 fs->nk = 0; 536 fs->nk = 0;
537 fs->np = 0; 537 fs->np = 0;
538 fs->nups = 0; 538 fs->nups = 0;
539 fs->nlocvars = 0; 539 fs->nlocvars = 0;
540 fs->nactvar = 0; 540 fs->nactvar = 0;
541 fs->firstlocal = ls->dyd->actvar.n; 541 fs->firstlocal = ls->dyd->actvar.n;
542 fs->bl = NULL; 542 fs->bl = NULL;
543 f = fs->f; 543 f = fs->f;
544 f->source = ls->source; 544 f->source = ls->source;
545 f->maxstacksize = 2; /* registers 0/1 are always valid */ 545 f->maxstacksize = 2; /* registers 0/1 are always valid */
546 enterblock(fs, bl, 0); 546 enterblock(fs, bl, 0);
547} 547}
548 548
549 549
550static void close_func (LexState *ls) { 550static void close_func (LexState *ls) {
551 lua_State *L = ls->L; 551 lua_State *L = ls->L;
552 FuncState *fs = ls->fs; 552 FuncState *fs = ls->fs;
553 Proto *f = fs->f; 553 Proto *f = fs->f;
554 luaK_ret(fs, 0, 0); /* final return */ 554 luaK_ret(fs, 0, 0); /* final return */
555 leaveblock(fs); 555 leaveblock(fs);
556 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 556 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
557 f->sizecode = fs->pc; 557 f->sizecode = fs->pc;
558 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); 558 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
559 f->sizelineinfo = fs->pc; 559 f->sizelineinfo = fs->pc;
560 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); 560 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
561 f->sizek = fs->nk; 561 f->sizek = fs->nk;
562 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); 562 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
563 f->sizep = fs->np; 563 f->sizep = fs->np;
564 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); 564 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
565 f->sizelocvars = fs->nlocvars; 565 f->sizelocvars = fs->nlocvars;
566 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); 566 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
567 f->sizeupvalues = fs->nups; 567 f->sizeupvalues = fs->nups;
568 lua_assert(fs->bl == NULL); 568 lua_assert(fs->bl == NULL);
569 ls->fs = fs->prev; 569 ls->fs = fs->prev;
570 luaC_checkGC(L); 570 luaC_checkGC(L);
571} 571}
572 572
573 573
574 574
575/*============================================================*/ 575/*============================================================*/
576/* GRAMMAR RULES */ 576/* GRAMMAR RULES */
577/*============================================================*/ 577/*============================================================*/
578 578
579 579
580/* 580/*
581** check whether current token is in the follow set of a block. 581** check whether current token is in the follow set of a block.
582** 'until' closes syntactical blocks, but do not close scope, 582** 'until' closes syntactical blocks, but do not close scope,
583** so it is handled in separate. 583** so it is handled in separate.
584*/ 584*/
585static int block_follow (LexState *ls, int withuntil) { 585static int block_follow (LexState *ls, int withuntil) {
586 switch (ls->t.token) { 586 switch (ls->t.token) {
587 case TK_ELSE: case TK_ELSEIF: 587 case TK_ELSE: case TK_ELSEIF:
588 case TK_END: case TK_EOS: 588 case TK_END: case TK_EOS:
589 return 1; 589 return 1;
590 case TK_UNTIL: return withuntil; 590 case TK_UNTIL: return withuntil;
591 default: return 0; 591 default: return 0;
592 } 592 }
593} 593}
594 594
595 595
596static void statlist (LexState *ls) { 596static void statlist (LexState *ls) {
597 /* statlist -> { stat [';'] } */ 597 /* statlist -> { stat [';'] } */
598 while (!block_follow(ls, 1)) { 598 while (!block_follow(ls, 1)) {
599 if (ls->t.token == TK_RETURN) { 599 if (ls->t.token == TK_RETURN) {
600 statement(ls); 600 statement(ls);
601 return; /* 'return' must be last statement */ 601 return; /* 'return' must be last statement */
602 } 602 }
603 statement(ls); 603 statement(ls);
604 } 604 }
605} 605}
606 606
607 607
608static void fieldsel (LexState *ls, expdesc *v) { 608static void fieldsel (LexState *ls, expdesc *v) {
609 /* fieldsel -> ['.' | ':'] NAME */ 609 /* fieldsel -> ['.' | ':'] NAME */
610 FuncState *fs = ls->fs; 610 FuncState *fs = ls->fs;
611 expdesc key; 611 expdesc key;
612 luaK_exp2anyregup(fs, v); 612 luaK_exp2anyregup(fs, v);
613 luaX_next(ls); /* skip the dot or colon */ 613 luaX_next(ls); /* skip the dot or colon */
614 checkname(ls, &key); 614 checkname(ls, &key);
615 luaK_indexed(fs, v, &key); 615 luaK_indexed(fs, v, &key);
616} 616}
617 617
618 618
619static void yindex (LexState *ls, expdesc *v) { 619static void yindex (LexState *ls, expdesc *v) {
620 /* index -> '[' expr ']' */ 620 /* index -> '[' expr ']' */
621 luaX_next(ls); /* skip the '[' */ 621 luaX_next(ls); /* skip the '[' */
622 expr(ls, v); 622 expr(ls, v);
623 luaK_exp2val(ls->fs, v); 623 luaK_exp2val(ls->fs, v);
624 checknext(ls, ']'); 624 checknext(ls, ']');
625} 625}
626 626
627 627
628/* 628/*
629** {====================================================================== 629** {======================================================================
630** Rules for Constructors 630** Rules for Constructors
631** ======================================================================= 631** =======================================================================
632*/ 632*/
633 633
634 634
635struct ConsControl { 635struct ConsControl {
636 expdesc v; /* last list item read */ 636 expdesc v; /* last list item read */
637 expdesc *t; /* table descriptor */ 637 expdesc *t; /* table descriptor */
638 int nh; /* total number of 'record' elements */ 638 int nh; /* total number of 'record' elements */
639 int na; /* total number of array elements */ 639 int na; /* total number of array elements */
640 int tostore; /* number of array elements pending to be stored */ 640 int tostore; /* number of array elements pending to be stored */
641}; 641};
642 642
643 643
644static void recfield (LexState *ls, struct ConsControl *cc) { 644static void recfield (LexState *ls, struct ConsControl *cc) {
645 /* recfield -> (NAME | '['exp1']') = exp1 */ 645 /* recfield -> (NAME | '['exp1']') = exp1 */
646 FuncState *fs = ls->fs; 646 FuncState *fs = ls->fs;
647 int reg = ls->fs->freereg; 647 int reg = ls->fs->freereg;
648 expdesc key, val; 648 expdesc key, val;
649 int rkkey; 649 int rkkey;
650 if (ls->t.token == TK_NAME) { 650 if (ls->t.token == TK_NAME) {
651 checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); 651 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
652 checkname(ls, &key); 652 checkname(ls, &key);
653 } 653 }
654 else /* ls->t.token == '[' */ 654 else /* ls->t.token == '[' */
655 yindex(ls, &key); 655 yindex(ls, &key);
656 cc->nh++; 656 cc->nh++;
657 checknext(ls, '='); 657 checknext(ls, '=');
658 rkkey = luaK_exp2RK(fs, &key); 658 rkkey = luaK_exp2RK(fs, &key);
659 expr(ls, &val); 659 expr(ls, &val);
660 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); 660 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
661 fs->freereg = reg; /* free registers */ 661 fs->freereg = reg; /* free registers */
662} 662}
663 663
664 664
665static void closelistfield (FuncState *fs, struct ConsControl *cc) { 665static void closelistfield (FuncState *fs, struct ConsControl *cc) {
666 if (cc->v.k == VVOID) return; /* there is no list item */ 666 if (cc->v.k == VVOID) return; /* there is no list item */
667 luaK_exp2nextreg(fs, &cc->v); 667 luaK_exp2nextreg(fs, &cc->v);
668 cc->v.k = VVOID; 668 cc->v.k = VVOID;
669 if (cc->tostore == LFIELDS_PER_FLUSH) { 669 if (cc->tostore == LFIELDS_PER_FLUSH) {
670 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ 670 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
671 cc->tostore = 0; /* no more items pending */ 671 cc->tostore = 0; /* no more items pending */
672 } 672 }
673} 673}
674 674
675 675
676static void lastlistfield (FuncState *fs, struct ConsControl *cc) { 676static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
677 if (cc->tostore == 0) return; 677 if (cc->tostore == 0) return;
678 if (hasmultret(cc->v.k)) { 678 if (hasmultret(cc->v.k)) {
679 luaK_setmultret(fs, &cc->v); 679 luaK_setmultret(fs, &cc->v);
680 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); 680 luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
681 cc->na--; /* do not count last expression (unknown number of elements) */ 681 cc->na--; /* do not count last expression (unknown number of elements) */
682 } 682 }
683 else { 683 else {
684 if (cc->v.k != VVOID) 684 if (cc->v.k != VVOID)
685 luaK_exp2nextreg(fs, &cc->v); 685 luaK_exp2nextreg(fs, &cc->v);
686 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); 686 luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
687 } 687 }
688} 688}
689 689
690 690
691static void listfield (LexState *ls, struct ConsControl *cc) { 691static void listfield (LexState *ls, struct ConsControl *cc) {
692 /* listfield -> exp */ 692 /* listfield -> exp */
693 expr(ls, &cc->v); 693 expr(ls, &cc->v);
694 checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); 694 checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
695 cc->na++; 695 cc->na++;
696 cc->tostore++; 696 cc->tostore++;
697} 697}
698 698
699 699
700static void field (LexState *ls, struct ConsControl *cc) { 700static void field (LexState *ls, struct ConsControl *cc) {
701 /* field -> listfield | recfield */ 701 /* field -> listfield | recfield */
702 switch(ls->t.token) { 702 switch(ls->t.token) {
703 case TK_NAME: { /* may be 'listfield' or 'recfield' */ 703 case TK_NAME: { /* may be 'listfield' or 'recfield' */
704 if (luaX_lookahead(ls) != '=') /* expression? */ 704 if (luaX_lookahead(ls) != '=') /* expression? */
705 listfield(ls, cc); 705 listfield(ls, cc);
706 else 706 else
707 recfield(ls, cc); 707 recfield(ls, cc);
708 break; 708 break;
709 } 709 }
710 case '[': { 710 case '[': {
711 recfield(ls, cc); 711 recfield(ls, cc);
712 break; 712 break;
713 } 713 }
714 default: { 714 default: {
715 listfield(ls, cc); 715 listfield(ls, cc);
716 break; 716 break;
717 } 717 }
718 } 718 }
719} 719}
720 720
721 721
722static void constructor (LexState *ls, expdesc *t) { 722static void constructor (LexState *ls, expdesc *t) {
723 /* constructor -> '{' [ field { sep field } [sep] ] '}' 723 /* constructor -> '{' [ field { sep field } [sep] ] '}'
724 sep -> ',' | ';' */ 724 sep -> ',' | ';' */
725 FuncState *fs = ls->fs; 725 FuncState *fs = ls->fs;
726 int line = ls->linenumber; 726 int line = ls->linenumber;
727 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); 727 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
728 struct ConsControl cc; 728 struct ConsControl cc;
729 cc.na = cc.nh = cc.tostore = 0; 729 cc.na = cc.nh = cc.tostore = 0;
730 cc.t = t; 730 cc.t = t;
731 init_exp(t, VRELOCABLE, pc); 731 init_exp(t, VRELOCABLE, pc);
732 init_exp(&cc.v, VVOID, 0); /* no value (yet) */ 732 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
733 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ 733 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */
734 checknext(ls, '{'); 734 checknext(ls, '{');
735 do { 735 do {
736 lua_assert(cc.v.k == VVOID || cc.tostore > 0); 736 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
737 if (ls->t.token == '}') break; 737 if (ls->t.token == '}') break;
738 closelistfield(fs, &cc); 738 closelistfield(fs, &cc);
739 field(ls, &cc); 739 field(ls, &cc);
740 } while (testnext(ls, ',') || testnext(ls, ';')); 740 } while (testnext(ls, ',') || testnext(ls, ';'));
741 check_match(ls, '}', '{', line); 741 check_match(ls, '}', '{', line);
742 lastlistfield(fs, &cc); 742 lastlistfield(fs, &cc);
743 SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ 743 SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
744 SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ 744 SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
745} 745}
746 746
747/* }====================================================================== */ 747/* }====================================================================== */
748 748
749 749
750 750
751static void parlist (LexState *ls) { 751static void parlist (LexState *ls) {
752 /* parlist -> [ param { ',' param } ] */ 752 /* parlist -> [ param { ',' param } ] */
753 FuncState *fs = ls->fs; 753 FuncState *fs = ls->fs;
754 Proto *f = fs->f; 754 Proto *f = fs->f;
755 int nparams = 0; 755 int nparams = 0;
756 f->is_vararg = 0; 756 f->is_vararg = 0;
757 if (ls->t.token != ')') { /* is 'parlist' not empty? */ 757 if (ls->t.token != ')') { /* is 'parlist' not empty? */
758 do { 758 do {
759 switch (ls->t.token) { 759 switch (ls->t.token) {
760 case TK_NAME: { /* param -> NAME */ 760 case TK_NAME: { /* param -> NAME */
761 new_localvar(ls, str_checkname(ls)); 761 new_localvar(ls, str_checkname(ls));
762 nparams++; 762 nparams++;
763 break; 763 break;
764 } 764 }
765 case TK_DOTS: { /* param -> '...' */ 765 case TK_DOTS: { /* param -> '...' */
766 luaX_next(ls); 766 luaX_next(ls);
767 f->is_vararg = 2; /* declared vararg */ 767 f->is_vararg = 2; /* declared vararg */
768 break; 768 break;
769 } 769 }
770 default: luaX_syntaxerror(ls, "<name> or '...' expected"); 770 default: luaX_syntaxerror(ls, "<name> or '...' expected");
771 } 771 }
772 } while (!f->is_vararg && testnext(ls, ',')); 772 } while (!f->is_vararg && testnext(ls, ','));
773 } 773 }
774 adjustlocalvars(ls, nparams); 774 adjustlocalvars(ls, nparams);
775 f->numparams = cast_byte(fs->nactvar); 775 f->numparams = cast_byte(fs->nactvar);
776 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ 776 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
777} 777}
778 778
779 779
780static void body (LexState *ls, expdesc *e, int ismethod, int line) { 780static void body (LexState *ls, expdesc *e, int ismethod, int line) {
781 /* body -> '(' parlist ')' block END */ 781 /* body -> '(' parlist ')' block END */
782 FuncState new_fs; 782 FuncState new_fs;
783 BlockCnt bl; 783 BlockCnt bl;
784 new_fs.f = addprototype(ls); 784 new_fs.f = addprototype(ls);
785 new_fs.f->linedefined = line; 785 new_fs.f->linedefined = line;
786 open_func(ls, &new_fs, &bl); 786 open_func(ls, &new_fs, &bl);
787 checknext(ls, '('); 787 checknext(ls, '(');
788 if (ismethod) { 788 if (ismethod) {
789 new_localvarliteral(ls, "self"); /* create 'self' parameter */ 789 new_localvarliteral(ls, "self"); /* create 'self' parameter */
790 adjustlocalvars(ls, 1); 790 adjustlocalvars(ls, 1);
791 } 791 }
792 parlist(ls); 792 parlist(ls);
793 checknext(ls, ')'); 793 checknext(ls, ')');
794 statlist(ls); 794 statlist(ls);
795 new_fs.f->lastlinedefined = ls->linenumber; 795 new_fs.f->lastlinedefined = ls->linenumber;
796 check_match(ls, TK_END, TK_FUNCTION, line); 796 check_match(ls, TK_END, TK_FUNCTION, line);
797 codeclosure(ls, e); 797 codeclosure(ls, e);
798 close_func(ls); 798 close_func(ls);
799} 799}
800 800
801 801
802static int explist (LexState *ls, expdesc *v) { 802static int explist (LexState *ls, expdesc *v) {
803 /* explist -> expr { ',' expr } */ 803 /* explist -> expr { ',' expr } */
804 int n = 1; /* at least one expression */ 804 int n = 1; /* at least one expression */
805 expr(ls, v); 805 expr(ls, v);
806 while (testnext(ls, ',')) { 806 while (testnext(ls, ',')) {
807 luaK_exp2nextreg(ls->fs, v); 807 luaK_exp2nextreg(ls->fs, v);
808 expr(ls, v); 808 expr(ls, v);
809 n++; 809 n++;
810 } 810 }
811 return n; 811 return n;
812} 812}
813 813
814 814
815static void funcargs (LexState *ls, expdesc *f, int line) { 815static void funcargs (LexState *ls, expdesc *f, int line) {
816 FuncState *fs = ls->fs; 816 FuncState *fs = ls->fs;
817 expdesc args; 817 expdesc args;
818 int base, nparams; 818 int base, nparams;
819 switch (ls->t.token) { 819 switch (ls->t.token) {
820 case '(': { /* funcargs -> '(' [ explist ] ')' */ 820 case '(': { /* funcargs -> '(' [ explist ] ')' */
821 luaX_next(ls); 821 luaX_next(ls);
822 if (ls->t.token == ')') /* arg list is empty? */ 822 if (ls->t.token == ')') /* arg list is empty? */
823 args.k = VVOID; 823 args.k = VVOID;
824 else { 824 else {
825 explist(ls, &args); 825 explist(ls, &args);
826 luaK_setmultret(fs, &args); 826 luaK_setmultret(fs, &args);
827 } 827 }
828 check_match(ls, ')', '(', line); 828 check_match(ls, ')', '(', line);
829 break; 829 break;
830 } 830 }
831 case '{': { /* funcargs -> constructor */ 831 case '{': { /* funcargs -> constructor */
832 constructor(ls, &args); 832 constructor(ls, &args);
833 break; 833 break;
834 } 834 }
835 case TK_STRING: { /* funcargs -> STRING */ 835 case TK_STRING: { /* funcargs -> STRING */
836 codestring(ls, &args, ls->t.seminfo.ts); 836 codestring(ls, &args, ls->t.seminfo.ts);
837 luaX_next(ls); /* must use 'seminfo' before 'next' */ 837 luaX_next(ls); /* must use 'seminfo' before 'next' */
838 break; 838 break;
839 } 839 }
840 default: { 840 default: {
841 luaX_syntaxerror(ls, "function arguments expected"); 841 luaX_syntaxerror(ls, "function arguments expected");
842 } 842 }
843 } 843 }
844 lua_assert(f->k == VNONRELOC); 844 lua_assert(f->k == VNONRELOC);
845 base = f->u.info; /* base register for call */ 845 base = f->u.info; /* base register for call */
846 if (hasmultret(args.k)) 846 if (hasmultret(args.k))
847 nparams = LUA_MULTRET; /* open call */ 847 nparams = LUA_MULTRET; /* open call */
848 else { 848 else {
849 if (args.k != VVOID) 849 if (args.k != VVOID)
850 luaK_exp2nextreg(fs, &args); /* close last argument */ 850 luaK_exp2nextreg(fs, &args); /* close last argument */
851 nparams = fs->freereg - (base+1); 851 nparams = fs->freereg - (base+1);
852 } 852 }
853 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); 853 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
854 luaK_fixline(fs, line); 854 luaK_fixline(fs, line);
855 fs->freereg = base+1; /* call remove function and arguments and leaves 855 fs->freereg = base+1; /* call remove function and arguments and leaves
856 (unless changed) one result */ 856 (unless changed) one result */
857} 857}
858 858
859 859
860 860
861 861
862/* 862/*
863** {====================================================================== 863** {======================================================================
864** Expression parsing 864** Expression parsing
865** ======================================================================= 865** =======================================================================
866*/ 866*/
867 867
868 868
869static void primaryexp (LexState *ls, expdesc *v) { 869static void primaryexp (LexState *ls, expdesc *v) {
870 /* primaryexp -> NAME | '(' expr ')' */ 870 /* primaryexp -> NAME | '(' expr ')' */
871 switch (ls->t.token) { 871 switch (ls->t.token) {
872 case '(': { 872 case '(': {
873 int line = ls->linenumber; 873 int line = ls->linenumber;
874 luaX_next(ls); 874 luaX_next(ls);
875 expr(ls, v); 875 expr(ls, v);
876 check_match(ls, ')', '(', line); 876 check_match(ls, ')', '(', line);
877 luaK_dischargevars(ls->fs, v); 877 luaK_dischargevars(ls->fs, v);
878 return; 878 return;
879 } 879 }
880 case TK_NAME: { 880 case TK_NAME: {
881 singlevar(ls, v); 881 singlevar(ls, v);
882 return; 882 return;
883 } 883 }
884 default: { 884 default: {
885 luaX_syntaxerror(ls, "unexpected symbol"); 885 luaX_syntaxerror(ls, "unexpected symbol");
886 } 886 }
887 } 887 }
888} 888}
889 889
890 890
891static void suffixedexp (LexState *ls, expdesc *v) { 891static void suffixedexp (LexState *ls, expdesc *v) {
892 /* suffixedexp -> 892 /* suffixedexp ->
893 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ 893 primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
894 FuncState *fs = ls->fs; 894 FuncState *fs = ls->fs;
895 int line = ls->linenumber; 895 int line = ls->linenumber;
896 primaryexp(ls, v); 896 primaryexp(ls, v);
897 for (;;) { 897 for (;;) {
898 switch (ls->t.token) { 898 switch (ls->t.token) {
899 case '.': { /* fieldsel */ 899 case '.': { /* fieldsel */
900 fieldsel(ls, v); 900 fieldsel(ls, v);
901 break; 901 break;
902 } 902 }
903 case '[': { /* '[' exp1 ']' */ 903 case '[': { /* '[' exp1 ']' */
904 expdesc key; 904 expdesc key;
905 luaK_exp2anyregup(fs, v); 905 luaK_exp2anyregup(fs, v);
906 yindex(ls, &key); 906 yindex(ls, &key);
907 luaK_indexed(fs, v, &key); 907 luaK_indexed(fs, v, &key);
908 break; 908 break;
909 } 909 }
910 case ':': { /* ':' NAME funcargs */ 910 case ':': { /* ':' NAME funcargs */
911 expdesc key; 911 expdesc key;
912 luaX_next(ls); 912 luaX_next(ls);
913 checkname(ls, &key); 913 checkname(ls, &key);
914 luaK_self(fs, v, &key); 914 luaK_self(fs, v, &key);
915 funcargs(ls, v, line); 915 funcargs(ls, v, line);
916 break; 916 break;
917 } 917 }
918 case '(': case TK_STRING: case '{': { /* funcargs */ 918 case '(': case TK_STRING: case '{': { /* funcargs */
919 luaK_exp2nextreg(fs, v); 919 luaK_exp2nextreg(fs, v);
920 funcargs(ls, v, line); 920 funcargs(ls, v, line);
921 break; 921 break;
922 } 922 }
923 default: return; 923 default: return;
924 } 924 }
925 } 925 }
926} 926}
927 927
928 928
929static void simpleexp (LexState *ls, expdesc *v) { 929static void simpleexp (LexState *ls, expdesc *v) {
930 /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | 930 /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
931 constructor | FUNCTION body | suffixedexp */ 931 constructor | FUNCTION body | suffixedexp */
932 switch (ls->t.token) { 932 switch (ls->t.token) {
933#ifndef _KERNEL 933#ifndef _KERNEL
934 case TK_FLT: { 934 case TK_FLT: {
935 init_exp(v, VKFLT, 0); 935 init_exp(v, VKFLT, 0);
936 v->u.nval = ls->t.seminfo.r; 936 v->u.nval = ls->t.seminfo.r;
937 break; 937 break;
938 } 938 }
939#endif /* _KERNEL */ 939#endif /* _KERNEL */
940 case TK_INT: { 940 case TK_INT: {
941 init_exp(v, VKINT, 0); 941 init_exp(v, VKINT, 0);
942 v->u.ival = ls->t.seminfo.i; 942 v->u.ival = ls->t.seminfo.i;
943 break; 943 break;
944 } 944 }
945 case TK_STRING: { 945 case TK_STRING: {
946 codestring(ls, v, ls->t.seminfo.ts); 946 codestring(ls, v, ls->t.seminfo.ts);
947 break; 947 break;
948 } 948 }
949 case TK_NIL: { 949 case TK_NIL: {
950 init_exp(v, VNIL, 0); 950 init_exp(v, VNIL, 0);
951 break; 951 break;
952 } 952 }
953 case TK_TRUE: { 953 case TK_TRUE: {
954 init_exp(v, VTRUE, 0); 954 init_exp(v, VTRUE, 0);
955 break; 955 break;
956 } 956 }
957 case TK_FALSE: { 957 case TK_FALSE: {
958 init_exp(v, VFALSE, 0); 958 init_exp(v, VFALSE, 0);
959 break; 959 break;
960 } 960 }
961 case TK_DOTS: { /* vararg */ 961 case TK_DOTS: { /* vararg */
962 FuncState *fs = ls->fs; 962 FuncState *fs = ls->fs;
963 check_condition(ls, fs->f->is_vararg, 963 check_condition(ls, fs->f->is_vararg,
964 "cannot use '...' outside a vararg function"); 964 "cannot use '...' outside a vararg function");
965 fs->f->is_vararg = 1; /* function actually uses vararg */ 965 fs->f->is_vararg = 1; /* function actually uses vararg */
966 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); 966 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
967 break; 967 break;
968 } 968 }
969 case '{': { /* constructor */ 969 case '{': { /* constructor */
970 constructor(ls, v); 970 constructor(ls, v);
971 return; 971 return;
972 } 972 }
973 case TK_FUNCTION: { 973 case TK_FUNCTION: {
974 luaX_next(ls); 974 luaX_next(ls);
975 body(ls, v, 0, ls->linenumber); 975 body(ls, v, 0, ls->linenumber);
976 return; 976 return;
977 } 977 }
978 default: { 978 default: {
979 suffixedexp(ls, v); 979 suffixedexp(ls, v);
980 return; 980 return;
981 } 981 }
982 } 982 }
983 luaX_next(ls); 983 luaX_next(ls);
984} 984}
985 985
986 986
987static UnOpr getunopr (int op) { 987static UnOpr getunopr (int op) {
988 switch (op) { 988 switch (op) {
989 case TK_NOT: return OPR_NOT; 989 case TK_NOT: return OPR_NOT;
990 case '-': return OPR_MINUS; 990 case '-': return OPR_MINUS;
991 case '~': return OPR_BNOT; 991 case '~': return OPR_BNOT;
992 case '#': return OPR_LEN; 992 case '#': return OPR_LEN;
993 default: return OPR_NOUNOPR; 993 default: return OPR_NOUNOPR;
994 } 994 }
995} 995}
996 996
997 997
998static BinOpr getbinopr (int op) { 998static BinOpr getbinopr (int op) {
999 switch (op) { 999 switch (op) {
1000 case '+': return OPR_ADD; 1000 case '+': return OPR_ADD;
1001 case '-': return OPR_SUB; 1001 case '-': return OPR_SUB;
1002 case '*': return OPR_MUL; 1002 case '*': return OPR_MUL;
1003 case '%': return OPR_MOD; 1003 case '%': return OPR_MOD;
1004#ifndef _KERNEL 1004#ifndef _KERNEL
1005 case '^': return OPR_POW; 1005 case '^': return OPR_POW;
1006 case '/': return OPR_DIV; 1006 case '/': return OPR_DIV;
1007#else /* _KERNEL */ 1007#else /* _KERNEL */
1008 case '/': return OPR_IDIV; 1008 case '/': return OPR_IDIV;
1009#endif /* _KERNEL */ 1009#endif /* _KERNEL */
1010 case TK_IDIV: return OPR_IDIV; 1010 case TK_IDIV: return OPR_IDIV;
1011 case '&': return OPR_BAND; 1011 case '&': return OPR_BAND;
1012 case '|': return OPR_BOR; 1012 case '|': return OPR_BOR;
1013 case '~': return OPR_BXOR; 1013 case '~': return OPR_BXOR;
1014 case TK_SHL: return OPR_SHL; 1014 case TK_SHL: return OPR_SHL;
1015 case TK_SHR: return OPR_SHR; 1015 case TK_SHR: return OPR_SHR;
1016 case TK_CONCAT: return OPR_CONCAT; 1016 case TK_CONCAT: return OPR_CONCAT;
1017 case TK_NE: return OPR_NE; 1017 case TK_NE: return OPR_NE;
1018 case TK_EQ: return OPR_EQ; 1018 case TK_EQ: return OPR_EQ;
1019 case '<': return OPR_LT; 1019 case '<': return OPR_LT;
1020 case TK_LE: return OPR_LE; 1020 case TK_LE: return OPR_LE;
1021 case '>': return OPR_GT; 1021 case '>': return OPR_GT;
1022 case TK_GE: return OPR_GE; 1022 case TK_GE: return OPR_GE;
1023 case TK_AND: return OPR_AND; 1023 case TK_AND: return OPR_AND;
1024 case TK_OR: return OPR_OR; 1024 case TK_OR: return OPR_OR;
1025 default: return OPR_NOBINOPR; 1025 default: return OPR_NOBINOPR;
1026 } 1026 }
1027} 1027}
1028 1028
1029 1029
1030static const struct { 1030static const struct {
1031 lu_byte left; /* left priority for each binary operator */ 1031 lu_byte left; /* left priority for each binary operator */
1032 lu_byte right; /* right priority */ 1032 lu_byte right; /* right priority */
1033} priority[] = { /* ORDER OPR */ 1033} priority[] = { /* ORDER OPR */
1034 {10, 10}, {10, 10}, /* '+' '-' */ 1034 {10, 10}, {10, 10}, /* '+' '-' */
1035 {11, 11}, {11, 11}, /* '*' '%' */ 1035 {11, 11}, {11, 11}, /* '*' '%' */
1036#ifndef _KERNEL 1036#ifndef _KERNEL
1037 {14, 13}, /* '^' (right associative) */ 1037 {14, 13}, /* '^' (right associative) */
1038 {11, 11}, {11, 11}, /* '/' '//' */ 1038 {11, 11}, {11, 11}, /* '/' '//' */
1039#else /* _KERNEL */ 1039#else /* _KERNEL */
1040 {11, 11}, /* '//' */ 1040 {11, 11}, /* '//' */
1041#endif /* _KERNEL */ 1041#endif /* _KERNEL */
1042 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ 1042 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
1043 {7, 7}, {7, 7}, /* '<<' '>>' */ 1043 {7, 7}, {7, 7}, /* '<<' '>>' */
1044 {9, 8}, /* '..' (right associative) */ 1044 {9, 8}, /* '..' (right associative) */
1045 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ 1045 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
1046 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ 1046 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
1047 {2, 2}, {1, 1} /* and, or */ 1047 {2, 2}, {1, 1} /* and, or */
1048}; 1048};
1049 1049
1050#define UNARY_PRIORITY 12 /* priority for unary operators */ 1050#define UNARY_PRIORITY 12 /* priority for unary operators */
1051 1051
1052 1052
1053/* 1053/*
1054** subexpr -> (simpleexp | unop subexpr) { binop subexpr } 1054** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1055** where 'binop' is any binary operator with a priority higher than 'limit' 1055** where 'binop' is any binary operator with a priority higher than 'limit'
1056*/ 1056*/
1057static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { 1057static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1058 BinOpr op; 1058 BinOpr op;
1059 UnOpr uop; 1059 UnOpr uop;
1060 enterlevel(ls); 1060 enterlevel(ls);
1061 uop = getunopr(ls->t.token); 1061 uop = getunopr(ls->t.token);
1062 if (uop != OPR_NOUNOPR) { 1062 if (uop != OPR_NOUNOPR) {
1063 int line = ls->linenumber; 1063 int line = ls->linenumber;
1064 luaX_next(ls); 1064 luaX_next(ls);
1065 subexpr(ls, v, UNARY_PRIORITY); 1065 subexpr(ls, v, UNARY_PRIORITY);
1066 luaK_prefix(ls->fs, uop, v, line); 1066 luaK_prefix(ls->fs, uop, v, line);
1067 } 1067 }
1068 else simpleexp(ls, v); 1068 else simpleexp(ls, v);
1069 /* expand while operators have priorities higher than 'limit' */ 1069 /* expand while operators have priorities higher than 'limit' */
1070 op = getbinopr(ls->t.token); 1070 op = getbinopr(ls->t.token);
1071 while (op != OPR_NOBINOPR && priority[op].left > limit) { 1071 while (op != OPR_NOBINOPR && priority[op].left > limit) {
1072 expdesc v2; 1072 expdesc v2;
1073 BinOpr nextop; 1073 BinOpr nextop;
1074 int line = ls->linenumber; 1074 int line = ls->linenumber;
1075 luaX_next(ls); 1075 luaX_next(ls);
1076 luaK_infix(ls->fs, op, v); 1076 luaK_infix(ls->fs, op, v);
1077 /* read sub-expression with higher priority */ 1077 /* read sub-expression with higher priority */
1078 nextop = subexpr(ls, &v2, priority[op].right); 1078 nextop = subexpr(ls, &v2, priority[op].right);
1079 luaK_posfix(ls->fs, op, v, &v2, line); 1079 luaK_posfix(ls->fs, op, v, &v2, line);
1080 op = nextop; 1080 op = nextop;
1081 } 1081 }
1082 leavelevel(ls); 1082 leavelevel(ls);
1083 return op; /* return first untreated operator */ 1083 return op; /* return first untreated operator */
1084} 1084}
1085 1085
1086 1086
1087static void expr (LexState *ls, expdesc *v) { 1087static void expr (LexState *ls, expdesc *v) {
1088 subexpr(ls, v, 0); 1088 subexpr(ls, v, 0);
1089} 1089}
1090 1090
1091/* }==================================================================== */ 1091/* }==================================================================== */
1092 1092
1093 1093
1094 1094
1095/* 1095/*
1096** {====================================================================== 1096** {======================================================================
1097** Rules for Statements 1097** Rules for Statements
1098** ======================================================================= 1098** =======================================================================
1099*/ 1099*/
1100 1100
1101 1101
1102static void block (LexState *ls) { 1102static void block (LexState *ls) {
1103 /* block -> statlist */ 1103 /* block -> statlist */
1104 FuncState *fs = ls->fs; 1104 FuncState *fs = ls->fs;
1105 BlockCnt bl; 1105 BlockCnt bl;
1106 enterblock(fs, &bl, 0); 1106 enterblock(fs, &bl, 0);
1107 statlist(ls); 1107 statlist(ls);
1108 leaveblock(fs); 1108 leaveblock(fs);
1109} 1109}
1110 1110
1111 1111
1112/* 1112/*
1113** structure to chain all variables in the left-hand side of an 1113** structure to chain all variables in the left-hand side of an
1114** assignment 1114** assignment
1115*/ 1115*/
1116struct LHS_assign { 1116struct LHS_assign {
1117 struct LHS_assign *prev; 1117 struct LHS_assign *prev;
1118 expdesc v; /* variable (global, local, upvalue, or indexed) */ 1118 expdesc v; /* variable (global, local, upvalue, or indexed) */
1119}; 1119};
1120 1120
1121 1121
1122/* 1122/*
1123** check whether, in an assignment to an upvalue/local variable, the 1123** check whether, in an assignment to an upvalue/local variable, the
1124** upvalue/local variable is begin used in a previous assignment to a 1124** upvalue/local variable is begin used in a previous assignment to a
1125** table. If so, save original upvalue/local value in a safe place and 1125** table. If so, save original upvalue/local value in a safe place and
1126** use this safe copy in the previous assignment. 1126** use this safe copy in the previous assignment.
1127*/ 1127*/
1128static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { 1128static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1129 FuncState *fs = ls->fs; 1129 FuncState *fs = ls->fs;
1130 int extra = fs->freereg; /* eventual position to save local variable */ 1130 int extra = fs->freereg; /* eventual position to save local variable */
1131 int conflict = 0; 1131 int conflict = 0;
1132 for (; lh; lh = lh->prev) { /* check all previous assignments */ 1132 for (; lh; lh = lh->prev) { /* check all previous assignments */
1133 if (lh->v.k == VINDEXED) { /* assigning to a table? */ 1133 if (lh->v.k == VINDEXED) { /* assigning to a table? */
1134 /* table is the upvalue/local being assigned now? */ 1134 /* table is the upvalue/local being assigned now? */
1135 if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { 1135 if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
1136 conflict = 1; 1136 conflict = 1;
1137 lh->v.u.ind.vt = VLOCAL; 1137 lh->v.u.ind.vt = VLOCAL;
1138 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ 1138 lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
1139 } 1139 }
1140 /* index is the local being assigned? (index cannot be upvalue) */ 1140 /* index is the local being assigned? (index cannot be upvalue) */
1141 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { 1141 if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
1142 conflict = 1; 1142 conflict = 1;
1143 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 1143 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
1144 } 1144 }
1145 } 1145 }
1146 } 1146 }
1147 if (conflict) { 1147 if (conflict) {
1148 /* copy upvalue/local value to a temporary (in position 'extra') */ 1148 /* copy upvalue/local value to a temporary (in position 'extra') */
1149 OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; 1149 OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
1150 luaK_codeABC(fs, op, extra, v->u.info, 0); 1150 luaK_codeABC(fs, op, extra, v->u.info, 0);
1151 luaK_reserveregs(fs, 1); 1151 luaK_reserveregs(fs, 1);
1152 } 1152 }
1153} 1153}
1154 1154
1155 1155
1156static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 1156static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
1157 expdesc e; 1157 expdesc e;
1158 check_condition(ls, vkisvar(lh->v.k), "syntax error"); 1158 check_condition(ls, vkisvar(lh->v.k), "syntax error");
1159 if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ 1159 if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */
1160 struct LHS_assign nv; 1160 struct LHS_assign nv;
1161 nv.prev = lh; 1161 nv.prev = lh;
1162 suffixedexp(ls, &nv.v); 1162 suffixedexp(ls, &nv.v);
1163 if (nv.v.k != VINDEXED) 1163 if (nv.v.k != VINDEXED)
1164 check_conflict(ls, lh, &nv.v); 1164 check_conflict(ls, lh, &nv.v);
1165 checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, 1165 checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
1166 "C levels"); 1166 "C levels");
1167 assignment(ls, &nv, nvars+1); 1167 assignment(ls, &nv, nvars+1);
1168 } 1168 }
1169 else { /* assignment -> '=' explist */ 1169 else { /* assignment -> '=' explist */
1170 int nexps; 1170 int nexps;
1171 checknext(ls, '='); 1171 checknext(ls, '=');
1172 nexps = explist(ls, &e); 1172 nexps = explist(ls, &e);
1173 if (nexps != nvars) { 1173 if (nexps != nvars) {
1174 adjust_assign(ls, nvars, nexps, &e); 1174 adjust_assign(ls, nvars, nexps, &e);
1175 if (nexps > nvars) 1175 if (nexps > nvars)
1176 ls->fs->freereg -= nexps - nvars; /* remove extra values */ 1176 ls->fs->freereg -= nexps - nvars; /* remove extra values */
1177 } 1177 }
1178 else { 1178 else {
1179 luaK_setoneret(ls->fs, &e); /* close last expression */ 1179 luaK_setoneret(ls->fs, &e); /* close last expression */
1180 luaK_storevar(ls->fs, &lh->v, &e); 1180 luaK_storevar(ls->fs, &lh->v, &e);
1181 return; /* avoid default */ 1181 return; /* avoid default */
1182 } 1182 }
1183 } 1183 }
1184 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ 1184 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
1185 luaK_storevar(ls->fs, &lh->v, &e); 1185 luaK_storevar(ls->fs, &lh->v, &e);
1186} 1186}
1187 1187
1188 1188
1189static int cond (LexState *ls) { 1189static int cond (LexState *ls) {
1190 /* cond -> exp */ 1190 /* cond -> exp */
1191 expdesc v; 1191 expdesc v;
1192 expr(ls, &v); /* read condition */ 1192 expr(ls, &v); /* read condition */
1193 if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ 1193 if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */
1194 luaK_goiftrue(ls->fs, &v); 1194 luaK_goiftrue(ls->fs, &v);
1195 return v.f; 1195 return v.f;
1196} 1196}
1197 1197
1198 1198
1199static void gotostat (LexState *ls, int pc) { 1199static void gotostat (LexState *ls, int pc) {
1200 int line = ls->linenumber; 1200 int line = ls->linenumber;
1201 TString *label; 1201 TString *label;
1202 int g; 1202 int g;
1203 if (testnext(ls, TK_GOTO)) 1203 if (testnext(ls, TK_GOTO))
1204 label = str_checkname(ls); 1204 label = str_checkname(ls);
1205 else { 1205 else {
1206 luaX_next(ls); /* skip break */ 1206 luaX_next(ls); /* skip break */
1207 label = luaS_new(ls->L, "break"); 1207 label = luaS_new(ls->L, "break");
1208 } 1208 }
1209 g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); 1209 g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
1210 findlabel(ls, g); /* close it if label already defined */ 1210 findlabel(ls, g); /* close it if label already defined */
1211} 1211}
1212 1212
1213 1213
1214/* check for repeated labels on the same block */ 1214/* check for repeated labels on the same block */
1215static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { 1215static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1216 int i; 1216 int i;
1217 for (i = fs->bl->firstlabel; i < ll->n; i++) { 1217 for (i = fs->bl->firstlabel; i < ll->n; i++) {
1218 if (eqstr(label, ll->arr[i].name)) { 1218 if (eqstr(label, ll->arr[i].name)) {
1219 const char *msg = luaO_pushfstring(fs->ls->L, 1219 const char *msg = luaO_pushfstring(fs->ls->L,
1220 "label '%s' already defined on line %d", 1220 "label '%s' already defined on line %d",
1221 getstr(label), ll->arr[i].line); 1221 getstr(label), ll->arr[i].line);
1222 semerror(fs->ls, msg); 1222 semerror(fs->ls, msg);
1223 } 1223 }
1224 } 1224 }
1225} 1225}
1226 1226
1227 1227
1228/* skip no-op statements */ 1228/* skip no-op statements */
1229static void skipnoopstat (LexState *ls) { 1229static void skipnoopstat (LexState *ls) {
1230 while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) 1230 while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
1231 statement(ls); 1231 statement(ls);
1232} 1232}
1233 1233
1234 1234
1235static void labelstat (LexState *ls, TString *label, int line) { 1235static void labelstat (LexState *ls, TString *label, int line) {
1236 /* label -> '::' NAME '::' */ 1236 /* label -> '::' NAME '::' */
1237 FuncState *fs = ls->fs; 1237 FuncState *fs = ls->fs;
1238 Labellist *ll = &ls->dyd->label; 1238 Labellist *ll = &ls->dyd->label;
1239 int l; /* index of new label being created */ 1239 int l; /* index of new label being created */
1240 checkrepeated(fs, ll, label); /* check for repeated labels */ 1240 checkrepeated(fs, ll, label); /* check for repeated labels */
1241 checknext(ls, TK_DBCOLON); /* skip double colon */ 1241 checknext(ls, TK_DBCOLON); /* skip double colon */
1242 /* create new entry for this label */ 1242 /* create new entry for this label */
1243 l = newlabelentry(ls, ll, label, line, fs->pc); 1243 l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
1244 skipnoopstat(ls); /* skip other no-op statements */ 1244 skipnoopstat(ls); /* skip other no-op statements */
1245 if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ 1245 if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
1246 /* assume that locals are already out of scope */ 1246 /* assume that locals are already out of scope */
1247 ll->arr[l].nactvar = fs->bl->nactvar; 1247 ll->arr[l].nactvar = fs->bl->nactvar;
1248 } 1248 }
1249 findgotos(ls, &ll->arr[l]); 1249 findgotos(ls, &ll->arr[l]);
1250} 1250}
1251 1251
1252 1252
1253static void whilestat (LexState *ls, int line) { 1253static void whilestat (LexState *ls, int line) {
1254 /* whilestat -> WHILE cond DO block END */ 1254 /* whilestat -> WHILE cond DO block END */
1255 FuncState *fs = ls->fs; 1255 FuncState *fs = ls->fs;
1256 int whileinit; 1256 int whileinit;
1257 int condexit; 1257 int condexit;
1258 BlockCnt bl; 1258 BlockCnt bl;
1259 luaX_next(ls); /* skip WHILE */ 1259 luaX_next(ls); /* skip WHILE */
1260 whileinit = luaK_getlabel(fs); 1260 whileinit = luaK_getlabel(fs);
1261 condexit = cond(ls); 1261 condexit = cond(ls);
1262 enterblock(fs, &bl, 1); 1262 enterblock(fs, &bl, 1);
1263 checknext(ls, TK_DO); 1263 checknext(ls, TK_DO);
1264 block(ls); 1264 block(ls);
1265 luaK_jumpto(fs, whileinit); 1265 luaK_jumpto(fs, whileinit);
1266 check_match(ls, TK_END, TK_WHILE, line); 1266 check_match(ls, TK_END, TK_WHILE, line);
1267 leaveblock(fs); 1267 leaveblock(fs);
1268 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ 1268 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1269} 1269}
1270 1270
1271 1271
1272static void repeatstat (LexState *ls, int line) { 1272static void repeatstat (LexState *ls, int line) {
1273 /* repeatstat -> REPEAT block UNTIL cond */ 1273 /* repeatstat -> REPEAT block UNTIL cond */
1274 int condexit; 1274 int condexit;
1275 FuncState *fs = ls->fs; 1275 FuncState *fs = ls->fs;
1276 int repeat_init = luaK_getlabel(fs); 1276 int repeat_init = luaK_getlabel(fs);
1277 BlockCnt bl1, bl2; 1277 BlockCnt bl1, bl2;
1278 enterblock(fs, &bl1, 1); /* loop block */ 1278 enterblock(fs, &bl1, 1); /* loop block */
1279 enterblock(fs, &bl2, 0); /* scope block */ 1279 enterblock(fs, &bl2, 0); /* scope block */
1280 luaX_next(ls); /* skip REPEAT */ 1280 luaX_next(ls); /* skip REPEAT */
1281 statlist(ls); 1281 statlist(ls);
1282 check_match(ls, TK_UNTIL, TK_REPEAT, line); 1282 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1283 condexit = cond(ls); /* read condition (inside scope block) */ 1283 condexit = cond(ls); /* read condition (inside scope block) */
1284 if (bl2.upval) /* upvalues? */ 1284 if (bl2.upval) /* upvalues? */
1285 luaK_patchclose(fs, condexit, bl2.nactvar); 1285 luaK_patchclose(fs, condexit, bl2.nactvar);
1286 leaveblock(fs); /* finish scope */ 1286 leaveblock(fs); /* finish scope */
1287 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ 1287 luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
1288 leaveblock(fs); /* finish loop */ 1288 leaveblock(fs); /* finish loop */
1289} 1289}
1290 1290
1291 1291
1292static int exp1 (LexState *ls) { 1292static int exp1 (LexState *ls) {
1293 expdesc e; 1293 expdesc e;
1294 int reg; 1294 int reg;
1295 expr(ls, &e); 1295 expr(ls, &e);
1296 luaK_exp2nextreg(ls->fs, &e); 1296 luaK_exp2nextreg(ls->fs, &e);
1297 lua_assert(e.k == VNONRELOC); 1297 lua_assert(e.k == VNONRELOC);
1298 reg = e.u.info; 1298 reg = e.u.info;
1299 return reg; 1299 return reg;
1300} 1300}
1301 1301
1302 1302
1303static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { 1303static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1304 /* forbody -> DO block */ 1304 /* forbody -> DO block */
1305 BlockCnt bl; 1305 BlockCnt bl;
1306 FuncState *fs = ls->fs; 1306 FuncState *fs = ls->fs;
1307 int prep, endfor; 1307 int prep, endfor;
1308 adjustlocalvars(ls, 3); /* control variables */ 1308 adjustlocalvars(ls, 3); /* control variables */
1309 checknext(ls, TK_DO); 1309 checknext(ls, TK_DO);
1310 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); 1310 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1311 enterblock(fs, &bl, 0); /* scope for declared variables */ 1311 enterblock(fs, &bl, 0); /* scope for declared variables */
1312 adjustlocalvars(ls, nvars); 1312 adjustlocalvars(ls, nvars);
1313 luaK_reserveregs(fs, nvars); 1313 luaK_reserveregs(fs, nvars);
1314 block(ls); 1314 block(ls);
1315 leaveblock(fs); /* end of scope for declared variables */ 1315 leaveblock(fs); /* end of scope for declared variables */
1316 luaK_patchtohere(fs, prep); 1316 luaK_patchtohere(fs, prep);
1317 if (isnum) /* numeric for? */ 1317 if (isnum) /* numeric for? */
1318 endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); 1318 endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
1319 else { /* generic for */ 1319 else { /* generic for */
1320 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); 1320 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1321 luaK_fixline(fs, line); 1321 luaK_fixline(fs, line);
1322 endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); 1322 endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
1323 } 1323 }
1324 luaK_patchlist(fs, endfor, prep + 1); 1324 luaK_patchlist(fs, endfor, prep + 1);
1325 luaK_fixline(fs, line); 1325 luaK_fixline(fs, line);
1326} 1326}
1327 1327
1328 1328
1329static void fornum (LexState *ls, TString *varname, int line) { 1329static void fornum (LexState *ls, TString *varname, int line) {
1330 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 1330 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1331 FuncState *fs = ls->fs; 1331 FuncState *fs = ls->fs;
1332 int base = fs->freereg; 1332 int base = fs->freereg;
1333 new_localvarliteral(ls, "(for index)"); 1333 new_localvarliteral(ls, "(for index)");
1334 new_localvarliteral(ls, "(for limit)"); 1334 new_localvarliteral(ls, "(for limit)");
1335 new_localvarliteral(ls, "(for step)"); 1335 new_localvarliteral(ls, "(for step)");
1336 new_localvar(ls, varname); 1336 new_localvar(ls, varname);
1337 checknext(ls, '='); 1337 checknext(ls, '=');
1338 exp1(ls); /* initial value */ 1338 exp1(ls); /* initial value */
1339 checknext(ls, ','); 1339 checknext(ls, ',');
1340 exp1(ls); /* limit */ 1340 exp1(ls); /* limit */
1341 if (testnext(ls, ',')) 1341 if (testnext(ls, ','))
1342 exp1(ls); /* optional step */ 1342 exp1(ls); /* optional step */
1343 else { /* default step = 1 */ 1343 else { /* default step = 1 */
1344 luaK_codek(fs, fs->freereg, luaK_intK(fs, 1)); 1344 luaK_codek(fs, fs->freereg, luaK_intK(fs, 1));
1345 luaK_reserveregs(fs, 1); 1345 luaK_reserveregs(fs, 1);
1346 } 1346 }
1347 forbody(ls, base, line, 1, 1); 1347 forbody(ls, base, line, 1, 1);
1348} 1348}
1349 1349
1350 1350
1351static void forlist (LexState *ls, TString *indexname) { 1351static void forlist (LexState *ls, TString *indexname) {
1352 /* forlist -> NAME {,NAME} IN explist forbody */ 1352 /* forlist -> NAME {,NAME} IN explist forbody */
1353 FuncState *fs = ls->fs; 1353 FuncState *fs = ls->fs;
1354 expdesc e; 1354 expdesc e;
1355 int nvars = 4; /* gen, state, control, plus at least one declared var */ 1355 int nvars = 4; /* gen, state, control, plus at least one declared var */
1356 int line; 1356 int line;
1357 int base = fs->freereg; 1357 int base = fs->freereg;
1358 /* create control variables */ 1358 /* create control variables */
1359 new_localvarliteral(ls, "(for generator)"); 1359 new_localvarliteral(ls, "(for generator)");
1360 new_localvarliteral(ls, "(for state)"); 1360 new_localvarliteral(ls, "(for state)");
1361 new_localvarliteral(ls, "(for control)"); 1361 new_localvarliteral(ls, "(for control)");
1362 /* create declared variables */ 1362 /* create declared variables */
1363 new_localvar(ls, indexname); 1363 new_localvar(ls, indexname);
1364 while (testnext(ls, ',')) { 1364 while (testnext(ls, ',')) {
1365 new_localvar(ls, str_checkname(ls)); 1365 new_localvar(ls, str_checkname(ls));
1366 nvars++; 1366 nvars++;
1367 } 1367 }
1368 checknext(ls, TK_IN); 1368 checknext(ls, TK_IN);
1369 line = ls->linenumber; 1369 line = ls->linenumber;
1370 adjust_assign(ls, 3, explist(ls, &e), &e); 1370 adjust_assign(ls, 3, explist(ls, &e), &e);
1371 luaK_checkstack(fs, 3); /* extra space to call generator */ 1371 luaK_checkstack(fs, 3); /* extra space to call generator */
1372 forbody(ls, base, line, nvars - 3, 0); 1372 forbody(ls, base, line, nvars - 3, 0);
1373} 1373}
1374 1374
1375 1375
1376static void forstat (LexState *ls, int line) { 1376static void forstat (LexState *ls, int line) {
1377 /* forstat -> FOR (fornum | forlist) END */ 1377 /* forstat -> FOR (fornum | forlist) END */
1378 FuncState *fs = ls->fs; 1378 FuncState *fs = ls->fs;
1379 TString *varname; 1379 TString *varname;
1380 BlockCnt bl; 1380 BlockCnt bl;
1381 enterblock(fs, &bl, 1); /* scope for loop and control variables */ 1381 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1382 luaX_next(ls); /* skip 'for' */ 1382 luaX_next(ls); /* skip 'for' */
1383 varname = str_checkname(ls); /* first variable name */ 1383 varname = str_checkname(ls); /* first variable name */
1384 switch (ls->t.token) { 1384 switch (ls->t.token) {
1385 case '=': fornum(ls, varname, line); break; 1385 case '=': fornum(ls, varname, line); break;
1386 case ',': case TK_IN: forlist(ls, varname); break; 1386 case ',': case TK_IN: forlist(ls, varname); break;
1387 default: luaX_syntaxerror(ls, "'=' or 'in' expected"); 1387 default: luaX_syntaxerror(ls, "'=' or 'in' expected");
1388 } 1388 }
1389 check_match(ls, TK_END, TK_FOR, line); 1389 check_match(ls, TK_END, TK_FOR, line);
1390 leaveblock(fs); /* loop scope ('break' jumps to this point) */ 1390 leaveblock(fs); /* loop scope ('break' jumps to this point) */
1391} 1391}
1392 1392
1393 1393
1394static void test_then_block (LexState *ls, int *escapelist) { 1394static void test_then_block (LexState *ls, int *escapelist) {
1395 /* test_then_block -> [IF | ELSEIF] cond THEN block */ 1395 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1396 BlockCnt bl; 1396 BlockCnt bl;
1397 FuncState *fs = ls->fs; 1397 FuncState *fs = ls->fs;
1398 expdesc v; 1398 expdesc v;
1399 int jf; /* instruction to skip 'then' code (if condition is false) */ 1399 int jf; /* instruction to skip 'then' code (if condition is false) */
1400 luaX_next(ls); /* skip IF or ELSEIF */ 1400 luaX_next(ls); /* skip IF or ELSEIF */
1401 expr(ls, &v); /* read condition */ 1401 expr(ls, &v); /* read condition */
1402 checknext(ls, TK_THEN); 1402 checknext(ls, TK_THEN);
1403 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { 1403 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1404 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ 1404 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
1405 enterblock(fs, &bl, 0); /* must enter block before 'goto' */ 1405 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1406 gotostat(ls, v.t); /* handle goto/break */ 1406 gotostat(ls, v.t); /* handle goto/break */
1407 skipnoopstat(ls); /* skip other no-op statements */ 1407 skipnoopstat(ls); /* skip other no-op statements */
1408 if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ 1408 if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
1409 leaveblock(fs); 1409 leaveblock(fs);
1410 return; /* and that is it */ 1410 return; /* and that is it */
1411 } 1411 }
1412 else /* must skip over 'then' part if condition is false */ 1412 else /* must skip over 'then' part if condition is false */
1413 jf = luaK_jump(fs); 1413 jf = luaK_jump(fs);
1414 } 1414 }
1415 else { /* regular case (not goto/break) */ 1415 else { /* regular case (not goto/break) */
1416 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ 1416 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1417 enterblock(fs, &bl, 0); 1417 enterblock(fs, &bl, 0);
1418 jf = v.f; 1418 jf = v.f;
1419 } 1419 }
1420 statlist(ls); /* 'then' part */ 1420 statlist(ls); /* 'then' part */
1421 leaveblock(fs); 1421 leaveblock(fs);
1422 if (ls->t.token == TK_ELSE || 1422 if (ls->t.token == TK_ELSE ||
1423 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ 1423 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
1424 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ 1424 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
1425 luaK_patchtohere(fs, jf); 1425 luaK_patchtohere(fs, jf);
1426} 1426}
1427 1427
1428 1428
1429static void ifstat (LexState *ls, int line) { 1429static void ifstat (LexState *ls, int line) {
1430 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ 1430 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1431 FuncState *fs = ls->fs; 1431 FuncState *fs = ls->fs;
1432 int escapelist = NO_JUMP; /* exit list for finished parts */ 1432 int escapelist = NO_JUMP; /* exit list for finished parts */
1433 test_then_block(ls, &escapelist); /* IF cond THEN block */ 1433 test_then_block(ls, &escapelist); /* IF cond THEN block */
1434 while (ls->t.token == TK_ELSEIF) 1434 while (ls->t.token == TK_ELSEIF)
1435 test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ 1435 test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
1436 if (testnext(ls, TK_ELSE)) 1436 if (testnext(ls, TK_ELSE))
1437 block(ls); /* 'else' part */ 1437 block(ls); /* 'else' part */
1438 check_match(ls, TK_END, TK_IF, line); 1438 check_match(ls, TK_END, TK_IF, line);
1439 luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ 1439 luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
1440} 1440}
1441 1441
1442 1442
1443static void localfunc (LexState *ls) { 1443static void localfunc (LexState *ls) {
1444 expdesc b; 1444 expdesc b;
1445 FuncState *fs = ls->fs; 1445 FuncState *fs = ls->fs;
1446 new_localvar(ls, str_checkname(ls)); /* new local variable */ 1446 new_localvar(ls, str_checkname(ls)); /* new local variable */
1447 adjustlocalvars(ls, 1); /* enter its scope */ 1447 adjustlocalvars(ls, 1); /* enter its scope */
1448 body(ls, &b, 0, ls->linenumber); /* function created in next register */ 1448 body(ls, &b, 0, ls->linenumber); /* function created in next register */
1449 /* debug information will only see the variable after this point! */ 1449 /* debug information will only see the variable after this point! */
1450 getlocvar(fs, b.u.info)->startpc = fs->pc; 1450 getlocvar(fs, b.u.info)->startpc = fs->pc;
1451} 1451}
1452 1452
1453 1453
1454static void localstat (LexState *ls) { 1454static void localstat (LexState *ls) {
1455 /* stat -> LOCAL NAME {',' NAME} ['=' explist] */ 1455 /* stat -> LOCAL NAME {',' NAME} ['=' explist] */
1456 int nvars = 0; 1456 int nvars = 0;
1457 int nexps; 1457 int nexps;
1458 expdesc e; 1458 expdesc e;
1459 do { 1459 do {
1460 new_localvar(ls, str_checkname(ls)); 1460 new_localvar(ls, str_checkname(ls));
1461 nvars++; 1461 nvars++;
1462 } while (testnext(ls, ',')); 1462 } while (testnext(ls, ','));
1463 if (testnext(ls, '=')) 1463 if (testnext(ls, '='))
1464 nexps = explist(ls, &e); 1464 nexps = explist(ls, &e);
1465 else { 1465 else {
1466 e.k = VVOID; 1466 e.k = VVOID;
1467 nexps = 0; 1467 nexps = 0;
1468 } 1468 }
1469 adjust_assign(ls, nvars, nexps, &e); 1469 adjust_assign(ls, nvars, nexps, &e);
1470 adjustlocalvars(ls, nvars); 1470 adjustlocalvars(ls, nvars);
1471} 1471}
1472 1472
1473 1473
1474static int funcname (LexState *ls, expdesc *v) { 1474static int funcname (LexState *ls, expdesc *v) {
1475 /* funcname -> NAME {fieldsel} [':' NAME] */ 1475 /* funcname -> NAME {fieldsel} [':' NAME] */
1476 int ismethod = 0; 1476 int ismethod = 0;
1477 singlevar(ls, v); 1477 singlevar(ls, v);
1478 while (ls->t.token == '.') 1478 while (ls->t.token == '.')
1479 fieldsel(ls, v); 1479 fieldsel(ls, v);
1480 if (ls->t.token == ':') { 1480 if (ls->t.token == ':') {
1481 ismethod = 1; 1481 ismethod = 1;
1482 fieldsel(ls, v); 1482 fieldsel(ls, v);
1483 } 1483 }
1484 return ismethod; 1484 return ismethod;
1485} 1485}
1486 1486
1487 1487
1488static void funcstat (LexState *ls, int line) { 1488static void funcstat (LexState *ls, int line) {
1489 /* funcstat -> FUNCTION funcname body */ 1489 /* funcstat -> FUNCTION funcname body */
1490 int ismethod; 1490 int ismethod;
1491 expdesc v, b; 1491 expdesc v, b;
1492 luaX_next(ls); /* skip FUNCTION */ 1492 luaX_next(ls); /* skip FUNCTION */
1493 ismethod = funcname(ls, &v); 1493 ismethod = funcname(ls, &v);
1494 body(ls, &b, ismethod, line); 1494 body(ls, &b, ismethod, line);
1495 luaK_storevar(ls->fs, &v, &b); 1495 luaK_storevar(ls->fs, &v, &b);
1496 luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ 1496 luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
1497} 1497}
1498 1498
1499 1499
1500static void exprstat (LexState *ls) { 1500static void exprstat (LexState *ls) {
1501 /* stat -> func | assignment */ 1501 /* stat -> func | assignment */
1502 FuncState *fs = ls->fs; 1502 FuncState *fs = ls->fs;
1503 struct LHS_assign v; 1503 struct LHS_assign v;
1504 suffixedexp(ls, &v.v); 1504 suffixedexp(ls, &v.v);
1505 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ 1505 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1506 v.prev = NULL; 1506 v.prev = NULL;
1507 assignment(ls, &v, 1); 1507 assignment(ls, &v, 1);
1508 } 1508 }
1509 else { /* stat -> func */ 1509 else { /* stat -> func */
1510 check_condition(ls, v.v.k == VCALL, "syntax error"); 1510 check_condition(ls, v.v.k == VCALL, "syntax error");
1511 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ 1511 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1512 } 1512 }
1513} 1513}
1514 1514
1515 1515
1516static void retstat (LexState *ls) { 1516static void retstat (LexState *ls) {
1517 /* stat -> RETURN [explist] [';'] */ 1517 /* stat -> RETURN [explist] [';'] */
1518 FuncState *fs = ls->fs; 1518 FuncState *fs = ls->fs;
1519 expdesc e; 1519 expdesc e;
1520 int first, nret; /* registers with returned values */ 1520 int first, nret; /* registers with returned values */
1521 if (block_follow(ls, 1) || ls->t.token == ';') 1521 if (block_follow(ls, 1) || ls->t.token == ';')
1522 first = nret = 0; /* return no values */ 1522 first = nret = 0; /* return no values */
1523 else { 1523 else {
1524 nret = explist(ls, &e); /* optional return values */ 1524 nret = explist(ls, &e); /* optional return values */
1525 if (hasmultret(e.k)) { 1525 if (hasmultret(e.k)) {
1526 luaK_setmultret(fs, &e); 1526 luaK_setmultret(fs, &e);
1527 if (e.k == VCALL && nret == 1) { /* tail call? */ 1527 if (e.k == VCALL && nret == 1) { /* tail call? */
1528 SET_OPCODE(getcode(fs,&e), OP_TAILCALL); 1528 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1529 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); 1529 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1530 } 1530 }
1531 first = fs->nactvar; 1531 first = fs->nactvar;
1532 nret = LUA_MULTRET; /* return all values */ 1532 nret = LUA_MULTRET; /* return all values */
1533 } 1533 }
1534 else { 1534 else {
1535 if (nret == 1) /* only one single value? */ 1535 if (nret == 1) /* only one single value? */
1536 first = luaK_exp2anyreg(fs, &e); 1536 first = luaK_exp2anyreg(fs, &e);
1537 else { 1537 else {
1538 luaK_exp2nextreg(fs, &e); /* values must go to the stack */ 1538 luaK_exp2nextreg(fs, &e); /* values must go to the stack */
1539 first = fs->nactvar; /* return all active values */ 1539 first = fs->nactvar; /* return all active values */
1540 lua_assert(nret == fs->freereg - first); 1540 lua_assert(nret == fs->freereg - first);
1541 } 1541 }
1542 } 1542 }
1543 } 1543 }
1544 luaK_ret(fs, first, nret); 1544 luaK_ret(fs, first, nret);
1545 testnext(ls, ';'); /* skip optional semicolon */ 1545 testnext(ls, ';'); /* skip optional semicolon */
1546} 1546}
1547 1547
1548 1548
1549static void statement (LexState *ls) { 1549static void statement (LexState *ls) {
1550 int line = ls->linenumber; /* may be needed for error messages */ 1550 int line = ls->linenumber; /* may be needed for error messages */
1551 enterlevel(ls); 1551 enterlevel(ls);
1552 switch (ls->t.token) { 1552 switch (ls->t.token) {
1553 case ';': { /* stat -> ';' (empty statement) */ 1553 case ';': { /* stat -> ';' (empty statement) */
1554 luaX_next(ls); /* skip ';' */ 1554 luaX_next(ls); /* skip ';' */
1555 break; 1555 break;
1556 } 1556 }
1557 case TK_IF: { /* stat -> ifstat */ 1557 case TK_IF: { /* stat -> ifstat */
1558 ifstat(ls, line); 1558 ifstat(ls, line);
1559 break; 1559 break;
1560 } 1560 }
1561 case TK_WHILE: { /* stat -> whilestat */ 1561 case TK_WHILE: { /* stat -> whilestat */
1562 whilestat(ls, line); 1562 whilestat(ls, line);
1563 break; 1563 break;
1564 } 1564 }
1565 case TK_DO: { /* stat -> DO block END */ 1565 case TK_DO: { /* stat -> DO block END */
1566 luaX_next(ls); /* skip DO */ 1566 luaX_next(ls); /* skip DO */
1567 block(ls); 1567 block(ls);
1568 check_match(ls, TK_END, TK_DO, line); 1568 check_match(ls, TK_END, TK_DO, line);
1569 break; 1569 break;
1570 } 1570 }
1571 case TK_FOR: { /* stat -> forstat */ 1571 case TK_FOR: { /* stat -> forstat */
1572 forstat(ls, line); 1572 forstat(ls, line);
1573 break; 1573 break;
1574 } 1574 }
1575 case TK_REPEAT: { /* stat -> repeatstat */ 1575 case TK_REPEAT: { /* stat -> repeatstat */
1576 repeatstat(ls, line); 1576 repeatstat(ls, line);
1577 break; 1577 break;
1578 } 1578 }
1579 case TK_FUNCTION: { /* stat -> funcstat */ 1579 case TK_FUNCTION: { /* stat -> funcstat */
1580 funcstat(ls, line); 1580 funcstat(ls, line);
1581 break; 1581 break;
1582 } 1582 }
1583 case TK_LOCAL: { /* stat -> localstat */ 1583 case TK_LOCAL: { /* stat -> localstat */
1584 luaX_next(ls); /* skip LOCAL */ 1584 luaX_next(ls); /* skip LOCAL */
1585 if (testnext(ls, TK_FUNCTION)) /* local function? */ 1585 if (testnext(ls, TK_FUNCTION)) /* local function? */
1586 localfunc(ls); 1586 localfunc(ls);
1587 else 1587 else
1588 localstat(ls); 1588 localstat(ls);
1589 break; 1589 break;
1590 } 1590 }
1591 case TK_DBCOLON: { /* stat -> label */ 1591 case TK_DBCOLON: { /* stat -> label */
1592 luaX_next(ls); /* skip double colon */ 1592 luaX_next(ls); /* skip double colon */
1593 labelstat(ls, str_checkname(ls), line); 1593 labelstat(ls, str_checkname(ls), line);
1594 break; 1594 break;
1595 } 1595 }
1596 case TK_RETURN: { /* stat -> retstat */ 1596 case TK_RETURN: { /* stat -> retstat */
1597 luaX_next(ls); /* skip RETURN */ 1597 luaX_next(ls); /* skip RETURN */
1598 retstat(ls); 1598 retstat(ls);
1599 break; 1599 break;
1600 } 1600 }
1601 case TK_BREAK: /* stat -> breakstat */ 1601 case TK_BREAK: /* stat -> breakstat */
1602 case TK_GOTO: { /* stat -> 'goto' NAME */ 1602 case TK_GOTO: { /* stat -> 'goto' NAME */
1603 gotostat(ls, luaK_jump(ls->fs)); 1603 gotostat(ls, luaK_jump(ls->fs));
1604 break; 1604 break;
1605 } 1605 }
1606 default: { /* stat -> func | assignment */ 1606 default: { /* stat -> func | assignment */
1607 exprstat(ls); 1607 exprstat(ls);
1608 break; 1608 break;
1609 } 1609 }
1610 } 1610 }
1611 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && 1611 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1612 ls->fs->freereg >= ls->fs->nactvar); 1612 ls->fs->freereg >= ls->fs->nactvar);
1613 ls->fs->freereg = ls->fs->nactvar; /* free registers */ 1613 ls->fs->freereg = ls->fs->nactvar; /* free registers */
1614 leavelevel(ls); 1614 leavelevel(ls);
1615} 1615}
1616 1616
1617/* }====================================================================== */ 1617/* }====================================================================== */
1618 1618
1619 1619
1620/* 1620/*
1621** compiles the main function, which is a regular vararg function with an 1621** compiles the main function, which is a regular vararg function with an
1622** upvalue named LUA_ENV 1622** upvalue named LUA_ENV
1623*/ 1623*/
1624static void mainfunc (LexState *ls, FuncState *fs) { 1624static void mainfunc (LexState *ls, FuncState *fs) {
1625 BlockCnt bl; 1625 BlockCnt bl;
1626 expdesc v; 1626 expdesc v;
1627 open_func(ls, fs, &bl); 1627 open_func(ls, fs, &bl);
1628 fs->f->is_vararg = 2; /* main function is always declared vararg */ 1628 fs->f->is_vararg = 2; /* main function is always declared vararg */
1629 init_exp(&v, VLOCAL, 0); /* create and... */ 1629 init_exp(&v, VLOCAL, 0); /* create and... */
1630 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ 1630 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
1631 luaX_next(ls); /* read first token */ 1631 luaX_next(ls); /* read first token */
1632 statlist(ls); /* parse main body */ 1632 statlist(ls); /* parse main body */
1633 check(ls, TK_EOS); 1633 check(ls, TK_EOS);
1634 close_func(ls); 1634 close_func(ls);
1635} 1635}
1636 1636
1637 1637
1638LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 1638LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1639 Dyndata *dyd, const char *name, int firstchar) { 1639 Dyndata *dyd, const char *name, int firstchar) {
1640 LexState lexstate; 1640 LexState lexstate;
1641 FuncState funcstate; 1641 FuncState funcstate;
1642 LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ 1642 LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */
1643 setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ 1643 setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
1644 luaD_inctop(L); 1644 luaD_inctop(L);
1645 lexstate.h = luaH_new(L); /* create table for scanner */ 1645 lexstate.h = luaH_new(L); /* create table for scanner */
1646 sethvalue(L, L->top, lexstate.h); /* anchor it */ 1646 sethvalue(L, L->top, lexstate.h); /* anchor it */
1647 luaD_inctop(L); 1647 luaD_inctop(L);
1648 funcstate.f = cl->p = luaF_newproto(L); 1648 funcstate.f = cl->p = luaF_newproto(L);
1649 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ 1649 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1650 lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ 1650 lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
1651 lexstate.buff = buff; 1651 lexstate.buff = buff;
1652 lexstate.dyd = dyd; 1652 lexstate.dyd = dyd;
1653 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; 1653 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
1654 luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); 1654 luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
1655 mainfunc(&lexstate, &funcstate); 1655 mainfunc(&lexstate, &funcstate);
1656 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); 1656 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1657 /* all scopes should be correctly finished */ 1657 /* all scopes should be correctly finished */
1658 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); 1658 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1659 L->top--; /* remove scanner's table */ 1659 L->top--; /* remove scanner's table */
1660 return cl; /* closure is on the stack, too */ 1660 return cl; /* closure is on the stack, too */
1661} 1661}
1662 1662

cvs diff -r1.11 -r1.12 src/external/mit/lua/dist/src/lstrlib.c (switch to unified diff)

--- src/external/mit/lua/dist/src/lstrlib.c 2016/01/28 14:41:39 1.11
+++ src/external/mit/lua/dist/src/lstrlib.c 2016/03/25 08:15:20 1.12
@@ -1,1577 +1,1578 @@ @@ -1,1577 +1,1578 @@
1/* $NetBSD: lstrlib.c,v 1.11 2016/01/28 14:41:39 lneto Exp $ */ 1/* $NetBSD: lstrlib.c,v 1.12 2016/03/25 08:15:20 mbalmer Exp $ */
2 2
3/* 3/*
4** Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp  4** Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp
5** Standard library for string operations and pattern-matching 5** Standard library for string operations and pattern-matching
6** See Copyright Notice in lua.h 6** See Copyright Notice in lua.h
7*/ 7*/
8 8
9#define lstrlib_c 9#define lstrlib_c
10#define LUA_LIB 10#define LUA_LIB
11 11
12#include "lprefix.h" 12#include "lprefix.h"
13 13
14 14
15#ifndef _KERNEL 15#ifndef _KERNEL
16#include <ctype.h> 16#include <ctype.h>
17#include <float.h> 17#include <float.h>
18#include <limits.h> 18#include <limits.h>
19#include <stddef.h> 19#include <stddef.h>
20#include <stdio.h> 20#include <stdio.h>
21#include <stdlib.h> 21#include <stdlib.h>
22#include <string.h> 22#include <string.h>
23#endif /* _KERNEL */ 23#endif /* _KERNEL */
24 24
25#include "lua.h" 25#include "lua.h"
26 26
27#include "lauxlib.h" 27#include "lauxlib.h"
28#include "lualib.h" 28#include "lualib.h"
29 29
30 30
31/* 31/*
32** maximum number of captures that a pattern can do during 32** maximum number of captures that a pattern can do during
33** pattern-matching. This limit is arbitrary. 33** pattern-matching. This limit is arbitrary.
34*/ 34*/
35#if !defined(LUA_MAXCAPTURES) 35#if !defined(LUA_MAXCAPTURES)
36#define LUA_MAXCAPTURES 32 36#define LUA_MAXCAPTURES 32
37#endif 37#endif
38 38
39 39
40/* macro to 'unsign' a character */ 40/* macro to 'unsign' a character */
41#define uchar(c) ((unsigned char)(c)) 41#define uchar(c) ((unsigned char)(c))
42 42
43 43
44/* 44/*
45** Some sizes are better limited to fit in 'int', but must also fit in 45** Some sizes are better limited to fit in 'int', but must also fit in
46** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) 46** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
47*/ 47*/
48#define MAX_SIZET ((size_t)(~(size_t)0)) 48#define MAX_SIZET ((size_t)(~(size_t)0))
49 49
50#define MAXSIZE \ 50#define MAXSIZE \
51 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) 51 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
52 52
53 53
54 54
55 55
56static int str_len (lua_State *L) { 56static int str_len (lua_State *L) {
57 size_t l; 57 size_t l;
58 luaL_checklstring(L, 1, &l); 58 luaL_checklstring(L, 1, &l);
59 lua_pushinteger(L, (lua_Integer)l); 59 lua_pushinteger(L, (lua_Integer)l);
60 return 1; 60 return 1;
61} 61}
62 62
63 63
64/* translate a relative string position: negative means back from end */ 64/* translate a relative string position: negative means back from end */
65static lua_Integer posrelat (lua_Integer pos, size_t len) { 65static lua_Integer posrelat (lua_Integer pos, size_t len) {
66 if (pos >= 0) return pos; 66 if (pos >= 0) return pos;
67 else if (0u - (size_t)pos > len) return 0; 67 else if (0u - (size_t)pos > len) return 0;
68 else return (lua_Integer)len + pos + 1; 68 else return (lua_Integer)len + pos + 1;
69} 69}
70 70
71 71
72static int str_sub (lua_State *L) { 72static int str_sub (lua_State *L) {
73 size_t l; 73 size_t l;
74 const char *s = luaL_checklstring(L, 1, &l); 74 const char *s = luaL_checklstring(L, 1, &l);
75 lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); 75 lua_Integer start = posrelat(luaL_checkinteger(L, 2), l);
76 lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); 76 lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l);
77 if (start < 1) start = 1; 77 if (start < 1) start = 1;
78 if (end > (lua_Integer)l) end = l; 78 if (end > (lua_Integer)l) end = l;
79 if (start <= end) 79 if (start <= end)
80 lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1); 80 lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
81 else lua_pushliteral(L, ""); 81 else lua_pushliteral(L, "");
82 return 1; 82 return 1;
83} 83}
84 84
85 85
86static int str_reverse (lua_State *L) { 86static int str_reverse (lua_State *L) {
87 size_t l, i; 87 size_t l, i;
88 luaL_Buffer b; 88 luaL_Buffer b;
89 const char *s = luaL_checklstring(L, 1, &l); 89 const char *s = luaL_checklstring(L, 1, &l);
90 char *p = luaL_buffinitsize(L, &b, l); 90 char *p = luaL_buffinitsize(L, &b, l);
91 for (i = 0; i < l; i++) 91 for (i = 0; i < l; i++)
92 p[i] = s[l - i - 1]; 92 p[i] = s[l - i - 1];
93 luaL_pushresultsize(&b, l); 93 luaL_pushresultsize(&b, l);
94 return 1; 94 return 1;
95} 95}
96 96
97 97
98static int str_lower (lua_State *L) { 98static int str_lower (lua_State *L) {
99 size_t l; 99 size_t l;
100 size_t i; 100 size_t i;
101 luaL_Buffer b; 101 luaL_Buffer b;
102 const char *s = luaL_checklstring(L, 1, &l); 102 const char *s = luaL_checklstring(L, 1, &l);
103 char *p = luaL_buffinitsize(L, &b, l); 103 char *p = luaL_buffinitsize(L, &b, l);
104 for (i=0; i<l; i++) 104 for (i=0; i<l; i++)
105 p[i] = tolower(uchar(s[i])); 105 p[i] = tolower(uchar(s[i]));
106 luaL_pushresultsize(&b, l); 106 luaL_pushresultsize(&b, l);
107 return 1; 107 return 1;
108} 108}
109 109
110 110
111static int str_upper (lua_State *L) { 111static int str_upper (lua_State *L) {
112 size_t l; 112 size_t l;
113 size_t i; 113 size_t i;
114 luaL_Buffer b; 114 luaL_Buffer b;
115 const char *s = luaL_checklstring(L, 1, &l); 115 const char *s = luaL_checklstring(L, 1, &l);
116 char *p = luaL_buffinitsize(L, &b, l); 116 char *p = luaL_buffinitsize(L, &b, l);
117 for (i=0; i<l; i++) 117 for (i=0; i<l; i++)
118 p[i] = toupper(uchar(s[i])); 118 p[i] = toupper(uchar(s[i]));
119 luaL_pushresultsize(&b, l); 119 luaL_pushresultsize(&b, l);
120 return 1; 120 return 1;
121} 121}
122 122
123 123
124static int str_rep (lua_State *L) { 124static int str_rep (lua_State *L) {
125 size_t l, lsep; 125 size_t l, lsep;
126 const char *s = luaL_checklstring(L, 1, &l); 126 const char *s = luaL_checklstring(L, 1, &l);
127 lua_Integer n = luaL_checkinteger(L, 2); 127 lua_Integer n = luaL_checkinteger(L, 2);
128 const char *sep = luaL_optlstring(L, 3, "", &lsep); 128 const char *sep = luaL_optlstring(L, 3, "", &lsep);
129 if (n <= 0) lua_pushliteral(L, ""); 129 if (n <= 0) lua_pushliteral(L, "");
130 else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ 130 else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */
131 return luaL_error(L, "resulting string too large"); 131 return luaL_error(L, "resulting string too large");
132 else { 132 else {
133 size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; 133 size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
134 luaL_Buffer b; 134 luaL_Buffer b;
135 char *p = luaL_buffinitsize(L, &b, totallen); 135 char *p = luaL_buffinitsize(L, &b, totallen);
136 while (n-- > 1) { /* first n-1 copies (followed by separator) */ 136 while (n-- > 1) { /* first n-1 copies (followed by separator) */
137 memcpy(p, s, l * sizeof(char)); p += l; 137 memcpy(p, s, l * sizeof(char)); p += l;
138 if (lsep > 0) { /* empty 'memcpy' is not that cheap */ 138 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
139 memcpy(p, sep, lsep * sizeof(char)); 139 memcpy(p, sep, lsep * sizeof(char));
140 p += lsep; 140 p += lsep;
141 } 141 }
142 } 142 }
143 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ 143 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */
144 luaL_pushresultsize(&b, totallen); 144 luaL_pushresultsize(&b, totallen);
145 } 145 }
146 return 1; 146 return 1;
147} 147}
148 148
149 149
150static int str_byte (lua_State *L) { 150static int str_byte (lua_State *L) {
151 size_t l; 151 size_t l;
152 const char *s = luaL_checklstring(L, 1, &l); 152 const char *s = luaL_checklstring(L, 1, &l);
153 lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); 153 lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l);
154 lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); 154 lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l);
155 int n, i; 155 int n, i;
156 if (posi < 1) posi = 1; 156 if (posi < 1) posi = 1;
157 if (pose > (lua_Integer)l) pose = l; 157 if (pose > (lua_Integer)l) pose = l;
158 if (posi > pose) return 0; /* empty interval; return no values */ 158 if (posi > pose) return 0; /* empty interval; return no values */
159 if (pose - posi >= INT_MAX) /* arithmetic overflow? */ 159 if (pose - posi >= INT_MAX) /* arithmetic overflow? */
160 return luaL_error(L, "string slice too long"); 160 return luaL_error(L, "string slice too long");
161 n = (int)(pose - posi) + 1; 161 n = (int)(pose - posi) + 1;
162 luaL_checkstack(L, n, "string slice too long"); 162 luaL_checkstack(L, n, "string slice too long");
163 for (i=0; i<n; i++) 163 for (i=0; i<n; i++)
164 lua_pushinteger(L, uchar(s[posi+i-1])); 164 lua_pushinteger(L, uchar(s[posi+i-1]));
165 return n; 165 return n;
166} 166}
167 167
168 168
169static int str_char (lua_State *L) { 169static int str_char (lua_State *L) {
170 int n = lua_gettop(L); /* number of arguments */ 170 int n = lua_gettop(L); /* number of arguments */
171 int i; 171 int i;
172 luaL_Buffer b; 172 luaL_Buffer b;
173 char *p = luaL_buffinitsize(L, &b, n); 173 char *p = luaL_buffinitsize(L, &b, n);
174 for (i=1; i<=n; i++) { 174 for (i=1; i<=n; i++) {
175 lua_Integer c = luaL_checkinteger(L, i); 175 lua_Integer c = luaL_checkinteger(L, i);
176 luaL_argcheck(L, uchar(c) == c, i, "value out of range"); 176 luaL_argcheck(L, uchar(c) == c, i, "value out of range");
177 p[i - 1] = uchar(c); 177 p[i - 1] = uchar(c);
178 } 178 }
179 luaL_pushresultsize(&b, n); 179 luaL_pushresultsize(&b, n);
180 return 1; 180 return 1;
181} 181}
182 182
183 183
184static int writer (lua_State *L, const void *b, size_t size, void *B) { 184static int writer (lua_State *L, const void *b, size_t size, void *B) {
185 (void)L; 185 (void)L;
186 luaL_addlstring((luaL_Buffer *) B, (const char *)b, size); 186 luaL_addlstring((luaL_Buffer *) B, (const char *)b, size);
187 return 0; 187 return 0;
188} 188}
189 189
190 190
191static int str_dump (lua_State *L) { 191static int str_dump (lua_State *L) {
192 luaL_Buffer b; 192 luaL_Buffer b;
193 int strip = lua_toboolean(L, 2); 193 int strip = lua_toboolean(L, 2);
194 luaL_checktype(L, 1, LUA_TFUNCTION); 194 luaL_checktype(L, 1, LUA_TFUNCTION);
195 lua_settop(L, 1); 195 lua_settop(L, 1);
196 luaL_buffinit(L,&b); 196 luaL_buffinit(L,&b);
197 if (lua_dump(L, writer, &b, strip) != 0) 197 if (lua_dump(L, writer, &b, strip) != 0)
198 return luaL_error(L, "unable to dump given function"); 198 return luaL_error(L, "unable to dump given function");
199 luaL_pushresult(&b); 199 luaL_pushresult(&b);
200 return 1; 200 return 1;
201} 201}
202 202
203 203
204 204
205/* 205/*
206** {====================================================== 206** {======================================================
207** PATTERN MATCHING 207** PATTERN MATCHING
208** ======================================================= 208** =======================================================
209*/ 209*/
210 210
211 211
212#define CAP_UNFINISHED (-1) 212#define CAP_UNFINISHED (-1)
213#define CAP_POSITION (-2) 213#define CAP_POSITION (-2)
214 214
215 215
216typedef struct MatchState { 216typedef struct MatchState {
217 const char *src_init; /* init of source string */ 217 const char *src_init; /* init of source string */
218 const char *src_end; /* end ('\0') of source string */ 218 const char *src_end; /* end ('\0') of source string */
219 const char *p_end; /* end ('\0') of pattern */ 219 const char *p_end; /* end ('\0') of pattern */
220 lua_State *L; 220 lua_State *L;
221 size_t nrep; /* limit to avoid non-linear complexity */ 221 size_t nrep; /* limit to avoid non-linear complexity */
222 int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ 222 int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
223 int level; /* total number of captures (finished or unfinished) */ 223 int level; /* total number of captures (finished or unfinished) */
224 struct { 224 struct {
225 const char *init; 225 const char *init;
226 ptrdiff_t len; 226 ptrdiff_t len;
227 } capture[LUA_MAXCAPTURES]; 227 } capture[LUA_MAXCAPTURES];
228} MatchState; 228} MatchState;
229 229
230 230
231/* recursive function */ 231/* recursive function */
232static const char *match (MatchState *ms, const char *s, const char *p); 232static const char *match (MatchState *ms, const char *s, const char *p);
233 233
234 234
235/* maximum recursion depth for 'match' */ 235/* maximum recursion depth for 'match' */
236#if !defined(MAXCCALLS) 236#if !defined(MAXCCALLS)
237#define MAXCCALLS 200 237#define MAXCCALLS 200
238#endif 238#endif
239 239
240 240
241/* 241/*
242** parameters to control the maximum number of operators handled in 242** parameters to control the maximum number of operators handled in
243** a match (to avoid non-linear complexity). The maximum will be: 243** a match (to avoid non-linear complexity). The maximum will be:
244** (subject length) * A_REPS + B_REPS 244** (subject length) * A_REPS + B_REPS
245*/ 245*/
246#if !defined(A_REPS) 246#if !defined(A_REPS)
247#define A_REPS 4 247#define A_REPS 4
248#define B_REPS 100000 248#define B_REPS 100000
249#endif 249#endif
250 250
251 251
252#define L_ESC '%' 252#define L_ESC '%'
253#define SPECIALS "^$*+?.([%-" 253#define SPECIALS "^$*+?.([%-"
254 254
255 255
256static int check_capture (MatchState *ms, int l) { 256static int check_capture (MatchState *ms, int l) {
257 l -= '1'; 257 l -= '1';
258 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) 258 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
259 return luaL_error(ms->L, "invalid capture index %%%d", l + 1); 259 return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
260 return l; 260 return l;
261} 261}
262 262
263 263
264static int capture_to_close (MatchState *ms) { 264static int capture_to_close (MatchState *ms) {
265 int level = ms->level; 265 int level = ms->level;
266 for (level--; level>=0; level--) 266 for (level--; level>=0; level--)
267 if (ms->capture[level].len == CAP_UNFINISHED) return level; 267 if (ms->capture[level].len == CAP_UNFINISHED) return level;
268 return luaL_error(ms->L, "invalid pattern capture"); 268 return luaL_error(ms->L, "invalid pattern capture");
269} 269}
270 270
271 271
272static const char *classend (MatchState *ms, const char *p) { 272static const char *classend (MatchState *ms, const char *p) {
273 switch (*p++) { 273 switch (*p++) {
274 case L_ESC: { 274 case L_ESC: {
275 if (p == ms->p_end) 275 if (p == ms->p_end)
276 luaL_error(ms->L, "malformed pattern (ends with '%%')"); 276 luaL_error(ms->L, "malformed pattern (ends with '%%')");
277 return p+1; 277 return p+1;
278 } 278 }
279 case '[': { 279 case '[': {
280 if (*p == '^') p++; 280 if (*p == '^') p++;
281 do { /* look for a ']' */ 281 do { /* look for a ']' */
282 if (p == ms->p_end) 282 if (p == ms->p_end)
283 luaL_error(ms->L, "malformed pattern (missing ']')"); 283 luaL_error(ms->L, "malformed pattern (missing ']')");
284 if (*(p++) == L_ESC && p < ms->p_end) 284 if (*(p++) == L_ESC && p < ms->p_end)
285 p++; /* skip escapes (e.g. '%]') */ 285 p++; /* skip escapes (e.g. '%]') */
286 } while (*p != ']'); 286 } while (*p != ']');
287 return p+1; 287 return p+1;
288 } 288 }
289 default: { 289 default: {
290 return p; 290 return p;
291 } 291 }
292 } 292 }
293} 293}
294 294
295 295
296static int match_class (int c, int cl) { 296static int match_class (int c, int cl) {
297 int res; 297 int res;
298 switch (tolower(cl)) { 298 switch (tolower(cl)) {
299 case 'a' : res = isalpha(c); break; 299 case 'a' : res = isalpha(c); break;
300 case 'c' : res = iscntrl(c); break; 300 case 'c' : res = iscntrl(c); break;
301 case 'd' : res = isdigit(c); break; 301 case 'd' : res = isdigit(c); break;
302 case 'g' : res = isgraph(c); break; 302 case 'g' : res = isgraph(c); break;
303 case 'l' : res = islower(c); break; 303 case 'l' : res = islower(c); break;
304 case 'p' : res = ispunct(c); break; 304 case 'p' : res = ispunct(c); break;
305 case 's' : res = isspace(c); break; 305 case 's' : res = isspace(c); break;
306 case 'u' : res = isupper(c); break; 306 case 'u' : res = isupper(c); break;
307 case 'w' : res = isalnum(c); break; 307 case 'w' : res = isalnum(c); break;
308 case 'x' : res = isxdigit(c); break; 308 case 'x' : res = isxdigit(c); break;
309 case 'z' : res = (c == 0); break; /* deprecated option */ 309 case 'z' : res = (c == 0); break; /* deprecated option */
310 default: return (cl == c); 310 default: return (cl == c);
311 } 311 }
312 return (islower(cl) ? res : !res); 312 return (islower(cl) ? res : !res);
313} 313}
314 314
315 315
316static int matchbracketclass (int c, const char *p, const char *ec) { 316static int matchbracketclass (int c, const char *p, const char *ec) {
317 int sig = 1; 317 int sig = 1;
318 if (*(p+1) == '^') { 318 if (*(p+1) == '^') {
319 sig = 0; 319 sig = 0;
320 p++; /* skip the '^' */ 320 p++; /* skip the '^' */
321 } 321 }
322 while (++p < ec) { 322 while (++p < ec) {
323 if (*p == L_ESC) { 323 if (*p == L_ESC) {
324 p++; 324 p++;
325 if (match_class(c, uchar(*p))) 325 if (match_class(c, uchar(*p)))
326 return sig; 326 return sig;
327 } 327 }
328 else if ((*(p+1) == '-') && (p+2 < ec)) { 328 else if ((*(p+1) == '-') && (p+2 < ec)) {
329 p+=2; 329 p+=2;
330 if (uchar(*(p-2)) <= c && c <= uchar(*p)) 330 if (uchar(*(p-2)) <= c && c <= uchar(*p))
331 return sig; 331 return sig;
332 } 332 }
333 else if (uchar(*p) == c) return sig; 333 else if (uchar(*p) == c) return sig;
334 } 334 }
335 return !sig; 335 return !sig;
336} 336}
337 337
338 338
339static int singlematch (MatchState *ms, const char *s, const char *p, 339static int singlematch (MatchState *ms, const char *s, const char *p,
340 const char *ep) { 340 const char *ep) {
341 if (s >= ms->src_end) 341 if (s >= ms->src_end)
342 return 0; 342 return 0;
343 else { 343 else {
344 int c = uchar(*s); 344 int c = uchar(*s);
345 switch (*p) { 345 switch (*p) {
346 case '.': return 1; /* matches any char */ 346 case '.': return 1; /* matches any char */
347 case L_ESC: return match_class(c, uchar(*(p+1))); 347 case L_ESC: return match_class(c, uchar(*(p+1)));
348 case '[': return matchbracketclass(c, p, ep-1); 348 case '[': return matchbracketclass(c, p, ep-1);
349 default: return (uchar(*p) == c); 349 default: return (uchar(*p) == c);
350 } 350 }
351 } 351 }
352} 352}
353 353
354 354
355static const char *matchbalance (MatchState *ms, const char *s, 355static const char *matchbalance (MatchState *ms, const char *s,
356 const char *p) { 356 const char *p) {
357 if (p >= ms->p_end - 1) 357 if (p >= ms->p_end - 1)
358 luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); 358 luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
359 if (*s != *p) return NULL; 359 if (*s != *p) return NULL;
360 else { 360 else {
361 int b = *p; 361 int b = *p;
362 int e = *(p+1); 362 int e = *(p+1);
363 int cont = 1; 363 int cont = 1;
364 while (++s < ms->src_end) { 364 while (++s < ms->src_end) {
365 if (*s == e) { 365 if (*s == e) {
366 if (--cont == 0) return s+1; 366 if (--cont == 0) return s+1;
367 } 367 }
368 else if (*s == b) cont++; 368 else if (*s == b) cont++;
369 } 369 }
370 } 370 }
371 return NULL; /* string ends out of balance */ 371 return NULL; /* string ends out of balance */
372} 372}
373 373
374 374
375static const char *max_expand (MatchState *ms, const char *s, 375static const char *max_expand (MatchState *ms, const char *s,
376 const char *p, const char *ep) { 376 const char *p, const char *ep) {
377 ptrdiff_t i = 0; /* counts maximum expand for item */ 377 ptrdiff_t i = 0; /* counts maximum expand for item */
378 while (singlematch(ms, s + i, p, ep)) 378 while (singlematch(ms, s + i, p, ep))
379 i++; 379 i++;
380 /* keeps trying to match with the maximum repetitions */ 380 /* keeps trying to match with the maximum repetitions */
381 while (i>=0) { 381 while (i>=0) {
382 const char *res = match(ms, (s+i), ep+1); 382 const char *res = match(ms, (s+i), ep+1);
383 if (res) return res; 383 if (res) return res;
384 i--; /* else didn't match; reduce 1 repetition to try again */ 384 i--; /* else didn't match; reduce 1 repetition to try again */
385 } 385 }
386 return NULL; 386 return NULL;
387} 387}
388 388
389 389
390static const char *min_expand (MatchState *ms, const char *s, 390static const char *min_expand (MatchState *ms, const char *s,
391 const char *p, const char *ep) { 391 const char *p, const char *ep) {
392 for (;;) { 392 for (;;) {
393 const char *res = match(ms, s, ep+1); 393 const char *res = match(ms, s, ep+1);
394 if (res != NULL) 394 if (res != NULL)
395 return res; 395 return res;
396 else if (singlematch(ms, s, p, ep)) 396 else if (singlematch(ms, s, p, ep))
397 s++; /* try with one more repetition */ 397 s++; /* try with one more repetition */
398 else return NULL; 398 else return NULL;
399 } 399 }
400} 400}
401 401
402 402
403static const char *start_capture (MatchState *ms, const char *s, 403static const char *start_capture (MatchState *ms, const char *s,
404 const char *p, int what) { 404 const char *p, int what) {
405 const char *res; 405 const char *res;
406 int level = ms->level; 406 int level = ms->level;
407 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); 407 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
408 ms->capture[level].init = s; 408 ms->capture[level].init = s;
409 ms->capture[level].len = what; 409 ms->capture[level].len = what;
410 ms->level = level+1; 410 ms->level = level+1;
411 if ((res=match(ms, s, p)) == NULL) /* match failed? */ 411 if ((res=match(ms, s, p)) == NULL) /* match failed? */
412 ms->level--; /* undo capture */ 412 ms->level--; /* undo capture */
413 return res; 413 return res;
414} 414}
415 415
416 416
417static const char *end_capture (MatchState *ms, const char *s, 417static const char *end_capture (MatchState *ms, const char *s,
418 const char *p) { 418 const char *p) {
419 int l = capture_to_close(ms); 419 int l = capture_to_close(ms);
420 const char *res; 420 const char *res;
421 ms->capture[l].len = s - ms->capture[l].init; /* close capture */ 421 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
422 if ((res = match(ms, s, p)) == NULL) /* match failed? */ 422 if ((res = match(ms, s, p)) == NULL) /* match failed? */
423 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ 423 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
424 return res; 424 return res;
425} 425}
426 426
427 427
428static const char *match_capture (MatchState *ms, const char *s, int l) { 428static const char *match_capture (MatchState *ms, const char *s, int l) {
429 size_t len; 429 size_t len;
430 l = check_capture(ms, l); 430 l = check_capture(ms, l);
431 len = ms->capture[l].len; 431 len = ms->capture[l].len;
432 if ((size_t)(ms->src_end-s) >= len && 432 if ((size_t)(ms->src_end-s) >= len &&
433 memcmp(ms->capture[l].init, s, len) == 0) 433 memcmp(ms->capture[l].init, s, len) == 0)
434 return s+len; 434 return s+len;
435 else return NULL; 435 else return NULL;
436} 436}
437 437
438 438
439static const char *match (MatchState *ms, const char *s, const char *p) { 439static const char *match (MatchState *ms, const char *s, const char *p) {
440 if (ms->matchdepth-- == 0) 440 if (ms->matchdepth-- == 0)
441 luaL_error(ms->L, "pattern too complex"); 441 luaL_error(ms->L, "pattern too complex");
442 init: /* using goto's to optimize tail recursion */ 442 init: /* using goto's to optimize tail recursion */
443 if (p != ms->p_end) { /* end of pattern? */ 443 if (p != ms->p_end) { /* end of pattern? */
444 switch (*p) { 444 switch (*p) {
445 case '(': { /* start capture */ 445 case '(': { /* start capture */
446 if (*(p + 1) == ')') /* position capture? */ 446 if (*(p + 1) == ')') /* position capture? */
447 s = start_capture(ms, s, p + 2, CAP_POSITION); 447 s = start_capture(ms, s, p + 2, CAP_POSITION);
448 else 448 else
449 s = start_capture(ms, s, p + 1, CAP_UNFINISHED); 449 s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
450 break; 450 break;
451 } 451 }
452 case ')': { /* end capture */ 452 case ')': { /* end capture */
453 s = end_capture(ms, s, p + 1); 453 s = end_capture(ms, s, p + 1);
454 break; 454 break;
455 } 455 }
456 case '$': { 456 case '$': {
457 if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ 457 if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */
458 goto dflt; /* no; go to default */ 458 goto dflt; /* no; go to default */
459 s = (s == ms->src_end) ? s : NULL; /* check end of string */ 459 s = (s == ms->src_end) ? s : NULL; /* check end of string */
460 break; 460 break;
461 } 461 }
462 case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ 462 case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
463 switch (*(p + 1)) { 463 switch (*(p + 1)) {
464 case 'b': { /* balanced string? */ 464 case 'b': { /* balanced string? */
465 s = matchbalance(ms, s, p + 2); 465 s = matchbalance(ms, s, p + 2);
466 if (s != NULL) { 466 if (s != NULL) {
467 p += 4; goto init; /* return match(ms, s, p + 4); */ 467 p += 4; goto init; /* return match(ms, s, p + 4); */
468 } /* else fail (s == NULL) */ 468 } /* else fail (s == NULL) */
469 break; 469 break;
470 } 470 }
471 case 'f': { /* frontier? */ 471 case 'f': { /* frontier? */
472 const char *ep; char previous; 472 const char *ep; char previous;
473 p += 2; 473 p += 2;
474 if (*p != '[') 474 if (*p != '[')
475 luaL_error(ms->L, "missing '[' after '%%f' in pattern"); 475 luaL_error(ms->L, "missing '[' after '%%f' in pattern");
476 ep = classend(ms, p); /* points to what is next */ 476 ep = classend(ms, p); /* points to what is next */
477 previous = (s == ms->src_init) ? '\0' : *(s - 1); 477 previous = (s == ms->src_init) ? '\0' : *(s - 1);
478 if (!matchbracketclass(uchar(previous), p, ep - 1) && 478 if (!matchbracketclass(uchar(previous), p, ep - 1) &&
479 matchbracketclass(uchar(*s), p, ep - 1)) { 479 matchbracketclass(uchar(*s), p, ep - 1)) {
480 p = ep; goto init; /* return match(ms, s, ep); */ 480 p = ep; goto init; /* return match(ms, s, ep); */
481 } 481 }
482 s = NULL; /* match failed */ 482 s = NULL; /* match failed */
483 break; 483 break;
484 } 484 }
485 case '0': case '1': case '2': case '3': 485 case '0': case '1': case '2': case '3':
486 case '4': case '5': case '6': case '7': 486 case '4': case '5': case '6': case '7':
487 case '8': case '9': { /* capture results (%0-%9)? */ 487 case '8': case '9': { /* capture results (%0-%9)? */
488 s = match_capture(ms, s, uchar(*(p + 1))); 488 s = match_capture(ms, s, uchar(*(p + 1)));
489 if (s != NULL) { 489 if (s != NULL) {
490 p += 2; goto init; /* return match(ms, s, p + 2) */ 490 p += 2; goto init; /* return match(ms, s, p + 2) */
491 } 491 }
492 break; 492 break;
493 } 493 }
494 default: goto dflt; 494 default: goto dflt;
495 } 495 }
496 break; 496 break;
497 } 497 }
498 default: dflt: { /* pattern class plus optional suffix */ 498 default: dflt: { /* pattern class plus optional suffix */
499 const char *ep = classend(ms, p); /* points to optional suffix */ 499 const char *ep = classend(ms, p); /* points to optional suffix */
500 /* does not match at least once? */ 500 /* does not match at least once? */
501 if (!singlematch(ms, s, p, ep)) { 501 if (!singlematch(ms, s, p, ep)) {
502 if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ 502 if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */
503 p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ 503 p = ep + 1; goto init; /* return match(ms, s, ep + 1); */
504 } 504 }
505 else /* '+' or no suffix */ 505 else /* '+' or no suffix */
506 s = NULL; /* fail */ 506 s = NULL; /* fail */
507 } 507 }
508 else { /* matched once */ 508 else { /* matched once */
509 if (ms->nrep-- == 0) 509 if (ms->nrep-- == 0)
510 luaL_error(ms->L, "pattern too complex"); 510 luaL_error(ms->L, "pattern too complex");
511 switch (*ep) { /* handle optional suffix */ 511 switch (*ep) { /* handle optional suffix */
512 case '?': { /* optional */ 512 case '?': { /* optional */
513 const char *res; 513 const char *res;
514 if ((res = match(ms, s + 1, ep + 1)) != NULL) 514 if ((res = match(ms, s + 1, ep + 1)) != NULL)
515 s = res; 515 s = res;
516 else { 516 else {
517 p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ 517 p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */
518 } 518 }
519 break; 519 break;
520 } 520 }
521 case '+': /* 1 or more repetitions */ 521 case '+': /* 1 or more repetitions */
522 s++; /* 1 match already done */ 522 s++; /* 1 match already done */
523 /* FALLTHROUGH */ 523 /* FALLTHROUGH */
524 case '*': /* 0 or more repetitions */ 524 case '*': /* 0 or more repetitions */
525 s = max_expand(ms, s, p, ep); 525 s = max_expand(ms, s, p, ep);
526 break; 526 break;
527 case '-': /* 0 or more repetitions (minimum) */ 527 case '-': /* 0 or more repetitions (minimum) */
528 s = min_expand(ms, s, p, ep); 528 s = min_expand(ms, s, p, ep);
529 break; 529 break;
530 default: /* no suffix */ 530 default: /* no suffix */
531 s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ 531 s++; p = ep; goto init; /* return match(ms, s + 1, ep); */
532 } 532 }
533 } 533 }
534 break; 534 break;
535 } 535 }
536 } 536 }
537 } 537 }
538 ms->matchdepth++; 538 ms->matchdepth++;
539 return s; 539 return s;
540} 540}
541 541
542 542
543 543
544static const char *lmemfind (const char *s1, size_t l1, 544static const char *lmemfind (const char *s1, size_t l1,
545 const char *s2, size_t l2) { 545 const char *s2, size_t l2) {
546 if (l2 == 0) return s1; /* empty strings are everywhere */ 546 if (l2 == 0) return s1; /* empty strings are everywhere */
547 else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ 547 else if (l2 > l1) return NULL; /* avoids a negative 'l1' */
548 else { 548 else {
549 const char *init; /* to search for a '*s2' inside 's1' */ 549 const char *init; /* to search for a '*s2' inside 's1' */
550 l2--; /* 1st char will be checked by 'memchr' */ 550 l2--; /* 1st char will be checked by 'memchr' */
551 l1 = l1-l2; /* 's2' cannot be found after that */ 551 l1 = l1-l2; /* 's2' cannot be found after that */
552 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { 552 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
553 init++; /* 1st char is already checked */ 553 init++; /* 1st char is already checked */
554 if (memcmp(init, s2+1, l2) == 0) 554 if (memcmp(init, s2+1, l2) == 0)
555 return init-1; 555 return init-1;
556 else { /* correct 'l1' and 's1' to try again */ 556 else { /* correct 'l1' and 's1' to try again */
557 l1 -= init-s1; 557 l1 -= init-s1;
558 s1 = init; 558 s1 = init;
559 } 559 }
560 } 560 }
561 return NULL; /* not found */ 561 return NULL; /* not found */
562 } 562 }
563} 563}
564 564
565 565
566static void push_onecapture (MatchState *ms, int i, const char *s, 566static void push_onecapture (MatchState *ms, int i, const char *s,
567 const char *e) { 567 const char *e) {
568 if (i >= ms->level) { 568 if (i >= ms->level) {
569 if (i == 0) /* ms->level == 0, too */ 569 if (i == 0) /* ms->level == 0, too */
570 lua_pushlstring(ms->L, s, e - s); /* add whole match */ 570 lua_pushlstring(ms->L, s, e - s); /* add whole match */
571 else 571 else
572 luaL_error(ms->L, "invalid capture index %%%d", i + 1); 572 luaL_error(ms->L, "invalid capture index %%%d", i + 1);
573 } 573 }
574 else { 574 else {
575 ptrdiff_t l = ms->capture[i].len; 575 ptrdiff_t l = ms->capture[i].len;
576 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); 576 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
577 if (l == CAP_POSITION) 577 if (l == CAP_POSITION)
578 lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); 578 lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
579 else 579 else
580 lua_pushlstring(ms->L, ms->capture[i].init, l); 580 lua_pushlstring(ms->L, ms->capture[i].init, l);
581 } 581 }
582} 582}
583 583
584 584
585static int push_captures (MatchState *ms, const char *s, const char *e) { 585static int push_captures (MatchState *ms, const char *s, const char *e) {
586 int i; 586 int i;
587 int nlevels = (ms->level == 0 && s) ? 1 : ms->level; 587 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
588 luaL_checkstack(ms->L, nlevels, "too many captures"); 588 luaL_checkstack(ms->L, nlevels, "too many captures");
589 for (i = 0; i < nlevels; i++) 589 for (i = 0; i < nlevels; i++)
590 push_onecapture(ms, i, s, e); 590 push_onecapture(ms, i, s, e);
591 return nlevels; /* number of strings pushed */ 591 return nlevels; /* number of strings pushed */
592} 592}
593 593
594 594
595/* check whether pattern has no special characters */ 595/* check whether pattern has no special characters */
596static int nospecials (const char *p, size_t l) { 596static int nospecials (const char *p, size_t l) {
597 size_t upto = 0; 597 size_t upto = 0;
598 do { 598 do {
599 if (strpbrk(p + upto, SPECIALS)) 599 if (strpbrk(p + upto, SPECIALS))
600 return 0; /* pattern has a special character */ 600 return 0; /* pattern has a special character */
601 upto += strlen(p + upto) + 1; /* may have more after \0 */ 601 upto += strlen(p + upto) + 1; /* may have more after \0 */
602 } while (upto <= l); 602 } while (upto <= l);
603 return 1; /* no special chars found */ 603 return 1; /* no special chars found */
604} 604}
605 605
606 606
607static void prepstate (MatchState *ms, lua_State *L, 607static void prepstate (MatchState *ms, lua_State *L,
608 const char *s, size_t ls, const char *p, size_t lp) { 608 const char *s, size_t ls, const char *p, size_t lp) {
609 ms->L = L; 609 ms->L = L;
610 ms->matchdepth = MAXCCALLS; 610 ms->matchdepth = MAXCCALLS;
611 ms->src_init = s; 611 ms->src_init = s;
612 ms->src_end = s + ls; 612 ms->src_end = s + ls;
613 ms->p_end = p + lp; 613 ms->p_end = p + lp;
614 if (ls < (MAX_SIZET - B_REPS) / A_REPS) 614 if (ls < (MAX_SIZET - B_REPS) / A_REPS)
615 ms->nrep = A_REPS * ls + B_REPS; 615 ms->nrep = A_REPS * ls + B_REPS;
616 else /* overflow (very long subject) */ 616 else /* overflow (very long subject) */
617 ms->nrep = MAX_SIZET; /* no limit */ 617 ms->nrep = MAX_SIZET; /* no limit */
618} 618}
619 619
620 620
621static void reprepstate (MatchState *ms) { 621static void reprepstate (MatchState *ms) {
622 ms->level = 0; 622 ms->level = 0;
623 lua_assert(ms->matchdepth == MAXCCALLS); 623 lua_assert(ms->matchdepth == MAXCCALLS);
624} 624}
625 625
626 626
627static int str_find_aux (lua_State *L, int find) { 627static int str_find_aux (lua_State *L, int find) {
628 size_t ls, lp; 628 size_t ls, lp;
629 const char *s = luaL_checklstring(L, 1, &ls); 629 const char *s = luaL_checklstring(L, 1, &ls);
630 const char *p = luaL_checklstring(L, 2, &lp); 630 const char *p = luaL_checklstring(L, 2, &lp);
631 lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); 631 lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls);
632 if (init < 1) init = 1; 632 if (init < 1) init = 1;
633 else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ 633 else if (init > (lua_Integer)ls + 1) { /* start after string's end? */
634 lua_pushnil(L); /* cannot find anything */ 634 lua_pushnil(L); /* cannot find anything */
635 return 1; 635 return 1;
636 } 636 }
637 /* explicit request or no special characters? */ 637 /* explicit request or no special characters? */
638 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { 638 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
639 /* do a plain search */ 639 /* do a plain search */
640 const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp); 640 const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
641 if (s2) { 641 if (s2) {
642 lua_pushinteger(L, (s2 - s) + 1); 642 lua_pushinteger(L, (s2 - s) + 1);
643 lua_pushinteger(L, (s2 - s) + lp); 643 lua_pushinteger(L, (s2 - s) + lp);
644 return 2; 644 return 2;
645 } 645 }
646 } 646 }
647 else { 647 else {
648 MatchState ms; 648 MatchState ms;
649 const char *s1 = s + init - 1; 649 const char *s1 = s + init - 1;
650 int anchor = (*p == '^'); 650 int anchor = (*p == '^');
651 if (anchor) { 651 if (anchor) {
652 p++; lp--; /* skip anchor character */ 652 p++; lp--; /* skip anchor character */
653 } 653 }
654 prepstate(&ms, L, s, ls, p, lp); 654 prepstate(&ms, L, s, ls, p, lp);
655 do { 655 do {
656 const char *res; 656 const char *res;
657 reprepstate(&ms); 657 reprepstate(&ms);
658 if ((res=match(&ms, s1, p)) != NULL) { 658 if ((res=match(&ms, s1, p)) != NULL) {
659 if (find) { 659 if (find) {
660 lua_pushinteger(L, (s1 - s) + 1); /* start */ 660 lua_pushinteger(L, (s1 - s) + 1); /* start */
661 lua_pushinteger(L, res - s); /* end */ 661 lua_pushinteger(L, res - s); /* end */
662 return push_captures(&ms, NULL, 0) + 2; 662 return push_captures(&ms, NULL, 0) + 2;
663 } 663 }
664 else 664 else
665 return push_captures(&ms, s1, res); 665 return push_captures(&ms, s1, res);
666 } 666 }
667 } while (s1++ < ms.src_end && !anchor); 667 } while (s1++ < ms.src_end && !anchor);
668 } 668 }
669 lua_pushnil(L); /* not found */ 669 lua_pushnil(L); /* not found */
670 return 1; 670 return 1;
671} 671}
672 672
673 673
674static int str_find (lua_State *L) { 674static int str_find (lua_State *L) {
675 return str_find_aux(L, 1); 675 return str_find_aux(L, 1);
676} 676}
677 677
678 678
679static int str_match (lua_State *L) { 679static int str_match (lua_State *L) {
680 return str_find_aux(L, 0); 680 return str_find_aux(L, 0);
681} 681}
682 682
683 683
684/* state for 'gmatch' */ 684/* state for 'gmatch' */
685typedef struct GMatchState { 685typedef struct GMatchState {
686 const char *src; /* current position */ 686 const char *src; /* current position */
687 const char *p; /* pattern */ 687 const char *p; /* pattern */
688 MatchState ms; /* match state */ 688 MatchState ms; /* match state */
689} GMatchState; 689} GMatchState;
690 690
691 691
692static int gmatch_aux (lua_State *L) { 692static int gmatch_aux (lua_State *L) {
693 GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); 693 GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
694 const char *src; 694 const char *src;
 695 gm->ms.L = L;
695 for (src = gm->src; src <= gm->ms.src_end; src++) { 696 for (src = gm->src; src <= gm->ms.src_end; src++) {
696 const char *e; 697 const char *e;
697 reprepstate(&gm->ms); 698 reprepstate(&gm->ms);
698 if ((e = match(&gm->ms, src, gm->p)) != NULL) { 699 if ((e = match(&gm->ms, src, gm->p)) != NULL) {
699 if (e == src) /* empty match? */ 700 if (e == src) /* empty match? */
700 gm->src =src + 1; /* go at least one position */ 701 gm->src =src + 1; /* go at least one position */
701 else 702 else
702 gm->src = e; 703 gm->src = e;
703 return push_captures(&gm->ms, src, e); 704 return push_captures(&gm->ms, src, e);
704 } 705 }
705 } 706 }
706 return 0; /* not found */ 707 return 0; /* not found */
707} 708}
708 709
709 710
710static int gmatch (lua_State *L) { 711static int gmatch (lua_State *L) {
711 size_t ls, lp; 712 size_t ls, lp;
712 const char *s = luaL_checklstring(L, 1, &ls); 713 const char *s = luaL_checklstring(L, 1, &ls);
713 const char *p = luaL_checklstring(L, 2, &lp); 714 const char *p = luaL_checklstring(L, 2, &lp);
714 GMatchState *gm; 715 GMatchState *gm;
715 lua_settop(L, 2); /* keep them on closure to avoid being collected */ 716 lua_settop(L, 2); /* keep them on closure to avoid being collected */
716 gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); 717 gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
717 prepstate(&gm->ms, L, s, ls, p, lp); 718 prepstate(&gm->ms, L, s, ls, p, lp);
718 gm->src = s; gm->p = p; 719 gm->src = s; gm->p = p;
719 lua_pushcclosure(L, gmatch_aux, 3); 720 lua_pushcclosure(L, gmatch_aux, 3);
720 return 1; 721 return 1;
721} 722}
722 723
723 724
724static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, 725static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
725 const char *e) { 726 const char *e) {
726 size_t l, i; 727 size_t l, i;
727 lua_State *L = ms->L; 728 lua_State *L = ms->L;
728 const char *news = lua_tolstring(L, 3, &l); 729 const char *news = lua_tolstring(L, 3, &l);
729 for (i = 0; i < l; i++) { 730 for (i = 0; i < l; i++) {
730 if (news[i] != L_ESC) 731 if (news[i] != L_ESC)
731 luaL_addchar(b, news[i]); 732 luaL_addchar(b, news[i]);
732 else { 733 else {
733 i++; /* skip ESC */ 734 i++; /* skip ESC */
734 if (!isdigit(uchar(news[i]))) { 735 if (!isdigit(uchar(news[i]))) {
735 if (news[i] != L_ESC) 736 if (news[i] != L_ESC)
736 luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); 737 luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
737 luaL_addchar(b, news[i]); 738 luaL_addchar(b, news[i]);
738 } 739 }
739 else if (news[i] == '0') 740 else if (news[i] == '0')
740 luaL_addlstring(b, s, e - s); 741 luaL_addlstring(b, s, e - s);
741 else { 742 else {
742 push_onecapture(ms, news[i] - '1', s, e); 743 push_onecapture(ms, news[i] - '1', s, e);
743 luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ 744 luaL_tolstring(L, -1, NULL); /* if number, convert it to string */
744 lua_remove(L, -2); /* remove original value */ 745 lua_remove(L, -2); /* remove original value */
745 luaL_addvalue(b); /* add capture to accumulated result */ 746 luaL_addvalue(b); /* add capture to accumulated result */
746 } 747 }
747 } 748 }
748 } 749 }
749} 750}
750 751
751 752
752static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, 753static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
753 const char *e, int tr) { 754 const char *e, int tr) {
754 lua_State *L = ms->L; 755 lua_State *L = ms->L;
755 switch (tr) { 756 switch (tr) {
756 case LUA_TFUNCTION: { 757 case LUA_TFUNCTION: {
757 int n; 758 int n;
758 lua_pushvalue(L, 3); 759 lua_pushvalue(L, 3);
759 n = push_captures(ms, s, e); 760 n = push_captures(ms, s, e);
760 lua_call(L, n, 1); 761 lua_call(L, n, 1);
761 break; 762 break;
762 } 763 }
763 case LUA_TTABLE: { 764 case LUA_TTABLE: {
764 push_onecapture(ms, 0, s, e); 765 push_onecapture(ms, 0, s, e);
765 lua_gettable(L, 3); 766 lua_gettable(L, 3);
766 break; 767 break;
767 } 768 }
768 default: { /* LUA_TNUMBER or LUA_TSTRING */ 769 default: { /* LUA_TNUMBER or LUA_TSTRING */
769 add_s(ms, b, s, e); 770 add_s(ms, b, s, e);
770 return; 771 return;
771 } 772 }
772 } 773 }
773 if (!lua_toboolean(L, -1)) { /* nil or false? */ 774 if (!lua_toboolean(L, -1)) { /* nil or false? */
774 lua_pop(L, 1); 775 lua_pop(L, 1);
775 lua_pushlstring(L, s, e - s); /* keep original text */ 776 lua_pushlstring(L, s, e - s); /* keep original text */
776 } 777 }
777 else if (!lua_isstring(L, -1)) 778 else if (!lua_isstring(L, -1))
778 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); 779 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
779 luaL_addvalue(b); /* add result to accumulator */ 780 luaL_addvalue(b); /* add result to accumulator */
780} 781}
781 782
782 783
783static int str_gsub (lua_State *L) { 784static int str_gsub (lua_State *L) {
784 size_t srcl, lp; 785 size_t srcl, lp;
785 const char *src = luaL_checklstring(L, 1, &srcl); 786 const char *src = luaL_checklstring(L, 1, &srcl);
786 const char *p = luaL_checklstring(L, 2, &lp); 787 const char *p = luaL_checklstring(L, 2, &lp);
787 int tr = lua_type(L, 3); 788 int tr = lua_type(L, 3);
788 lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); 789 lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
789 int anchor = (*p == '^'); 790 int anchor = (*p == '^');
790 lua_Integer n = 0; 791 lua_Integer n = 0;
791 MatchState ms; 792 MatchState ms;
792 luaL_Buffer b; 793 luaL_Buffer b;
793 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || 794 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
794 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, 795 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
795 "string/function/table expected"); 796 "string/function/table expected");
796 luaL_buffinit(L, &b); 797 luaL_buffinit(L, &b);
797 if (anchor) { 798 if (anchor) {
798 p++; lp--; /* skip anchor character */ 799 p++; lp--; /* skip anchor character */
799 } 800 }
800 prepstate(&ms, L, src, srcl, p, lp); 801 prepstate(&ms, L, src, srcl, p, lp);
801 while (n < max_s) { 802 while (n < max_s) {
802 const char *e; 803 const char *e;
803 reprepstate(&ms); 804 reprepstate(&ms);
804 if ((e = match(&ms, src, p)) != NULL) { 805 if ((e = match(&ms, src, p)) != NULL) {
805 n++; 806 n++;
806 add_value(&ms, &b, src, e, tr); 807 add_value(&ms, &b, src, e, tr);
807 } 808 }
808 if (e && e>src) /* non empty match? */ 809 if (e && e>src) /* non empty match? */
809 src = e; /* skip it */ 810 src = e; /* skip it */
810 else if (src < ms.src_end) 811 else if (src < ms.src_end)
811 luaL_addchar(&b, *src++); 812 luaL_addchar(&b, *src++);
812 else break; 813 else break;
813 if (anchor) break; 814 if (anchor) break;
814 } 815 }
815 luaL_addlstring(&b, src, ms.src_end-src); 816 luaL_addlstring(&b, src, ms.src_end-src);
816 luaL_pushresult(&b); 817 luaL_pushresult(&b);
817 lua_pushinteger(L, n); /* number of substitutions */ 818 lua_pushinteger(L, n); /* number of substitutions */
818 return 2; 819 return 2;
819} 820}
820 821
821/* }====================================================== */ 822/* }====================================================== */
822 823
823 824
824 825
825/* 826/*
826** {====================================================== 827** {======================================================
827** STRING FORMAT 828** STRING FORMAT
828** ======================================================= 829** =======================================================
829*/ 830*/
830 831
831#if !defined(lua_number2strx) /* { */ 832#if !defined(lua_number2strx) /* { */
832 833
833/* 834/*
834** Hexadecimal floating-point formatter 835** Hexadecimal floating-point formatter
835*/ 836*/
836 837
837#include <locale.h> 838#include <locale.h>
838#include <math.h> 839#include <math.h>
839 840
840#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) 841#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
841 842
842 843
843/* 844/*
844** Number of bits that goes into the first digit. It can be any value 845** Number of bits that goes into the first digit. It can be any value
845** between 1 and 4; the following definition tries to align the number 846** between 1 and 4; the following definition tries to align the number
846** to nibble boundaries by making what is left after that first digit a 847** to nibble boundaries by making what is left after that first digit a
847** multiple of 4. 848** multiple of 4.
848*/ 849*/
849#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1) 850#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1)
850 851
851 852
852/* 853/*
853** Add integer part of 'x' to buffer and return new 'x' 854** Add integer part of 'x' to buffer and return new 'x'
854*/ 855*/
855static lua_Number adddigit (char *buff, int n, lua_Number x) { 856static lua_Number adddigit (char *buff, int n, lua_Number x) {
856 lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ 857 lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
857 int d = (int)dd; 858 int d = (int)dd;
858 buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ 859 buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
859 return x - dd; /* return what is left */ 860 return x - dd; /* return what is left */
860} 861}
861 862
862 863
863static int num2straux (char *buff, int sz, lua_Number x) { 864static int num2straux (char *buff, int sz, lua_Number x) {
864 if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */ 865 if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
865 return l_sprintf(buff, sz, LUA_NUMBER_FMT, x); /* equal to '%g' */ 866 return l_sprintf(buff, sz, LUA_NUMBER_FMT, x); /* equal to '%g' */
866 else if (x == 0) { /* can be -0... */ 867 else if (x == 0) { /* can be -0... */
867 /* create "0" or "-0" followed by exponent */ 868 /* create "0" or "-0" followed by exponent */
868 return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", x); 869 return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", x);
869 } 870 }
870 else { 871 else {
871 int e; 872 int e;
872 lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ 873 lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
873 int n = 0; /* character count */ 874 int n = 0; /* character count */
874 if (m < 0) { /* is number negative? */ 875 if (m < 0) { /* is number negative? */
875 buff[n++] = '-'; /* add signal */ 876 buff[n++] = '-'; /* add signal */
876 m = -m; /* make it positive */ 877 m = -m; /* make it positive */
877 } 878 }
878 buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ 879 buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
879 m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ 880 m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
880 e -= L_NBFD; /* this digit goes before the radix point */ 881 e -= L_NBFD; /* this digit goes before the radix point */
881 if (m > 0) { /* more digits? */ 882 if (m > 0) { /* more digits? */
882 buff[n++] = lua_getlocaledecpoint(); /* add radix point */ 883 buff[n++] = lua_getlocaledecpoint(); /* add radix point */
883 do { /* add as many digits as needed */ 884 do { /* add as many digits as needed */
884 m = adddigit(buff, n++, m * 16); 885 m = adddigit(buff, n++, m * 16);
885 } while (m > 0); 886 } while (m > 0);
886 } 887 }
887 n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ 888 n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */
888 lua_assert(n < sz); 889 lua_assert(n < sz);
889 return n; 890 return n;
890 } 891 }
891} 892}
892 893
893 894
894static int lua_number2strx (lua_State *L, char *buff, int sz, 895static int lua_number2strx (lua_State *L, char *buff, int sz,
895 const char *fmt, lua_Number x) { 896 const char *fmt, lua_Number x) {
896 int n = num2straux(buff, sz, x); 897 int n = num2straux(buff, sz, x);
897 if (fmt[SIZELENMOD] == 'A') { 898 if (fmt[SIZELENMOD] == 'A') {
898 int i; 899 int i;
899 for (i = 0; i < n; i++) 900 for (i = 0; i < n; i++)
900 buff[i] = toupper(uchar(buff[i])); 901 buff[i] = toupper(uchar(buff[i]));
901 } 902 }
902 else if (fmt[SIZELENMOD] != 'a') 903 else if (fmt[SIZELENMOD] != 'a')
903 luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); 904 luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
904 return n; 905 return n;
905} 906}
906 907
907#endif /* } */ 908#endif /* } */
908 909
909 910
910/* 911/*
911** Maximum size of each formatted item. This maximum size is produced 912** Maximum size of each formatted item. This maximum size is produced
912** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', 913** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
913** and '\0') + number of decimal digits to represent maxfloat (which 914** and '\0') + number of decimal digits to represent maxfloat (which
914** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra 915** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra
915** expenses", such as locale-dependent stuff) 916** expenses", such as locale-dependent stuff)
916*/ 917*/
917#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) 918#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP))
918 919
919 920
920/* valid flags in a format specification */ 921/* valid flags in a format specification */
921#define FLAGS "-+ #0" 922#define FLAGS "-+ #0"
922 923
923/* 924/*
924** maximum size of each format specification (such as "%-099.99d") 925** maximum size of each format specification (such as "%-099.99d")
925*/ 926*/
926#define MAX_FORMAT 32 927#define MAX_FORMAT 32
927 928
928 929
929static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { 930static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
930 size_t l; 931 size_t l;
931 const char *s = luaL_checklstring(L, arg, &l); 932 const char *s = luaL_checklstring(L, arg, &l);
932 luaL_addchar(b, '"'); 933 luaL_addchar(b, '"');
933 while (l--) { 934 while (l--) {
934 if (*s == '"' || *s == '\\' || *s == '\n') { 935 if (*s == '"' || *s == '\\' || *s == '\n') {
935 luaL_addchar(b, '\\'); 936 luaL_addchar(b, '\\');
936 luaL_addchar(b, *s); 937 luaL_addchar(b, *s);
937 } 938 }
938 else if (*s == '\0' || iscntrl(uchar(*s))) { 939 else if (*s == '\0' || iscntrl(uchar(*s))) {
939 char buff[10]; 940 char buff[10];
940 if (!isdigit(uchar(*(s+1)))) 941 if (!isdigit(uchar(*(s+1))))
941 l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); 942 l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
942 else 943 else
943 l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); 944 l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
944 luaL_addstring(b, buff); 945 luaL_addstring(b, buff);
945 } 946 }
946 else 947 else
947 luaL_addchar(b, *s); 948 luaL_addchar(b, *s);
948 s++; 949 s++;
949 } 950 }
950 luaL_addchar(b, '"'); 951 luaL_addchar(b, '"');
951} 952}
952 953
953static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { 954static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
954 const char *p = strfrmt; 955 const char *p = strfrmt;
955 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ 956 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
956 if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) 957 if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
957 luaL_error(L, "invalid format (repeated flags)"); 958 luaL_error(L, "invalid format (repeated flags)");
958 if (isdigit(uchar(*p))) p++; /* skip width */ 959 if (isdigit(uchar(*p))) p++; /* skip width */
959 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ 960 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
960 if (*p == '.') { 961 if (*p == '.') {
961 p++; 962 p++;
962 if (isdigit(uchar(*p))) p++; /* skip precision */ 963 if (isdigit(uchar(*p))) p++; /* skip precision */
963 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ 964 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
964 } 965 }
965 if (isdigit(uchar(*p))) 966 if (isdigit(uchar(*p)))
966 luaL_error(L, "invalid format (width or precision too long)"); 967 luaL_error(L, "invalid format (width or precision too long)");
967 *(form++) = '%'; 968 *(form++) = '%';
968 memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); 969 memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
969 form += (p - strfrmt) + 1; 970 form += (p - strfrmt) + 1;
970 *form = '\0'; 971 *form = '\0';
971 return p; 972 return p;
972} 973}
973 974
974 975
975/* 976/*
976** add length modifier into formats 977** add length modifier into formats
977*/ 978*/
978static void addlenmod (char *form, const char *lenmod) { 979static void addlenmod (char *form, const char *lenmod) {
979 size_t l = strlen(form); 980 size_t l = strlen(form);
980 size_t lm = strlen(lenmod); 981 size_t lm = strlen(lenmod);
981 char spec = form[l - 1]; 982 char spec = form[l - 1];
982 strcpy(form + l - 1, lenmod); 983 strcpy(form + l - 1, lenmod);
983 form[l + lm - 1] = spec; 984 form[l + lm - 1] = spec;
984 form[l + lm] = '\0'; 985 form[l + lm] = '\0';
985} 986}
986 987
987 988
988static int str_format (lua_State *L) { 989static int str_format (lua_State *L) {
989 int top = lua_gettop(L); 990 int top = lua_gettop(L);
990 int arg = 1; 991 int arg = 1;
991 size_t sfl; 992 size_t sfl;
992 const char *strfrmt = luaL_checklstring(L, arg, &sfl); 993 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
993 const char *strfrmt_end = strfrmt+sfl; 994 const char *strfrmt_end = strfrmt+sfl;
994 luaL_Buffer b; 995 luaL_Buffer b;
995 luaL_buffinit(L, &b); 996 luaL_buffinit(L, &b);
996 while (strfrmt < strfrmt_end) { 997 while (strfrmt < strfrmt_end) {
997 if (*strfrmt != L_ESC) 998 if (*strfrmt != L_ESC)
998 luaL_addchar(&b, *strfrmt++); 999 luaL_addchar(&b, *strfrmt++);
999 else if (*++strfrmt == L_ESC) 1000 else if (*++strfrmt == L_ESC)
1000 luaL_addchar(&b, *strfrmt++); /* %% */ 1001 luaL_addchar(&b, *strfrmt++); /* %% */
1001 else { /* format item */ 1002 else { /* format item */
1002 char form[MAX_FORMAT]; /* to store the format ('%...') */ 1003 char form[MAX_FORMAT]; /* to store the format ('%...') */
1003 char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ 1004 char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */
1004 int nb = 0; /* number of bytes in added item */ 1005 int nb = 0; /* number of bytes in added item */
1005 if (++arg > top) 1006 if (++arg > top)
1006 luaL_argerror(L, arg, "no value"); 1007 luaL_argerror(L, arg, "no value");
1007 strfrmt = scanformat(L, strfrmt, form); 1008 strfrmt = scanformat(L, strfrmt, form);
1008 switch (*strfrmt++) { 1009 switch (*strfrmt++) {
1009 case 'c': { 1010 case 'c': {
1010 nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); 1011 nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg));
1011 break; 1012 break;
1012 } 1013 }
1013 case 'd': case 'i': 1014 case 'd': case 'i':
1014 case 'o': case 'u': case 'x': case 'X': { 1015 case 'o': case 'u': case 'x': case 'X': {
1015 lua_Integer n = luaL_checkinteger(L, arg); 1016 lua_Integer n = luaL_checkinteger(L, arg);
1016 addlenmod(form, LUA_INTEGER_FRMLEN); 1017 addlenmod(form, LUA_INTEGER_FRMLEN);
1017 nb = l_sprintf(buff, MAX_ITEM, form, n); 1018 nb = l_sprintf(buff, MAX_ITEM, form, n);
1018 break; 1019 break;
1019 } 1020 }
1020#ifndef _KERNEL 1021#ifndef _KERNEL
1021 case 'a': case 'A': 1022 case 'a': case 'A':
1022 addlenmod(form, LUA_NUMBER_FRMLEN); 1023 addlenmod(form, LUA_NUMBER_FRMLEN);
1023 nb = lua_number2strx(L, buff, MAX_ITEM, form, 1024 nb = lua_number2strx(L, buff, MAX_ITEM, form,
1024 luaL_checknumber(L, arg)); 1025 luaL_checknumber(L, arg));
1025 break; 1026 break;
1026 case 'e': case 'E': case 'f': 1027 case 'e': case 'E': case 'f':
1027 case 'g': case 'G': { 1028 case 'g': case 'G': {
1028 addlenmod(form, LUA_NUMBER_FRMLEN); 1029 addlenmod(form, LUA_NUMBER_FRMLEN);
1029 nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg)); 1030 nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg));
1030 break; 1031 break;
1031 } 1032 }
1032#endif /* _KERNEL */ 1033#endif /* _KERNEL */
1033 case 'q': { 1034 case 'q': {
1034 addquoted(L, &b, arg); 1035 addquoted(L, &b, arg);
1035 break; 1036 break;
1036 } 1037 }
1037 case 's': { 1038 case 's': {
1038 size_t l; 1039 size_t l;
1039 const char *s = luaL_tolstring(L, arg, &l); 1040 const char *s = luaL_tolstring(L, arg, &l);
1040 if (form[2] == '\0') /* no modifiers? */ 1041 if (form[2] == '\0') /* no modifiers? */
1041 luaL_addvalue(&b); /* keep entire string */ 1042 luaL_addvalue(&b); /* keep entire string */
1042 else { 1043 else {
1043 luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); 1044 luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
1044 if (!strchr(form, '.') && l >= 100) { 1045 if (!strchr(form, '.') && l >= 100) {
1045 /* no precision and string is too long to be formatted */ 1046 /* no precision and string is too long to be formatted */
1046 luaL_addvalue(&b); /* keep entire string */ 1047 luaL_addvalue(&b); /* keep entire string */
1047 } 1048 }
1048 else { /* format the string into 'buff' */ 1049 else { /* format the string into 'buff' */
1049 nb = l_sprintf(buff, MAX_ITEM, form, s); 1050 nb = l_sprintf(buff, MAX_ITEM, form, s);
1050 lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ 1051 lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
1051 } 1052 }
1052 } 1053 }
1053 break; 1054 break;
1054 } 1055 }
1055 default: { /* also treat cases 'pnLlh' */ 1056 default: { /* also treat cases 'pnLlh' */
1056 return luaL_error(L, "invalid option '%%%c' to 'format'", 1057 return luaL_error(L, "invalid option '%%%c' to 'format'",
1057 *(strfrmt - 1)); 1058 *(strfrmt - 1));
1058 } 1059 }
1059 } 1060 }
1060 lua_assert(nb < MAX_ITEM); 1061 lua_assert(nb < MAX_ITEM);
1061 luaL_addsize(&b, nb); 1062 luaL_addsize(&b, nb);
1062 } 1063 }
1063 } 1064 }
1064 luaL_pushresult(&b); 1065 luaL_pushresult(&b);
1065 return 1; 1066 return 1;
1066} 1067}
1067 1068
1068/* }====================================================== */ 1069/* }====================================================== */
1069 1070
1070 1071
1071/* 1072/*
1072** {====================================================== 1073** {======================================================
1073** PACK/UNPACK 1074** PACK/UNPACK
1074** ======================================================= 1075** =======================================================
1075*/ 1076*/
1076 1077
1077 1078
1078/* value used for padding */ 1079/* value used for padding */
1079#if !defined(LUA_PACKPADBYTE) 1080#if !defined(LUA_PACKPADBYTE)
1080#define LUA_PACKPADBYTE 0x00 1081#define LUA_PACKPADBYTE 0x00
1081#endif 1082#endif
1082 1083
1083/* maximum size for the binary representation of an integer */ 1084/* maximum size for the binary representation of an integer */
1084#define MAXINTSIZE 16 1085#define MAXINTSIZE 16
1085 1086
1086/* number of bits in a character */ 1087/* number of bits in a character */
1087#define NB CHAR_BIT 1088#define NB CHAR_BIT
1088 1089
1089/* mask for one character (NB 1's) */ 1090/* mask for one character (NB 1's) */
1090#define MC ((1 << NB) - 1) 1091#define MC ((1 << NB) - 1)
1091 1092
1092/* size of a lua_Integer */ 1093/* size of a lua_Integer */
1093#define SZINT ((int)sizeof(lua_Integer)) 1094#define SZINT ((int)sizeof(lua_Integer))
1094 1095
1095 1096
1096/* dummy union to get native endianness */ 1097/* dummy union to get native endianness */
1097static const union { 1098static const union {
1098 int dummy; 1099 int dummy;
1099 char little; /* true iff machine is little endian */ 1100 char little; /* true iff machine is little endian */
1100} nativeendian = {1}; 1101} nativeendian = {1};
1101 1102
1102 1103
1103/* dummy structure to get native alignment requirements */ 1104/* dummy structure to get native alignment requirements */
1104struct cD { 1105struct cD {
1105 char c; 1106 char c;
1106#ifndef _KERNEL 1107#ifndef _KERNEL
1107 union { double d; void *p; lua_Integer i; lua_Number n; } u; 1108 union { double d; void *p; lua_Integer i; lua_Number n; } u;
1108#else /* _KERNEL */ 1109#else /* _KERNEL */
1109 union { void *p; lua_Integer i; lua_Number n; } u; 1110 union { void *p; lua_Integer i; lua_Number n; } u;
1110#endif /* _KERNEL */ 1111#endif /* _KERNEL */
1111}; 1112};
1112 1113
1113#define MAXALIGN (offsetof(struct cD, u)) 1114#define MAXALIGN (offsetof(struct cD, u))
1114 1115
1115 1116
1116#ifndef _KERNEL 1117#ifndef _KERNEL
1117/* 1118/*
1118** Union for serializing floats 1119** Union for serializing floats
1119*/ 1120*/
1120typedef union Ftypes { 1121typedef union Ftypes {
1121 float f; 1122 float f;
1122 double d; 1123 double d;
1123 lua_Number n; 1124 lua_Number n;
1124 char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ 1125 char buff[5 * sizeof(lua_Number)]; /* enough for any float type */
1125} Ftypes; 1126} Ftypes;
1126#endif /* _KERNEL */ 1127#endif /* _KERNEL */
1127 1128
1128 1129
1129/* 1130/*
1130** information to pack/unpack stuff 1131** information to pack/unpack stuff
1131*/ 1132*/
1132typedef struct Header { 1133typedef struct Header {
1133 lua_State *L; 1134 lua_State *L;
1134 int islittle; 1135 int islittle;
1135 int maxalign; 1136 int maxalign;
1136} Header; 1137} Header;
1137 1138
1138 1139
1139/* 1140/*
1140** options for pack/unpack 1141** options for pack/unpack
1141*/ 1142*/
1142typedef enum KOption { 1143typedef enum KOption {
1143 Kint, /* signed integers */ 1144 Kint, /* signed integers */
1144 Kuint, /* unsigned integers */ 1145 Kuint, /* unsigned integers */
1145#ifndef _KERNEL 1146#ifndef _KERNEL
1146 Kfloat, /* floating-point numbers */ 1147 Kfloat, /* floating-point numbers */
1147#endif /* _KERNEL */ 1148#endif /* _KERNEL */
1148 Kchar, /* fixed-length strings */ 1149 Kchar, /* fixed-length strings */
1149 Kstring, /* strings with prefixed length */ 1150 Kstring, /* strings with prefixed length */
1150 Kzstr, /* zero-terminated strings */ 1151 Kzstr, /* zero-terminated strings */
1151 Kpadding, /* padding */ 1152 Kpadding, /* padding */
1152 Kpaddalign, /* padding for alignment */ 1153 Kpaddalign, /* padding for alignment */
1153 Knop /* no-op (configuration or spaces) */ 1154 Knop /* no-op (configuration or spaces) */
1154} KOption; 1155} KOption;
1155 1156
1156 1157
1157/* 1158/*
1158** Read an integer numeral from string 'fmt' or return 'df' if 1159** Read an integer numeral from string 'fmt' or return 'df' if
1159** there is no numeral 1160** there is no numeral
1160*/ 1161*/
1161static int digit (int c) { return '0' <= c && c <= '9'; } 1162static int digit (int c) { return '0' <= c && c <= '9'; }
1162 1163
1163static int getnum (const char **fmt, int df) { 1164static int getnum (const char **fmt, int df) {
1164 if (!digit(**fmt)) /* no number? */ 1165 if (!digit(**fmt)) /* no number? */
1165 return df; /* return default value */ 1166 return df; /* return default value */
1166 else { 1167 else {
1167 int a = 0; 1168 int a = 0;
1168 do { 1169 do {
1169 a = a*10 + (*((*fmt)++) - '0'); 1170 a = a*10 + (*((*fmt)++) - '0');
1170 } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); 1171 } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10);
1171 return a; 1172 return a;
1172 } 1173 }
1173} 1174}
1174 1175
1175 1176
1176/* 1177/*
1177** Read an integer numeral and raises an error if it is larger 1178** Read an integer numeral and raises an error if it is larger
1178** than the maximum size for integers. 1179** than the maximum size for integers.
1179*/ 1180*/
1180static int getnumlimit (Header *h, const char **fmt, int df) { 1181static int getnumlimit (Header *h, const char **fmt, int df) {
1181 int sz = getnum(fmt, df); 1182 int sz = getnum(fmt, df);
1182 if (sz > MAXINTSIZE || sz <= 0) 1183 if (sz > MAXINTSIZE || sz <= 0)
1183 luaL_error(h->L, "integral size (%d) out of limits [1,%d]", 1184 luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
1184 sz, MAXINTSIZE); 1185 sz, MAXINTSIZE);
1185 return sz; 1186 return sz;
1186} 1187}
1187 1188
1188 1189
1189/* 1190/*
1190** Initialize Header 1191** Initialize Header
1191*/ 1192*/
1192static void initheader (lua_State *L, Header *h) { 1193static void initheader (lua_State *L, Header *h) {
1193 h->L = L; 1194 h->L = L;
1194 h->islittle = nativeendian.little; 1195 h->islittle = nativeendian.little;
1195 h->maxalign = 1; 1196 h->maxalign = 1;
1196} 1197}
1197 1198
1198 1199
1199/* 1200/*
1200** Read and classify next option. 'size' is filled with option's size. 1201** Read and classify next option. 'size' is filled with option's size.
1201*/ 1202*/
1202static KOption getoption (Header *h, const char **fmt, int *size) { 1203static KOption getoption (Header *h, const char **fmt, int *size) {
1203 int opt = *((*fmt)++); 1204 int opt = *((*fmt)++);
1204 *size = 0; /* default */ 1205 *size = 0; /* default */
1205 switch (opt) { 1206 switch (opt) {
1206 case 'b': *size = sizeof(char); return Kint; 1207 case 'b': *size = sizeof(char); return Kint;
1207 case 'B': *size = sizeof(char); return Kuint; 1208 case 'B': *size = sizeof(char); return Kuint;
1208 case 'h': *size = sizeof(short); return Kint; 1209 case 'h': *size = sizeof(short); return Kint;
1209 case 'H': *size = sizeof(short); return Kuint; 1210 case 'H': *size = sizeof(short); return Kuint;
1210 case 'l': *size = sizeof(long); return Kint; 1211 case 'l': *size = sizeof(long); return Kint;
1211 case 'L': *size = sizeof(long); return Kuint; 1212 case 'L': *size = sizeof(long); return Kuint;
1212 case 'j': *size = sizeof(lua_Integer); return Kint; 1213 case 'j': *size = sizeof(lua_Integer); return Kint;
1213 case 'J': *size = sizeof(lua_Integer); return Kuint; 1214 case 'J': *size = sizeof(lua_Integer); return Kuint;
1214 case 'T': *size = sizeof(size_t); return Kuint; 1215 case 'T': *size = sizeof(size_t); return Kuint;
1215#ifndef _KERNEL 1216#ifndef _KERNEL
1216 case 'f': *size = sizeof(float); return Kfloat; 1217 case 'f': *size = sizeof(float); return Kfloat;
1217 case 'd': *size = sizeof(double); return Kfloat; 1218 case 'd': *size = sizeof(double); return Kfloat;
1218 case 'n': *size = sizeof(lua_Number); return Kfloat; 1219 case 'n': *size = sizeof(lua_Number); return Kfloat;
1219#else /* _KERNEL */ 1220#else /* _KERNEL */
1220 case 'n': *size = sizeof(lua_Number); return Kint; 1221 case 'n': *size = sizeof(lua_Number); return Kint;
1221#endif /* _KERNEL */ 1222#endif /* _KERNEL */
1222 case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; 1223 case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
1223 case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; 1224 case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
1224 case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; 1225 case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
1225 case 'c': 1226 case 'c':
1226 *size = getnum(fmt, -1); 1227 *size = getnum(fmt, -1);
1227 if (*size == -1) 1228 if (*size == -1)
1228 luaL_error(h->L, "missing size for format option 'c'"); 1229 luaL_error(h->L, "missing size for format option 'c'");
1229 return Kchar; 1230 return Kchar;
1230 case 'z': return Kzstr; 1231 case 'z': return Kzstr;
1231 case 'x': *size = 1; return Kpadding; 1232 case 'x': *size = 1; return Kpadding;
1232 case 'X': return Kpaddalign; 1233 case 'X': return Kpaddalign;
1233 case ' ': break; 1234 case ' ': break;
1234 case '<': h->islittle = 1; break; 1235 case '<': h->islittle = 1; break;
1235 case '>': h->islittle = 0; break; 1236 case '>': h->islittle = 0; break;
1236 case '=': h->islittle = nativeendian.little; break; 1237 case '=': h->islittle = nativeendian.little; break;
1237 case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; 1238 case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break;
1238 default: luaL_error(h->L, "invalid format option '%c'", opt); 1239 default: luaL_error(h->L, "invalid format option '%c'", opt);
1239 } 1240 }
1240 return Knop; 1241 return Knop;
1241} 1242}
1242 1243
1243 1244
1244/* 1245/*
1245** Read, classify, and fill other details about the next option. 1246** Read, classify, and fill other details about the next option.
1246** 'psize' is filled with option's size, 'notoalign' with its 1247** 'psize' is filled with option's size, 'notoalign' with its
1247** alignment requirements. 1248** alignment requirements.
1248** Local variable 'size' gets the size to be aligned. (Kpadal option 1249** Local variable 'size' gets the size to be aligned. (Kpadal option
1249** always gets its full alignment, other options are limited by  1250** always gets its full alignment, other options are limited by
1250** the maximum alignment ('maxalign'). Kchar option needs no alignment 1251** the maximum alignment ('maxalign'). Kchar option needs no alignment
1251** despite its size. 1252** despite its size.
1252*/ 1253*/
1253static KOption getdetails (Header *h, size_t totalsize, 1254static KOption getdetails (Header *h, size_t totalsize,
1254 const char **fmt, int *psize, int *ntoalign) { 1255 const char **fmt, int *psize, int *ntoalign) {
1255 KOption opt = getoption(h, fmt, psize); 1256 KOption opt = getoption(h, fmt, psize);
1256 int align = *psize; /* usually, alignment follows size */ 1257 int align = *psize; /* usually, alignment follows size */
1257 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ 1258 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
1258 if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) 1259 if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1259 luaL_argerror(h->L, 1, "invalid next option for option 'X'"); 1260 luaL_argerror(h->L, 1, "invalid next option for option 'X'");
1260 } 1261 }
1261 if (align <= 1 || opt == Kchar) /* need no alignment? */ 1262 if (align <= 1 || opt == Kchar) /* need no alignment? */
1262 *ntoalign = 0; 1263 *ntoalign = 0;
1263 else { 1264 else {
1264 if (align > h->maxalign) /* enforce maximum alignment */ 1265 if (align > h->maxalign) /* enforce maximum alignment */
1265 align = h->maxalign; 1266 align = h->maxalign;
1266 if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ 1267 if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */
1267 luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); 1268 luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1268 *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); 1269 *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
1269 } 1270 }
1270 return opt; 1271 return opt;
1271} 1272}
1272 1273
1273 1274
1274/* 1275/*
1275** Pack integer 'n' with 'size' bytes and 'islittle' endianness. 1276** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
1276** The final 'if' handles the case when 'size' is larger than 1277** The final 'if' handles the case when 'size' is larger than
1277** the size of a Lua integer, correcting the extra sign-extension 1278** the size of a Lua integer, correcting the extra sign-extension
1278** bytes if necessary (by default they would be zeros). 1279** bytes if necessary (by default they would be zeros).
1279*/ 1280*/
1280static void packint (luaL_Buffer *b, lua_Unsigned n, 1281static void packint (luaL_Buffer *b, lua_Unsigned n,
1281 int islittle, int size, int neg) { 1282 int islittle, int size, int neg) {
1282 char *buff = luaL_prepbuffsize(b, size); 1283 char *buff = luaL_prepbuffsize(b, size);
1283 int i; 1284 int i;
1284 buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ 1285 buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */
1285 for (i = 1; i < size; i++) { 1286 for (i = 1; i < size; i++) {
1286 n >>= NB; 1287 n >>= NB;
1287 buff[islittle ? i : size - 1 - i] = (char)(n & MC); 1288 buff[islittle ? i : size - 1 - i] = (char)(n & MC);
1288 } 1289 }
1289 if (neg && size > SZINT) { /* negative number need sign extension? */ 1290 if (neg && size > SZINT) { /* negative number need sign extension? */
1290 for (i = SZINT; i < size; i++) /* correct extra bytes */ 1291 for (i = SZINT; i < size; i++) /* correct extra bytes */
1291 buff[islittle ? i : size - 1 - i] = (char)MC; 1292 buff[islittle ? i : size - 1 - i] = (char)MC;
1292 } 1293 }
1293 luaL_addsize(b, size); /* add result to buffer */ 1294 luaL_addsize(b, size); /* add result to buffer */
1294} 1295}
1295 1296
1296 1297
1297#ifndef _KERNEL 1298#ifndef _KERNEL
1298/* 1299/*
1299** Copy 'size' bytes from 'src' to 'dest', correcting endianness if 1300** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
1300** given 'islittle' is different from native endianness. 1301** given 'islittle' is different from native endianness.
1301*/ 1302*/
1302static void copywithendian (volatile char *dest, volatile const char *src, 1303static void copywithendian (volatile char *dest, volatile const char *src,
1303 int size, int islittle) { 1304 int size, int islittle) {
1304 if (islittle == nativeendian.little) { 1305 if (islittle == nativeendian.little) {
1305 while (size-- != 0) 1306 while (size-- != 0)
1306 *(dest++) = *(src++); 1307 *(dest++) = *(src++);
1307 } 1308 }
1308 else { 1309 else {
1309 dest += size - 1; 1310 dest += size - 1;
1310 while (size-- != 0) 1311 while (size-- != 0)
1311 *(dest--) = *(src++); 1312 *(dest--) = *(src++);
1312 } 1313 }
1313} 1314}
1314#endif /* _KERNEL */ 1315#endif /* _KERNEL */
1315 1316
1316 1317
1317static int str_pack (lua_State *L) { 1318static int str_pack (lua_State *L) {
1318 luaL_Buffer b; 1319 luaL_Buffer b;
1319 Header h; 1320 Header h;
1320 const char *fmt = luaL_checkstring(L, 1); /* format string */ 1321 const char *fmt = luaL_checkstring(L, 1); /* format string */
1321 int arg = 1; /* current argument to pack */ 1322 int arg = 1; /* current argument to pack */
1322 size_t totalsize = 0; /* accumulate total size of result */ 1323 size_t totalsize = 0; /* accumulate total size of result */
1323 initheader(L, &h); 1324 initheader(L, &h);
1324 lua_pushnil(L); /* mark to separate arguments from string buffer */ 1325 lua_pushnil(L); /* mark to separate arguments from string buffer */
1325 luaL_buffinit(L, &b); 1326 luaL_buffinit(L, &b);
1326 while (*fmt != '\0') { 1327 while (*fmt != '\0') {
1327 int size, ntoalign; 1328 int size, ntoalign;
1328 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); 1329 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1329 totalsize += ntoalign + size; 1330 totalsize += ntoalign + size;
1330 while (ntoalign-- > 0) 1331 while (ntoalign-- > 0)
1331 luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */ 1332 luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */
1332 arg++; 1333 arg++;
1333 switch (opt) { 1334 switch (opt) {
1334 case Kint: { /* signed integers */ 1335 case Kint: { /* signed integers */
1335 lua_Integer n = luaL_checkinteger(L, arg); 1336 lua_Integer n = luaL_checkinteger(L, arg);
1336 if (size < SZINT) { /* need overflow check? */ 1337 if (size < SZINT) { /* need overflow check? */
1337 lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); 1338 lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
1338 luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); 1339 luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
1339 } 1340 }
1340 packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); 1341 packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
1341 break; 1342 break;
1342 } 1343 }
1343 case Kuint: { /* unsigned integers */ 1344 case Kuint: { /* unsigned integers */
1344 lua_Integer n = luaL_checkinteger(L, arg); 1345 lua_Integer n = luaL_checkinteger(L, arg);
1345 if (size < SZINT) /* need overflow check? */ 1346 if (size < SZINT) /* need overflow check? */
1346 luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), 1347 luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
1347 arg, "unsigned overflow"); 1348 arg, "unsigned overflow");
1348 packint(&b, (lua_Unsigned)n, h.islittle, size, 0); 1349 packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
1349 break; 1350 break;
1350 } 1351 }
1351#ifndef _KERNEL 1352#ifndef _KERNEL
1352 case Kfloat: { /* floating-point options */ 1353 case Kfloat: { /* floating-point options */
1353 volatile Ftypes u; 1354 volatile Ftypes u;
1354 char *buff = luaL_prepbuffsize(&b, size); 1355 char *buff = luaL_prepbuffsize(&b, size);
1355 lua_Number n = luaL_checknumber(L, arg); /* get argument */ 1356 lua_Number n = luaL_checknumber(L, arg); /* get argument */
1356 if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ 1357 if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */
1357 else if (size == sizeof(u.d)) u.d = (double)n; 1358 else if (size == sizeof(u.d)) u.d = (double)n;
1358 else u.n = n; 1359 else u.n = n;
1359 /* move 'u' to final result, correcting endianness if needed */ 1360 /* move 'u' to final result, correcting endianness if needed */
1360 copywithendian(buff, u.buff, size, h.islittle); 1361 copywithendian(buff, u.buff, size, h.islittle);
1361 luaL_addsize(&b, size); 1362 luaL_addsize(&b, size);
1362 break; 1363 break;
1363 } 1364 }
1364#endif /* _KERNEL */ 1365#endif /* _KERNEL */
1365 case Kchar: { /* fixed-size string */ 1366 case Kchar: { /* fixed-size string */
1366 size_t len; 1367 size_t len;
1367 const char *s = luaL_checklstring(L, arg, &len); 1368 const char *s = luaL_checklstring(L, arg, &len);
1368 if ((size_t)size <= len) /* string larger than (or equal to) needed? */ 1369 if ((size_t)size <= len) /* string larger than (or equal to) needed? */
1369 luaL_addlstring(&b, s, size); /* truncate string to asked size */ 1370 luaL_addlstring(&b, s, size); /* truncate string to asked size */
1370 else { /* string smaller than needed */ 1371 else { /* string smaller than needed */
1371 luaL_addlstring(&b, s, len); /* add it all */ 1372 luaL_addlstring(&b, s, len); /* add it all */
1372 while (len++ < (size_t)size) /* pad extra space */ 1373 while (len++ < (size_t)size) /* pad extra space */
1373 luaL_addchar(&b, LUA_PACKPADBYTE); 1374 luaL_addchar(&b, LUA_PACKPADBYTE);
1374 } 1375 }
1375 break; 1376 break;
1376 } 1377 }
1377 case Kstring: { /* strings with length count */ 1378 case Kstring: { /* strings with length count */
1378 size_t len; 1379 size_t len;
1379 const char *s = luaL_checklstring(L, arg, &len); 1380 const char *s = luaL_checklstring(L, arg, &len);
1380 luaL_argcheck(L, size >= (int)sizeof(size_t) || 1381 luaL_argcheck(L, size >= (int)sizeof(size_t) ||
1381 len < ((size_t)1 << (size * NB)), 1382 len < ((size_t)1 << (size * NB)),
1382 arg, "string length does not fit in given size"); 1383 arg, "string length does not fit in given size");
1383 packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ 1384 packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */
1384 luaL_addlstring(&b, s, len); 1385 luaL_addlstring(&b, s, len);
1385 totalsize += len; 1386 totalsize += len;
1386 break; 1387 break;
1387 } 1388 }
1388 case Kzstr: { /* zero-terminated string */ 1389 case Kzstr: { /* zero-terminated string */
1389 size_t len; 1390 size_t len;
1390 const char *s = luaL_checklstring(L, arg, &len); 1391 const char *s = luaL_checklstring(L, arg, &len);
1391 luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); 1392 luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
1392 luaL_addlstring(&b, s, len); 1393 luaL_addlstring(&b, s, len);
1393 luaL_addchar(&b, '\0'); /* add zero at the end */ 1394 luaL_addchar(&b, '\0'); /* add zero at the end */
1394 totalsize += len + 1; 1395 totalsize += len + 1;
1395 break; 1396 break;
1396 } 1397 }
1397 case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */ 1398 case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
1398 case Kpaddalign: case Knop: 1399 case Kpaddalign: case Knop:
1399 arg--; /* undo increment */ 1400 arg--; /* undo increment */
1400 break; 1401 break;
1401 } 1402 }
1402 } 1403 }
1403 luaL_pushresult(&b); 1404 luaL_pushresult(&b);
1404 return 1; 1405 return 1;
1405} 1406}
1406 1407
1407 1408
1408static int str_packsize (lua_State *L) { 1409static int str_packsize (lua_State *L) {
1409 Header h; 1410 Header h;
1410 const char *fmt = luaL_checkstring(L, 1); /* format string */ 1411 const char *fmt = luaL_checkstring(L, 1); /* format string */
1411 size_t totalsize = 0; /* accumulate total size of result */ 1412 size_t totalsize = 0; /* accumulate total size of result */
1412 initheader(L, &h); 1413 initheader(L, &h);
1413 while (*fmt != '\0') { 1414 while (*fmt != '\0') {
1414 int size, ntoalign; 1415 int size, ntoalign;
1415 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); 1416 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1416 size += ntoalign; /* total space used by option */ 1417 size += ntoalign; /* total space used by option */
1417 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, 1418 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1418 "format result too large"); 1419 "format result too large");
1419 totalsize += size; 1420 totalsize += size;
1420 switch (opt) { 1421 switch (opt) {
1421 case Kstring: /* strings with length count */ 1422 case Kstring: /* strings with length count */
1422 case Kzstr: /* zero-terminated string */ 1423 case Kzstr: /* zero-terminated string */
1423 luaL_argerror(L, 1, "variable-length format"); 1424 luaL_argerror(L, 1, "variable-length format");
1424 /* call never return, but to avoid warnings: *//* FALLTHROUGH */ 1425 /* call never return, but to avoid warnings: *//* FALLTHROUGH */
1425 default: break; 1426 default: break;
1426 } 1427 }
1427 } 1428 }
1428 lua_pushinteger(L, (lua_Integer)totalsize); 1429 lua_pushinteger(L, (lua_Integer)totalsize);
1429 return 1; 1430 return 1;
1430} 1431}
1431 1432
1432 1433
1433/* 1434/*
1434** Unpack an integer with 'size' bytes and 'islittle' endianness. 1435** Unpack an integer with 'size' bytes and 'islittle' endianness.
1435** If size is smaller than the size of a Lua integer and integer 1436** If size is smaller than the size of a Lua integer and integer
1436** is signed, must do sign extension (propagating the sign to the 1437** is signed, must do sign extension (propagating the sign to the
1437** higher bits); if size is larger than the size of a Lua integer, 1438** higher bits); if size is larger than the size of a Lua integer,
1438** it must check the unread bytes to see whether they do not cause an 1439** it must check the unread bytes to see whether they do not cause an
1439** overflow. 1440** overflow.
1440*/ 1441*/
1441static lua_Integer unpackint (lua_State *L, const char *str, 1442static lua_Integer unpackint (lua_State *L, const char *str,
1442 int islittle, int size, int issigned) { 1443 int islittle, int size, int issigned) {
1443 lua_Unsigned res = 0; 1444 lua_Unsigned res = 0;
1444 int i; 1445 int i;
1445 int limit = (size <= SZINT) ? size : SZINT; 1446 int limit = (size <= SZINT) ? size : SZINT;
1446 for (i = limit - 1; i >= 0; i--) { 1447 for (i = limit - 1; i >= 0; i--) {
1447 res <<= NB; 1448 res <<= NB;
1448 res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; 1449 res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
1449 } 1450 }
1450 if (size < SZINT) { /* real size smaller than lua_Integer? */ 1451 if (size < SZINT) { /* real size smaller than lua_Integer? */
1451 if (issigned) { /* needs sign extension? */ 1452 if (issigned) { /* needs sign extension? */
1452 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); 1453 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
1453 res = ((res ^ mask) - mask); /* do sign extension */ 1454 res = ((res ^ mask) - mask); /* do sign extension */
1454 } 1455 }
1455 } 1456 }
1456 else if (size > SZINT) { /* must check unread bytes */ 1457 else if (size > SZINT) { /* must check unread bytes */
1457 int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; 1458 int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
1458 for (i = limit; i < size; i++) { 1459 for (i = limit; i < size; i++) {
1459 if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) 1460 if ((unsigned char)str[islittle ? i : size - 1 - i] != mask)
1460 luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); 1461 luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
1461 } 1462 }
1462 } 1463 }
1463 return (lua_Integer)res; 1464 return (lua_Integer)res;
1464} 1465}
1465 1466
1466 1467
1467static int str_unpack (lua_State *L) { 1468static int str_unpack (lua_State *L) {
1468 Header h; 1469 Header h;
1469 const char *fmt = luaL_checkstring(L, 1); 1470 const char *fmt = luaL_checkstring(L, 1);
1470 size_t ld; 1471 size_t ld;
1471 const char *data = luaL_checklstring(L, 2, &ld); 1472 const char *data = luaL_checklstring(L, 2, &ld);
1472 size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; 1473 size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1;
1473 int n = 0; /* number of results */ 1474 int n = 0; /* number of results */
1474 luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); 1475 luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
1475 initheader(L, &h); 1476 initheader(L, &h);
1476 while (*fmt != '\0') { 1477 while (*fmt != '\0') {
1477 int size, ntoalign; 1478 int size, ntoalign;
1478 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); 1479 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1479 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) 1480 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld)
1480 luaL_argerror(L, 2, "data string too short"); 1481 luaL_argerror(L, 2, "data string too short");
1481 pos += ntoalign; /* skip alignment */ 1482 pos += ntoalign; /* skip alignment */
1482 /* stack space for item + next position */ 1483 /* stack space for item + next position */
1483 luaL_checkstack(L, 2, "too many results"); 1484 luaL_checkstack(L, 2, "too many results");
1484 n++; 1485 n++;
1485 switch (opt) { 1486 switch (opt) {
1486 case Kint: 1487 case Kint:
1487 case Kuint: { 1488 case Kuint: {
1488 lua_Integer res = unpackint(L, data + pos, h.islittle, size, 1489 lua_Integer res = unpackint(L, data + pos, h.islittle, size,
1489 (opt == Kint)); 1490 (opt == Kint));
1490 lua_pushinteger(L, res); 1491 lua_pushinteger(L, res);
1491 break; 1492 break;
1492 } 1493 }
1493#ifndef _KERNEL 1494#ifndef _KERNEL
1494 case Kfloat: { 1495 case Kfloat: {
1495 volatile Ftypes u; 1496 volatile Ftypes u;
1496 lua_Number num; 1497 lua_Number num;
1497 copywithendian(u.buff, data + pos, size, h.islittle); 1498 copywithendian(u.buff, data + pos, size, h.islittle);
1498 if (size == sizeof(u.f)) num = (lua_Number)u.f; 1499 if (size == sizeof(u.f)) num = (lua_Number)u.f;
1499 else if (size == sizeof(u.d)) num = (lua_Number)u.d; 1500 else if (size == sizeof(u.d)) num = (lua_Number)u.d;
1500 else num = u.n; 1501 else num = u.n;
1501 lua_pushnumber(L, num); 1502 lua_pushnumber(L, num);
1502 break; 1503 break;
1503 } 1504 }
1504#endif /* _KERNEL */ 1505#endif /* _KERNEL */
1505 case Kchar: { 1506 case Kchar: {
1506 lua_pushlstring(L, data + pos, size); 1507 lua_pushlstring(L, data + pos, size);
1507 break; 1508 break;
1508 } 1509 }
1509 case Kstring: { 1510 case Kstring: {
1510 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); 1511 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1511 luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); 1512 luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short");
1512 lua_pushlstring(L, data + pos + size, len); 1513 lua_pushlstring(L, data + pos + size, len);
1513 pos += len; /* skip string */ 1514 pos += len; /* skip string */
1514 break; 1515 break;
1515 } 1516 }
1516 case Kzstr: { 1517 case Kzstr: {
1517 size_t len = (int)strlen(data + pos); 1518 size_t len = (int)strlen(data + pos);
1518 lua_pushlstring(L, data + pos, len); 1519 lua_pushlstring(L, data + pos, len);
1519 pos += len + 1; /* skip string plus final '\0' */ 1520 pos += len + 1; /* skip string plus final '\0' */
1520 break; 1521 break;
1521 } 1522 }
1522 case Kpaddalign: case Kpadding: case Knop: 1523 case Kpaddalign: case Kpadding: case Knop:
1523 n--; /* undo increment */ 1524 n--; /* undo increment */
1524 break; 1525 break;
1525 } 1526 }
1526 pos += size; 1527 pos += size;
1527 } 1528 }
1528 lua_pushinteger(L, pos + 1); /* next position */ 1529 lua_pushinteger(L, pos + 1); /* next position */
1529 return n + 1; 1530 return n + 1;
1530} 1531}
1531 1532
1532/* }====================================================== */ 1533/* }====================================================== */
1533 1534
1534 1535
1535static const luaL_Reg strlib[] = { 1536static const luaL_Reg strlib[] = {
1536 {"byte", str_byte}, 1537 {"byte", str_byte},
1537 {"char", str_char}, 1538 {"char", str_char},
1538 {"dump", str_dump}, 1539 {"dump", str_dump},
1539 {"find", str_find}, 1540 {"find", str_find},
1540 {"format", str_format}, 1541 {"format", str_format},
1541 {"gmatch", gmatch}, 1542 {"gmatch", gmatch},
1542 {"gsub", str_gsub}, 1543 {"gsub", str_gsub},
1543 {"len", str_len}, 1544 {"len", str_len},
1544 {"lower", str_lower}, 1545 {"lower", str_lower},
1545 {"match", str_match}, 1546 {"match", str_match},
1546 {"rep", str_rep}, 1547 {"rep", str_rep},
1547 {"reverse", str_reverse}, 1548 {"reverse", str_reverse},
1548 {"sub", str_sub}, 1549 {"sub", str_sub},
1549 {"upper", str_upper}, 1550 {"upper", str_upper},
1550 {"pack", str_pack}, 1551 {"pack", str_pack},
1551 {"packsize", str_packsize}, 1552 {"packsize", str_packsize},
1552 {"unpack", str_unpack}, 1553 {"unpack", str_unpack},
1553 {NULL, NULL} 1554 {NULL, NULL}
1554}; 1555};
1555 1556
1556 1557
1557static void createmetatable (lua_State *L) { 1558static void createmetatable (lua_State *L) {
1558 lua_createtable(L, 0, 1); /* table to be metatable for strings */ 1559 lua_createtable(L, 0, 1); /* table to be metatable for strings */
1559 lua_pushliteral(L, ""); /* dummy string */ 1560 lua_pushliteral(L, ""); /* dummy string */
1560 lua_pushvalue(L, -2); /* copy table */ 1561 lua_pushvalue(L, -2); /* copy table */
1561 lua_setmetatable(L, -2); /* set table as metatable for strings */ 1562 lua_setmetatable(L, -2); /* set table as metatable for strings */
1562 lua_pop(L, 1); /* pop dummy string */ 1563 lua_pop(L, 1); /* pop dummy string */
1563 lua_pushvalue(L, -2); /* get string library */ 1564 lua_pushvalue(L, -2); /* get string library */
1564 lua_setfield(L, -2, "__index"); /* metatable.__index = string */ 1565 lua_setfield(L, -2, "__index"); /* metatable.__index = string */
1565 lua_pop(L, 1); /* pop metatable */ 1566 lua_pop(L, 1); /* pop metatable */
1566} 1567}
1567 1568
1568 1569
1569/* 1570/*
1570** Open string library 1571** Open string library
1571*/ 1572*/
1572LUAMOD_API int luaopen_string (lua_State *L) { 1573LUAMOD_API int luaopen_string (lua_State *L) {
1573 luaL_newlib(L, strlib); 1574 luaL_newlib(L, strlib);
1574 createmetatable(L); 1575 createmetatable(L);
1575 return 1; 1576 return 1;
1576} 1577}
1577 1578