aboutsummaryrefslogtreecommitdiff
path: root/src/luajit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/luajit.c')
-rw-r--r--src/luajit.c134
1 files changed, 74 insertions, 60 deletions
diff --git a/src/luajit.c b/src/luajit.c
index 9e15b26d..1ca24301 100644
--- a/src/luajit.c
+++ b/src/luajit.c
@@ -61,8 +61,9 @@ static void laction(int i)
61 61
62static void print_usage(void) 62static void print_usage(void)
63{ 63{
64 fprintf(stderr, 64 fputs("usage: ", stderr);
65 "usage: %s [options]... [script [args]...].\n" 65 fputs(progname, stderr);
66 fputs(" [options]... [script [args]...].\n"
66 "Available options are:\n" 67 "Available options are:\n"
67 " -e chunk Execute string " LUA_QL("chunk") ".\n" 68 " -e chunk Execute string " LUA_QL("chunk") ".\n"
68 " -l name Require library " LUA_QL("name") ".\n" 69 " -l name Require library " LUA_QL("name") ".\n"
@@ -73,16 +74,14 @@ static void print_usage(void)
73 " -v Show version information.\n" 74 " -v Show version information.\n"
74 " -E Ignore environment variables.\n" 75 " -E Ignore environment variables.\n"
75 " -- Stop handling options.\n" 76 " -- Stop handling options.\n"
76 " - Execute stdin and stop handling options.\n" 77 " - Execute stdin and stop handling options.\n", stderr);
77 ,
78 progname);
79 fflush(stderr); 78 fflush(stderr);
80} 79}
81 80
82static void l_message(const char *pname, const char *msg) 81static void l_message(const char *pname, const char *msg)
83{ 82{
84 if (pname) fprintf(stderr, "%s: ", pname); 83 if (pname) { fputs(pname, stderr); fputc(':', stderr); fputc(' ', stderr); }
85 fprintf(stderr, "%s\n", msg); 84 fputs(msg, stderr); fputc('\n', stderr);
86 fflush(stderr); 85 fflush(stderr);
87} 86}
88 87
@@ -125,7 +124,7 @@ static int docall(lua_State *L, int narg, int clear)
125#endif 124#endif
126 lua_remove(L, base); /* remove traceback function */ 125 lua_remove(L, base); /* remove traceback function */
127 /* force a complete garbage collection in case of errors */ 126 /* force a complete garbage collection in case of errors */
128 if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); 127 if (status != LUA_OK) lua_gc(L, LUA_GCCOLLECT, 0);
129 return status; 128 return status;
130} 129}
131 130
@@ -153,22 +152,15 @@ static void print_jit_status(lua_State *L)
153 putc('\n', stdout); 152 putc('\n', stdout);
154} 153}
155 154
156static int getargs(lua_State *L, char **argv, int n) 155static void createargtable(lua_State *L, char **argv, int argc, int argf)
157{ 156{
158 int narg;
159 int i; 157 int i;
160 int argc = 0; 158 lua_createtable(L, argc - argf, argf);
161 while (argv[argc]) argc++; /* count total number of arguments */
162 narg = argc - (n + 1); /* number of arguments to the script */
163 luaL_checkstack(L, narg + 3, "too many arguments to script");
164 for (i = n+1; i < argc; i++)
165 lua_pushstring(L, argv[i]);
166 lua_createtable(L, narg, n + 1);
167 for (i = 0; i < argc; i++) { 159 for (i = 0; i < argc; i++) {
168 lua_pushstring(L, argv[i]); 160 lua_pushstring(L, argv[i]);
169 lua_rawseti(L, -2, i - n); 161 lua_rawseti(L, -2, i - argf);
170 } 162 }
171 return narg; 163 lua_setglobal(L, "arg");
172} 164}
173 165
174static int dofile(lua_State *L, const char *name) 166static int dofile(lua_State *L, const char *name)
@@ -257,9 +249,9 @@ static void dotty(lua_State *L)
257 const char *oldprogname = progname; 249 const char *oldprogname = progname;
258 progname = NULL; 250 progname = NULL;
259 while ((status = loadline(L)) != -1) { 251 while ((status = loadline(L)) != -1) {
260 if (status == 0) status = docall(L, 0, 0); 252 if (status == LUA_OK) status = docall(L, 0, 0);
261 report(L, status); 253 report(L, status);
262 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ 254 if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */
263 lua_getglobal(L, "print"); 255 lua_getglobal(L, "print");
264 lua_insert(L, 1); 256 lua_insert(L, 1);
265 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) 257 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
@@ -274,21 +266,30 @@ static void dotty(lua_State *L)
274 progname = oldprogname; 266 progname = oldprogname;
275} 267}
276 268
277static int handle_script(lua_State *L, char **argv, int n) 269static int handle_script(lua_State *L, char **argx)
278{ 270{
279 int status; 271 int status;
280 const char *fname; 272 const char *fname = argx[0];
281 int narg = getargs(L, argv, n); /* collect arguments */ 273 if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0)
282 lua_setglobal(L, "arg");
283 fname = argv[n];
284 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
285 fname = NULL; /* stdin */ 274 fname = NULL; /* stdin */
286 status = luaL_loadfile(L, fname); 275 status = luaL_loadfile(L, fname);
287 lua_insert(L, -(narg+1)); 276 if (status == LUA_OK) {
288 if (status == 0) 277 /* Fetch args from arg table. LUA_INIT or -e might have changed them. */
278 int narg = 0;
279 lua_getglobal(L, "arg");
280 if (lua_istable(L, -1)) {
281 do {
282 narg++;
283 lua_rawgeti(L, -narg, narg);
284 } while (!lua_isnil(L, -1));
285 lua_pop(L, 1);
286 lua_remove(L, -narg);
287 narg--;
288 } else {
289 lua_pop(L, 1);
290 }
289 status = docall(L, narg, 0); 291 status = docall(L, narg, 0);
290 else 292 }
291 lua_pop(L, narg);
292 return report(L, status); 293 return report(L, status);
293} 294}
294 295
@@ -385,7 +386,8 @@ static int dobytecode(lua_State *L, char **argv)
385 } 386 }
386 for (argv++; *argv != NULL; narg++, argv++) 387 for (argv++; *argv != NULL; narg++, argv++)
387 lua_pushstring(L, *argv); 388 lua_pushstring(L, *argv);
388 return report(L, lua_pcall(L, narg, 0, 0)); 389 report(L, lua_pcall(L, narg, 0, 0));
390 return -1;
389} 391}
390 392
391/* check that argument has no extra characters at the end */ 393/* check that argument has no extra characters at the end */
@@ -406,7 +408,7 @@ static int collectargs(char **argv, int *flags)
406 switch (argv[i][1]) { /* Check option. */ 408 switch (argv[i][1]) { /* Check option. */
407 case '-': 409 case '-':
408 notail(argv[i]); 410 notail(argv[i]);
409 return (argv[i+1] != NULL ? i+1 : 0); 411 return i+1;
410 case '\0': 412 case '\0':
411 return i; 413 return i;
412 case 'i': 414 case 'i':
@@ -431,23 +433,23 @@ static int collectargs(char **argv, int *flags)
431 case 'b': /* LuaJIT extension */ 433 case 'b': /* LuaJIT extension */
432 if (*flags) return -1; 434 if (*flags) return -1;
433 *flags |= FLAGS_EXEC; 435 *flags |= FLAGS_EXEC;
434 return 0; 436 return i+1;
435 case 'E': 437 case 'E':
436 *flags |= FLAGS_NOENV; 438 *flags |= FLAGS_NOENV;
437 break; 439 break;
438 default: return -1; /* invalid option */ 440 default: return -1; /* invalid option */
439 } 441 }
440 } 442 }
441 return 0; 443 return i;
442} 444}
443 445
444static int runargs(lua_State *L, char **argv, int n) 446static int runargs(lua_State *L, char **argv, int argn)
445{ 447{
446 int i; 448 int i;
447 for (i = 1; i < n; i++) { 449 for (i = 1; i < argn; i++) {
448 if (argv[i] == NULL) continue; 450 if (argv[i] == NULL) continue;
449 lua_assert(argv[i][0] == '-'); 451 lua_assert(argv[i][0] == '-');
450 switch (argv[i][1]) { /* option */ 452 switch (argv[i][1]) {
451 case 'e': { 453 case 'e': {
452 const char *chunk = argv[i] + 2; 454 const char *chunk = argv[i] + 2;
453 if (*chunk == '\0') chunk = argv[++i]; 455 if (*chunk == '\0') chunk = argv[++i];
@@ -461,10 +463,10 @@ static int runargs(lua_State *L, char **argv, int n)
461 if (*filename == '\0') filename = argv[++i]; 463 if (*filename == '\0') filename = argv[++i];
462 lua_assert(filename != NULL); 464 lua_assert(filename != NULL);
463 if (dolibrary(L, filename)) 465 if (dolibrary(L, filename))
464 return 1; /* stop if file fails */ 466 return 1;
465 break; 467 break;
466 } 468 }
467 case 'j': { /* LuaJIT extension */ 469 case 'j': { /* LuaJIT extension. */
468 const char *cmd = argv[i] + 2; 470 const char *cmd = argv[i] + 2;
469 if (*cmd == '\0') cmd = argv[++i]; 471 if (*cmd == '\0') cmd = argv[++i];
470 lua_assert(cmd != NULL); 472 lua_assert(cmd != NULL);
@@ -472,16 +474,16 @@ static int runargs(lua_State *L, char **argv, int n)
472 return 1; 474 return 1;
473 break; 475 break;
474 } 476 }
475 case 'O': /* LuaJIT extension */ 477 case 'O': /* LuaJIT extension. */
476 if (dojitopt(L, argv[i] + 2)) 478 if (dojitopt(L, argv[i] + 2))
477 return 1; 479 return 1;
478 break; 480 break;
479 case 'b': /* LuaJIT extension */ 481 case 'b': /* LuaJIT extension. */
480 return dobytecode(L, argv+i); 482 return dobytecode(L, argv+i);
481 default: break; 483 default: break;
482 } 484 }
483 } 485 }
484 return 0; 486 return LUA_OK;
485} 487}
486 488
487static int handle_luainit(lua_State *L) 489static int handle_luainit(lua_State *L)
@@ -492,7 +494,7 @@ static int handle_luainit(lua_State *L)
492 const char *init = getenv(LUA_INIT); 494 const char *init = getenv(LUA_INIT);
493#endif 495#endif
494 if (init == NULL) 496 if (init == NULL)
495 return 0; /* status OK */ 497 return LUA_OK;
496 else if (init[0] == '@') 498 else if (init[0] == '@')
497 return dofile(L, init+1); 499 return dofile(L, init+1);
498 else 500 else
@@ -509,45 +511,57 @@ static int pmain(lua_State *L)
509{ 511{
510 struct Smain *s = &smain; 512 struct Smain *s = &smain;
511 char **argv = s->argv; 513 char **argv = s->argv;
512 int script; 514 int argn;
513 int flags = 0; 515 int flags = 0;
514 globalL = L; 516 globalL = L;
515 if (argv[0] && argv[0][0]) progname = argv[0]; 517 if (argv[0] && argv[0][0]) progname = argv[0];
516 LUAJIT_VERSION_SYM(); /* linker-enforced version check */ 518
517 script = collectargs(argv, &flags); 519 LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */
518 if (script < 0) { /* invalid args? */ 520
521 argn = collectargs(argv, &flags);
522 if (argn < 0) { /* Invalid args? */
519 print_usage(); 523 print_usage();
520 s->status = 1; 524 s->status = 1;
521 return 0; 525 return 0;
522 } 526 }
527
523 if ((flags & FLAGS_NOENV)) { 528 if ((flags & FLAGS_NOENV)) {
524 lua_pushboolean(L, 1); 529 lua_pushboolean(L, 1);
525 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 530 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
526 } 531 }
527 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 532
528 luaL_openlibs(L); /* open libraries */ 533 /* Stop collector during library initialization. */
534 lua_gc(L, LUA_GCSTOP, 0);
535 luaL_openlibs(L);
529 lua_gc(L, LUA_GCRESTART, -1); 536 lua_gc(L, LUA_GCRESTART, -1);
537
538 createargtable(L, argv, s->argc, argn);
539
530 if (!(flags & FLAGS_NOENV)) { 540 if (!(flags & FLAGS_NOENV)) {
531 s->status = handle_luainit(L); 541 s->status = handle_luainit(L);
532 if (s->status != 0) return 0; 542 if (s->status != LUA_OK) return 0;
533 } 543 }
544
534 if ((flags & FLAGS_VERSION)) print_version(); 545 if ((flags & FLAGS_VERSION)) print_version();
535 s->status = runargs(L, argv, (script > 0) ? script : s->argc); 546
536 if (s->status != 0) return 0; 547 s->status = runargs(L, argv, argn);
537 if (script) { 548 if (s->status != LUA_OK) return 0;
538 s->status = handle_script(L, argv, script); 549
539 if (s->status != 0) return 0; 550 if (s->argc > argn) {
551 s->status = handle_script(L, argv + argn);
552 if (s->status != LUA_OK) return 0;
540 } 553 }
554
541 if ((flags & FLAGS_INTERACTIVE)) { 555 if ((flags & FLAGS_INTERACTIVE)) {
542 print_jit_status(L); 556 print_jit_status(L);
543 dotty(L); 557 dotty(L);
544 } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { 558 } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
545 if (lua_stdin_is_tty()) { 559 if (lua_stdin_is_tty()) {
546 print_version(); 560 print_version();
547 print_jit_status(L); 561 print_jit_status(L);
548 dotty(L); 562 dotty(L);
549 } else { 563 } else {
550 dofile(L, NULL); /* executes stdin as a file */ 564 dofile(L, NULL); /* Executes stdin as a file. */
551 } 565 }
552 } 566 }
553 return 0; 567 return 0;
@@ -556,7 +570,7 @@ static int pmain(lua_State *L)
556int main(int argc, char **argv) 570int main(int argc, char **argv)
557{ 571{
558 int status; 572 int status;
559 lua_State *L = lua_open(); /* create state */ 573 lua_State *L = lua_open();
560 if (L == NULL) { 574 if (L == NULL) {
561 l_message(argv[0], "cannot create state: not enough memory"); 575 l_message(argv[0], "cannot create state: not enough memory");
562 return EXIT_FAILURE; 576 return EXIT_FAILURE;
@@ -566,6 +580,6 @@ int main(int argc, char **argv)
566 status = lua_cpcall(L, pmain, NULL); 580 status = lua_cpcall(L, pmain, NULL);
567 report(L, status); 581 report(L, status);
568 lua_close(L); 582 lua_close(L);
569 return (status || smain.status) ? EXIT_FAILURE : EXIT_SUCCESS; 583 return (status || smain.status > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
570} 584}
571 585