aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-04-26 17:39:38 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-04-26 17:39:38 -0300
commit4eb49163c662e7c1546754774acf75b893ea23df (patch)
treee7745d5283a0282af13568fc1c008d0adb8f4ce1
parent79cb336d74697ca38d6d2f2068781086cfaa9076 (diff)
downloadlua-4eb49163c662e7c1546754774acf75b893ea23df.tar.gz
lua-4eb49163c662e7c1546754774acf75b893ea23df.tar.bz2
lua-4eb49163c662e7c1546754774acf75b893ea23df.zip
error handler in 'lua.c' tries '__tostring' metamethod if error
message is not a string
-rw-r--r--ldblib.c23
-rw-r--r--lua.c39
2 files changed, 33 insertions, 29 deletions
diff --git a/ldblib.c b/ldblib.c
index 441c478c..d8224a8e 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.105 2006/09/11 14:07:24 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*/
@@ -319,21 +319,18 @@ static int db_debug (lua_State *L) {
319#define LEVELS2 10 /* size of the second part of the stack */ 319#define LEVELS2 10 /* size of the second part of the stack */
320 320
321static int db_errorfb (lua_State *L) { 321static int db_errorfb (lua_State *L) {
322 int level; 322 lua_Debug ar;
323 int firstpart = 1; /* still before eventual `...' */ 323 int firstpart = 1; /* still before eventual `...' */
324 int arg; 324 int arg;
325 lua_State *L1 = getthread(L, &arg); 325 lua_State *L1 = getthread(L, &arg);
326 lua_Debug ar; 326 const char *msg = lua_tostring(L, arg + 1);
327 if (lua_isnumber(L, arg+2)) { 327 int level = (lua_isnumber(L, arg + 2)) ?
328 level = (int)lua_tointeger(L, arg+2); 328 (int)lua_tointeger(L, arg + 2) :
329 lua_pop(L, 1); 329 (L == L1) ? 1 : 0; /* level 0 may be this own function */
330 } 330 lua_settop(L, ++arg);
331 else 331 if (msg) lua_pushfstring(L, "%s\n", msg);
332 level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ 332 else if (!lua_isnil(L, arg)) /* is there a non-string 'msg'? */
333 if (lua_gettop(L) == arg) 333 return 1; /* return it untouched */
334 lua_pushliteral(L, "");
335 else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
336 else lua_pushliteral(L, "\n");
337 lua_pushliteral(L, "stack traceback:"); 334 lua_pushliteral(L, "stack traceback:");
338 while (lua_getstack(L1, level++, &ar)) { 335 while (lua_getstack(L1, level++, &ar)) {
339 if (level > LEVELS1 && firstpart) { 336 if (level > LEVELS1 && firstpart) {
diff --git a/lua.c b/lua.c
index 38419c14..c8951a1f 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.163 2006/09/18 14:03:18 roberto Exp roberto $ 2** $Id: lua.c,v 1.164 2006/10/10 17:40:17 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*/
@@ -41,7 +41,7 @@ static void laction (int i) {
41 41
42static void print_usage (void) { 42static void print_usage (void) {
43 fprintf(stderr, 43 fprintf(stderr,
44 "usage: %s [options] [script [args]].\n" 44 "usage: %s [options] [script [args]]\n"
45 "Available options are:\n" 45 "Available options are:\n"
46 " -e stat execute string " LUA_QL("stat") "\n" 46 " -e stat execute string " LUA_QL("stat") "\n"
47 " -l name require library " LUA_QL("name") "\n" 47 " -l name require library " LUA_QL("name") "\n"
@@ -73,20 +73,27 @@ static int report (lua_State *L, int status) {
73} 73}
74 74
75 75
76static int traceback (lua_State *L) { 76static int gettraceback (lua_State *L) {
77 lua_getfield(L, LUA_GLOBALSINDEX, "debug"); 77 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
78 if (!lua_istable(L, -1)) { 78 if (!lua_istable(L, -1)) return 0;
79 lua_pop(L, 1); 79 lua_getfield(L, -1, "traceback"); /* check 'debug.traceback' */
80 return 1; 80 if (!lua_isfunction(L, -1)) return 0;
81 } 81 return 1; /* there is a function 'debug.traceback' */
82 lua_getfield(L, -1, "traceback"); 82}
83 if (!lua_isfunction(L, -1)) { 83
84 lua_pop(L, 2); 84
85 return 1; 85static int traceback (lua_State *L) {
86 if (lua_isnoneornil(L, 1)) /* no error object? */
87 return 1; /* keep it that way */
88 if (!gettraceback(L)) /* no 'debug.traceback' function? */
89 lua_pushvalue(L, 1); /* keep original message */
90 else {
91 lua_pushvalue(L, 1); /* pass error message */
92 lua_pushinteger(L, 2); /* skip this function and traceback */
93 lua_call(L, 2, 1); /* call traceback */
86 } 94 }
87 lua_pushvalue(L, 1); /* pass error message */ 95 if (!lua_isstring(L, -1) && !luaL_callmeta(L, 1, "__tostring"))
88 lua_pushinteger(L, 2); /* skip this function and traceback */ 96 lua_pushliteral(L, "(no error message)");
89 lua_call(L, 2, 1); /* call debug.traceback */
90 return 1; 97 return 1;
91} 98}
92 99
@@ -96,6 +103,7 @@ static int docall (lua_State *L, int narg, int clear) {
96 int base = lua_gettop(L) - narg; /* function index */ 103 int base = lua_gettop(L) - narg; /* function index */
97 lua_pushcfunction(L, traceback); /* push traceback function */ 104 lua_pushcfunction(L, traceback); /* push traceback function */
98 lua_insert(L, base); /* put it under chunk and args */ 105 lua_insert(L, base); /* put it under chunk and args */
106 globalL = L; /* to be available to 'laction' */
99 signal(SIGINT, laction); 107 signal(SIGINT, laction);
100 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); 108 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
101 signal(SIGINT, SIG_DFL); 109 signal(SIGINT, SIG_DFL);
@@ -160,7 +168,7 @@ static const char *get_prompt (lua_State *L, int firstline) {
160} 168}
161 169
162/* mark in error messages for incomplete statements */ 170/* mark in error messages for incomplete statements */
163#define mark LUA_QL("<eof>") 171#define mark "<eof>"
164#define marklen (sizeof(mark) - 1) 172#define marklen (sizeof(mark) - 1)
165 173
166static int incomplete (lua_State *L, int status) { 174static int incomplete (lua_State *L, int status) {
@@ -344,7 +352,6 @@ static int pmain (lua_State *L) {
344 char **argv = s->argv; 352 char **argv = s->argv;
345 int script; 353 int script;
346 int has_i = 0, has_v = 0, has_e = 0; 354 int has_i = 0, has_v = 0, has_e = 0;
347 globalL = L;
348 if (argv[0] && argv[0][0]) progname = argv[0]; 355 if (argv[0] && argv[0][0]) progname = argv[0];
349 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 356 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
350 luaL_openlibs(L); /* open libraries */ 357 luaL_openlibs(L); /* open libraries */