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 | ||
