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