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 3901762d..53902480 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
@@ -154,22 +153,15 @@ static void print_jit_status(lua_State *L)
154 lua_settop(L, 0); /* clear stack */ 153 lua_settop(L, 0); /* clear stack */
155} 154}
156 155
157static int getargs(lua_State *L, char **argv, int n) 156static void createargtable(lua_State *L, char **argv, int argc, int argf)
158{ 157{
159 int narg;
160 int i; 158 int i;
161 int argc = 0; 159 lua_createtable(L, argc - argf, argf);
162 while (argv[argc]) argc++; /* count total number of arguments */
163 narg = argc - (n + 1); /* number of arguments to the script */
164 luaL_checkstack(L, narg + 3, "too many arguments to script");
165 for (i = n+1; i < argc; i++)
166 lua_pushstring(L, argv[i]);
167 lua_createtable(L, narg, n + 1);
168 for (i = 0; i < argc; i++) { 160 for (i = 0; i < argc; i++) {
169 lua_pushstring(L, argv[i]); 161 lua_pushstring(L, argv[i]);
170 lua_rawseti(L, -2, i - n); 162 lua_rawseti(L, -2, i - argf);
171 } 163 }
172 return narg; 164 lua_setglobal(L, "arg");
173} 165}
174 166
175static int dofile(lua_State *L, const char *name) 167static int dofile(lua_State *L, const char *name)
@@ -258,9 +250,9 @@ static void dotty(lua_State *L)
258 const char *oldprogname = progname; 250 const char *oldprogname = progname;
259 progname = NULL; 251 progname = NULL;
260 while ((status = loadline(L)) != -1) { 252 while ((status = loadline(L)) != -1) {
261 if (status == 0) status = docall(L, 0, 0); 253 if (status == LUA_OK) status = docall(L, 0, 0);
262 report(L, status); 254 report(L, status);
263 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ 255 if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */
264 lua_getglobal(L, "print"); 256 lua_getglobal(L, "print");
265 lua_insert(L, 1); 257 lua_insert(L, 1);
266 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) 258 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
@@ -275,21 +267,30 @@ static void dotty(lua_State *L)
275 progname = oldprogname; 267 progname = oldprogname;
276} 268}
277 269
278static int handle_script(lua_State *L, char **argv, int n) 270static int handle_script(lua_State *L, char **argx)
279{ 271{
280 int status; 272 int status;
281 const char *fname; 273 const char *fname = argx[0];
282 int narg = getargs(L, argv, n); /* collect arguments */ 274 if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0)
283 lua_setglobal(L, "arg");
284 fname = argv[n];
285 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
286 fname = NULL; /* stdin */ 275 fname = NULL; /* stdin */
287 status = luaL_loadfile(L, fname); 276 status = luaL_loadfile(L, fname);
288 lua_insert(L, -(narg+1)); 277 if (status == LUA_OK) {
289 if (status == 0) 278 /* Fetch args from arg table. LUA_INIT or -e might have changed them. */
279 int narg = 0;
280 lua_getglobal(L, "arg");
281 if (lua_istable(L, -1)) {
282 do {
283 narg++;
284 lua_rawgeti(L, -narg, narg);
285 } while (!lua_isnil(L, -1));
286 lua_pop(L, 1);
287 lua_remove(L, -narg);
288 narg--;
289 } else {
290 lua_pop(L, 1);
291 }
290 status = docall(L, narg, 0); 292 status = docall(L, narg, 0);
291 else 293 }
292 lua_pop(L, narg);
293 return report(L, status); 294 return report(L, status);
294} 295}
295 296
@@ -386,7 +387,8 @@ static int dobytecode(lua_State *L, char **argv)
386 } 387 }
387 for (argv++; *argv != NULL; narg++, argv++) 388 for (argv++; *argv != NULL; narg++, argv++)
388 lua_pushstring(L, *argv); 389 lua_pushstring(L, *argv);
389 return report(L, lua_pcall(L, narg, 0, 0)); 390 report(L, lua_pcall(L, narg, 0, 0));
391 return -1;
390} 392}
391 393
392/* check that argument has no extra characters at the end */ 394/* check that argument has no extra characters at the end */
@@ -407,7 +409,7 @@ static int collectargs(char **argv, int *flags)
407 switch (argv[i][1]) { /* Check option. */ 409 switch (argv[i][1]) { /* Check option. */
408 case '-': 410 case '-':
409 notail(argv[i]); 411 notail(argv[i]);
410 return (argv[i+1] != NULL ? i+1 : 0); 412 return i+1;
411 case '\0': 413 case '\0':
412 return i; 414 return i;
413 case 'i': 415 case 'i':
@@ -433,23 +435,23 @@ static int collectargs(char **argv, int *flags)
433 case 'b': /* LuaJIT extension */ 435 case 'b': /* LuaJIT extension */
434 if (*flags) return -1; 436 if (*flags) return -1;
435 *flags |= FLAGS_EXEC; 437 *flags |= FLAGS_EXEC;
436 return 0; 438 return i+1;
437 case 'E': 439 case 'E':
438 *flags |= FLAGS_NOENV; 440 *flags |= FLAGS_NOENV;
439 break; 441 break;
440 default: return -1; /* invalid option */ 442 default: return -1; /* invalid option */
441 } 443 }
442 } 444 }
443 return 0; 445 return i;
444} 446}
445 447
446static int runargs(lua_State *L, char **argv, int n) 448static int runargs(lua_State *L, char **argv, int argn)
447{ 449{
448 int i; 450 int i;
449 for (i = 1; i < n; i++) { 451 for (i = 1; i < argn; i++) {
450 if (argv[i] == NULL) continue; 452 if (argv[i] == NULL) continue;
451 lua_assert(argv[i][0] == '-'); 453 lua_assert(argv[i][0] == '-');
452 switch (argv[i][1]) { /* option */ 454 switch (argv[i][1]) {
453 case 'e': { 455 case 'e': {
454 const char *chunk = argv[i] + 2; 456 const char *chunk = argv[i] + 2;
455 if (*chunk == '\0') chunk = argv[++i]; 457 if (*chunk == '\0') chunk = argv[++i];
@@ -463,10 +465,10 @@ static int runargs(lua_State *L, char **argv, int n)
463 if (*filename == '\0') filename = argv[++i]; 465 if (*filename == '\0') filename = argv[++i];
464 lua_assert(filename != NULL); 466 lua_assert(filename != NULL);
465 if (dolibrary(L, filename)) 467 if (dolibrary(L, filename))
466 return 1; /* stop if file fails */ 468 return 1;
467 break; 469 break;
468 } 470 }
469 case 'j': { /* LuaJIT extension */ 471 case 'j': { /* LuaJIT extension. */
470 const char *cmd = argv[i] + 2; 472 const char *cmd = argv[i] + 2;
471 if (*cmd == '\0') cmd = argv[++i]; 473 if (*cmd == '\0') cmd = argv[++i];
472 lua_assert(cmd != NULL); 474 lua_assert(cmd != NULL);
@@ -474,16 +476,16 @@ static int runargs(lua_State *L, char **argv, int n)
474 return 1; 476 return 1;
475 break; 477 break;
476 } 478 }
477 case 'O': /* LuaJIT extension */ 479 case 'O': /* LuaJIT extension. */
478 if (dojitopt(L, argv[i] + 2)) 480 if (dojitopt(L, argv[i] + 2))
479 return 1; 481 return 1;
480 break; 482 break;
481 case 'b': /* LuaJIT extension */ 483 case 'b': /* LuaJIT extension. */
482 return dobytecode(L, argv+i); 484 return dobytecode(L, argv+i);
483 default: break; 485 default: break;
484 } 486 }
485 } 487 }
486 return 0; 488 return LUA_OK;
487} 489}
488 490
489static int handle_luainit(lua_State *L) 491static int handle_luainit(lua_State *L)
@@ -494,7 +496,7 @@ static int handle_luainit(lua_State *L)
494 const char *init = getenv(LUA_INIT); 496 const char *init = getenv(LUA_INIT);
495#endif 497#endif
496 if (init == NULL) 498 if (init == NULL)
497 return 0; /* status OK */ 499 return LUA_OK;
498 else if (init[0] == '@') 500 else if (init[0] == '@')
499 return dofile(L, init+1); 501 return dofile(L, init+1);
500 else 502 else
@@ -511,45 +513,57 @@ static int pmain(lua_State *L)
511{ 513{
512 struct Smain *s = &smain; 514 struct Smain *s = &smain;
513 char **argv = s->argv; 515 char **argv = s->argv;
514 int script; 516 int argn;
515 int flags = 0; 517 int flags = 0;
516 globalL = L; 518 globalL = L;
517 if (argv[0] && argv[0][0]) progname = argv[0]; 519 if (argv[0] && argv[0][0]) progname = argv[0];
518 LUAJIT_VERSION_SYM(); /* linker-enforced version check */ 520
519 script = collectargs(argv, &flags); 521 LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */
520 if (script < 0) { /* invalid args? */ 522
523 argn = collectargs(argv, &flags);
524 if (argn < 0) { /* Invalid args? */
521 print_usage(); 525 print_usage();
522 s->status = 1; 526 s->status = 1;
523 return 0; 527 return 0;
524 } 528 }
529
525 if ((flags & FLAGS_NOENV)) { 530 if ((flags & FLAGS_NOENV)) {
526 lua_pushboolean(L, 1); 531 lua_pushboolean(L, 1);
527 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 532 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
528 } 533 }
529 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 534
530 luaL_openlibs(L); /* open libraries */ 535 /* Stop collector during library initialization. */
536 lua_gc(L, LUA_GCSTOP, 0);
537 luaL_openlibs(L);
531 lua_gc(L, LUA_GCRESTART, -1); 538 lua_gc(L, LUA_GCRESTART, -1);
539
540 createargtable(L, argv, s->argc, argn);
541
532 if (!(flags & FLAGS_NOENV)) { 542 if (!(flags & FLAGS_NOENV)) {
533 s->status = handle_luainit(L); 543 s->status = handle_luainit(L);
534 if (s->status != 0) return 0; 544 if (s->status != LUA_OK) return 0;
535 } 545 }
546
536 if ((flags & FLAGS_VERSION)) print_version(); 547 if ((flags & FLAGS_VERSION)) print_version();
537 s->status = runargs(L, argv, (script > 0) ? script : s->argc); 548
538 if (s->status != 0) return 0; 549 s->status = runargs(L, argv, argn);
539 if (script) { 550 if (s->status != LUA_OK) return 0;
540 s->status = handle_script(L, argv, script); 551
541 if (s->status != 0) return 0; 552 if (s->argc > argn) {
553 s->status = handle_script(L, argv + argn);
554 if (s->status != LUA_OK) return 0;
542 } 555 }
556
543 if ((flags & FLAGS_INTERACTIVE)) { 557 if ((flags & FLAGS_INTERACTIVE)) {
544 print_jit_status(L); 558 print_jit_status(L);
545 dotty(L); 559 dotty(L);
546 } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { 560 } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
547 if (lua_stdin_is_tty()) { 561 if (lua_stdin_is_tty()) {
548 print_version(); 562 print_version();
549 print_jit_status(L); 563 print_jit_status(L);
550 dotty(L); 564 dotty(L);
551 } else { 565 } else {
552 dofile(L, NULL); /* executes stdin as a file */ 566 dofile(L, NULL); /* Executes stdin as a file. */
553 } 567 }
554 } 568 }
555 return 0; 569 return 0;
@@ -558,7 +572,7 @@ static int pmain(lua_State *L)
558int main(int argc, char **argv) 572int main(int argc, char **argv)
559{ 573{
560 int status; 574 int status;
561 lua_State *L = lua_open(); /* create state */ 575 lua_State *L = lua_open();
562 if (L == NULL) { 576 if (L == NULL) {
563 l_message(argv[0], "cannot create state: not enough memory"); 577 l_message(argv[0], "cannot create state: not enough memory");
564 return EXIT_FAILURE; 578 return EXIT_FAILURE;
@@ -568,6 +582,6 @@ int main(int argc, char **argv)
568 status = lua_cpcall(L, pmain, NULL); 582 status = lua_cpcall(L, pmain, NULL);
569 report(L, status); 583 report(L, status);
570 lua_close(L); 584 lua_close(L);
571 return (status || smain.status) ? EXIT_FAILURE : EXIT_SUCCESS; 585 return (status || smain.status > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
572} 586}
573 587