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