diff options
Diffstat (limited to 'liolib.c')
| -rw-r--r-- | liolib.c | 75 |
1 files changed, 47 insertions, 28 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.75 2000/08/31 13:30:10 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.76 2000/08/31 20:23:40 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -107,7 +107,7 @@ static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { | |||
| 107 | FILE *f; | 107 | FILE *f; |
| 108 | lua_getglobals(L); | 108 | lua_getglobals(L); |
| 109 | lua_getref(L, ctrl->ref[inout]); | 109 | lua_getref(L, ctrl->ref[inout]); |
| 110 | lua_rawget(L); | 110 | lua_rawget(L, -2); |
| 111 | f = gethandle(L, ctrl, -1); | 111 | f = gethandle(L, ctrl, -1); |
| 112 | if (f == NULL) | 112 | if (f == NULL) |
| 113 | luaL_verror(L, "global variable `%.10s' is not a file handle", | 113 | luaL_verror(L, "global variable `%.10s' is not a file handle", |
| @@ -564,58 +564,77 @@ static int io_debug (lua_State *L) { | |||
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | 566 | ||
| 567 | 567 | #define LEVELS1 12 /* size of the first part of the stack */ | |
| 568 | #define MESSAGESIZE 150 | 568 | #define LEVELS2 10 /* size of the second part of the stack */ |
| 569 | #define MAXMESSAGE (MESSAGESIZE*10) | ||
| 570 | |||
| 571 | 569 | ||
| 572 | static int errorfb (lua_State *L) { | 570 | static int errorfb (lua_State *L) { |
| 573 | char buff[MAXMESSAGE]; | ||
| 574 | int level = 1; /* skip level 0 (it's this function) */ | 571 | int level = 1; /* skip level 0 (it's this function) */ |
| 572 | int firstpart = 1; /* still before eventual `...' */ | ||
| 575 | lua_Debug ar; | 573 | lua_Debug ar; |
| 576 | sprintf(buff, "error: %.200s\n", lua_tostring(L, 1)); | 574 | lua_settop(L, 1); |
| 575 | luaL_checktype(L, 1, "string"); | ||
| 576 | lua_pushstring(L, "error: "); | ||
| 577 | lua_insert(L, 1); | ||
| 578 | lua_pushstring(L, "\nstack traceback:\n"); | ||
| 579 | lua_concat(L, 3); | ||
| 577 | while (lua_getstack(L, level++, &ar)) { | 580 | while (lua_getstack(L, level++, &ar)) { |
| 581 | char buff[120]; /* enough to fit following `sprintf's */ | ||
| 578 | char buffchunk[60]; | 582 | char buffchunk[60]; |
| 583 | int toconcat = 1; /* number of strings in the stack to concat */ | ||
| 584 | if (level > LEVELS1 && firstpart) { | ||
| 585 | /* no more than `LEVELS2' more levels? */ | ||
| 586 | if (!lua_getstack(L, level+LEVELS2, &ar)) | ||
| 587 | level--; /* keep going */ | ||
| 588 | else { | ||
| 589 | lua_pushstring(L, " ...\n"); /* too many levels */ | ||
| 590 | lua_concat(L, 2); | ||
| 591 | while (lua_getstack(L, level+LEVELS2, &ar)) /* get last levels */ | ||
| 592 | level++; | ||
| 593 | } | ||
| 594 | firstpart = 0; | ||
| 595 | continue; | ||
| 596 | } | ||
| 597 | sprintf(buff, "%4d: ", level-1); | ||
| 598 | lua_pushstring(L, buff); toconcat++; | ||
| 579 | lua_getinfo(L, "Snl", &ar); | 599 | lua_getinfo(L, "Snl", &ar); |
| 580 | luaL_chunkid(buffchunk, ar.source, sizeof(buffchunk)); | 600 | luaL_chunkid(buffchunk, ar.source, sizeof(buffchunk)); |
| 581 | if (level == 2) strcat(buff, "stack traceback:\n"); | ||
| 582 | strcat(buff, " "); | ||
| 583 | if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) { | ||
| 584 | strcat(buff, "...\n"); | ||
| 585 | break; /* buffer is full */ | ||
| 586 | } | ||
| 587 | switch (*ar.namewhat) { | 601 | switch (*ar.namewhat) { |
| 588 | case 'g': case 'l': /* global, local */ | 602 | case 'g': case 'l': /* global, local */ |
| 589 | sprintf(buff+strlen(buff), "function `%.50s'", ar.name); | 603 | sprintf(buff, "function `%.50s'", ar.name); |
| 590 | break; | 604 | break; |
| 591 | case 'f': /* field */ | 605 | case 'f': /* field */ |
| 592 | sprintf(buff+strlen(buff), "method `%.50s'", ar.name); | 606 | sprintf(buff, "method `%.50s'", ar.name); |
| 593 | break; | 607 | break; |
| 594 | case 't': /* tag method */ | 608 | case 't': /* tag method */ |
| 595 | sprintf(buff+strlen(buff), "`%.50s' tag method", ar.name); | 609 | sprintf(buff, "`%.50s' tag method", ar.name); |
| 596 | break; | 610 | break; |
| 597 | default: { | 611 | default: { |
| 598 | if (*ar.what == 'm') /* main? */ | 612 | if (*ar.what == 'm') /* main? */ |
| 599 | sprintf(buff+strlen(buff), "main of %.70s", buffchunk); | 613 | sprintf(buff, "main of %.70s", buffchunk); |
| 600 | else if (*ar.what == 'C') /* C function? */ | 614 | else if (*ar.what == 'C') /* C function? */ |
| 601 | sprintf(buff+strlen(buff), "%.70s", buffchunk); | 615 | sprintf(buff, "%.70s", buffchunk); |
| 602 | else | 616 | else |
| 603 | sprintf(buff+strlen(buff), "function <%d:%.70s>", | 617 | sprintf(buff, "function <%d:%.70s>", ar.linedefined, buffchunk); |
| 604 | ar.linedefined, buffchunk); | ||
| 605 | ar.source = NULL; | 618 | ar.source = NULL; |
| 606 | } | 619 | } |
| 607 | } | 620 | } |
| 608 | if (ar.currentline > 0) | 621 | lua_pushstring(L, buff); toconcat++; |
| 609 | sprintf(buff+strlen(buff), " at line %d", ar.currentline); | 622 | if (ar.currentline > 0) { |
| 610 | if (ar.source) | 623 | sprintf(buff, " at line %d", ar.currentline); |
| 611 | sprintf(buff+strlen(buff), " [%.70s]", buffchunk); | 624 | lua_pushstring(L, buff); toconcat++; |
| 612 | strcat(buff, "\n"); | 625 | } |
| 626 | if (ar.source) { | ||
| 627 | sprintf(buff, " [%.70s]", buffchunk); | ||
| 628 | lua_pushstring(L, buff); toconcat++; | ||
| 629 | } | ||
| 630 | lua_pushstring(L, "\n"); toconcat++; | ||
| 631 | lua_concat(L, toconcat); | ||
| 613 | } | 632 | } |
| 614 | lua_getglobals(L); | 633 | lua_getglobals(L); |
| 615 | lua_pushstring(L, LUA_ALERT); | 634 | lua_pushstring(L, LUA_ALERT); |
| 616 | lua_rawget(L); | 635 | lua_rawget(L, -2); |
| 617 | if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ | 636 | if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ |
| 618 | lua_pushstring(L, buff); | 637 | lua_pushvalue(L, -3); /* error message */ |
| 619 | lua_call(L, 1, 0); | 638 | lua_call(L, 1, 0); |
| 620 | } | 639 | } |
| 621 | return 0; | 640 | return 0; |
