summaryrefslogtreecommitdiff
path: root/lua.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-09 15:19:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-09 15:19:44 -0300
commita960e62c3e0eb03469947d054e6b89b8f39631a3 (patch)
tree15fea1410299c2622b76d60ad8d4a9d48d67dbd6 /lua.c
parentc51aa6ee33bff335ce5d5cb9cebe155219da85c0 (diff)
downloadlua-a960e62c3e0eb03469947d054e6b89b8f39631a3.tar.gz
lua-a960e62c3e0eb03469947d054e6b89b8f39631a3.tar.bz2
lua-a960e62c3e0eb03469947d054e6b89b8f39631a3.zip
new options; no more _ALERT; no more getargs
Diffstat (limited to 'lua.c')
-rw-r--r--lua.c264
1 files changed, 120 insertions, 144 deletions
diff --git a/lua.c b/lua.c
index b0892d1d..1ed3a902 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.93 2002/06/20 20:40:09 roberto Exp roberto $ 2** $Id: lua.c,v 1.94 2002/06/26 16:37:39 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*/
@@ -45,42 +45,62 @@ static lua_State *L = NULL;
45static const char *progname; 45static const char *progname;
46 46
47 47
48static lua_Hook old_linehook = NULL; 48static lua_Hook old_hook = NULL;
49static lua_Hook old_callhook = NULL; 49static int old_mask = 0;
50 50
51 51
52static void lstop (void) { 52static void lstop (lua_State *l, lua_Debug *ar) {
53 lua_setlinehook(L, old_linehook); 53 (void)ar; /* unused arg. */
54 lua_setcallhook(L, old_callhook); 54 lua_sethook(l, old_hook, old_mask);
55 luaL_error(L, "interrupted!"); 55 luaL_error(l, "interrupted!");
56} 56}
57 57
58 58
59static void laction (int i) { 59static void laction (int i) {
60 signal(i, SIG_DFL); /* if another SIGINT happens before lstop, 60 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
61 terminate process (default action) */ 61 terminate process (default action) */
62 old_linehook = lua_setlinehook(L, (lua_Hook)lstop); 62 old_hook = lua_gethook(L);
63 old_callhook = lua_setcallhook(L, (lua_Hook)lstop); 63 old_mask = lua_gethookmask(L);
64 lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT(1));
64} 65}
65 66
66 67
67static void report (int status) { 68static void print_usage (void) {
69 fprintf(stderr,
70 "usage: %s [options] [prog [args]].\n"
71 "Available options are:\n"
72 " - execute stdin as a file\n"
73 " -e stat execute string `stat'\n"
74 " -i enter interactive mode after executing `prog'\n"
75 " -l name execute file `name'\n"
76 " -v print version information\n"
77 " -- stop handling arguments\n" ,
78 progname);
79}
80
81
82static void l_message (const char *pname, const char *msg) {
83 if (pname) fprintf(stderr, "%s: ", pname);
84 fprintf(stderr, "%s\n", msg);
85}
86
87
88static void report (int status, int traceback) {
89 const char *msg;
68 if (status) { 90 if (status) {
69 if (status == LUA_ERRRUN) { 91 if (status == LUA_ERRRUN) {
70 if (lua_isstring(L, -2) && lua_isstring(L, -1)) 92 if (!traceback) lua_pop(L, 1); /* remove traceback */
71 lua_concat(L, 2); /* concat error message and traceback */ 93 else {
72 else 94 if (lua_isstring(L, -2) && lua_isstring(L, -1))
73 lua_remove(L, -2); /* lease only traceback on stack */ 95 lua_concat(L, 2); /* concat error message and traceback */
74 } 96 else
75 lua_getglobal(L, "_ALERT"); 97 lua_remove(L, -2); /* leave only traceback on stack */
76 if (lua_isfunction(L, -1)) { 98 }
77 lua_pushvalue(L, -2);
78 lua_pcall(L, 1, 0);
79 }
80 else {
81 lua_pop(L, 1);
82 fprintf(stderr, "%s", lua_tostring(L, -1));
83 } 99 }
100 msg = lua_tostring(L, -1);
101 if (msg == NULL) msg = "(no message)";
102 l_message(progname, msg);
103 lua_pop(L, 1);
84 } 104 }
85} 105}
86 106
@@ -97,74 +117,36 @@ static int lcall (int clear) {
97} 117}
98 118
99 119
100static void print_usage (void) {
101 fprintf(stderr,
102 "usage: %s [options]. Available options are:\n"
103 " - execute stdin as a file\n"
104 " -c close Lua when exiting\n"
105 " -e stat execute string `stat'\n"
106 " -f name execute file `name' with remaining arguments in table `arg'\n"
107 " -i enter interactive mode\n"
108 " -v print version information\n"
109 " a=b set global `a' to string `b'\n"
110 " name execute file `name'\n",
111 progname);
112}
113
114
115static int l_panic (lua_State *l) { 120static int l_panic (lua_State *l) {
116 (void)l; 121 (void)l;
117 fputs("unable to recover; exiting\n", stderr); 122 l_message(progname, "unable to recover; exiting");
118 return 0; 123 return 0;
119} 124}
120 125
121 126
122static void print_version (void) { 127static void print_version (void) {
123 printf("%.80s %.80s\n", LUA_VERSION, LUA_COPYRIGHT); 128 l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
124} 129}
125 130
126 131
127static void assign (const char *arg) { 132static void getargs (char *argv[], int n) {
128 char *eq = strchr(arg, '='); /* arg is `name=value'; find the `=' */
129 lua_pushlstring(L, arg, eq-arg); /* push name */
130 lua_pushstring(L, eq+1); /* push value */
131 lua_settable(L, LUA_GLOBALSINDEX); /* _G.name = value */
132}
133
134
135static void getargs (char *argv[]) {
136 int i; 133 int i;
137 lua_newtable(L); 134 lua_newtable(L);
138 for (i=0; argv[i]; i++) { 135 for (i=0; argv[i]; i++) {
139 /* arg[i] = argv[i] */ 136 lua_pushnumber(L, i - n);
140 lua_pushnumber(L, i);
141 lua_pushstring(L, argv[i]); 137 lua_pushstring(L, argv[i]);
142 lua_rawset(L, -3); 138 lua_rawset(L, -3);
143 } 139 }
144 /* arg.n = maximum index in table `arg' */ 140 /* arg.n = maximum index in table `arg' */
145 lua_pushliteral(L, "n"); 141 lua_pushliteral(L, "n");
146 lua_pushnumber(L, i-1); 142 lua_pushnumber(L, i-n-1);
147 lua_rawset(L, -3); 143 lua_rawset(L, -3);
148} 144}
149 145
150 146
151static int l_alert (lua_State *l) {
152 if (progname) fprintf(stderr, "%s: ", progname);
153 fprintf(stderr, "%s\n", luaL_check_string(l, 1));
154 return 0;
155}
156
157
158static int l_getargs (lua_State *l) {
159 char **argv = (char **)lua_touserdata(l, lua_upvalueindex(1));
160 getargs(argv);
161 return 1;
162}
163
164
165static int docall (int status) { 147static int docall (int status) {
166 if (status == 0) status = lcall(1); 148 if (status == 0) status = lcall(1);
167 report(status); 149 report(status, 1);
168 return status; 150 return status;
169} 151}
170 152
@@ -258,20 +240,20 @@ static void manual_input (int version) {
258 if (version) print_version(); 240 if (version) print_version();
259 while ((status = load_string()) != -1) { 241 while ((status = load_string()) != -1) {
260 if (status == 0) status = lcall(0); 242 if (status == 0) status = lcall(0);
261 report(status); 243 report(status, 0);
262 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ 244 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
263 lua_getglobal(L, "print"); 245 lua_getglobal(L, "print");
264 lua_insert(L, 1); 246 lua_insert(L, 1);
265 lua_pcall(L, lua_gettop(L)-1, 0); 247 lua_pcall(L, lua_gettop(L)-1, 0);
266 } 248 }
267 } 249 }
268 printf("\n"); 250 fputs("\n", stdout);
269 progname = oldprogname; 251 progname = oldprogname;
270} 252}
271 253
272 254
273static int handle_argv (char *argv[], int *toclose) { 255static int handle_argv (char *argv[], int *interactive) {
274 if (*argv == NULL) { /* no more arguments? */ 256 if (argv[1] == NULL) { /* no more arguments? */
275 if (isatty(0)) { 257 if (isatty(0)) {
276 manual_input(1); 258 manual_input(1);
277 } 259 }
@@ -280,85 +262,80 @@ static int handle_argv (char *argv[], int *toclose) {
280 } 262 }
281 else { /* other arguments; loop over them */ 263 else { /* other arguments; loop over them */
282 int i; 264 int i;
283 for (i = 0; argv[i] != NULL; i++) { 265 for (i = 1; argv[i] != NULL; i++) {
284 if (argv[i][0] != '-') { /* not an option? */ 266 if (argv[i][0] != '-') break; /* not an option? */
285 if (strchr(argv[i], '=')) 267 switch (argv[i][1]) { /* option */
286 assign(argv[i]); 268 case '-': { /* `--' */
287 else 269 i++; /* skip this argument */
288 if (file_input(argv[i])) 270 goto endloop; /* stop handling arguments */
289 return EXIT_FAILURE; /* stop if file fails */
290 } 271 }
291 else switch (argv[i][1]) { /* option */ 272 case '\0': {
292 case '\0': { 273 file_input(NULL); /* executes stdin as a file */
293 file_input(NULL); /* executes stdin as a file */ 274 break;
294 break; 275 }
295 } 276 case 'i': {
296 case 'i': { 277 *interactive = 1;
297 manual_input(0); 278 break;
298 break; 279 }
299 } 280 case 'v': {
300 case 'c': { 281 print_version();
301 *toclose = 1; 282 break;
302 break; 283 }
303 } 284 case 'e': {
304 case 'v': { 285 const char *chunk = argv[i] + 2;
305 print_version(); 286 if (*chunk == '\0') chunk = argv[++i];
306 break; 287 if (chunk == NULL) {
307 } 288 print_usage();
308 case 'e': { 289 return EXIT_FAILURE;
309 const char *chunk = argv[i] + 2;
310 if (*chunk == '\0') chunk = argv[++i];
311 if (chunk == NULL) {
312 print_usage();
313 return EXIT_FAILURE;
314 }
315 if (dostring(chunk, "=command line") != 0)
316 return EXIT_FAILURE;
317 break;
318 }
319 case 'f': {
320 const char *filename = argv[i] + 2;
321 if (*filename == '\0') filename = argv[++i];
322 if (filename == NULL) {
323 print_usage();
324 return EXIT_FAILURE;
325 }
326 getargs(argv+i); /* collect remaining arguments */
327 lua_setglobal(L, "arg");
328 return file_input(filename); /* stop scanning arguments */
329 }
330 case 's': {
331 fprintf(stderr,
332 "%s: option `-s' is deprecated (dynamic stack now)\n",
333 progname);
334 break;
335 } 290 }
336 default: { 291 if (dostring(chunk, "=<command line>") != 0)
292 return EXIT_FAILURE;
293 break;
294 }
295 case 'l': {
296 const char *filename = argv[i] + 2;
297 if (*filename == '\0') filename = argv[++i];
298 if (filename == NULL) {
337 print_usage(); 299 print_usage();
338 return EXIT_FAILURE; 300 return EXIT_FAILURE;
339 } 301 }
302 if (file_input(filename))
303 return EXIT_FAILURE; /* stop if file fails */
304 break;
305 }
306 case 'c': {
307 l_message(progname, "option `-c' is deprecated");
308 break;
309 }
310 case 's': {
311 l_message(progname, "option `-s' is deprecated");
312 break;
313 }
314 default: {
315 print_usage();
316 return EXIT_FAILURE;
340 } 317 }
318 }
319 } endloop:
320 if (argv[i] != NULL) {
321 const char *filename = argv[i];
322 getargs(argv, i); /* collect remaining arguments */
323 lua_setglobal(L, "arg");
324 return file_input(filename); /* stop scanning arguments */
341 } 325 }
342 } 326 }
343 return EXIT_SUCCESS; 327 return EXIT_SUCCESS;
344} 328}
345 329
346 330
347static void register_own (char *argv[]) { 331static int openstdlibs (lua_State *l) {
348 lua_pushudataval(L, argv); 332 return lua_baselibopen(l) +
349 lua_pushcclosure(L, l_getargs, 1); 333 lua_tablibopen(l) +
350 lua_setglobal(L, "getargs"); 334 lua_iolibopen(l) +
351 lua_register(L, "_ALERT", l_alert); 335 lua_strlibopen(l) +
352} 336 lua_mathlibopen(l) +
353 337 lua_dblibopen(l) +
354 338 0;
355static void openstdlibs (lua_State *l) {
356 lua_baselibopen(l);
357 lua_tablibopen(l);
358 lua_iolibopen(l);
359 lua_strlibopen(l);
360 lua_mathlibopen(l);
361 lua_dblibopen(l);
362} 339}
363 340
364 341
@@ -374,18 +351,17 @@ static int handle_luainit (void) {
374 351
375int main (int argc, char *argv[]) { 352int main (int argc, char *argv[]) {
376 int status; 353 int status;
377 int toclose = 0; 354 int interactive = 0;
378 (void)argc; /* to avoid warnings */ 355 (void)argc; /* to avoid warnings */
379 progname = argv[0]; 356 progname = argv[0];
380 L = lua_open(); /* create state */ 357 L = lua_open(); /* create state */
381 lua_atpanic(L, l_panic); 358 lua_atpanic(L, l_panic);
382 LUA_USERINIT(L); /* open libraries */ 359 lua_pop(L, LUA_USERINIT(L)); /* open libraries, dischard any results */
383 register_own(argv); /* create own function */
384 status = handle_luainit(); 360 status = handle_luainit();
385 if (status != 0) return status; 361 if (status != 0) return status;
386 status = handle_argv(argv+1, &toclose); 362 status = handle_argv(argv, &interactive);
387 if (toclose) 363 if (status == 0 && interactive) manual_input(0);
388 lua_close(L); 364 lua_close(L);
389 return status; 365 return status;
390} 366}
391 367