diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:32 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:32 -0300 |
commit | 6e80c1cde193b767d63d2cc30ebd71d65512e061 (patch) | |
tree | cb599bdc956c0dc9b3d469bb01de47185db3e4e2 /liolib.c | |
parent | f67f324377aff66d78479eaaffbb94a6b092ae45 (diff) | |
download | lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.tar.gz lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.tar.bz2 lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.zip |
new version for API
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; |