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