diff options
| author | Mike Pall <mike> | 2016-07-17 16:23:49 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2016-07-17 16:23:49 +0200 |
| commit | 92d9ff211ae864777a8580b5a7326d5f408161ce (patch) | |
| tree | 894941850627260d7c54c86f406c54b1b370f415 /src | |
| parent | 7374046299678889202459f6c26fa78b3118eae9 (diff) | |
| download | luajit-92d9ff211ae864777a8580b5a7326d5f408161ce.tar.gz luajit-92d9ff211ae864777a8580b5a7326d5f408161ce.tar.bz2 luajit-92d9ff211ae864777a8580b5a7326d5f408161ce.zip | |
Set arg table before evaluating LUA_INIT and -e chunks.
Diffstat (limited to 'src')
| -rw-r--r-- | src/luajit.c | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/src/luajit.c b/src/luajit.c index 00e12bd3..4de2d43c 100644 --- a/src/luajit.c +++ b/src/luajit.c | |||
| @@ -152,22 +152,15 @@ static void print_jit_status(lua_State *L) | |||
| 152 | putc('\n', stdout); | 152 | putc('\n', stdout); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static int getargs(lua_State *L, char **argv, int n) | 155 | static void createargtable(lua_State *L, char **argv, int argc, int argf) |
| 156 | { | 156 | { |
| 157 | int narg; | ||
| 158 | int i; | 157 | int i; |
| 159 | int argc = 0; | 158 | lua_createtable(L, argc - argf, argf); |
| 160 | while (argv[argc]) argc++; /* count total number of arguments */ | ||
| 161 | narg = argc - (n + 1); /* number of arguments to the script */ | ||
| 162 | luaL_checkstack(L, narg + 3, "too many arguments to script"); | ||
| 163 | for (i = n+1; i < argc; i++) | ||
| 164 | lua_pushstring(L, argv[i]); | ||
| 165 | lua_createtable(L, narg, n + 1); | ||
| 166 | for (i = 0; i < argc; i++) { | 159 | for (i = 0; i < argc; i++) { |
| 167 | lua_pushstring(L, argv[i]); | 160 | lua_pushstring(L, argv[i]); |
| 168 | lua_rawseti(L, -2, i - n); | 161 | lua_rawseti(L, -2, i - argf); |
| 169 | } | 162 | } |
| 170 | return narg; | 163 | lua_setglobal(L, "arg"); |
| 171 | } | 164 | } |
| 172 | 165 | ||
| 173 | static int dofile(lua_State *L, const char *name) | 166 | static int dofile(lua_State *L, const char *name) |
| @@ -273,21 +266,30 @@ static void dotty(lua_State *L) | |||
| 273 | progname = oldprogname; | 266 | progname = oldprogname; |
| 274 | } | 267 | } |
| 275 | 268 | ||
| 276 | static int handle_script(lua_State *L, char **argv, int n) | 269 | static int handle_script(lua_State *L, char **argx) |
| 277 | { | 270 | { |
| 278 | int status; | 271 | int status; |
| 279 | const char *fname; | 272 | const char *fname = argx[0]; |
| 280 | int narg = getargs(L, argv, n); /* collect arguments */ | 273 | if (strcmp(fname, "-") == 0 && strcmp(argx[-1], "--") != 0) |
| 281 | lua_setglobal(L, "arg"); | ||
| 282 | fname = argv[n]; | ||
| 283 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) | ||
| 284 | fname = NULL; /* stdin */ | 274 | fname = NULL; /* stdin */ |
| 285 | status = luaL_loadfile(L, fname); | 275 | status = luaL_loadfile(L, fname); |
| 286 | lua_insert(L, -(narg+1)); | 276 | if (status == 0) { |
| 287 | 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 | } | ||
| 288 | status = docall(L, narg, 0); | 291 | status = docall(L, narg, 0); |
| 289 | else | 292 | } |
| 290 | lua_pop(L, narg); | ||
| 291 | return report(L, status); | 293 | return report(L, status); |
| 292 | } | 294 | } |
| 293 | 295 | ||
| @@ -384,7 +386,8 @@ static int dobytecode(lua_State *L, char **argv) | |||
| 384 | } | 386 | } |
| 385 | for (argv++; *argv != NULL; narg++, argv++) | 387 | for (argv++; *argv != NULL; narg++, argv++) |
| 386 | lua_pushstring(L, *argv); | 388 | lua_pushstring(L, *argv); |
| 387 | return report(L, lua_pcall(L, narg, 0, 0)); | 389 | report(L, lua_pcall(L, narg, 0, 0)); |
| 390 | return 1; | ||
| 388 | } | 391 | } |
| 389 | 392 | ||
| 390 | /* check that argument has no extra characters at the end */ | 393 | /* check that argument has no extra characters at the end */ |
| @@ -405,7 +408,7 @@ static int collectargs(char **argv, int *flags) | |||
| 405 | switch (argv[i][1]) { /* Check option. */ | 408 | switch (argv[i][1]) { /* Check option. */ |
| 406 | case '-': | 409 | case '-': |
| 407 | notail(argv[i]); | 410 | notail(argv[i]); |
| 408 | return (argv[i+1] != NULL ? i+1 : 0); | 411 | return i+1; |
| 409 | case '\0': | 412 | case '\0': |
| 410 | return i; | 413 | return i; |
| 411 | case 'i': | 414 | case 'i': |
| @@ -430,23 +433,23 @@ static int collectargs(char **argv, int *flags) | |||
| 430 | case 'b': /* LuaJIT extension */ | 433 | case 'b': /* LuaJIT extension */ |
| 431 | if (*flags) return -1; | 434 | if (*flags) return -1; |
| 432 | *flags |= FLAGS_EXEC; | 435 | *flags |= FLAGS_EXEC; |
| 433 | return 0; | 436 | return i+1; |
| 434 | case 'E': | 437 | case 'E': |
| 435 | *flags |= FLAGS_NOENV; | 438 | *flags |= FLAGS_NOENV; |
| 436 | break; | 439 | break; |
| 437 | default: return -1; /* invalid option */ | 440 | default: return -1; /* invalid option */ |
| 438 | } | 441 | } |
| 439 | } | 442 | } |
| 440 | return 0; | 443 | return i; |
| 441 | } | 444 | } |
| 442 | 445 | ||
| 443 | static int runargs(lua_State *L, char **argv, int n) | 446 | static int runargs(lua_State *L, char **argv, int argn) |
| 444 | { | 447 | { |
| 445 | int i; | 448 | int i; |
| 446 | for (i = 1; i < n; i++) { | 449 | for (i = 1; i < argn; i++) { |
| 447 | if (argv[i] == NULL) continue; | 450 | if (argv[i] == NULL) continue; |
| 448 | lua_assert(argv[i][0] == '-'); | 451 | lua_assert(argv[i][0] == '-'); |
| 449 | switch (argv[i][1]) { /* option */ | 452 | switch (argv[i][1]) { |
| 450 | case 'e': { | 453 | case 'e': { |
| 451 | const char *chunk = argv[i] + 2; | 454 | const char *chunk = argv[i] + 2; |
| 452 | if (*chunk == '\0') chunk = argv[++i]; | 455 | if (*chunk == '\0') chunk = argv[++i]; |
| @@ -460,10 +463,10 @@ static int runargs(lua_State *L, char **argv, int n) | |||
| 460 | if (*filename == '\0') filename = argv[++i]; | 463 | if (*filename == '\0') filename = argv[++i]; |
| 461 | lua_assert(filename != NULL); | 464 | lua_assert(filename != NULL); |
| 462 | if (dolibrary(L, filename)) | 465 | if (dolibrary(L, filename)) |
| 463 | return 1; /* stop if file fails */ | 466 | return 1; |
| 464 | break; | 467 | break; |
| 465 | } | 468 | } |
| 466 | case 'j': { /* LuaJIT extension */ | 469 | case 'j': { /* LuaJIT extension. */ |
| 467 | const char *cmd = argv[i] + 2; | 470 | const char *cmd = argv[i] + 2; |
| 468 | if (*cmd == '\0') cmd = argv[++i]; | 471 | if (*cmd == '\0') cmd = argv[++i]; |
| 469 | lua_assert(cmd != NULL); | 472 | lua_assert(cmd != NULL); |
| @@ -471,11 +474,11 @@ static int runargs(lua_State *L, char **argv, int n) | |||
| 471 | return 1; | 474 | return 1; |
| 472 | break; | 475 | break; |
| 473 | } | 476 | } |
| 474 | case 'O': /* LuaJIT extension */ | 477 | case 'O': /* LuaJIT extension. */ |
| 475 | if (dojitopt(L, argv[i] + 2)) | 478 | if (dojitopt(L, argv[i] + 2)) |
| 476 | return 1; | 479 | return 1; |
| 477 | break; | 480 | break; |
| 478 | case 'b': /* LuaJIT extension */ | 481 | case 'b': /* LuaJIT extension. */ |
| 479 | return dobytecode(L, argv+i); | 482 | return dobytecode(L, argv+i); |
| 480 | default: break; | 483 | default: break; |
| 481 | } | 484 | } |
| @@ -508,45 +511,57 @@ static int pmain(lua_State *L) | |||
| 508 | { | 511 | { |
| 509 | struct Smain *s = &smain; | 512 | struct Smain *s = &smain; |
| 510 | char **argv = s->argv; | 513 | char **argv = s->argv; |
| 511 | int script; | 514 | int argn; |
| 512 | int flags = 0; | 515 | int flags = 0; |
| 513 | globalL = L; | 516 | globalL = L; |
| 514 | if (argv[0] && argv[0][0]) progname = argv[0]; | 517 | if (argv[0] && argv[0][0]) progname = argv[0]; |
| 515 | LUAJIT_VERSION_SYM(); /* linker-enforced version check */ | 518 | |
| 516 | script = collectargs(argv, &flags); | 519 | LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */ |
| 517 | if (script < 0) { /* invalid args? */ | 520 | |
| 521 | argn = collectargs(argv, &flags); | ||
| 522 | if (argn < 0) { /* Invalid args? */ | ||
| 518 | print_usage(); | 523 | print_usage(); |
| 519 | s->status = 1; | 524 | s->status = 1; |
| 520 | return 0; | 525 | return 0; |
| 521 | } | 526 | } |
| 527 | |||
| 522 | if ((flags & FLAGS_NOENV)) { | 528 | if ((flags & FLAGS_NOENV)) { |
| 523 | lua_pushboolean(L, 1); | 529 | lua_pushboolean(L, 1); |
| 524 | lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); | 530 | lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); |
| 525 | } | 531 | } |
| 526 | lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ | 532 | |
| 527 | luaL_openlibs(L); /* open libraries */ | 533 | /* Stop collector during library initialization. */ |
| 534 | lua_gc(L, LUA_GCSTOP, 0); | ||
| 535 | luaL_openlibs(L); | ||
| 528 | lua_gc(L, LUA_GCRESTART, -1); | 536 | lua_gc(L, LUA_GCRESTART, -1); |
| 537 | |||
| 538 | createargtable(L, argv, s->argc, argn); | ||
| 539 | |||
| 529 | if (!(flags & FLAGS_NOENV)) { | 540 | if (!(flags & FLAGS_NOENV)) { |
| 530 | s->status = handle_luainit(L); | 541 | s->status = handle_luainit(L); |
| 531 | if (s->status != 0) return 0; | 542 | if (s->status != 0) return 0; |
| 532 | } | 543 | } |
| 544 | |||
| 533 | if ((flags & FLAGS_VERSION)) print_version(); | 545 | if ((flags & FLAGS_VERSION)) print_version(); |
| 534 | s->status = runargs(L, argv, (script > 0) ? script : s->argc); | 546 | |
| 547 | s->status = runargs(L, argv, argn); | ||
| 535 | if (s->status != 0) return 0; | 548 | if (s->status != 0) return 0; |
| 536 | if (script) { | 549 | |
| 537 | s->status = handle_script(L, argv, script); | 550 | if (s->argc > argn) { |
| 551 | s->status = handle_script(L, argv + argn); | ||
| 538 | if (s->status != 0) return 0; | 552 | if (s->status != 0) return 0; |
| 539 | } | 553 | } |
| 554 | |||
| 540 | if ((flags & FLAGS_INTERACTIVE)) { | 555 | if ((flags & FLAGS_INTERACTIVE)) { |
| 541 | print_jit_status(L); | 556 | print_jit_status(L); |
| 542 | dotty(L); | 557 | dotty(L); |
| 543 | } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { | 558 | } else if (s->argc == argn && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) { |
| 544 | if (lua_stdin_is_tty()) { | 559 | if (lua_stdin_is_tty()) { |
| 545 | print_version(); | 560 | print_version(); |
| 546 | print_jit_status(L); | 561 | print_jit_status(L); |
| 547 | dotty(L); | 562 | dotty(L); |
| 548 | } else { | 563 | } else { |
| 549 | dofile(L, NULL); /* executes stdin as a file */ | 564 | dofile(L, NULL); /* Executes stdin as a file. */ |
| 550 | } | 565 | } |
| 551 | } | 566 | } |
| 552 | return 0; | 567 | return 0; |
| @@ -555,7 +570,7 @@ static int pmain(lua_State *L) | |||
| 555 | int main(int argc, char **argv) | 570 | int main(int argc, char **argv) |
| 556 | { | 571 | { |
| 557 | int status; | 572 | int status; |
| 558 | lua_State *L = lua_open(); /* create state */ | 573 | lua_State *L = lua_open(); |
| 559 | if (L == NULL) { | 574 | if (L == NULL) { |
| 560 | l_message(argv[0], "cannot create state: not enough memory"); | 575 | l_message(argv[0], "cannot create state: not enough memory"); |
| 561 | return EXIT_FAILURE; | 576 | return EXIT_FAILURE; |
