summaryrefslogtreecommitdiff
path: root/lbaselib.c
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 /lbaselib.c
parentb36b2a061c88be22e36900146cbcad39bab07f5d (diff)
downloadlua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.gz
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.bz2
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.zip
new way to handle errors
Diffstat (limited to 'lbaselib.c')
-rw-r--r--lbaselib.c140
1 files changed, 44 insertions, 96 deletions
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