LCOV - code coverage report
Current view: top level - src - lua.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 59.3 % 270 160
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1