Lua 5.1.4: lua.c
The default standalone Lua interpreter
L0001    
L0006    
L0007    
L0008    #include <signal.h>
L0009    #include <stdio.h>
L0010    #include <stdlib.h>
L0011    #include <string.h>
L0012    
L0013    #define lua_c
L0014    
L0015    #include "lua.h"
L0016    
L0017    #include "lauxlib.h"
L0018    #include "lualib.h"
L0019    
L0020    
L0021    
L0022    static lua_State *globalL = NULL;
L0023    
L0024    static const char *progname = LUA_PROGNAME;
L0025    
L0026    
L0027    
L0028    static void lstop (lua_State *L, lua_Debug *ar) {
L0029      (void)ar;  
L0030      lua_sethook(L, NULL, 0, 0);
L0031      luaL_error(L, "interrupted!");
L0032    }
L0033    
L0034    
L0035    static void laction (int i) {
L0036      signal(i, SIG_DFL); 
L0038      lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
L0039    }
L0040    
L0041    
L0042    static void print_usage (void) {
L0043      fprintf(stderr,
L0044      "usage: %s [options] [script [args]].\n"
L0045      "Available options are:\n"
L0046      "  -e stat  execute string " LUA_QL("stat") "\n"
L0047      "  -l name  require library " LUA_QL("name") "\n"
L0048      "  -i       enter interactive mode after executing " LUA_QL("script") "\n"
L0049      "  -v       show version information\n"
L0050      "  --       stop handling options\n"
L0051      "  -        execute stdin and stop handling options\n"
L0052      ,
L0053      progname);
L0054      fflush(stderr);
L0055    }
L0056    
L0057    
L0058    static void l_message (const char *pname, const char *msg) {
L0059      if (pname) fprintf(stderr, "%s: ", pname);
L0060      fprintf(stderr, "%s\n", msg);
L0061      fflush(stderr);
L0062    }
L0063    
L0064    
L0065    static int report (lua_State *L, int status) {
L0066      if (status && !lua_isnil(L, -1)) {
L0067        const char *msg = lua_tostring(L, -1);
L0068        if (msg == NULL) msg = "(error object is not a string)";
L0069        l_message(progname, msg);
L0070        lua_pop(L, 1);
L0071      }
L0072      return status;
L0073    }
L0074    
L0075    
L0076    static int traceback (lua_State *L) {
L0077      if (!lua_isstring(L, 1))  
L0078        return 1;  
L0079      lua_getfield(L, LUA_GLOBALSINDEX, "debug");
L0080      if (!lua_istable(L, -1)) {
L0081        lua_pop(L, 1);
L0082        return 1;
L0083      }
L0084      lua_getfield(L, -1, "traceback");
L0085      if (!lua_isfunction(L, -1)) {
L0086        lua_pop(L, 2);
L0087        return 1;
L0088      }
L0089      lua_pushvalue(L, 1);  
L0090      lua_pushinteger(L, 2);  
L0091      lua_call(L, 2, 1);  
L0092      return 1;
L0093    }
L0094    
L0095    
L0096    static int docall (lua_State *L, int narg, int clear) {
L0097      int status;
L0098      int base = lua_gettop(L) - narg;  
L0099      lua_pushcfunction(L, traceback);  
L0100      lua_insert(L, base);  
L0101      signal(SIGINT, laction);
L0102      status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
L0103      signal(SIGINT, SIG_DFL);
L0104      lua_remove(L, base);  
L0105      
L0106      if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
L0107      return status;
L0108    }
L0109    
L0110    
L0111    static void print_version (void) {
L0112      l_message(NULL, LUA_RELEASE "  " LUA_COPYRIGHT);
L0113    }
L0114    
L0115    
L0116    static int getargs (lua_State *L, char **argv, int n) {
L0117      int narg;
L0118      int i;
L0119      int argc = 0;
L0120      while (argv[argc]) argc++;  
L0121      narg = argc - (n + 1);  
L0122      luaL_checkstack(L, narg + 3, "too many arguments to script");
L0123      for (i=n+1; i < argc; i++)
L0124        lua_pushstring(L, argv[i]);
L0125      lua_createtable(L, narg, n + 1);
L0126      for (i=0; i < argc; i++) {
L0127        lua_pushstring(L, argv[i]);
L0128        lua_rawseti(L, -2, i - n);
L0129      }
L0130      return narg;
L0131    }
L0132    
L0133    
L0134    static int dofile (lua_State *L, const char *name) {
L0135      int status = luaL_loadfile(L, name) || docall(L, 0, 1);
L0136      return report(L, status);
L0137    }
L0138    
L0139    
L0140    static int dostring (lua_State *L, const char *s, const char *name) {
L0141      int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
L0142      return report(L, status);
L0143    }
L0144    
L0145    
L0146    static int dolibrary (lua_State *L, const char *name) {
L0147      lua_getglobal(L, "require");
L0148      lua_pushstring(L, name);
L0149      return report(L, docall(L, 1, 1));
L0150    }
L0151    
L0152    
L0153    static const char *get_prompt (lua_State *L, int firstline) {
L0154      const char *p;
L0155      lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
L0156      p = lua_tostring(L, -1);
L0157      if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
L0158      lua_pop(L, 1);  
L0159      return p;
L0160    }
L0161    
L0162    
L0163    static int incomplete (lua_State *L, int status) {
L0164      if (status == LUA_ERRSYNTAX) {
L0165        size_t lmsg;
L0166        const char *msg = lua_tolstring(L, -1, &lmsg);
L0167        const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
L0168        if (strstr(msg, LUA_QL("<eof>")) == tp) {
L0169          lua_pop(L, 1);
L0170          return 1;
L0171        }
L0172      }
L0173      return 0;  
L0174    }
L0175    
L0176    
L0177    static int pushline (lua_State *L, int firstline) {
L0178      char buffer[LUA_MAXINPUT];
L0179      char *b = buffer;
L0180      size_t l;
L0181      const char *prmt = get_prompt(L, firstline);
L0182      if (lua_readline(L, b, prmt) == 0)
L0183        return 0;  
L0184      l = strlen(b);
L0185      if (l > 0 && b[l-1] == '\n')  
L0186        b[l-1] = '\0';  
L0187      if (firstline && b[0] == '=')  
L0188        lua_pushfstring(L, "return %s", b+1);  
L0189      else
L0190        lua_pushstring(L, b);
L0191      lua_freeline(L, b);
L0192      return 1;
L0193    }
L0194    
L0195    
L0196    static int loadline (lua_State *L) {
L0197      int status;
L0198      lua_settop(L, 0);
L0199      if (!pushline(L, 1))
L0200        return -1;  
L0201      for (;;) {  
L0202        status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
L0203        if (!incomplete(L, status)) break;  
L0204        if (!pushline(L, 0))  
L0205          return -1;
L0206        lua_pushliteral(L, "\n");  
L0207        lua_insert(L, -2);  
L0208        lua_concat(L, 3);  
L0209      }
L0210      lua_saveline(L, 1);
L0211      lua_remove(L, 1);  
L0212      return status;
L0213    }
L0214    
L0215    
L0216    static void dotty (lua_State *L) {
L0217      int status;
L0218      const char *oldprogname = progname;
L0219      progname = NULL;
L0220      while ((status = loadline(L)) != -1) {
L0221        if (status == 0) status = docall(L, 0, 0);
L0222        report(L, status);
L0223        if (status == 0 && lua_gettop(L) > 0) {  
L0224          lua_getglobal(L, "print");
L0225          lua_insert(L, 1);
L0226          if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
L0227            l_message(progname, lua_pushfstring(L,
L0228                                   "error calling " LUA_QL("print") " (%s)",
L0229                                   lua_tostring(L, -1)));
L0230        }
L0231      }
L0232      lua_settop(L, 0);  
L0233      fputs("\n", stdout);
L0234      fflush(stdout);
L0235      progname = oldprogname;
L0236    }
L0237    
L0238    
L0239    static int handle_script (lua_State *L, char **argv, int n) {
L0240      int status;
L0241      const char *fname;
L0242      int narg = getargs(L, argv, n);  
L0243      lua_setglobal(L, "arg");
L0244      fname = argv[n];
L0245      if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) 
L0246        fname = NULL;  
L0247      status = luaL_loadfile(L, fname);
L0248      lua_insert(L, -(narg+1));
L0249      if (status == 0)
L0250        status = docall(L, narg, 0);
L0251      else
L0252        lua_pop(L, narg);      
L0253      return report(L, status);
L0254    }
L0255    
L0256    
L0257    
L0258    #define notail(x)	{if ((x)[2] != '\0') return -1;}
L0259    
L0260    
L0261    static int collectargs (char **argv, int *pi, int *pv, int *pe) {
L0262      int i;
L0263      for (i = 1; argv[i] != NULL; i++) {
L0264        if (argv[i][0] != '-')  
L0265            return i;
L0266        switch (argv[i][1]) {  
L0267          case '-':
L0268            notail(argv[i]);
L0269            return (argv[i+1] != NULL ? i+1 : 0);
L0270          case '\0':
L0271            return i;
L0272          case 'i':
L0273            notail(argv[i]);
L0274            *pi = 1;  
L0275          case 'v':
L0276            notail(argv[i]);
L0277            *pv = 1;
L0278            break;
L0279          case 'e':
L0280            *pe = 1;  
L0281          case 'l':
L0282            if (argv[i][2] == '\0') {
L0283              i++;
L0284              if (argv[i] == NULL) return -1;
L0285            }
L0286            break;
L0287          default: return -1;  
L0288        }
L0289      }
L0290      return 0;
L0291    }
L0292    
L0293    
L0294    static int runargs (lua_State *L, char **argv, int n) {
L0295      int i;
L0296      for (i = 1; i < n; i++) {
L0297        if (argv[i] == NULL) continue;
L0298        lua_assert(argv[i][0] == '-');
L0299        switch (argv[i][1]) {  
L0300          case 'e': {
L0301            const char *chunk = argv[i] + 2;
L0302            if (*chunk == '\0') chunk = argv[++i];
L0303            lua_assert(chunk != NULL);
L0304            if (dostring(L, chunk, "=(command line)") != 0)
L0305              return 1;
L0306            break;
L0307          }
L0308          case 'l': {
L0309            const char *filename = argv[i] + 2;
L0310            if (*filename == '\0') filename = argv[++i];
L0311            lua_assert(filename != NULL);
L0312            if (dolibrary(L, filename))
L0313              return 1;  
L0314            break;
L0315          }
L0316          default: break;
L0317        }
L0318      }
L0319      return 0;
L0320    }
L0321    
L0322    
L0323    static int handle_luainit (lua_State *L) {
L0324      const char *init = getenv(LUA_INIT);
L0325      if (init == NULL) return 0;  
L0326      else if (init[0] == '@')
L0327        return dofile(L, init+1);
L0328      else
L0329        return dostring(L, init, "=" LUA_INIT);
L0330    }
L0331    
L0332    
L0333    struct Smain {
L0334      int argc;
L0335      char **argv;
L0336      int status;
L0337    };
L0338    
L0339    
L0340    static int pmain (lua_State *L) {
L0341      struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
L0342      char **argv = s->argv;
L0343      int script;
L0344      int has_i = 0, has_v = 0, has_e = 0;
L0345      globalL = L;
L0346      if (argv[0] && argv[0][0]) progname = argv[0];
L0347      lua_gc(L, LUA_GCSTOP, 0);  
L0348      luaL_openlibs(L);  
L0349      lua_gc(L, LUA_GCRESTART, 0);
L0350      s->status = handle_luainit(L);
L0351      if (s->status != 0) return 0;
L0352      script = collectargs(argv, &has_i, &has_v, &has_e);
L0353      if (script < 0) {  
L0354        print_usage();
L0355        s->status = 1;
L0356        return 0;
L0357      }
L0358      if (has_v) print_version();
L0359      s->status = runargs(L, argv, (script > 0) ? script : s->argc);
L0360      if (s->status != 0) return 0;
L0361      if (script)
L0362        s->status = handle_script(L, argv, script);
L0363      if (s->status != 0) return 0;
L0364      if (has_i)
L0365        dotty(L);
L0366      else if (script == 0 && !has_e && !has_v) {
L0367        if (lua_stdin_is_tty()) {
L0368          print_version();
L0369          dotty(L);
L0370        }
L0371        else dofile(L, NULL);  
L0372      }
L0373      return 0;
L0374    }
L0375    
L0376    
L0377    int main (int argc, char **argv) {
L0378      int status;
L0379      struct Smain s;
L0380      lua_State *L = lua_open();  
L0381      if (L == NULL) {
L0382        l_message(argv[0], "cannot create state: not enough memory");
L0383        return EXIT_FAILURE;
L0384      }
L0385      s.argc = argc;
L0386      s.argv = argv;
L0387      status = lua_cpcall(L, &pmain, &s);
L0388      report(L, status);
L0389      lua_close(L);
L0390      return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
L0391    }
L0392    
Generated by pretty.lua