diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-01 17:48:12 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-01 17:48:12 -0300 |
commit | 751cd867d3e0338279fa6f3390c8b7ddc0108659 (patch) | |
tree | 726f6f3cd49109382b2c0d7ee6a1e0fea740afbd /lbaselib.c | |
parent | b36b2a061c88be22e36900146cbcad39bab07f5d (diff) | |
download | lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.gz lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.bz2 lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.zip |
new way to handle errors
Diffstat (limited to 'lbaselib.c')
-rw-r--r-- | lbaselib.c | 140 |
1 files changed, 44 insertions, 96 deletions
@@ -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 | */ |
27 | static int luaB__ALERT (lua_State *L) { | 27 | static 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 | */ |
37 | static int luaB__ERRORMESSAGE (lua_State *L) { | 38 | static 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 | ||
116 | static int luaB_error (lua_State *L) { | 113 | static 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 | ||
220 | static int passresults (lua_State *L, int status, int oldtop) { | 218 | static 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 | ||
238 | static 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 | |||
247 | static int luaB_loadstring (lua_State *L) { | 228 | static 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 | |||
256 | static 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 | ||
263 | static int luaB_loadfile (lua_State *L) { | 236 | static 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 | ||
279 | static int aux_unpack (lua_State *L, int arg) { | 251 | static 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 | ||
290 | static int luaB_unpack (lua_State *L) { | 262 | static int luaB_pcall (lua_State *L) { |
291 | return aux_unpack(L, 1); | ||
292 | } | ||
293 | |||
294 | |||
295 | static 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 | ||