diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 12:32:22 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 12:32:22 -0300 |
| commit | a2fa48a570b01b2a2cd37f01799f08f693fc5892 (patch) | |
| tree | b41fc7e88f7f941ae1589921f8d7c0ff57146f4d /lua.c | |
| parent | 8b2b8790b5c419282f4fa0c7faa168379647b3b9 (diff) | |
| download | lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.tar.gz lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.tar.bz2 lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.zip | |
new (old?) error handling scheme
Diffstat (limited to 'lua.c')
| -rw-r--r-- | lua.c | 74 |
1 files changed, 38 insertions, 36 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.96 2002/07/10 20:44:34 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.97 2002/07/10 20:49:01 roberto Exp roberto $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,8 +35,8 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */ | |||
| 35 | #endif | 35 | #endif |
| 36 | 36 | ||
| 37 | 37 | ||
| 38 | #ifndef LUA_USERINIT | 38 | #ifndef lua_userinit |
| 39 | #define LUA_USERINIT(L) openstdlibs(L) | 39 | #define lua_userinit(L) openstdlibs(L) |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | 42 | ||
| @@ -80,23 +80,17 @@ static void print_usage (void) { | |||
| 80 | 80 | ||
| 81 | 81 | ||
| 82 | static void l_message (const char *pname, const char *msg) { | 82 | static void l_message (const char *pname, const char *msg) { |
| 83 | size_t l = strlen(msg); | ||
| 83 | if (pname) fprintf(stderr, "%s: ", pname); | 84 | if (pname) fprintf(stderr, "%s: ", pname); |
| 84 | fprintf(stderr, "%s", msg); | 85 | fprintf(stderr, "%s", msg); |
| 86 | if (l > 0 && msg[l-1] != '\n') /* does not end with newline? */ | ||
| 87 | fprintf(stderr, "\n"); /* add a newline */ | ||
| 85 | } | 88 | } |
| 86 | 89 | ||
| 87 | 90 | ||
| 88 | static void report (int status, int traceback) { | 91 | static void report (int status) { |
| 89 | const char *msg; | 92 | const char *msg; |
| 90 | if (status) { | 93 | if (status) { |
| 91 | if (status == LUA_ERRRUN) { | ||
| 92 | if (!traceback) lua_pop(L, 1); /* remove traceback */ | ||
| 93 | else { | ||
| 94 | if (lua_isstring(L, -2) && lua_isstring(L, -1)) | ||
| 95 | lua_concat(L, 2); /* concat error message and traceback */ | ||
| 96 | else | ||
| 97 | lua_remove(L, -2); /* leave only traceback on stack */ | ||
| 98 | } | ||
| 99 | } | ||
| 100 | msg = lua_tostring(L, -1); | 94 | msg = lua_tostring(L, -1); |
| 101 | if (msg == NULL) msg = "(no message)"; | 95 | if (msg == NULL) msg = "(no message)"; |
| 102 | l_message(progname, msg); | 96 | l_message(progname, msg); |
| @@ -108,9 +102,12 @@ static void report (int status, int traceback) { | |||
| 108 | static int lcall (int clear) { | 102 | static int lcall (int clear) { |
| 109 | int status; | 103 | int status; |
| 110 | int top = lua_gettop(L); | 104 | int top = lua_gettop(L); |
| 105 | lua_getglobal(L, "_TRACEBACK"); /* get traceback function */ | ||
| 106 | lua_insert(L, top); /* put it under chunk */ | ||
| 111 | signal(SIGINT, laction); | 107 | signal(SIGINT, laction); |
| 112 | status = lua_pcall(L, 0, LUA_MULTRET); | 108 | status = lua_pcall(L, 0, LUA_MULTRET, -2); |
| 113 | signal(SIGINT, SIG_DFL); | 109 | signal(SIGINT, SIG_DFL); |
| 110 | lua_remove(L, top); /* remove traceback function */ | ||
| 114 | if (status == 0 && clear) | 111 | if (status == 0 && clear) |
| 115 | lua_settop(L, top); /* remove eventual results */ | 112 | lua_settop(L, top); /* remove eventual results */ |
| 116 | return status; | 113 | return status; |
| @@ -119,13 +116,13 @@ static int lcall (int clear) { | |||
| 119 | 116 | ||
| 120 | static int l_panic (lua_State *l) { | 117 | static int l_panic (lua_State *l) { |
| 121 | (void)l; | 118 | (void)l; |
| 122 | l_message(progname, "unable to recover; exiting\n"); | 119 | l_message(progname, "unable to recover; exiting"); |
| 123 | return 0; | 120 | return 0; |
| 124 | } | 121 | } |
| 125 | 122 | ||
| 126 | 123 | ||
| 127 | static void print_version (void) { | 124 | static void print_version (void) { |
| 128 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT "\n"); | 125 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT); |
| 129 | } | 126 | } |
| 130 | 127 | ||
| 131 | 128 | ||
| @@ -146,7 +143,7 @@ static void getargs (char *argv[], int n) { | |||
| 146 | 143 | ||
| 147 | static int docall (int status) { | 144 | static int docall (int status) { |
| 148 | if (status == 0) status = lcall(1); | 145 | if (status == 0) status = lcall(1); |
| 149 | report(status, 1); | 146 | report(status); |
| 150 | return status; | 147 | return status; |
| 151 | } | 148 | } |
| 152 | 149 | ||
| @@ -161,13 +158,21 @@ static int dostring (const char *s, const char *name) { | |||
| 161 | } | 158 | } |
| 162 | 159 | ||
| 163 | 160 | ||
| 164 | #ifndef save_line | 161 | /* |
| 165 | #define save_line(b) /* empty */ | 162 | ** this macro can be used by some `history' system to save lines |
| 163 | ** read in manual input | ||
| 164 | */ | ||
| 165 | #ifndef lua_saveline | ||
| 166 | #define lua_saveline(L,line) /* empty */ | ||
| 166 | #endif | 167 | #endif |
| 167 | 168 | ||
| 168 | 169 | ||
| 169 | #ifndef read_line | 170 | /* |
| 170 | #define read_line(p) readline(p) | 171 | ** this macro defines a function to show the prompt and reads the |
| 172 | ** next line for manual input | ||
| 173 | */ | ||
| 174 | #ifndef lua_readline | ||
| 175 | #define lua_readline(L,prompt) readline(L,prompt) | ||
| 171 | 176 | ||
| 172 | /* maximum length of an input line */ | 177 | /* maximum length of an input line */ |
| 173 | #ifndef MAXINPUT | 178 | #ifndef MAXINPUT |
| @@ -175,7 +180,7 @@ static int dostring (const char *s, const char *name) { | |||
| 175 | #endif | 180 | #endif |
| 176 | 181 | ||
| 177 | 182 | ||
| 178 | static int readline (const char *prompt) { | 183 | static int readline (lua_State *l, const char *prompt) { |
| 179 | static char buffer[MAXINPUT]; | 184 | static char buffer[MAXINPUT]; |
| 180 | if (prompt) { | 185 | if (prompt) { |
| 181 | fputs(prompt, stdout); | 186 | fputs(prompt, stdout); |
| @@ -184,10 +189,7 @@ static int readline (const char *prompt) { | |||
| 184 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) | 189 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) |
| 185 | return 0; /* read fails */ | 190 | return 0; /* read fails */ |
| 186 | else { | 191 | else { |
| 187 | size_t l = strlen(buffer); | 192 | lua_pushstring(l, buffer); |
| 188 | if (l > 0 && buffer[l-1] == '\n') | ||
| 189 | buffer[l-1] = '\0'; /* remove eventual `\n' */ | ||
| 190 | lua_pushstring(L, buffer); | ||
| 191 | return 1; | 193 | return 1; |
| 192 | } | 194 | } |
| 193 | } | 195 | } |
| @@ -219,7 +221,7 @@ static int incomplete (int status) { | |||
| 219 | static int load_string (void) { | 221 | static int load_string (void) { |
| 220 | int status; | 222 | int status; |
| 221 | lua_settop(L, 0); | 223 | lua_settop(L, 0); |
| 222 | if (read_line(get_prompt(1)) == 0) /* no input? */ | 224 | if (lua_readline(L, get_prompt(1)) == 0) /* no input? */ |
| 223 | return -1; | 225 | return -1; |
| 224 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ | 226 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ |
| 225 | lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ | 227 | lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ |
| @@ -228,12 +230,11 @@ static int load_string (void) { | |||
| 228 | for (;;) { /* repeat until gets a complete line */ | 230 | for (;;) { /* repeat until gets a complete line */ |
| 229 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); | 231 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); |
| 230 | if (!incomplete(status)) break; /* cannot try to add lines? */ | 232 | if (!incomplete(status)) break; /* cannot try to add lines? */ |
| 231 | lua_pushliteral(L, "\n"); /* no; add line separator */ | 233 | if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */ |
| 232 | if (read_line(get_prompt(0)) == 0) /* no more input? */ | ||
| 233 | return -1; | 234 | return -1; |
| 234 | lua_concat(L, lua_gettop(L)); /* join lines and line separator */ | 235 | lua_concat(L, lua_gettop(L)); /* join lines */ |
| 235 | } | 236 | } |
| 236 | save_line(lua_tostring(L, 1)); | 237 | lua_saveline(L, lua_tostring(L, 1)); |
| 237 | lua_remove(L, 1); /* remove line */ | 238 | lua_remove(L, 1); /* remove line */ |
| 238 | return status; | 239 | return status; |
| 239 | } | 240 | } |
| @@ -245,11 +246,12 @@ static void manual_input (void) { | |||
| 245 | progname = NULL; | 246 | progname = NULL; |
| 246 | while ((status = load_string()) != -1) { | 247 | while ((status = load_string()) != -1) { |
| 247 | if (status == 0) status = lcall(0); | 248 | if (status == 0) status = lcall(0); |
| 248 | report(status, 0); | 249 | report(status); |
| 249 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ | 250 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ |
| 250 | lua_getglobal(L, "print"); | 251 | lua_getglobal(L, "print"); |
| 251 | lua_insert(L, 1); | 252 | lua_insert(L, 1); |
| 252 | lua_pcall(L, lua_gettop(L)-1, 0); | 253 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) |
| 254 | l_message(progname, "error calling `print'"); | ||
| 253 | } | 255 | } |
| 254 | } | 256 | } |
| 255 | lua_settop(L, 0); /* clear stack */ | 257 | lua_settop(L, 0); /* clear stack */ |
| @@ -311,11 +313,11 @@ static int handle_argv (char *argv[], int *interactive) { | |||
| 311 | break; | 313 | break; |
| 312 | } | 314 | } |
| 313 | case 'c': { | 315 | case 'c': { |
| 314 | l_message(progname, "option `-c' is deprecated\n"); | 316 | l_message(progname, "option `-c' is deprecated"); |
| 315 | break; | 317 | break; |
| 316 | } | 318 | } |
| 317 | case 's': { | 319 | case 's': { |
| 318 | l_message(progname, "option `-s' is deprecated\n"); | 320 | l_message(progname, "option `-s' is deprecated"); |
| 319 | break; | 321 | break; |
| 320 | } | 322 | } |
| 321 | default: { | 323 | default: { |
| @@ -364,7 +366,7 @@ int main (int argc, char *argv[]) { | |||
| 364 | progname = argv[0]; | 366 | progname = argv[0]; |
| 365 | L = lua_open(); /* create state */ | 367 | L = lua_open(); /* create state */ |
| 366 | lua_atpanic(L, l_panic); | 368 | lua_atpanic(L, l_panic); |
| 367 | lua_pop(L, LUA_USERINIT(L)); /* open libraries, discard any results */ | 369 | lua_pop(L, lua_userinit(L)); /* open libraries, discard any results */ |
| 368 | status = handle_luainit(); | 370 | status = handle_luainit(); |
| 369 | if (status != 0) return status; | 371 | if (status != 0) return status; |
| 370 | status = handle_argv(argv, &interactive); | 372 | status = handle_argv(argv, &interactive); |
