diff options
Diffstat (limited to 'src/luajit.c')
-rw-r--r-- | src/luajit.c | 134 |
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 | ||
62 | static void print_usage(void) | 62 | static 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 | ||
82 | static void l_message(const char *pname, const char *msg) | 81 | static 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 | ||
156 | static int getargs(lua_State *L, char **argv, int n) | 155 | static 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 | ||
174 | static int dofile(lua_State *L, const char *name) | 166 | static 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 | ||
277 | static int handle_script(lua_State *L, char **argv, int n) | 269 | static 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 | ||
444 | static int runargs(lua_State *L, char **argv, int n) | 446 | static 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 | ||
487 | static int handle_luainit(lua_State *L) | 489 | static 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) | |||
556 | int main(int argc, char **argv) | 570 | int 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 | ||