summaryrefslogtreecommitdiff
path: root/lua.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 /lua.c
parentb36b2a061c88be22e36900146cbcad39bab07f5d (diff)
downloadlua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.gz
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.tar.bz2
lua-751cd867d3e0338279fa6f3390c8b7ddc0108659.zip
new way to handle errors
Diffstat (limited to 'lua.c')
-rw-r--r--lua.c147
1 files changed, 68 insertions, 79 deletions
diff --git a/lua.c b/lua.c
index 5f050fc4..7508c4aa 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.83 2002/04/22 14:40:50 roberto Exp roberto $ 2** $Id: lua.c,v 1.84 2002/04/23 14:59:22 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*/
@@ -66,23 +66,30 @@ static void laction (int i) {
66} 66}
67 67
68 68
69/* Lua gives no message in such cases, so we provide one */ 69static void report (int status) {
70static void report (int result) { 70 if (status == 0) return;
71 if (result == LUA_ERRMEM || result == LUA_ERRERR) 71 else {
72 fprintf(stderr, "%s: %s\n", LUA_PROGNAME, luaL_errstr(result)); 72 const char *msg = lua_tostring(L, -1);
73 if (msg == NULL) msg = "(no message)";
74 fprintf(stderr, "error: %s\n", msg);
75 lua_pop(L, 1);
76 }
73} 77}
74 78
75 79
76static int ldo (int (*f)(lua_State *l, const char *), const char *name, 80static int lcall (int clear) {
77 int clear) { 81 int status;
78 int result;
79 int top = lua_gettop(L); 82 int top = lua_gettop(L);
83 lua_getglobal(L, "_ERRORMESSAGE");
84 lua_insert(L, top);
80 signal(SIGINT, laction); 85 signal(SIGINT, laction);
81 result = f(L, name); /* dostring | dofile */ 86 status = lua_pcall(L, 0, LUA_MULTRET, top);
82 signal(SIGINT, SIG_DFL); 87 signal(SIGINT, SIG_DFL);
83 if (clear) lua_settop(L, top); /* remove eventual results */ 88 if (status == 0) {
84 report(result); 89 if (clear) lua_settop(L, top); /* remove eventual results */
85 return result; 90 else lua_remove(L, top); /* else remove only error function */
91 }
92 return status;
86} 93}
87 94
88 95
@@ -138,16 +145,18 @@ static int l_getargs (lua_State *l) {
138 145
139 146
140static int file_input (const char *name) { 147static int file_input (const char *name) {
141 int result = ldo(lua_dofile, name, 1); 148 int status = lua_loadfile(L, name);
142 if (result) { 149 if (status == 0) status = lcall(1);
143 if (result == LUA_ERRFILE) { 150 report(status);
144 fprintf(stderr, "%s: %s ", LUA_PROGNAME, luaL_errstr(result)); 151 return status;
145 perror(name); 152}
146 } 153
147 return EXIT_FAILURE; 154
148 } 155static int dostring (const char *s) {
149 else 156 int status = lua_loadbuffer(L, s, strlen(s), s);
150 return EXIT_SUCCESS; 157 if (status == 0) status = lcall(1);
158 report(status);
159 return status;
151} 160}
152 161
153 162
@@ -177,85 +186,65 @@ static char *readline (const char *prompt) {
177#endif 186#endif
178 187
179 188
180static const char *get_prompt (int incomplete) { 189static const char *get_prompt (int firstline) {
181 const char *p = NULL; 190 const char *p = NULL;
182 lua_getglobal(L, incomplete ? "_PROMPT2" : "_PROMPT"); 191 lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
183 p = lua_tostring(L, -1); 192 p = lua_tostring(L, -1);
184 if (p == NULL) p = (incomplete ? PROMPT2 : PROMPT); 193 if (p == NULL) p = (firstline ? PROMPT : PROMPT2);
185 lua_pop(L, 1); /* remove global */ 194 lua_pop(L, 1); /* remove global */
186 return p; 195 return p;
187} 196}
188 197
189 198
190static int incomplete = 0; 199static int incomplete (int status) {
191 200 if (status == LUA_ERRSYNTAX &&
192static int trap_eof (lua_State *l) { 201 strstr(lua_tostring(L, -1), "last token read: `<eof>'") != NULL) {
193 const char *s = lua_tostring(l, 1); 202 lua_pop(L, 1);
194 if (strstr(s, "last token read: `<eof>'") != NULL) 203 return 1;
195 incomplete = 1; 204 }
196 else 205 else
197 fprintf(stderr, "error: %s\n", s); 206 return 0;
198 return 0;
199} 207}
200 208
201 209
202static int load_string (void) { 210static int load_string (void) {
203 lua_getglobal(L, "_ERRORMESSAGE"); 211 int firstline = 1;
204 lua_pushvalue(L, 1); 212 int status;
205 lua_setglobal(L, "_ERRORMESSAGE"); 213 lua_settop(L, 0);
206 incomplete = 0; 214 do { /* repeat until gets a complete line */
207 for (;;) { /* repeat until gets a complete line */ 215 char *buffer = readline(get_prompt(firstline));
208 int result;
209 char *buffer = readline(get_prompt(incomplete));
210 if (buffer == NULL) { /* input end? */ 216 if (buffer == NULL) { /* input end? */
211 lua_settop(L, 2); 217 lua_settop(L, 0);
212 lua_setglobal(L, "_ERRORMESSAGE"); 218 return -1; /* input end */
213 return 0;
214 } 219 }
215 if (!incomplete && buffer[0] == '=') { 220 if (firstline && buffer[0] == '=') {
216 buffer[0] = ' '; 221 buffer[0] = ' ';
217 lua_pushstring(L, "return"); 222 lua_pushstring(L, "return");
218 } 223 }
224 firstline = 0;
219 push_line(buffer); 225 push_line(buffer);
220 lua_concat(L, lua_gettop(L)-2); 226 lua_concat(L, lua_gettop(L));
221 incomplete = 0; 227 status = lua_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
222 result = lua_loadbuffer(L, lua_tostring(L, 3), lua_strlen(L, 3), "=stdin"); 228 } while (incomplete(status)); /* repeat loop to get rest of `line' */
223 if (incomplete) continue; /* repeat loop to get rest of `line' */ 229 save_line(lua_tostring(L, 1));
224 save_line(lua_tostring(L, 3)); 230 lua_remove(L, 1);
225 lua_remove(L, 3); 231 return status;
226 if (result == 0) {
227 lua_insert(L, 2); /* swap compiled chunk with old _ERRORMESSAGE */
228 lua_setglobal(L, "_ERRORMESSAGE"); /* restore old _ERRORMESSAGE */
229 return 1;
230 }
231 else
232 report(result);
233 }
234}
235
236
237static int lcall (lua_State *l, const char *name) {
238 (void)name; /* to avoid warnings */
239 return lua_call(l, 0, LUA_MULTRET);
240} 232}
241 233
242 234
243static void manual_input (int version) { 235static void manual_input (int version) {
236 int status;
244 if (version) print_version(); 237 if (version) print_version();
245 lua_settop(L, 0); 238 while ((status = load_string()) != -1) {
246 lua_pushcfunction(L, trap_eof); /* set up handler for incomplete lines */ 239 if (status == 0) status = lcall(0);
247 while (load_string()) { 240 report(status);
248 ldo(lcall, NULL, 0); 241 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
249 if (lua_gettop(L) > 1) { /* any result to print? */
250 lua_getglobal(L, "print"); 242 lua_getglobal(L, "print");
251 lua_insert(L, 2); 243 lua_insert(L, 1);
252 lua_call(L, lua_gettop(L)-2, 0); 244 lua_call(L, lua_gettop(L)-1, 0);
253 } 245 }
254 else
255 lua_settop(L, 1); /* remove eventual results */
256 } 246 }
257 printf("\n"); 247 printf("\n");
258 lua_pop(L, 1); /* remove trap_eof */
259} 248}
260 249
261 250
@@ -265,7 +254,7 @@ static int handle_argv (char *argv[], int *toclose) {
265 manual_input(1); 254 manual_input(1);
266 } 255 }
267 else 256 else
268 ldo(lua_dofile, NULL, 1); /* executes stdin as a file */ 257 file_input(NULL); /* executes stdin as a file */
269 } 258 }
270 else { /* other arguments; loop over them */ 259 else { /* other arguments; loop over them */
271 int i; 260 int i;
@@ -274,12 +263,12 @@ static int handle_argv (char *argv[], int *toclose) {
274 if (strchr(argv[i], '=')) 263 if (strchr(argv[i], '='))
275 assign(argv[i]); 264 assign(argv[i]);
276 else 265 else
277 if (file_input(argv[i]) != EXIT_SUCCESS) 266 if (file_input(argv[i]))
278 return EXIT_FAILURE; /* stop if file fails */ 267 return EXIT_FAILURE; /* stop if file fails */
279 } 268 }
280 else switch (argv[i][1]) { /* option */ 269 else switch (argv[i][1]) { /* option */
281 case '\0': { 270 case '\0': {
282 ldo(lua_dofile, NULL, 1); /* executes stdin as a file */ 271 file_input(NULL); /* executes stdin as a file */
283 break; 272 break;
284 } 273 }
285 case 'i': { 274 case 'i': {
@@ -300,7 +289,7 @@ static int handle_argv (char *argv[], int *toclose) {
300 print_usage(); 289 print_usage();
301 return EXIT_FAILURE; 290 return EXIT_FAILURE;
302 } 291 }
303 if (ldo(lua_dostring, argv[i], 1) != 0) { 292 if (dostring(argv[i]) != 0) {
304 fprintf(stderr, "%s: error running argument `%.99s'\n", 293 fprintf(stderr, "%s: error running argument `%.99s'\n",
305 LUA_PROGNAME, argv[i]); 294 LUA_PROGNAME, argv[i]);
306 return EXIT_FAILURE; 295 return EXIT_FAILURE;