aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-05-01 17:48:12 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-05-01 17:48:12 -0300
commit751cd867d3e0338279fa6f3390c8b7ddc0108659 (patch)
tree726f6f3cd49109382b2c0d7ee6a1e0fea740afbd
parentb36b2a061c88be22e36900146cbcad39bab07f5d (diff)
downloadlua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.gz
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.bz2
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.zip
new way to handle errors
-rw-r--r--lapi.c118
-rw-r--r--lauxlib.c16
-rw-r--r--lauxlib.h4
-rw-r--r--lbaselib.c140
-rw-r--r--ldblib.c10
-rw-r--r--ldo.c90
-rw-r--r--ldo.h5
-rw-r--r--lmem.c4
-rw-r--r--lmem.h5
-rw-r--r--lstate.c8
-rw-r--r--ltests.c8
-rw-r--r--lua.c147
-rw-r--r--lua.h20
13 files changed, 283 insertions, 292 deletions
diff --git a/lapi.c b/lapi.c
index 4eeada6c..42ed4a82 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,10 +1,12 @@
1/* 1/*
2** $Id: lapi.c,v 1.184 2002/04/16 17:08:28 roberto Exp roberto $ 2** $Id: lapi.c,v 1.185 2002/04/22 14:40:50 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <errno.h>
9#include <stdio.h>
8#include <string.h> 10#include <string.h>
9 11
10#include "lua.h" 12#include "lua.h"
@@ -516,7 +518,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex) {
516 518
517 519
518/* 520/*
519** `do' functions (run Lua code) 521** `load' and `call' functions (run Lua code)
520*/ 522*/
521 523
522LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { 524LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
@@ -529,17 +531,6 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
529} 531}
530 532
531 533
532LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
533 int status;
534 int errpos = lua_gettop(L) - nargs;
535 lua_getglobal(L, "_ERRORMESSAGE");
536 lua_insert(L, errpos); /* put below function and args */
537 status = lua_pcall(L, nargs, nresults, errpos);
538 lua_remove(L, errpos);
539 return status;
540}
541
542
543LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf) { 534LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf) {
544 int status; 535 int status;
545 const TObject *err; 536 const TObject *err;
@@ -551,31 +542,11 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf) {
551} 542}
552 543
553 544
554static int aux_do (lua_State *L, int status) { 545static int errfile (lua_State *L, const char *filename) {
555 if (status == 0) { /* parse OK? */ 546 char buff[150];
556 int err = lua_gettop(L); 547 sprintf(buff, "cannot read file `%.80s' (%.40s)", filename, strerror(errno));
557 lua_getglobal(L, "_ERRORMESSAGE"); 548 lua_pushstring(L, buff);
558 lua_insert(L, err); 549 return LUA_ERRFILE;
559 status = lua_pcall(L, 0, LUA_MULTRET, err); /* call main */
560 lua_remove(L, err); /* remove error function */
561 }
562 return status;
563}
564
565
566LUA_API int lua_dofile (lua_State *L, const char *filename) {
567 return aux_do(L, lua_loadfile(L, filename));
568}
569
570
571LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
572 const char *name) {
573 return aux_do(L, lua_loadbuffer(L, buff, size, name));
574}
575
576
577LUA_API int lua_dostring (lua_State *L, const char *str) {
578 return lua_dobuffer(L, str, strlen(str), str);
579} 550}
580 551
581 552
@@ -585,12 +556,12 @@ LUA_API int lua_loadfile (lua_State *L, const char *filename) {
585 int bin; /* flag for file mode */ 556 int bin; /* flag for file mode */
586 int nlevel; /* level on the stack of filename */ 557 int nlevel; /* level on the stack of filename */
587 FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); 558 FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
588 if (f == NULL) return LUA_ERRFILE; /* unable to open file */ 559 if (f == NULL) return errfile(L, filename); /* unable to open file */
589 bin = (ungetc(getc(f), f) == LUA_SIGNATURE[0]); 560 bin = (ungetc(getc(f), f) == LUA_SIGNATURE[0]);
590 if (bin && f != stdin) { 561 if (bin && f != stdin) {
591 fclose(f); 562 fclose(f);
592 f = fopen(filename, "rb"); /* reopen in binary mode */ 563 f = fopen(filename, "rb"); /* reopen in binary mode */
593 if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ 564 if (f == NULL) return errfile(L, filename); /* unable to reopen file */
594 } 565 }
595 if (filename == NULL) 566 if (filename == NULL)
596 lua_pushstring(L, "=stdin"); 567 lua_pushstring(L, "=stdin");
@@ -603,7 +574,8 @@ LUA_API int lua_loadfile (lua_State *L, const char *filename) {
603 filename = lua_tostring(L, -1); /* filename = `@'..filename */ 574 filename = lua_tostring(L, -1); /* filename = `@'..filename */
604 luaZ_Fopen(&z, f, filename); 575 luaZ_Fopen(&z, f, filename);
605 status = luaD_protectedparser(L, &z, bin); 576 status = luaD_protectedparser(L, &z, bin);
606 if (ferror(f)) status = LUA_ERRFILE; 577 if (ferror(f))
578 return errfile(L, filename);
607 lua_remove(L, nlevel); /* remove filename */ 579 lua_remove(L, nlevel); /* remove filename */
608 if (f != stdin) 580 if (f != stdin)
609 fclose(f); 581 fclose(f);
@@ -661,9 +633,10 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
661*/ 633*/
662 634
663 635
664LUA_API void lua_error (lua_State *L, const char *s) { 636LUA_API void lua_errorobj (lua_State *L) {
665 lua_lock(L); 637 lua_lock(L);
666 luaD_runerror(L, s); 638 api_checknelems(L, 1);
639 luaD_errorobj(L, L->top - 1, LUA_ERRRUN);
667 lua_unlock(L); 640 lua_unlock(L);
668} 641}
669 642
@@ -767,3 +740,62 @@ LUA_API int lua_pushupvalues (lua_State *L) {
767} 740}
768 741
769 742
743
744/*
745** {======================================================
746** compatibility code
747** =======================================================
748*/
749
750
751static void callalert (lua_State *L, int status) {
752 if (status != 0) {
753 int top = lua_gettop(L);
754 lua_getglobal(L, "_ALERT");
755 lua_insert(L, -2);
756 lua_pcall(L, 1, 0, 0);
757 lua_settop(L, top-1);
758 }
759}
760
761
762LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
763 int status;
764 int errpos = lua_gettop(L) - nargs;
765 lua_getglobal(L, "_ERRORMESSAGE");
766 lua_insert(L, errpos); /* put below function and args */
767 status = lua_pcall(L, nargs, nresults, errpos);
768 lua_remove(L, errpos);
769 callalert(L, status);
770 return status;
771}
772
773static int aux_do (lua_State *L, int status) {
774 if (status == 0) { /* parse OK? */
775 int err = lua_gettop(L);
776 lua_getglobal(L, "_ERRORMESSAGE");
777 lua_insert(L, err);
778 status = lua_pcall(L, 0, LUA_MULTRET, err); /* call main */
779 lua_remove(L, err); /* remove error function */
780 }
781 callalert(L, status);
782 return status;
783}
784
785
786LUA_API int lua_dofile (lua_State *L, const char *filename) {
787 return aux_do(L, lua_loadfile(L, filename));
788}
789
790
791LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
792 const char *name) {
793 return aux_do(L, lua_loadbuffer(L, buff, size, name));
794}
795
796
797LUA_API int lua_dostring (lua_State *L, const char *str) {
798 return lua_dobuffer(L, str, strlen(str), str);
799}
800
801/* }====================================================== */
diff --git a/lauxlib.c b/lauxlib.c
index d0df881e..46454d83 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.65 2002/04/04 20:25:55 roberto Exp roberto $ 2** $Id: lauxlib.c,v 1.66 2002/04/16 12:00:02 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,19 +21,6 @@
21#include "lualib.h" 21#include "lualib.h"
22 22
23 23
24LUALIB_API const char *luaL_errstr (int errcode) {
25 static const char *const errstr[] = {
26 "ok",
27 "run-time error",
28 "cannot read file",
29 "syntax error",
30 "not enough memory",
31 "error in error handling"
32 };
33 return errstr[errcode];
34}
35
36
37LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { 24LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
38 int i; 25 int i;
39 for (i=0; list[i]; i++) 26 for (i=0; list[i]; i++)
@@ -42,6 +29,7 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
42 return -1; /* name not found */ 29 return -1; /* name not found */
43} 30}
44 31
32
45LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) { 33LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
46 lua_Debug ar; 34 lua_Debug ar;
47 lua_getstack(L, 0, &ar); 35 lua_getstack(L, 0, &ar);
diff --git a/lauxlib.h b/lauxlib.h
index 6af70d44..6affc407 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.43 2002/03/20 12:54:08 roberto Exp roberto $ 2** $Id: lauxlib.h,v 1.44 2002/04/02 20:42:49 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -52,8 +52,6 @@ LUALIB_API int luaL_findstring (const char *name,
52LUALIB_API int luaL_ref (lua_State *L, int t); 52LUALIB_API int luaL_ref (lua_State *L, int t);
53LUALIB_API void luaL_unref (lua_State *L, int t, int ref); 53LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
54 54
55/* error messages corresponding to error codes */
56LUALIB_API const char *luaL_errstr (int errcode);
57 55
58 56
59/* 57/*
diff --git a/lbaselib.c b/lbaselib.c
index d6168294..6ec250cb 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.68 2002/04/15 20:54:41 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.69 2002/04/22 14:40:23 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -26,6 +26,7 @@
26*/ 26*/
27static int luaB__ALERT (lua_State *L) { 27static int luaB__ALERT (lua_State *L) {
28 fputs(luaL_check_string(L, 1), stderr); 28 fputs(luaL_check_string(L, 1), stderr);
29 putc('\n', stderr);
29 return 0; 30 return 0;
30} 31}
31 32
@@ -35,26 +36,22 @@ static int luaB__ALERT (lua_State *L) {
35** The library `liolib' redefines _ERRORMESSAGE for better error information. 36** The library `liolib' redefines _ERRORMESSAGE for better error information.
36*/ 37*/
37static int luaB__ERRORMESSAGE (lua_State *L) { 38static int luaB__ERRORMESSAGE (lua_State *L) {
39 lua_Debug ar;
38 luaL_check_type(L, 1, LUA_TSTRING); 40 luaL_check_type(L, 1, LUA_TSTRING);
39 lua_getglobal(L, LUA_ALERT); 41 lua_pushliteral(L, "error: ");
40 if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ 42 lua_pushvalue(L, 1);
41 lua_Debug ar; 43 if (lua_getstack(L, 1, &ar)) {
42 lua_pushliteral(L, "error: "); 44 lua_getinfo(L, "Sl", &ar);
43 lua_pushvalue(L, 1); 45 if (ar.source && ar.currentline > 0) {
44 if (lua_getstack(L, 1, &ar)) { 46 char buff[100];
45 lua_getinfo(L, "Sl", &ar); 47 sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline);
46 if (ar.source && ar.currentline > 0) { 48 lua_pushstring(L, buff);
47 char buff[100]; 49 lua_concat(L, 2);
48 sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline);
49 lua_pushstring(L, buff);
50 lua_concat(L, 2);
51 }
52 } 50 }
53 lua_pushliteral(L, "\n");
54 lua_concat(L, 3);
55 lua_rawcall(L, 1, 0);
56 } 51 }
57 return 0; 52 lua_pushliteral(L, "\n");
53 lua_concat(L, 3);
54 return 1;
58} 55}
59 56
60 57
@@ -114,7 +111,8 @@ static int luaB_tonumber (lua_State *L) {
114 111
115 112
116static int luaB_error (lua_State *L) { 113static int luaB_error (lua_State *L) {
117 lua_error(L, luaL_opt_string(L, 1, NULL)); 114 lua_settop(L, 1);
115 lua_errorobj(L);
118 return 0; /* to avoid warnings */ 116 return 0; /* to avoid warnings */
119} 117}
120 118
@@ -217,53 +215,27 @@ static int luaB_nexti (lua_State *L) {
217} 215}
218 216
219 217
220static int passresults (lua_State *L, int status, int oldtop) { 218static int passresults (lua_State *L, int status) {
221 if (status == 0) { 219 if (status == 0) return 1;
222 int nresults = lua_gettop(L) - oldtop; 220 else {
223 if (nresults > 0)
224 return nresults; /* results are already on the stack */
225 else {
226 lua_pushboolean(L, 1); /* at least one result to signal no errors */
227 return 1;
228 }
229 }
230 else { /* error */
231 lua_pushnil(L); 221 lua_pushnil(L);
232 lua_pushstring(L, luaL_errstr(status)); /* error code */ 222 lua_insert(L, -2);
233 return 2; 223 return 2;
234 } 224 }
235} 225}
236 226
237 227
238static int luaB_dostring (lua_State *L) {
239 int oldtop = lua_gettop(L);
240 size_t l;
241 const char *s = luaL_check_lstr(L, 1, &l);
242 const char *chunkname = luaL_opt_string(L, 2, s);
243 return passresults(L, lua_dobuffer(L, s, l, chunkname), oldtop);
244}
245
246
247static int luaB_loadstring (lua_State *L) { 228static int luaB_loadstring (lua_State *L) {
248 int oldtop = lua_gettop(L);
249 size_t l; 229 size_t l;
250 const char *s = luaL_check_lstr(L, 1, &l); 230 const char *s = luaL_check_lstr(L, 1, &l);
251 const char *chunkname = luaL_opt_string(L, 2, s); 231 const char *chunkname = luaL_opt_string(L, 2, s);
252 return passresults(L, lua_loadbuffer(L, s, l, chunkname), oldtop); 232 return passresults(L, lua_loadbuffer(L, s, l, chunkname));
253}
254
255
256static int luaB_dofile (lua_State *L) {
257 int oldtop = lua_gettop(L);
258 const char *fname = luaL_opt_string(L, 1, NULL);
259 return passresults(L, lua_dofile(L, fname), oldtop);
260} 233}
261 234
262 235
263static int luaB_loadfile (lua_State *L) { 236static int luaB_loadfile (lua_State *L) {
264 int oldtop = lua_gettop(L);
265 const char *fname = luaL_opt_string(L, 1, NULL); 237 const char *fname = luaL_opt_string(L, 1, NULL);
266 return passresults(L, lua_loadfile(L, fname), oldtop); 238 return passresults(L, lua_loadfile(L, fname));
267} 239}
268 240
269 241
@@ -276,53 +248,29 @@ static int luaB_assert (lua_State *L) {
276} 248}
277 249
278 250
279static int aux_unpack (lua_State *L, int arg) { 251static int luaB_unpack (lua_State *L) {
280 int n, i; 252 int n, i;
281 luaL_check_type(L, arg, LUA_TTABLE); 253 luaL_check_type(L, 1, LUA_TTABLE);
282 n = lua_getn(L, arg); 254 n = lua_getn(L, 1);
283 luaL_check_stack(L, n+LUA_MINSTACK, "table too big to unpack"); 255 luaL_check_stack(L, n+LUA_MINSTACK, "table too big to unpack");
284 for (i=1; i<=n; i++) /* push arg[1...n] */ 256 for (i=1; i<=n; i++) /* push arg[1...n] */
285 lua_rawgeti(L, arg, i); 257 lua_rawgeti(L, 1, i);
286 return n; 258 return n;
287} 259}
288 260
289 261
290static int luaB_unpack (lua_State *L) { 262static int luaB_pcall (lua_State *L) {
291 return aux_unpack(L, 1);
292}
293
294
295static int luaB_call (lua_State *L) {
296 int oldtop;
297 const char *options = luaL_opt_string(L, 3, "");
298 int err = 0; /* index of old error method */
299 int status; 263 int status;
300 int n; 264 luaL_check_any(L, 1);
301 if (!lua_isnone(L, 4)) { /* set new error method */ 265 luaL_check_any(L, 2);
302 lua_getglobal(L, "_ERRORMESSAGE"); 266 status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET, 1);
303 err = lua_gettop(L); /* get index */ 267 if (status != 0)
304 lua_pushvalue(L, 4); 268 return passresults(L, status);
305 lua_setglobal(L, "_ERRORMESSAGE"); 269 else {
306 } 270 lua_pushboolean(L, 1);
307 oldtop = lua_gettop(L); /* top before function-call preparation */ 271 lua_replace(L, 1);
308 /* push function */ 272 return lua_gettop(L); /* return `true' + all results */
309 lua_pushvalue(L, 1);
310 n = aux_unpack(L, 2); /* push arg[1...n] */
311 status = lua_call(L, n, LUA_MULTRET);
312 if (err != 0) { /* restore old error method */
313 lua_pushvalue(L, err);
314 lua_setglobal(L, "_ERRORMESSAGE");
315 }
316 if (status != 0) { /* error in call? */
317 if (strchr(options, 'x'))
318 lua_pushnil(L); /* return nil to signal the error */
319 else
320 lua_error(L, NULL); /* propagate error without additional messages */
321 return 1;
322 } 273 }
323 if (strchr(options, 'p')) /* pack results? */
324 lua_error(L, "obsolete option `p' in `call'");
325 return lua_gettop(L) - oldtop; /* results are already on the stack */
326} 274}
327 275
328 276
@@ -433,7 +381,9 @@ static int luaB_require (lua_State *L) {
433 else { /* must load it */ 381 else { /* must load it */
434 while (status == LUA_ERRFILE && (path = nextpath(L, path)) != NULL) { 382 while (status == LUA_ERRFILE && (path = nextpath(L, path)) != NULL) {
435 composename(L); 383 composename(L);
436 status = lua_dofile(L, lua_tostring(L, -1)); /* try to load it */ 384 status = lua_loadfile(L, lua_tostring(L, -1)); /* try to load it */
385 if (status == 0)
386 status = lua_pcall(L, 0, 0, 0);
437 lua_settop(L, 3); /* pop string and eventual results from dofile */ 387 lua_settop(L, 3); /* pop string and eventual results from dofile */
438 } 388 }
439 } 389 }
@@ -448,8 +398,8 @@ static int luaB_require (lua_State *L) {
448 luaL_verror(L, "could not load package `%.20s' from path `%.200s'", 398 luaL_verror(L, "could not load package `%.20s' from path `%.200s'",
449 lua_tostring(L, 1), lua_tostring(L, 3)); 399 lua_tostring(L, 1), lua_tostring(L, 3));
450 } 400 }
451 default: { /* error loading package */ 401 default: {
452 lua_error(L, NULL); 402 lua_error(L, "error loading package");
453 return 0; /* to avoid warnings */ 403 return 0; /* to avoid warnings */
454 } 404 }
455 } 405 }
@@ -474,13 +424,11 @@ static const luaL_reg base_funcs[] = {
474 {"unpack", luaB_unpack}, 424 {"unpack", luaB_unpack},
475 {"rawget", luaB_rawget}, 425 {"rawget", luaB_rawget},
476 {"rawset", luaB_rawset}, 426 {"rawset", luaB_rawset},
477 {"call", luaB_call}, 427 {"pcall", luaB_pcall},
478 {"collectgarbage", luaB_collectgarbage}, 428 {"collectgarbage", luaB_collectgarbage},
479 {"gcinfo", luaB_gcinfo}, 429 {"gcinfo", luaB_gcinfo},
480 {"loadfile", luaB_loadfile}, 430 {"loadfile", luaB_loadfile},
481 {"loadstring", luaB_loadstring}, 431 {"loadstring", luaB_loadstring},
482 {"dofile", luaB_dofile},
483 {"dostring", luaB_dostring},
484 {"require", luaB_require}, 432 {"require", luaB_require},
485 {NULL, NULL} 433 {NULL, NULL}
486}; 434};
@@ -497,7 +445,7 @@ static int luaB_resume (lua_State *L) {
497 lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1)); 445 lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1));
498 lua_settop(L, 0); 446 lua_settop(L, 0);
499 if (lua_resume(L, co) != 0) 447 if (lua_resume(L, co) != 0)
500 lua_error(L, "error running co-routine"); 448 lua_errorobj(L);
501 return lua_gettop(L); 449 return lua_gettop(L);
502} 450}
503 451
diff --git a/ldblib.c b/ldblib.c
index c38cf419..4e565256 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.47 2002/04/09 19:48:08 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.48 2002/04/22 14:40:50 roberto Exp roberto $
3** Interface from Lua to its debug API 3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -189,7 +189,6 @@ static int errorfb (lua_State *L) {
189 lua_Debug ar; 189 lua_Debug ar;
190 luaL_Buffer b; 190 luaL_Buffer b;
191 luaL_buffinit(L, &b); 191 luaL_buffinit(L, &b);
192 luaL_addstring(&b, "error: ");
193 luaL_addstring(&b, luaL_check_string(L, 1)); 192 luaL_addstring(&b, luaL_check_string(L, 1));
194 luaL_addstring(&b, "\n"); 193 luaL_addstring(&b, "\n");
195 while (lua_getstack(L, level++, &ar)) { 194 while (lua_getstack(L, level++, &ar)) {
@@ -243,12 +242,7 @@ static int errorfb (lua_State *L) {
243 luaL_addstring(&b, "\n"); 242 luaL_addstring(&b, "\n");
244 } 243 }
245 luaL_pushresult(&b); 244 luaL_pushresult(&b);
246 lua_getglobal(L, LUA_ALERT); 245 return 1;
247 if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */
248 lua_pushvalue(L, -2); /* error message */
249 lua_rawcall(L, 1, 0);
250 }
251 return 0;
252} 246}
253 247
254 248
diff --git a/ldo.c b/ldo.c
index c89d3a3c..4dfb7d9e 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,12 +1,11 @@
1/* 1/*
2** $Id: ldo.c,v 1.171 2002/04/16 17:08:28 roberto Exp roberto $ 2** $Id: ldo.c,v 1.172 2002/04/22 14:40:50 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <setjmp.h> 8#include <setjmp.h>
9#include <stdio.h>
10#include <stdlib.h> 9#include <stdlib.h>
11#include <string.h> 10#include <string.h>
12 11
@@ -38,7 +37,7 @@ struct lua_longjmp {
38 jmp_buf b; 37 jmp_buf b;
39 int allowhooks; /* `allowhook' state when protection was set */ 38 int allowhooks; /* `allowhook' state when protection was set */
40 volatile int status; /* error code */ 39 volatile int status; /* error code */
41 TObject err; /* function to be called in case of errors */ 40 TObject *err; /* error function -> message (start of `ud') */
42}; 41};
43 42
44 43
@@ -110,7 +109,7 @@ void luaD_growstack (lua_State *L, int n) {
110static void luaD_growCI (lua_State *L) { 109static void luaD_growCI (lua_State *L) {
111 L->ci--; 110 L->ci--;
112 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ 111 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
113 luaD_error(L, NULL, LUA_ERRERR); /* break run without error message */ 112 luaD_error(L, "error in error handling", LUA_ERRERR);
114 else { 113 else {
115 luaD_reallocCI(L, 2*L->size_ci); 114 luaD_reallocCI(L, 2*L->size_ci);
116 if (L->size_ci > LUA_MAXCALLS) 115 if (L->size_ci > LUA_MAXCALLS)
@@ -303,7 +302,12 @@ static void move_results (lua_State *L, TObject *from, TObject *to) {
303} 302}
304 303
305 304
306static void resume (lua_State *L, void *numres) { 305struct ResS {
306 TObject err;
307 int numres;
308};
309
310static void resume (lua_State *L, void *ud) {
307 StkId firstResult; 311 StkId firstResult;
308 CallInfo *ci = L->ci; 312 CallInfo *ci = L->ci;
309 if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ 313 if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */
@@ -316,9 +320,9 @@ static void resume (lua_State *L, void *numres) {
316 } 320 }
317 firstResult = luaV_execute(L); 321 firstResult = luaV_execute(L);
318 if (firstResult == NULL) /* yield? */ 322 if (firstResult == NULL) /* yield? */
319 *(int *)numres = L->ci->yield_results; 323 cast(struct ResS *, ud)->numres = L->ci->yield_results;
320 else { /* return */ 324 else { /* return */
321 *(int *)numres = L->top - firstResult; 325 cast(struct ResS *, ud)->numres = L->top - firstResult;
322 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 326 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
323 } 327 }
324} 328}
@@ -326,8 +330,7 @@ static void resume (lua_State *L, void *numres) {
326 330
327LUA_API int lua_resume (lua_State *L, lua_State *co) { 331LUA_API int lua_resume (lua_State *L, lua_State *co) {
328 CallInfo *ci; 332 CallInfo *ci;
329 int numres; 333 struct ResS ud;
330 TObject o;
331 int status; 334 int status;
332 lua_lock(L); 335 lua_lock(L);
333 ci = co->ci; 336 ci = co->ci;
@@ -335,11 +338,17 @@ LUA_API int lua_resume (lua_State *L, lua_State *co) {
335 luaD_runerror(L, "thread is dead - cannot be resumed"); 338 luaD_runerror(L, "thread is dead - cannot be resumed");
336 if (co->errorJmp != NULL) /* ?? */ 339 if (co->errorJmp != NULL) /* ?? */
337 luaD_runerror(L, "thread is active - cannot be resumed"); 340 luaD_runerror(L, "thread is active - cannot be resumed");
338 setsvalue(&o, luaS_newliteral(L, "_ERRORMESSAGE")); 341 if (L->errorJmp) {
339 luaV_gettable(L, gt(L), &o, &o); 342 setobj(&ud.err, L->errorJmp->err);
340 status = luaD_runprotected(co, resume, &o, &numres); 343 }
344 else
345 setnilvalue(&ud.err);
346 status = luaD_runprotected(co, resume, &ud.err);
341 if (status == 0) 347 if (status == 0)
342 move_results(L, co->top - numres, co->top); 348 move_results(L, co->top - ud.numres, co->top);
349 else {
350 setobj(L->top++, &ud.err);
351}
343 lua_unlock(L); 352 lua_unlock(L);
344 return status; 353 return status;
345} 354}
@@ -361,6 +370,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
361** Execute a protected call. 370** Execute a protected call.
362*/ 371*/
363struct CallS { /* data to `f_call' */ 372struct CallS { /* data to `f_call' */
373 TObject err; /* error field... */
364 StkId func; 374 StkId func;
365 int nresults; 375 int nresults;
366}; 376};
@@ -377,10 +387,12 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
377 int status; 387 int status;
378 c.func = L->top - (nargs+1); /* function to be called */ 388 c.func = L->top - (nargs+1); /* function to be called */
379 c.nresults = nresults; 389 c.nresults = nresults;
380 status = luaD_runprotected(L, &f_call, err, &c); 390 c.err = *err;
391 status = luaD_runprotected(L, &f_call, &c.err);
381 if (status != 0) { /* an error occurred? */ 392 if (status != 0) { /* an error occurred? */
382 L->top -= nargs+1; /* remove parameters and func from the stack */ 393 L->top -= nargs+1; /* remove parameters and func from the stack */
383 luaF_close(L, L->top); /* close eventual pending closures */ 394 luaF_close(L, L->top); /* close eventual pending closures */
395 setobj(L->top++, &c.err);
384 } 396 }
385 return status; 397 return status;
386} 398}
@@ -390,6 +402,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
390** Execute a protected parser. 402** Execute a protected parser.
391*/ 403*/
392struct SParser { /* data to `f_parser' */ 404struct SParser { /* data to `f_parser' */
405 TObject err; /* error field... */
393 ZIO *z; 406 ZIO *z;
394 int bin; 407 int bin;
395}; 408};
@@ -406,7 +419,6 @@ static void f_parser (lua_State *L, void *ud) {
406 419
407int luaD_protectedparser (lua_State *L, ZIO *z, int bin) { 420int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
408 struct SParser p; 421 struct SParser p;
409 TObject o;
410 lu_mem old_blocks; 422 lu_mem old_blocks;
411 int status; 423 int status;
412 lua_lock(L); 424 lua_lock(L);
@@ -415,16 +427,18 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
415 if (G(L)->nblocks/8 >= G(L)->GCthreshold/10) 427 if (G(L)->nblocks/8 >= G(L)->GCthreshold/10)
416 luaC_collectgarbage(L); 428 luaC_collectgarbage(L);
417 old_blocks = G(L)->nblocks; 429 old_blocks = G(L)->nblocks;
418 setsvalue(&o, luaS_newliteral(L, "_ERRORMESSAGE")); 430 setnilvalue(&p.err);
419 luaV_gettable(L, gt(L), &o, &o); 431 status = luaD_runprotected(L, f_parser, &p.err);
420 status = luaD_runprotected(L, f_parser, &o, &p);
421 if (status == 0) { 432 if (status == 0) {
422 /* add new memory to threshold (as it probably will stay) */ 433 /* add new memory to threshold (as it probably will stay) */
423 lua_assert(G(L)->nblocks >= old_blocks); 434 lua_assert(G(L)->nblocks >= old_blocks);
424 G(L)->GCthreshold += (G(L)->nblocks - old_blocks); 435 G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
425 } 436 }
426 else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ 437 else {
427 status = LUA_ERRSYNTAX; 438 setobj(L->top++, &p.err);
439 if (status == LUA_ERRRUN) /* an error occurred: correct error code */
440 status = LUA_ERRSYNTAX;
441 }
428 lua_unlock(L); 442 lua_unlock(L);
429 return status; 443 return status;
430} 444}
@@ -438,14 +452,18 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
438*/ 452*/
439 453
440 454
441static void message (lua_State *L, const char *msg) { 455static void message (lua_State *L, const TObject *msg, int nofunc) {
442 TObject *m = &L->errorJmp->err; 456 TObject *m = L->errorJmp->err;
443 if (ttype(m) == LUA_TFUNCTION) { 457 if (nofunc || ttype(m) != LUA_TFUNCTION) { /* no error function? */
458 setobj(m, msg); /* keep error message */
459 }
460 else { /* call error function */
444 setobj(L->top, m); 461 setobj(L->top, m);
445 incr_top(L); 462 incr_top(L);
446 setsvalue(L->top, luaS_new(L, msg)); 463 setobj(L->top, msg);
447 incr_top(L); 464 incr_top(L);
448 luaD_call(L, L->top - 2, 0); 465 luaD_call(L, L->top - 2, 1);
466 setobj(m, L->top - 1);
449 } 467 }
450} 468}
451 469
@@ -453,10 +471,10 @@ static void message (lua_State *L, const char *msg) {
453/* 471/*
454** Reports an error, and jumps up to the available recovery label 472** Reports an error, and jumps up to the available recovery label
455*/ 473*/
456void luaD_error (lua_State *L, const char *s, int errcode) { 474void luaD_errorobj (lua_State *L, const TObject *s, int errcode) {
457 if (L->errorJmp) { 475 if (L->errorJmp) {
458 L->errorJmp->status = errcode; 476 L->errorJmp->status = errcode;
459 if (s) message(L, s); 477 message(L, s, (errcode >= LUA_ERRMEM));
460 longjmp(L->errorJmp->b, 1); 478 longjmp(L->errorJmp->b, 1);
461 } 479 }
462 else { 480 else {
@@ -466,24 +484,34 @@ void luaD_error (lua_State *L, const char *s, int errcode) {
466} 484}
467 485
468 486
487void luaD_error (lua_State *L, const char *s, int errcode) {
488 TObject errobj;
489 if (errcode == LUA_ERRMEM && (G(L) == NULL || G(L)->GCthreshold == 0))
490 setnilvalue(&errobj); /* error bulding state */
491 else
492 setsvalue(&errobj, luaS_new(L, s));
493 luaD_errorobj(L, &errobj, errcode);
494}
495
496
469void luaD_runerror (lua_State *L, const char *s) { 497void luaD_runerror (lua_State *L, const char *s) {
470 luaD_error(L, s, LUA_ERRRUN); 498 luaD_error(L, s, LUA_ERRRUN);
471} 499}
472 500
473 501
474int luaD_runprotected (lua_State *L, Pfunc f, const TObject *err, void *ud) { 502int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
475 struct lua_longjmp lj; 503 struct lua_longjmp lj;
476 lj.ci = L->ci; 504 lj.ci = L->ci;
477 lj.top = L->top; 505 lj.top = L->top;
478 lj.allowhooks = L->allowhooks; 506 lj.allowhooks = L->allowhooks;
479 lj.status = 0; 507 lj.status = 0;
480 lj.err = *err; 508 lj.err = ud;
481 lj.previous = L->errorJmp; /* chain new error handler */ 509 lj.previous = L->errorJmp; /* chain new error handler */
482 L->errorJmp = &lj; 510 L->errorJmp = &lj;
483 if (setjmp(lj.b) == 0) 511 if (setjmp(lj.b) == 0)
484 (*f)(L, ud); 512 (*f)(L, ud);
485 else { /* an error occurred: restore the state */ 513 else { /* an error occurred */
486 L->ci = lj.ci; 514 L->ci = lj.ci; /* restore the state */
487 L->top = lj.top; 515 L->top = lj.top;
488 L->allowhooks = lj.allowhooks; 516 L->allowhooks = lj.allowhooks;
489 restore_stack_limit(L); 517 restore_stack_limit(L);
diff --git a/ldo.h b/ldo.h
index 5464e544..0c4dfbca 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.42 2002/03/25 17:47:14 roberto Exp roberto $ 2** $Id: ldo.h,v 1.43 2002/04/22 14:40:50 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -42,8 +42,9 @@ void luaD_reallocstack (lua_State *L, int newsize);
42void luaD_growstack (lua_State *L, int n); 42void luaD_growstack (lua_State *L, int n);
43 43
44void luaD_error (lua_State *L, const char *s, int errcode); 44void luaD_error (lua_State *L, const char *s, int errcode);
45void luaD_errorobj (lua_State *L, const TObject *s, int errcode);
45void luaD_runerror (lua_State *L, const char *s); 46void luaD_runerror (lua_State *L, const char *s);
46int luaD_runprotected (lua_State *L, Pfunc f, const TObject *err, void *ud); 47int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud);
47 48
48 49
49#endif 50#endif
diff --git a/lmem.c b/lmem.c
index 435cceef..f3d4d309 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.52 2001/11/28 20:13:13 roberto Exp roberto $ 2** $Id: lmem.c,v 1.53 2002/04/22 14:40:23 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -58,7 +58,7 @@ void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
58 block = l_realloc(block, oldsize, size); 58 block = l_realloc(block, oldsize, size);
59 if (block == NULL) { 59 if (block == NULL) {
60 if (L) 60 if (L)
61 luaD_error(L, NULL, LUA_ERRMEM); /* break run without error message */ 61 luaD_error(L, MEMERRMSG, LUA_ERRMEM);
62 else return NULL; /* error before creating state! */ 62 else return NULL; /* error before creating state! */
63 } 63 }
64 } 64 }
diff --git a/lmem.h b/lmem.h
index bb0ba5a9..1c896571 100644
--- a/lmem.h
+++ b/lmem.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.h,v 1.24 2001/09/07 17:30:16 roberto Exp $ 2** $Id: lmem.h,v 1.25 2001/11/28 20:13:13 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,6 +13,9 @@
13#include "llimits.h" 13#include "llimits.h"
14#include "lua.h" 14#include "lua.h"
15 15
16#define MEMERRMSG "not enough memory"
17
18
16void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size); 19void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size);
17 20
18void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, 21void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
diff --git a/lstate.c b/lstate.c
index 5360d343..bb568aa0 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.90 2002/04/22 14:40:23 roberto Exp roberto $ 2** $Id: lstate.c,v 1.91 2002/04/23 15:04:39 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -57,6 +57,7 @@ static void f_luaopen (lua_State *L, void *ud) {
57 UNUSED(ud); 57 UNUSED(ud);
58 /* create a new global state */ 58 /* create a new global state */
59 L->l_G = luaM_new(L, global_State); 59 L->l_G = luaM_new(L, global_State);
60 G(L)->GCthreshold = 0; /* mark it as unfinished state */
60 G(L)->strt.size = 0; 61 G(L)->strt.size = 0;
61 G(L)->strt.nuse = 0; 62 G(L)->strt.nuse = 0;
62 G(L)->strt.hash = NULL; 63 G(L)->strt.hash = NULL;
@@ -83,6 +84,7 @@ static void f_luaopen (lua_State *L, void *ud) {
83 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 84 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
84 luaT_init(L); 85 luaT_init(L);
85 luaX_init(L); 86 luaX_init(L);
87 luaS_fix(luaS_newliteral(L, MEMERRMSG));
86 G(L)->GCthreshold = 4*G(L)->nblocks; 88 G(L)->GCthreshold = 4*G(L)->nblocks;
87} 89}
88 90
@@ -122,12 +124,14 @@ LUA_API lua_State *lua_newthread (lua_State *OL) {
122 124
123LUA_API lua_State *lua_open (void) { 125LUA_API lua_State *lua_open (void) {
124 lua_State *L; 126 lua_State *L;
127 TObject dummy;
128 setnilvalue(&dummy);
125 L = luaM_new(NULL, lua_State); 129 L = luaM_new(NULL, lua_State);
126 if (L) { /* allocation OK? */ 130 if (L) { /* allocation OK? */
127 preinit_state(L); 131 preinit_state(L);
128 L->l_G = NULL; 132 L->l_G = NULL;
129 L->next = L->previous = L; 133 L->next = L->previous = L;
130 if (luaD_runprotected(L, f_luaopen, &luaO_nilobject, NULL) != 0) { 134 if (luaD_runprotected(L, f_luaopen, &dummy) != 0) {
131 /* memory allocation error: free partial state */ 135 /* memory allocation error: free partial state */
132 close_state(L); 136 close_state(L);
133 L = NULL; 137 L = NULL;
diff --git a/ltests.c b/ltests.c
index bd8469f3..b4d81ada 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.116 2002/04/05 18:54:31 roberto Exp roberto $ 2** $Id: ltests.c,v 1.117 2002/04/24 20:07:46 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -383,7 +383,11 @@ static int udataval (lua_State *L) {
383 383
384static int doonnewstack (lua_State *L) { 384static int doonnewstack (lua_State *L) {
385 lua_State *L1 = lua_newthread(L); 385 lua_State *L1 = lua_newthread(L);
386 int status = lua_dostring(L1, luaL_check_string(L, 1)); 386 size_t l;
387 const char *s = luaL_check_lstr(L, 1, &l);
388 int status = lua_loadbuffer(L1, s, l, s);
389 if (status == 0)
390 status = lua_pcall(L1, 0, 0, 0);
387 lua_pushnumber(L, status); 391 lua_pushnumber(L, status);
388 lua_closethread(L, L1); 392 lua_closethread(L, L1);
389 return 1; 393 return 1;
diff --git a/lua.c b/lua.c
index 5f050fc4..7508c4aa 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.83 2002/04/22 14:40:50 roberto Exp roberto $ 2** $Id: lua.c,v 1.84 2002/04/23 14:59:22 roberto Exp roberto $
3** Lua stand-alone interpreter 3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -66,23 +66,30 @@ static void laction (int i) {
66} 66}
67 67
68 68
69/* Lua gives no message in such cases, so we provide one */ 69static void report (int status) {
70static void report (int result) { 70 if (status == 0) return;
71 if (result == LUA_ERRMEM || result == LUA_ERRERR) 71 else {
72 fprintf(stderr, "%s: %s\n", LUA_PROGNAME, luaL_errstr(result)); 72 const char *msg = lua_tostring(L, -1);
73 if (msg == NULL) msg = "(no message)";
74 fprintf(stderr, "error: %s\n", msg);
75 lua_pop(L, 1);
76 }
73} 77}
74 78
75 79
76static int ldo (int (*f)(lua_State *l, const char *), const char *name, 80static int lcall (int clear) {
77 int clear) { 81 int status;
78 int result;
79 int top = lua_gettop(L); 82 int top = lua_gettop(L);
83 lua_getglobal(L, "_ERRORMESSAGE");
84 lua_insert(L, top);
80 signal(SIGINT, laction); 85 signal(SIGINT, laction);
81 result = f(L, name); /* dostring | dofile */ 86 status = lua_pcall(L, 0, LUA_MULTRET, top);
82 signal(SIGINT, SIG_DFL); 87 signal(SIGINT, SIG_DFL);
83 if (clear) lua_settop(L, top); /* remove eventual results */ 88 if (status == 0) {
84 report(result); 89 if (clear) lua_settop(L, top); /* remove eventual results */
85 return result; 90 else lua_remove(L, top); /* else remove only error function */
91 }
92 return status;
86} 93}
87 94
88 95
@@ -138,16 +145,18 @@ static int l_getargs (lua_State *l) {
138 145
139 146
140static int file_input (const char *name) { 147static int file_input (const char *name) {
141 int result = ldo(lua_dofile, name, 1); 148 int status = lua_loadfile(L, name);
142 if (result) { 149 if (status == 0) status = lcall(1);
143 if (result == LUA_ERRFILE) { 150 report(status);
144 fprintf(stderr, "%s: %s ", LUA_PROGNAME, luaL_errstr(result)); 151 return status;
145 perror(name); 152}
146 } 153
147 return EXIT_FAILURE; 154
148 } 155static int dostring (const char *s) {
149 else 156 int status = lua_loadbuffer(L, s, strlen(s), s);
150 return EXIT_SUCCESS; 157 if (status == 0) status = lcall(1);
158 report(status);
159 return status;
151} 160}
152 161
153 162
@@ -177,85 +186,65 @@ static char *readline (const char *prompt) {
177#endif 186#endif
178 187
179 188
180static const char *get_prompt (int incomplete) { 189static const char *get_prompt (int firstline) {
181 const char *p = NULL; 190 const char *p = NULL;
182 lua_getglobal(L, incomplete ? "_PROMPT2" : "_PROMPT"); 191 lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
183 p = lua_tostring(L, -1); 192 p = lua_tostring(L, -1);
184 if (p == NULL) p = (incomplete ? PROMPT2 : PROMPT); 193 if (p == NULL) p = (firstline ? PROMPT : PROMPT2);
185 lua_pop(L, 1); /* remove global */ 194 lua_pop(L, 1); /* remove global */
186 return p; 195 return p;
187} 196}
188 197
189 198
190static int incomplete = 0; 199static int incomplete (int status) {
191 200 if (status == LUA_ERRSYNTAX &&
192static int trap_eof (lua_State *l) { 201 strstr(lua_tostring(L, -1), "last token read: `<eof>'") != NULL) {
193 const char *s = lua_tostring(l, 1); 202 lua_pop(L, 1);
194 if (strstr(s, "last token read: `<eof>'") != NULL) 203 return 1;
195 incomplete = 1; 204 }
196 else 205 else
197 fprintf(stderr, "error: %s\n", s); 206 return 0;
198 return 0;
199} 207}
200 208
201 209
202static int load_string (void) { 210static int load_string (void) {
203 lua_getglobal(L, "_ERRORMESSAGE"); 211 int firstline = 1;
204 lua_pushvalue(L, 1); 212 int status;
205 lua_setglobal(L, "_ERRORMESSAGE"); 213 lua_settop(L, 0);
206 incomplete = 0; 214 do { /* repeat until gets a complete line */
207 for (;;) { /* repeat until gets a complete line */ 215 char *buffer = readline(get_prompt(firstline));
208 int result;
209 char *buffer = readline(get_prompt(incomplete));
210 if (buffer == NULL) { /* input end? */ 216 if (buffer == NULL) { /* input end? */
211 lua_settop(L, 2); 217 lua_settop(L, 0);
212 lua_setglobal(L, "_ERRORMESSAGE"); 218 return -1; /* input end */
213 return 0;
214 } 219 }
215 if (!incomplete && buffer[0] == '=') { 220 if (firstline && buffer[0] == '=') {
216 buffer[0] = ' '; 221 buffer[0] = ' ';
217 lua_pushstring(L, "return"); 222 lua_pushstring(L, "return");
218 } 223 }
224 firstline = 0;
219 push_line(buffer); 225 push_line(buffer);
220 lua_concat(L, lua_gettop(L)-2); 226 lua_concat(L, lua_gettop(L));
221 incomplete = 0; 227 status = lua_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
222 result = lua_loadbuffer(L, lua_tostring(L, 3), lua_strlen(L, 3), "=stdin"); 228 } while (incomplete(status)); /* repeat loop to get rest of `line' */
223 if (incomplete) continue; /* repeat loop to get rest of `line' */ 229 save_line(lua_tostring(L, 1));
224 save_line(lua_tostring(L, 3)); 230 lua_remove(L, 1);
225 lua_remove(L, 3); 231 return status;
226 if (result == 0) {
227 lua_insert(L, 2); /* swap compiled chunk with old _ERRORMESSAGE */
228 lua_setglobal(L, "_ERRORMESSAGE"); /* restore old _ERRORMESSAGE */
229 return 1;
230 }
231 else
232 report(result);
233 }
234}
235
236
237static int lcall (lua_State *l, const char *name) {
238 (void)name; /* to avoid warnings */
239 return lua_call(l, 0, LUA_MULTRET);
240} 232}
241 233
242 234
243static void manual_input (int version) { 235static void manual_input (int version) {
236 int status;
244 if (version) print_version(); 237 if (version) print_version();
245 lua_settop(L, 0); 238 while ((status = load_string()) != -1) {
246 lua_pushcfunction(L, trap_eof); /* set up handler for incomplete lines */ 239 if (status == 0) status = lcall(0);
247 while (load_string()) { 240 report(status);
248 ldo(lcall, NULL, 0); 241 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
249 if (lua_gettop(L) > 1) { /* any result to print? */
250 lua_getglobal(L, "print"); 242 lua_getglobal(L, "print");
251 lua_insert(L, 2); 243 lua_insert(L, 1);
252 lua_call(L, lua_gettop(L)-2, 0); 244 lua_call(L, lua_gettop(L)-1, 0);
253 } 245 }
254 else
255 lua_settop(L, 1); /* remove eventual results */
256 } 246 }
257 printf("\n"); 247 printf("\n");
258 lua_pop(L, 1); /* remove trap_eof */
259} 248}
260 249
261 250
@@ -265,7 +254,7 @@ static int handle_argv (char *argv[], int *toclose) {
265 manual_input(1); 254 manual_input(1);
266 } 255 }
267 else 256 else
268 ldo(lua_dofile, NULL, 1); /* executes stdin as a file */ 257 file_input(NULL); /* executes stdin as a file */
269 } 258 }
270 else { /* other arguments; loop over them */ 259 else { /* other arguments; loop over them */
271 int i; 260 int i;
@@ -274,12 +263,12 @@ static int handle_argv (char *argv[], int *toclose) {
274 if (strchr(argv[i], '=')) 263 if (strchr(argv[i], '='))
275 assign(argv[i]); 264 assign(argv[i]);
276 else 265 else
277 if (file_input(argv[i]) != EXIT_SUCCESS) 266 if (file_input(argv[i]))
278 return EXIT_FAILURE; /* stop if file fails */ 267 return EXIT_FAILURE; /* stop if file fails */
279 } 268 }
280 else switch (argv[i][1]) { /* option */ 269 else switch (argv[i][1]) { /* option */
281 case '\0': { 270 case '\0': {
282 ldo(lua_dofile, NULL, 1); /* executes stdin as a file */ 271 file_input(NULL); /* executes stdin as a file */
283 break; 272 break;
284 } 273 }
285 case 'i': { 274 case 'i': {
@@ -300,7 +289,7 @@ static int handle_argv (char *argv[], int *toclose) {
300 print_usage(); 289 print_usage();
301 return EXIT_FAILURE; 290 return EXIT_FAILURE;
302 } 291 }
303 if (ldo(lua_dostring, argv[i], 1) != 0) { 292 if (dostring(argv[i]) != 0) {
304 fprintf(stderr, "%s: error running argument `%.99s'\n", 293 fprintf(stderr, "%s: error running argument `%.99s'\n",
305 LUA_PROGNAME, argv[i]); 294 LUA_PROGNAME, argv[i]);
306 return EXIT_FAILURE; 295 return EXIT_FAILURE;
diff --git a/lua.h b/lua.h
index cb6cbaff..9ea98c11 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.128 2002/04/22 14:40:23 roberto Exp roberto $ 2** $Id: lua.h,v 1.129 2002/05/01 20:40:42 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - An Extensible Extension Language
4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil 4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
5** e-mail: info@lua.org 5** e-mail: info@lua.org
@@ -35,7 +35,7 @@
35#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) 35#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
36 36
37 37
38/* error codes for `lua_do*' and the like */ 38/* error codes for `lua_load*' and `lua_pcall' */
39#define LUA_ERRRUN 1 39#define LUA_ERRRUN 1
40#define LUA_ERRFILE 2 40#define LUA_ERRFILE 2
41#define LUA_ERRSYNTAX 3 41#define LUA_ERRSYNTAX 3
@@ -166,18 +166,13 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex);
166 166
167 167
168/* 168/*
169** `load' and `do' functions (load and run Lua code) 169** `load' and `call' functions (load and run Lua code)
170*/ 170*/
171LUA_API int lua_call (lua_State *L, int nargs, int nresults);
172LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults); 171LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults);
173LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf); 172LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf);
174LUA_API int lua_loadfile (lua_State *L, const char *filename); 173LUA_API int lua_loadfile (lua_State *L, const char *filename);
175LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size, 174LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size,
176 const char *name); 175 const char *name);
177LUA_API int lua_dofile (lua_State *L, const char *filename);
178LUA_API int lua_dostring (lua_State *L, const char *str);
179LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
180 const char *name);
181 176
182 177
183/* 178/*
@@ -243,10 +238,17 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size);
243 (sizeof(s)/sizeof(char))-1) 238 (sizeof(s)/sizeof(char))-1)
244 239
245 240
241
246/* 242/*
247** compatibility macros and functions 243** compatibility macros and functions
248*/ 244*/
249 245
246LUA_API int lua_call (lua_State *L, int nargs, int nresults);
247LUA_API int lua_dofile (lua_State *L, const char *filename);
248LUA_API int lua_dostring (lua_State *L, const char *str);
249LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
250 const char *name);
251
250LUA_API int lua_pushupvalues (lua_State *L); 252LUA_API int lua_pushupvalues (lua_State *L);
251 253
252#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) 254#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)