lua

A copy of the Lua development repository
Log | Files | Refs | README

lua.c (22395B)


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