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 3901762d..53902480 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 | ||
@@ -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 | ||
157 | static int getargs(lua_State *L, char **argv, int n) | 156 | static 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 | ||
175 | static int dofile(lua_State *L, const char *name) | 167 | static 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 | ||
278 | static int handle_script(lua_State *L, char **argv, int n) | 270 | static 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 | ||
446 | static int runargs(lua_State *L, char **argv, int n) | 448 | static 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 | ||
489 | static int handle_luainit(lua_State *L) | 491 | static 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) | |||
558 | int main(int argc, char **argv) | 572 | int 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 | ||