1 /* 2 ** $Id: lua.c $ 3 ** Lua stand-alone interpreter 4 ** See Copyright Notice in lua.h 5 */ 6 7 #define lua_c 8 9 #include "lprefix.h" 10 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 16 #include <signal.h> 17 18 #include "lua.h" 19 20 #include "lauxlib.h" 21 #include "lualib.h" 22 23 24 #if !defined(LUA_PROGNAME) 25 #define LUA_PROGNAME "lua" 26 #endif 27 28 #if !defined(LUA_INIT_VAR) 29 #define LUA_INIT_VAR "LUA_INIT" 30 #endif 31 32 #define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX 33 34 35 static lua_State *globalL = NULL; 36 37 static const char *progname = LUA_PROGNAME; 38 39 40 /* 41 ** Hook set by signal function to stop the interpreter. 42 */ 43 static void lstop (lua_State *L, lua_Debug *ar) { 44 (void)ar; /* unused arg. */ 45 lua_sethook(L, NULL, 0, 0); /* reset hook */ 46 luaL_error(L, "interrupted!"); 47 } 48 49 50 /* 51 ** Function to be called at a C signal. Because a C signal cannot 52 ** just change a Lua state (as there is no proper synchronization), 53 ** this function only sets a hook that, when called, will stop the 54 ** interpreter. 55 */ 56 static void laction (int i) { 57 int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT; 58 signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ 59 lua_sethook(globalL, lstop, flag, 1); 60 } 61 62 63 static void print_usage (const char *badoption) { 64 lua_writestringerror("%s: ", progname); 65 if (badoption[1] == 'e' || badoption[1] == 'l') 66 lua_writestringerror("'%s' needs argument\n", badoption); 67 else 68 lua_writestringerror("unrecognized option '%s'\n", badoption); 69 lua_writestringerror( 70 "usage: %s [options] [script [args]]\n" 71 "Available options are:\n" 72 " -e stat execute string 'stat'\n" 73 " -i enter interactive mode after executing 'script'\n" 74 " -l name require library 'name' into global 'name'\n" 75 " -v show version information\n" 76 " -E ignore environment variables\n" 77 " -W turn warnings on\n" 78 " -- stop handling options\n" 79 " - stop handling options and execute stdin\n" 80 , 81 progname); 82 } 83 84 85 /* 86 ** Prints an error message, adding the program name in front of it 87 ** (if present) 88 */ 89 static void l_message (const char *pname, const char *msg) { 90 if (pname) lua_writestringerror("%s: ", pname); 91 lua_writestringerror("%s\n", msg); 92 } 93 94 95 /* 96 ** Check whether 'status' is not OK and, if so, prints the error 97 ** message on the top of the stack. It assumes that the error object 98 ** is a string, as it was either generated by Lua or by 'msghandler'. 99 */ 100 static int report (lua_State *L, int status) { 101 if (status != LUA_OK) { 102 const char *msg = lua_tostring(L, -1); 103 l_message(progname, msg); 104 lua_pop(L, 1); /* remove message */ 105 } 106 return status; 107 } 108 109 110 /* 111 ** Message handler used to run all chunks 112 */ 113 static int msghandler (lua_State *L) { 114 const char *msg = lua_tostring(L, 1); 115 if (msg == NULL) { /* is error object not a string? */ 116 if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */ 117 lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */ 118 return 1; /* that is the message */ 119 else 120 msg = lua_pushfstring(L, "(error object is a %s value)", 121 luaL_typename(L, 1)); 122 } 123 luaL_traceback(L, L, msg, 1); /* append a standard traceback */ 124 return 1; /* return the traceback */ 125 } 126 127 128 /* 129 ** Interface to 'lua_pcall', which sets appropriate message function 130 ** and C-signal handler. Used to run all chunks. 131 */ 132 static int docall (lua_State *L, int narg, int nres) { 133 int status; 134 int base = lua_gettop(L) - narg; /* function index */ 135 lua_pushcfunction(L, msghandler); /* push message handler */ 136 lua_insert(L, base); /* put it under function and args */ 137 globalL = L; /* to be available to 'laction' */ 138 signal(SIGINT, laction); /* set C-signal handler */ 139 status = lua_pcall(L, narg, nres, base); 140 signal(SIGINT, SIG_DFL); /* reset C-signal handler */ 141 lua_remove(L, base); /* remove message handler from the stack */ 142 return status; 143 } 144 145 146 static void print_version (void) { 147 lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); 148 lua_writeline(); 149 } 150 151 152 /* 153 ** Create the 'arg' table, which stores all arguments from the 154 ** command line ('argv'). It should be aligned so that, at index 0, 155 ** it has 'argv[script]', which is the script name. The arguments 156 ** to the script (everything after 'script') go to positive indices; 157 ** other arguments (before the script name) go to negative indices. 158 ** If there is no script name, assume interpreter's name as base. 159 */ 160 static void createargtable (lua_State *L, char **argv, int argc, int script) { 161 int i, narg; 162 if (script == argc) script = 0; /* no script name? */ 163 narg = argc - (script + 1); /* number of positive indices */ 164 lua_createtable(L, narg, script + 1); 165 for (i = 0; i < argc; i++) { 166 lua_pushstring(L, argv[i]); 167 lua_rawseti(L, -2, i - script); 168 } 169 lua_setglobal(L, "arg"); 170 } 171 172 173 static int dochunk (lua_State *L, int status) { 174 if (status == LUA_OK) status = docall(L, 0, 0); 175 return report(L, status); 176 } 177 178 179 static int dofile (lua_State *L, const char *name) { 180 return dochunk(L, luaL_loadfile(L, name)); 181 } 182 183 184 static int dostring (lua_State *L, const char *s, const char *name) { 185 return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name)); 186 } 187 188 189 /* 190 ** Calls 'require(name)' and stores the result in a global variable 191 ** with the given name. 192 */ 193 static int dolibrary (lua_State *L, const char *name) { 194 int status; 195 lua_getglobal(L, "require"); 196 lua_pushstring(L, name); 197 status = docall(L, 1, 1); /* call 'require(name)' */ 198 if (status == LUA_OK) 199 lua_setglobal(L, name); /* global[name] = require return */ 200 return report(L, status); 201 } 202 203 204 /* 205 ** Push on the stack the contents of table 'arg' from 1 to #arg 206 */ 207 static int pushargs (lua_State *L) { 208 int i, n; 209 if (lua_getglobal(L, "arg") != LUA_TTABLE) 210 luaL_error(L, "'arg' is not a table"); 211 n = (int)luaL_len(L, -1); 212 luaL_checkstack(L, n + 3, "too many arguments to script"); 213 for (i = 1; i <= n; i++) 214 lua_rawgeti(L, -i, i); 215 lua_remove(L, -i); /* remove table from the stack */ 216 return n; 217 } 218 219 220 static int handle_script (lua_State *L, char **argv) { 221 int status; 222 const char *fname = argv[0]; 223 if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0) 224 fname = NULL; /* stdin */ 225 status = luaL_loadfile(L, fname); 226 if (status == LUA_OK) { 227 int n = pushargs(L); /* push arguments to script */ 228 status = docall(L, n, LUA_MULTRET); 229 } 230 return report(L, status); 231 } 232 233 234 /* bits of various argument indicators in 'args' */ 235 #define has_error 1 /* bad option */ 236 #define has_i 2 /* -i */ 237 #define has_v 4 /* -v */ 238 #define has_e 8 /* -e */ 239 #define has_E 16 /* -E */ 240 241 242 /* 243 ** Traverses all arguments from 'argv', returning a mask with those 244 ** needed before running any Lua code (or an error code if it finds 245 ** any invalid argument). 'first' returns the first not-handled argument 246 ** (either the script name or a bad argument in case of error). 247 */ 248 static int collectargs (char **argv, int *first) { 249 int args = 0; 250 int i; 251 for (i = 1; argv[i] != NULL; i++) { 252 *first = i; 253 if (argv[i][0] != '-') /* not an option? */ 254 return args; /* stop handling options */ 255 switch (argv[i][1]) { /* else check option */ 256 case '-': /* '--' */ 257 if (argv[i][2] != '\0') /* extra characters after '--'? */ 258 return has_error; /* invalid option */ 259 *first = i + 1; 260 return args; 261 case '\0': /* '-' */ 262 return args; /* script "name" is '-' */ 263 case 'E': 264 if (argv[i][2] != '\0') /* extra characters? */ 265 return has_error; /* invalid option */ 266 args |= has_E; 267 break; 268 case 'W': 269 if (argv[i][2] != '\0') /* extra characters? */ 270 return has_error; /* invalid option */ 271 break; 272 case 'i': 273 args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */ 274 case 'v': 275 if (argv[i][2] != '\0') /* extra characters? */ 276 return has_error; /* invalid option */ 277 args |= has_v; 278 break; 279 case 'e': 280 args |= has_e; /* FALLTHROUGH */ 281 case 'l': /* both options need an argument */ 282 if (argv[i][2] == '\0') { /* no concatenated argument? */ 283 i++; /* try next 'argv' */ 284 if (argv[i] == NULL || argv[i][0] == '-') 285 return has_error; /* no next argument or it is another option */ 286 } 287 break; 288 default: /* invalid option */ 289 return has_error; 290 } 291 } 292 *first = i; /* no script name */ 293 return args; 294 } 295 296 297 /* 298 ** Processes options 'e' and 'l', which involve running Lua code, and 299 ** 'W', which also affects the state. 300 ** Returns 0 if some code raises an error. 301 */ 302 static int runargs (lua_State *L, char **argv, int n) { 303 int i; 304 for (i = 1; i < n; i++) { 305 int option = argv[i][1]; 306 lua_assert(argv[i][0] == '-'); /* already checked */ 307 switch (option) { 308 case 'e': case 'l': { 309 int status; 310 const char *extra = argv[i] + 2; /* both options need an argument */ 311 if (*extra == '\0') extra = argv[++i]; 312 lua_assert(extra != NULL); 313 status = (option == 'e') 314 ? dostring(L, extra, "=(command line)") 315 : dolibrary(L, extra); 316 if (status != LUA_OK) return 0; 317 break; 318 } 319 case 'W': 320 lua_warning(L, "@on", 0); /* warnings on */ 321 break; 322 } 323 } 324 return 1; 325 } 326 327 328 static int handle_luainit (lua_State *L) { 329 const char *name = "=" LUA_INITVARVERSION; 330 const char *init = getenv(name + 1); 331 if (init == NULL) { 332 name = "=" LUA_INIT_VAR; 333 init = getenv(name + 1); /* try alternative name */ 334 } 335 if (init == NULL) return LUA_OK; 336 else if (init[0] == '@') 337 return dofile(L, init+1); 338 else 339 return dostring(L, init, name); 340 } 341 342 343 /* 344 ** {================================================================== 345 ** Read-Eval-Print Loop (REPL) 346 ** =================================================================== 347 */ 348 349 #if !defined(LUA_PROMPT) 350 #define LUA_PROMPT "> " 351 #define LUA_PROMPT2 ">> " 352 #endif 353 354 #if !defined(LUA_MAXINPUT) 355 #define LUA_MAXINPUT 512 356 #endif 357 358 359 /* 360 ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that 361 ** is, whether we're running lua interactively). 362 */ 363 #if !defined(lua_stdin_is_tty) /* { */ 364 365 #if defined(LUA_USE_POSIX) /* { */ 366 367 #include <unistd.h> 368 #define lua_stdin_is_tty() isatty(0) 369 370 #elif defined(LUA_USE_WINDOWS) /* }{ */ 371 372 #include <io.h> 373 #include <windows.h> 374 375 #define lua_stdin_is_tty() _isatty(_fileno(stdin)) 376 377 #else /* }{ */ 378 379 /* ISO C definition */ 380 #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ 381 382 #endif /* } */ 383 384 #endif /* } */ 385 386 387 /* 388 ** lua_readline defines how to show a prompt and then read a line from 389 ** the standard input. 390 ** lua_saveline defines how to "save" a read line in a "history". 391 ** lua_freeline defines how to free a line read by lua_readline. 392 */ 393 #if !defined(lua_readline) /* { */ 394 395 #if defined(LUA_USE_READLINE) /* { */ 396 397 #include <readline/readline.h> 398 #include <readline/history.h> 399 #define lua_initreadline(L) ((void)L, rl_readline_name="lua") 400 #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) 401 #define lua_saveline(L,line) ((void)L, add_history(line)) 402 #define lua_freeline(L,b) ((void)L, free(b)) 403 404 #else /* }{ */ 405 406 #define lua_initreadline(L) ((void)L) 407 #define lua_readline(L,b,p) \ 408 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ 409 fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ 410 #define lua_saveline(L,line) { (void)L; (void)line; } 411 #define lua_freeline(L,b) { (void)L; (void)b; } 412 413 #endif /* } */ 414 415 #endif /* } */ 416 417 418 /* 419 ** Return the string to be used as a prompt by the interpreter. Leave 420 ** the string (or nil, if using the default value) on the stack, to keep 421 ** it anchored. 422 */ 423 static const char *get_prompt (lua_State *L, int firstline) { 424 if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL) 425 return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */ 426 else { /* apply 'tostring' over the value */ 427 const char *p = luaL_tolstring(L, -1, NULL); 428 lua_remove(L, -2); /* remove original value */ 429 return p; 430 } 431 } 432 433 /* mark in error messages for incomplete statements */ 434 #define EOFMARK "<eof>" 435 #define marklen (sizeof(EOFMARK)/sizeof(char) - 1) 436 437 438 /* 439 ** Check whether 'status' signals a syntax error and the error 440 ** message at the top of the stack ends with the above mark for 441 ** incomplete statements. 442 */ 443 static int incomplete (lua_State *L, int status) { 444 if (status == LUA_ERRSYNTAX) { 445 size_t lmsg; 446 const char *msg = lua_tolstring(L, -1, &lmsg); 447 if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { 448 lua_pop(L, 1); 449 return 1; 450 } 451 } 452 return 0; /* else... */ 453 } 454 455 456 /* 457 ** Prompt the user, read a line, and push it into the Lua stack. 458 */ 459 static int pushline (lua_State *L, int firstline) { 460 char buffer[LUA_MAXINPUT]; 461 char *b = buffer; 462 size_t l; 463 const char *prmt = get_prompt(L, firstline); 464 int readstatus = lua_readline(L, b, prmt); 465 if (readstatus == 0) 466 return 0; /* no input (prompt will be popped by caller) */ 467 lua_pop(L, 1); /* remove prompt */ 468 l = strlen(b); 469 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ 470 b[--l] = '\0'; /* remove it */ 471 if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */ 472 lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */ 473 else 474 lua_pushlstring(L, b, l); 475 lua_freeline(L, b); 476 return 1; 477 } 478 479 480 /* 481 ** Try to compile line on the stack as 'return <line>;'; on return, stack 482 ** has either compiled chunk or original line (if compilation failed). 483 */ 484 static int addreturn (lua_State *L) { 485 const char *line = lua_tostring(L, -1); /* original line */ 486 const char *retline = lua_pushfstring(L, "return %s;", line); 487 int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin"); 488 if (status == LUA_OK) { 489 lua_remove(L, -2); /* remove modified line */ 490 if (line[0] != '\0') /* non empty? */ 491 lua_saveline(L, line); /* keep history */ 492 } 493 else 494 lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */ 495 return status; 496 } 497 498 499 /* 500 ** Read multiple lines until a complete Lua statement 501 */ 502 static int multiline (lua_State *L) { 503 for (;;) { /* repeat until gets a complete statement */ 504 size_t len; 505 const char *line = lua_tolstring(L, 1, &len); /* get what it has */ 506 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ 507 if (!incomplete(L, status) || !pushline(L, 0)) { 508 lua_saveline(L, line); /* keep history */ 509 return status; /* cannot or should not try to add continuation line */ 510 } 511 lua_pushliteral(L, "\n"); /* add newline... */ 512 lua_insert(L, -2); /* ...between the two lines */ 513 lua_concat(L, 3); /* join them */ 514 } 515 } 516 517 518 /* 519 ** Read a line and try to load (compile) it first as an expression (by 520 ** adding "return " in front of it) and second as a statement. Return 521 ** the final status of load/call with the resulting function (if any) 522 ** in the top of the stack. 523 */ 524 static int loadline (lua_State *L) { 525 int status; 526 lua_settop(L, 0); 527 if (!pushline(L, 1)) 528 return -1; /* no input */ 529 if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ 530 status = multiline(L); /* try as command, maybe with continuation lines */ 531 lua_remove(L, 1); /* remove line from the stack */ 532 lua_assert(lua_gettop(L) == 1); 533 return status; 534 } 535 536 537 /* 538 ** Prints (calling the Lua 'print' function) any values on the stack 539 */ 540 static void l_print (lua_State *L) { 541 int n = lua_gettop(L); 542 if (n > 0) { /* any result to be printed? */ 543 luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); 544 lua_getglobal(L, "print"); 545 lua_insert(L, 1); 546 if (lua_pcall(L, n, 0, 0) != LUA_OK) 547 l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)", 548 lua_tostring(L, -1))); 549 } 550 } 551 552 553 /* 554 ** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and 555 ** print any results. 556 */ 557 static void doREPL (lua_State *L) { 558 int status; 559 const char *oldprogname = progname; 560 progname = NULL; /* no 'progname' on errors in interactive mode */ 561 lua_initreadline(L); 562 while ((status = loadline(L)) != -1) { 563 if (status == LUA_OK) 564 status = docall(L, 0, LUA_MULTRET); 565 if (status == LUA_OK) l_print(L); 566 else report(L, status); 567 } 568 lua_settop(L, 0); /* clear stack */ 569 lua_writeline(); 570 progname = oldprogname; 571 } 572 573 /* }================================================================== */ 574 575 576 /* 577 ** Main body of stand-alone interpreter (to be called in protected mode). 578 ** Reads the options and handles them all. 579 */ 580 static int pmain (lua_State *L) { 581 int argc = (int)lua_tointeger(L, 1); 582 char **argv = (char **)lua_touserdata(L, 2); 583 int script; 584 int args = collectargs(argv, &script); 585 luaL_checkversion(L); /* check that interpreter has correct version */ 586 if (argv[0] && argv[0][0]) progname = argv[0]; 587 if (args == has_error) { /* bad arg? */ 588 print_usage(argv[script]); /* 'script' has index of bad arg. */ 589 return 0; 590 } 591 if (args & has_v) /* option '-v'? */ 592 print_version(); 593 if (args & has_E) { /* option '-E'? */ 594 lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ 595 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 596 } 597 luaL_openlibs(L); /* open standard libraries */ 598 createargtable(L, argv, argc, script); /* create table 'arg' */ 599 lua_gc(L, LUA_GCGEN, 0, 0); /* GC in generational mode */ 600 if (!(args & has_E)) { /* no option '-E'? */ 601 if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ 602 return 0; /* error running LUA_INIT */ 603 } 604 if (!runargs(L, argv, script)) /* execute arguments -e and -l */ 605 return 0; /* something failed */ 606 if (script < argc && /* execute main script (if there is one) */ 607 handle_script(L, argv + script) != LUA_OK) 608 return 0; 609 if (args & has_i) /* -i option? */ 610 doREPL(L); /* do read-eval-print loop */ 611 else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */ 612 if (lua_stdin_is_tty()) { /* running in interactive mode? */ 613 print_version(); 614 doREPL(L); /* do read-eval-print loop */ 615 } 616 else dofile(L, NULL); /* executes stdin as a file */ 617 } 618 lua_pushboolean(L, 1); /* signal no errors */ 619 return 1; 620 } 621 622 623 int main (int argc, char **argv) { 624 int status, result; 625 lua_State *L = luaL_newstate(); /* create state */ 626 if (L == NULL) { 627 l_message(argv[0], "cannot create state: not enough memory"); 628 return EXIT_FAILURE; 629 } 630 lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */ 631 lua_pushinteger(L, argc); /* 1st argument */ 632 lua_pushlightuserdata(L, argv); /* 2nd argument */ 633 status = lua_pcall(L, 2, 1, 0); /* do the call */ 634 result = lua_toboolean(L, -1); /* get result */ 635 report(L, status); 636 lua_close(L); 637 return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; 638 } 639 640