1*0a6a1f1dSLionel Sambuc /* $NetBSD: lua.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: lua.c,v 1.225 2015/03/30 15:42:59 roberto Exp
511be35a1SLionel Sambuc ** Lua stand-alone interpreter
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc
9*0a6a1f1dSLionel Sambuc #define lua_c
10*0a6a1f1dSLionel Sambuc
11*0a6a1f1dSLionel Sambuc #include "lprefix.h"
12*0a6a1f1dSLionel Sambuc
1311be35a1SLionel Sambuc
1411be35a1SLionel Sambuc #include <signal.h>
1511be35a1SLionel Sambuc #include <stdio.h>
1611be35a1SLionel Sambuc #include <stdlib.h>
1711be35a1SLionel Sambuc #include <string.h>
1811be35a1SLionel Sambuc
1911be35a1SLionel Sambuc #include "lua.h"
2011be35a1SLionel Sambuc
2111be35a1SLionel Sambuc #include "lauxlib.h"
2211be35a1SLionel Sambuc #include "lualib.h"
2311be35a1SLionel Sambuc
2411be35a1SLionel Sambuc
25*0a6a1f1dSLionel Sambuc #if !defined(LUA_PROMPT)
26*0a6a1f1dSLionel Sambuc #define LUA_PROMPT "> "
27*0a6a1f1dSLionel Sambuc #define LUA_PROMPT2 ">> "
28*0a6a1f1dSLionel Sambuc #endif
29*0a6a1f1dSLionel Sambuc
30*0a6a1f1dSLionel Sambuc #if !defined(LUA_PROGNAME)
31*0a6a1f1dSLionel Sambuc #define LUA_PROGNAME "lua"
32*0a6a1f1dSLionel Sambuc #endif
33*0a6a1f1dSLionel Sambuc
34*0a6a1f1dSLionel Sambuc #if !defined(LUA_MAXINPUT)
35*0a6a1f1dSLionel Sambuc #define LUA_MAXINPUT 512
36*0a6a1f1dSLionel Sambuc #endif
37*0a6a1f1dSLionel Sambuc
38*0a6a1f1dSLionel Sambuc #if !defined(LUA_INIT_VAR)
39*0a6a1f1dSLionel Sambuc #define LUA_INIT_VAR "LUA_INIT"
40*0a6a1f1dSLionel Sambuc #endif
41*0a6a1f1dSLionel Sambuc
42*0a6a1f1dSLionel Sambuc #define LUA_INITVARVERSION \
43*0a6a1f1dSLionel Sambuc LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
44*0a6a1f1dSLionel Sambuc
45*0a6a1f1dSLionel Sambuc
46*0a6a1f1dSLionel Sambuc /*
47*0a6a1f1dSLionel Sambuc ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
48*0a6a1f1dSLionel Sambuc ** is, whether we're running lua interactively).
49*0a6a1f1dSLionel Sambuc */
50*0a6a1f1dSLionel Sambuc #if !defined(lua_stdin_is_tty) /* { */
51*0a6a1f1dSLionel Sambuc
52*0a6a1f1dSLionel Sambuc #if defined(LUA_USE_POSIX) /* { */
53*0a6a1f1dSLionel Sambuc
54*0a6a1f1dSLionel Sambuc #include <unistd.h>
55*0a6a1f1dSLionel Sambuc #define lua_stdin_is_tty() isatty(0)
56*0a6a1f1dSLionel Sambuc
57*0a6a1f1dSLionel Sambuc #elif defined(LUA_USE_WINDOWS) /* }{ */
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc #include <io.h>
60*0a6a1f1dSLionel Sambuc #define lua_stdin_is_tty() _isatty(_fileno(stdin))
61*0a6a1f1dSLionel Sambuc
62*0a6a1f1dSLionel Sambuc #else /* }{ */
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc /* ISO C definition */
65*0a6a1f1dSLionel Sambuc #define lua_stdin_is_tty() 1 /* assume stdin is a tty */
66*0a6a1f1dSLionel Sambuc
67*0a6a1f1dSLionel Sambuc #endif /* } */
68*0a6a1f1dSLionel Sambuc
69*0a6a1f1dSLionel Sambuc #endif /* } */
70*0a6a1f1dSLionel Sambuc
71*0a6a1f1dSLionel Sambuc
72*0a6a1f1dSLionel Sambuc /*
73*0a6a1f1dSLionel Sambuc ** lua_readline defines how to show a prompt and then read a line from
74*0a6a1f1dSLionel Sambuc ** the standard input.
75*0a6a1f1dSLionel Sambuc ** lua_saveline defines how to "save" a read line in a "history".
76*0a6a1f1dSLionel Sambuc ** lua_freeline defines how to free a line read by lua_readline.
77*0a6a1f1dSLionel Sambuc */
78*0a6a1f1dSLionel Sambuc #if !defined(lua_readline) /* { */
79*0a6a1f1dSLionel Sambuc
80*0a6a1f1dSLionel Sambuc #if defined(LUA_USE_READLINE) /* { */
81*0a6a1f1dSLionel Sambuc
82*0a6a1f1dSLionel Sambuc #include <readline/readline.h>
83*0a6a1f1dSLionel Sambuc #include <readline/history.h>
84*0a6a1f1dSLionel Sambuc #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
85*0a6a1f1dSLionel Sambuc #define lua_saveline(L,line) ((void)L, add_history(line))
86*0a6a1f1dSLionel Sambuc #define lua_freeline(L,b) ((void)L, free(b))
87*0a6a1f1dSLionel Sambuc
88*0a6a1f1dSLionel Sambuc #else /* }{ */
89*0a6a1f1dSLionel Sambuc
90*0a6a1f1dSLionel Sambuc #define lua_readline(L,b,p) \
91*0a6a1f1dSLionel Sambuc ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
92*0a6a1f1dSLionel Sambuc fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
93*0a6a1f1dSLionel Sambuc #define lua_saveline(L,line) { (void)L; (void)line; }
94*0a6a1f1dSLionel Sambuc #define lua_freeline(L,b) { (void)L; (void)b; }
95*0a6a1f1dSLionel Sambuc
96*0a6a1f1dSLionel Sambuc #endif /* } */
97*0a6a1f1dSLionel Sambuc
98*0a6a1f1dSLionel Sambuc #endif /* } */
99*0a6a1f1dSLionel Sambuc
100*0a6a1f1dSLionel Sambuc
101*0a6a1f1dSLionel Sambuc
10211be35a1SLionel Sambuc
10311be35a1SLionel Sambuc static lua_State *globalL = NULL;
10411be35a1SLionel Sambuc
10511be35a1SLionel Sambuc static const char *progname = LUA_PROGNAME;
10611be35a1SLionel Sambuc
10711be35a1SLionel Sambuc
108*0a6a1f1dSLionel Sambuc /*
109*0a6a1f1dSLionel Sambuc ** Hook set by signal function to stop the interpreter.
110*0a6a1f1dSLionel Sambuc */
lstop(lua_State * L,lua_Debug * ar)11111be35a1SLionel Sambuc static void lstop (lua_State *L, lua_Debug *ar) {
11211be35a1SLionel Sambuc (void)ar; /* unused arg. */
113*0a6a1f1dSLionel Sambuc lua_sethook(L, NULL, 0, 0); /* reset hook */
11411be35a1SLionel Sambuc luaL_error(L, "interrupted!");
11511be35a1SLionel Sambuc }
11611be35a1SLionel Sambuc
11711be35a1SLionel Sambuc
118*0a6a1f1dSLionel Sambuc /*
119*0a6a1f1dSLionel Sambuc ** Function to be called at a C signal. Because a C signal cannot
120*0a6a1f1dSLionel Sambuc ** just change a Lua state (as there is no proper synchronization),
121*0a6a1f1dSLionel Sambuc ** this function only sets a hook that, when called, will stop the
122*0a6a1f1dSLionel Sambuc ** interpreter.
123*0a6a1f1dSLionel Sambuc */
laction(int i)12411be35a1SLionel Sambuc static void laction (int i) {
125*0a6a1f1dSLionel Sambuc signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
12611be35a1SLionel Sambuc lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
12711be35a1SLionel Sambuc }
12811be35a1SLionel Sambuc
12911be35a1SLionel Sambuc
print_usage(const char * badoption)130*0a6a1f1dSLionel Sambuc static void print_usage (const char *badoption) {
131*0a6a1f1dSLionel Sambuc lua_writestringerror("%s: ", progname);
132*0a6a1f1dSLionel Sambuc if (badoption[1] == 'e' || badoption[1] == 'l')
133*0a6a1f1dSLionel Sambuc lua_writestringerror("'%s' needs argument\n", badoption);
134*0a6a1f1dSLionel Sambuc else
135*0a6a1f1dSLionel Sambuc lua_writestringerror("unrecognized option '%s'\n", badoption);
136*0a6a1f1dSLionel Sambuc lua_writestringerror(
137*0a6a1f1dSLionel Sambuc "usage: %s [options] [script [args]]\n"
13811be35a1SLionel Sambuc "Available options are:\n"
139*0a6a1f1dSLionel Sambuc " -e stat execute string 'stat'\n"
140*0a6a1f1dSLionel Sambuc " -i enter interactive mode after executing 'script'\n"
141*0a6a1f1dSLionel Sambuc " -l name require library 'name'\n"
14211be35a1SLionel Sambuc " -v show version information\n"
143*0a6a1f1dSLionel Sambuc " -E ignore environment variables\n"
14411be35a1SLionel Sambuc " -- stop handling options\n"
145*0a6a1f1dSLionel Sambuc " - stop handling options and execute stdin\n"
14611be35a1SLionel Sambuc ,
14711be35a1SLionel Sambuc progname);
14811be35a1SLionel Sambuc }
14911be35a1SLionel Sambuc
15011be35a1SLionel Sambuc
151*0a6a1f1dSLionel Sambuc /*
152*0a6a1f1dSLionel Sambuc ** Prints an error message, adding the program name in front of it
153*0a6a1f1dSLionel Sambuc ** (if present)
154*0a6a1f1dSLionel Sambuc */
l_message(const char * pname,const char * msg)15511be35a1SLionel Sambuc static void l_message (const char *pname, const char *msg) {
156*0a6a1f1dSLionel Sambuc if (pname) lua_writestringerror("%s: ", pname);
157*0a6a1f1dSLionel Sambuc lua_writestringerror("%s\n", msg);
15811be35a1SLionel Sambuc }
15911be35a1SLionel Sambuc
16011be35a1SLionel Sambuc
161*0a6a1f1dSLionel Sambuc /*
162*0a6a1f1dSLionel Sambuc ** Check whether 'status' is not OK and, if so, prints the error
163*0a6a1f1dSLionel Sambuc ** message on the top of the stack. It assumes that the error object
164*0a6a1f1dSLionel Sambuc ** is a string, as it was either generated by Lua or by 'msghandler'.
165*0a6a1f1dSLionel Sambuc */
report(lua_State * L,int status)16611be35a1SLionel Sambuc static int report (lua_State *L, int status) {
167*0a6a1f1dSLionel Sambuc if (status != LUA_OK) {
16811be35a1SLionel Sambuc const char *msg = lua_tostring(L, -1);
16911be35a1SLionel Sambuc l_message(progname, msg);
170*0a6a1f1dSLionel Sambuc lua_pop(L, 1); /* remove message */
17111be35a1SLionel Sambuc }
17211be35a1SLionel Sambuc return status;
17311be35a1SLionel Sambuc }
17411be35a1SLionel Sambuc
17511be35a1SLionel Sambuc
176*0a6a1f1dSLionel Sambuc /*
177*0a6a1f1dSLionel Sambuc ** Message handler used to run all chunks
178*0a6a1f1dSLionel Sambuc */
msghandler(lua_State * L)179*0a6a1f1dSLionel Sambuc static int msghandler (lua_State *L) {
180*0a6a1f1dSLionel Sambuc const char *msg = lua_tostring(L, 1);
181*0a6a1f1dSLionel Sambuc if (msg == NULL) { /* is error object not a string? */
182*0a6a1f1dSLionel Sambuc if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
183*0a6a1f1dSLionel Sambuc lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
184*0a6a1f1dSLionel Sambuc return 1; /* that is the message */
185*0a6a1f1dSLionel Sambuc else
186*0a6a1f1dSLionel Sambuc msg = lua_pushfstring(L, "(error object is a %s value)",
187*0a6a1f1dSLionel Sambuc luaL_typename(L, 1));
18811be35a1SLionel Sambuc }
189*0a6a1f1dSLionel Sambuc luaL_traceback(L, L, msg, 1); /* append a standard traceback */
190*0a6a1f1dSLionel Sambuc return 1; /* return the traceback */
19111be35a1SLionel Sambuc }
19211be35a1SLionel Sambuc
19311be35a1SLionel Sambuc
194*0a6a1f1dSLionel Sambuc /*
195*0a6a1f1dSLionel Sambuc ** Interface to 'lua_pcall', which sets appropriate message function
196*0a6a1f1dSLionel Sambuc ** and C-signal handler. Used to run all chunks.
197*0a6a1f1dSLionel Sambuc */
docall(lua_State * L,int narg,int nres)198*0a6a1f1dSLionel Sambuc static int docall (lua_State *L, int narg, int nres) {
19911be35a1SLionel Sambuc int status;
20011be35a1SLionel Sambuc int base = lua_gettop(L) - narg; /* function index */
201*0a6a1f1dSLionel Sambuc lua_pushcfunction(L, msghandler); /* push message handler */
202*0a6a1f1dSLionel Sambuc lua_insert(L, base); /* put it under function and args */
203*0a6a1f1dSLionel Sambuc globalL = L; /* to be available to 'laction' */
204*0a6a1f1dSLionel Sambuc signal(SIGINT, laction); /* set C-signal handler */
205*0a6a1f1dSLionel Sambuc status = lua_pcall(L, narg, nres, base);
206*0a6a1f1dSLionel Sambuc signal(SIGINT, SIG_DFL); /* reset C-signal handler */
207*0a6a1f1dSLionel Sambuc lua_remove(L, base); /* remove message handler from the stack */
20811be35a1SLionel Sambuc return status;
20911be35a1SLionel Sambuc }
21011be35a1SLionel Sambuc
21111be35a1SLionel Sambuc
print_version(void)21211be35a1SLionel Sambuc static void print_version (void) {
213*0a6a1f1dSLionel Sambuc lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
214*0a6a1f1dSLionel Sambuc lua_writeline();
21511be35a1SLionel Sambuc }
21611be35a1SLionel Sambuc
21711be35a1SLionel Sambuc
218*0a6a1f1dSLionel Sambuc /*
219*0a6a1f1dSLionel Sambuc ** Create the 'arg' table, which stores all arguments from the
220*0a6a1f1dSLionel Sambuc ** command line ('argv'). It should be aligned so that, at index 0,
221*0a6a1f1dSLionel Sambuc ** it has 'argv[script]', which is the script name. The arguments
222*0a6a1f1dSLionel Sambuc ** to the script (everything after 'script') go to positive indices;
223*0a6a1f1dSLionel Sambuc ** other arguments (before the script name) go to negative indices.
224*0a6a1f1dSLionel Sambuc ** If there is no script name, assume interpreter's name as base.
225*0a6a1f1dSLionel Sambuc */
createargtable(lua_State * L,char ** argv,int argc,int script)226*0a6a1f1dSLionel Sambuc static void createargtable (lua_State *L, char **argv, int argc, int script) {
227*0a6a1f1dSLionel Sambuc int i, narg;
228*0a6a1f1dSLionel Sambuc if (script == argc) script = 0; /* no script name? */
229*0a6a1f1dSLionel Sambuc narg = argc - (script + 1); /* number of positive indices */
230*0a6a1f1dSLionel Sambuc lua_createtable(L, narg, script + 1);
23111be35a1SLionel Sambuc for (i = 0; i < argc; i++) {
23211be35a1SLionel Sambuc lua_pushstring(L, argv[i]);
233*0a6a1f1dSLionel Sambuc lua_rawseti(L, -2, i - script);
23411be35a1SLionel Sambuc }
235*0a6a1f1dSLionel Sambuc lua_setglobal(L, "arg");
236*0a6a1f1dSLionel Sambuc }
237*0a6a1f1dSLionel Sambuc
238*0a6a1f1dSLionel Sambuc
dochunk(lua_State * L,int status)239*0a6a1f1dSLionel Sambuc static int dochunk (lua_State *L, int status) {
240*0a6a1f1dSLionel Sambuc if (status == LUA_OK) status = docall(L, 0, 0);
241*0a6a1f1dSLionel Sambuc return report(L, status);
24211be35a1SLionel Sambuc }
24311be35a1SLionel Sambuc
24411be35a1SLionel Sambuc
dofile(lua_State * L,const char * name)24511be35a1SLionel Sambuc static int dofile (lua_State *L, const char *name) {
246*0a6a1f1dSLionel Sambuc return dochunk(L, luaL_loadfile(L, name));
24711be35a1SLionel Sambuc }
24811be35a1SLionel Sambuc
24911be35a1SLionel Sambuc
dostring(lua_State * L,const char * s,const char * name)25011be35a1SLionel Sambuc static int dostring (lua_State *L, const char *s, const char *name) {
251*0a6a1f1dSLionel Sambuc return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name));
252*0a6a1f1dSLionel Sambuc }
253*0a6a1f1dSLionel Sambuc
254*0a6a1f1dSLionel Sambuc
255*0a6a1f1dSLionel Sambuc /*
256*0a6a1f1dSLionel Sambuc ** Calls 'require(name)' and stores the result in a global variable
257*0a6a1f1dSLionel Sambuc ** with the given name.
258*0a6a1f1dSLionel Sambuc */
dolibrary(lua_State * L,const char * name)259*0a6a1f1dSLionel Sambuc static int dolibrary (lua_State *L, const char *name) {
260*0a6a1f1dSLionel Sambuc int status;
261*0a6a1f1dSLionel Sambuc lua_getglobal(L, "require");
262*0a6a1f1dSLionel Sambuc lua_pushstring(L, name);
263*0a6a1f1dSLionel Sambuc status = docall(L, 1, 1); /* call 'require(name)' */
264*0a6a1f1dSLionel Sambuc if (status == LUA_OK)
265*0a6a1f1dSLionel Sambuc lua_setglobal(L, name); /* global[name] = require return */
26611be35a1SLionel Sambuc return report(L, status);
26711be35a1SLionel Sambuc }
26811be35a1SLionel Sambuc
26911be35a1SLionel Sambuc
270*0a6a1f1dSLionel Sambuc /*
271*0a6a1f1dSLionel Sambuc ** Returns the string to be used as a prompt by the interpreter.
272*0a6a1f1dSLionel Sambuc */
get_prompt(lua_State * L,int firstline)27311be35a1SLionel Sambuc static const char *get_prompt (lua_State *L, int firstline) {
27411be35a1SLionel Sambuc const char *p;
275*0a6a1f1dSLionel Sambuc lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
27611be35a1SLionel Sambuc p = lua_tostring(L, -1);
27711be35a1SLionel Sambuc if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
27811be35a1SLionel Sambuc return p;
27911be35a1SLionel Sambuc }
28011be35a1SLionel Sambuc
281*0a6a1f1dSLionel Sambuc /* mark in error messages for incomplete statements */
282*0a6a1f1dSLionel Sambuc #define EOFMARK "<eof>"
283*0a6a1f1dSLionel Sambuc #define marklen (sizeof(EOFMARK)/sizeof(char) - 1)
28411be35a1SLionel Sambuc
285*0a6a1f1dSLionel Sambuc
286*0a6a1f1dSLionel Sambuc /*
287*0a6a1f1dSLionel Sambuc ** Check whether 'status' signals a syntax error and the error
288*0a6a1f1dSLionel Sambuc ** message at the top of the stack ends with the above mark for
289*0a6a1f1dSLionel Sambuc ** incomplete statements.
290*0a6a1f1dSLionel Sambuc */
incomplete(lua_State * L,int status)29111be35a1SLionel Sambuc static int incomplete (lua_State *L, int status) {
29211be35a1SLionel Sambuc if (status == LUA_ERRSYNTAX) {
29311be35a1SLionel Sambuc size_t lmsg;
29411be35a1SLionel Sambuc const char *msg = lua_tolstring(L, -1, &lmsg);
295*0a6a1f1dSLionel Sambuc if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
29611be35a1SLionel Sambuc lua_pop(L, 1);
29711be35a1SLionel Sambuc return 1;
29811be35a1SLionel Sambuc }
29911be35a1SLionel Sambuc }
30011be35a1SLionel Sambuc return 0; /* else... */
30111be35a1SLionel Sambuc }
30211be35a1SLionel Sambuc
30311be35a1SLionel Sambuc
304*0a6a1f1dSLionel Sambuc /*
305*0a6a1f1dSLionel Sambuc ** Prompt the user, read a line, and push it into the Lua stack.
306*0a6a1f1dSLionel Sambuc */
pushline(lua_State * L,int firstline)30711be35a1SLionel Sambuc static int pushline (lua_State *L, int firstline) {
30811be35a1SLionel Sambuc char buffer[LUA_MAXINPUT];
30911be35a1SLionel Sambuc char *b = buffer;
31011be35a1SLionel Sambuc size_t l;
31111be35a1SLionel Sambuc const char *prmt = get_prompt(L, firstline);
312*0a6a1f1dSLionel Sambuc int readstatus = lua_readline(L, b, prmt);
313*0a6a1f1dSLionel Sambuc if (readstatus == 0)
314*0a6a1f1dSLionel Sambuc return 0; /* no input (prompt will be popped by caller) */
315*0a6a1f1dSLionel Sambuc lua_pop(L, 1); /* remove prompt */
31611be35a1SLionel Sambuc l = strlen(b);
31711be35a1SLionel Sambuc if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
318*0a6a1f1dSLionel Sambuc b[--l] = '\0'; /* remove it */
319*0a6a1f1dSLionel Sambuc if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
320*0a6a1f1dSLionel Sambuc lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
32111be35a1SLionel Sambuc else
322*0a6a1f1dSLionel Sambuc lua_pushlstring(L, b, l);
32311be35a1SLionel Sambuc lua_freeline(L, b);
32411be35a1SLionel Sambuc return 1;
32511be35a1SLionel Sambuc }
32611be35a1SLionel Sambuc
32711be35a1SLionel Sambuc
328*0a6a1f1dSLionel Sambuc /*
329*0a6a1f1dSLionel Sambuc ** Try to compile line on the stack as 'return <line>'; on return, stack
330*0a6a1f1dSLionel Sambuc ** has either compiled chunk or original line (if compilation failed).
331*0a6a1f1dSLionel Sambuc */
addreturn(lua_State * L)332*0a6a1f1dSLionel Sambuc static int addreturn (lua_State *L) {
333*0a6a1f1dSLionel Sambuc int status;
334*0a6a1f1dSLionel Sambuc size_t len; const char *line;
335*0a6a1f1dSLionel Sambuc lua_pushliteral(L, "return ");
336*0a6a1f1dSLionel Sambuc lua_pushvalue(L, -2); /* duplicate line */
337*0a6a1f1dSLionel Sambuc lua_concat(L, 2); /* new line is "return ..." */
338*0a6a1f1dSLionel Sambuc line = lua_tolstring(L, -1, &len);
339*0a6a1f1dSLionel Sambuc if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) {
340*0a6a1f1dSLionel Sambuc lua_remove(L, -3); /* remove original line */
341*0a6a1f1dSLionel Sambuc line += sizeof("return")/sizeof(char); /* remove 'return' for history */
342*0a6a1f1dSLionel Sambuc if (line[0] != '\0') /* non empty? */
343*0a6a1f1dSLionel Sambuc lua_saveline(L, line); /* keep history */
344*0a6a1f1dSLionel Sambuc }
345*0a6a1f1dSLionel Sambuc else
346*0a6a1f1dSLionel Sambuc lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
347*0a6a1f1dSLionel Sambuc return status;
348*0a6a1f1dSLionel Sambuc }
349*0a6a1f1dSLionel Sambuc
350*0a6a1f1dSLionel Sambuc
351*0a6a1f1dSLionel Sambuc /*
352*0a6a1f1dSLionel Sambuc ** Read multiple lines until a complete Lua statement
353*0a6a1f1dSLionel Sambuc */
multiline(lua_State * L)354*0a6a1f1dSLionel Sambuc static int multiline (lua_State *L) {
355*0a6a1f1dSLionel Sambuc for (;;) { /* repeat until gets a complete statement */
356*0a6a1f1dSLionel Sambuc size_t len;
357*0a6a1f1dSLionel Sambuc const char *line = lua_tolstring(L, 1, &len); /* get what it has */
358*0a6a1f1dSLionel Sambuc int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
359*0a6a1f1dSLionel Sambuc if (!incomplete(L, status) || !pushline(L, 0)) {
360*0a6a1f1dSLionel Sambuc lua_saveline(L, line); /* keep history */
361*0a6a1f1dSLionel Sambuc return status; /* cannot or should not try to add continuation line */
362*0a6a1f1dSLionel Sambuc }
363*0a6a1f1dSLionel Sambuc lua_pushliteral(L, "\n"); /* add newline... */
364*0a6a1f1dSLionel Sambuc lua_insert(L, -2); /* ...between the two lines */
365*0a6a1f1dSLionel Sambuc lua_concat(L, 3); /* join them */
366*0a6a1f1dSLionel Sambuc }
367*0a6a1f1dSLionel Sambuc }
368*0a6a1f1dSLionel Sambuc
369*0a6a1f1dSLionel Sambuc
370*0a6a1f1dSLionel Sambuc /*
371*0a6a1f1dSLionel Sambuc ** Read a line and try to load (compile) it first as an expression (by
372*0a6a1f1dSLionel Sambuc ** adding "return " in front of it) and second as a statement. Return
373*0a6a1f1dSLionel Sambuc ** the final status of load/call with the resulting function (if any)
374*0a6a1f1dSLionel Sambuc ** in the top of the stack.
375*0a6a1f1dSLionel Sambuc */
loadline(lua_State * L)37611be35a1SLionel Sambuc static int loadline (lua_State *L) {
37711be35a1SLionel Sambuc int status;
37811be35a1SLionel Sambuc lua_settop(L, 0);
37911be35a1SLionel Sambuc if (!pushline(L, 1))
38011be35a1SLionel Sambuc return -1; /* no input */
381*0a6a1f1dSLionel Sambuc if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
382*0a6a1f1dSLionel Sambuc status = multiline(L); /* try as command, maybe with continuation lines */
383*0a6a1f1dSLionel Sambuc lua_remove(L, 1); /* remove line from the stack */
384*0a6a1f1dSLionel Sambuc lua_assert(lua_gettop(L) == 1);
38511be35a1SLionel Sambuc return status;
38611be35a1SLionel Sambuc }
38711be35a1SLionel Sambuc
38811be35a1SLionel Sambuc
389*0a6a1f1dSLionel Sambuc /*
390*0a6a1f1dSLionel Sambuc ** Prints (calling the Lua 'print' function) any values on the stack
391*0a6a1f1dSLionel Sambuc */
l_print(lua_State * L)392*0a6a1f1dSLionel Sambuc static void l_print (lua_State *L) {
393*0a6a1f1dSLionel Sambuc int n = lua_gettop(L);
394*0a6a1f1dSLionel Sambuc if (n > 0) { /* any result to be printed? */
395*0a6a1f1dSLionel Sambuc luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
39611be35a1SLionel Sambuc lua_getglobal(L, "print");
39711be35a1SLionel Sambuc lua_insert(L, 1);
398*0a6a1f1dSLionel Sambuc if (lua_pcall(L, n, 0, 0) != LUA_OK)
399*0a6a1f1dSLionel Sambuc l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
40011be35a1SLionel Sambuc lua_tostring(L, -1)));
40111be35a1SLionel Sambuc }
40211be35a1SLionel Sambuc }
403*0a6a1f1dSLionel Sambuc
404*0a6a1f1dSLionel Sambuc
405*0a6a1f1dSLionel Sambuc /*
406*0a6a1f1dSLionel Sambuc ** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and
407*0a6a1f1dSLionel Sambuc ** print any results.
408*0a6a1f1dSLionel Sambuc */
doREPL(lua_State * L)409*0a6a1f1dSLionel Sambuc static void doREPL (lua_State *L) {
410*0a6a1f1dSLionel Sambuc int status;
411*0a6a1f1dSLionel Sambuc const char *oldprogname = progname;
412*0a6a1f1dSLionel Sambuc progname = NULL; /* no 'progname' on errors in interactive mode */
413*0a6a1f1dSLionel Sambuc while ((status = loadline(L)) != -1) {
414*0a6a1f1dSLionel Sambuc if (status == LUA_OK)
415*0a6a1f1dSLionel Sambuc status = docall(L, 0, LUA_MULTRET);
416*0a6a1f1dSLionel Sambuc if (status == LUA_OK) l_print(L);
417*0a6a1f1dSLionel Sambuc else report(L, status);
418*0a6a1f1dSLionel Sambuc }
41911be35a1SLionel Sambuc lua_settop(L, 0); /* clear stack */
420*0a6a1f1dSLionel Sambuc lua_writeline();
42111be35a1SLionel Sambuc progname = oldprogname;
42211be35a1SLionel Sambuc }
42311be35a1SLionel Sambuc
42411be35a1SLionel Sambuc
425*0a6a1f1dSLionel Sambuc /*
426*0a6a1f1dSLionel Sambuc ** Push on the stack the contents of table 'arg' from 1 to #arg
427*0a6a1f1dSLionel Sambuc */
pushargs(lua_State * L)428*0a6a1f1dSLionel Sambuc static int pushargs (lua_State *L) {
429*0a6a1f1dSLionel Sambuc int i, n;
430*0a6a1f1dSLionel Sambuc if (lua_getglobal(L, "arg") != LUA_TTABLE)
431*0a6a1f1dSLionel Sambuc luaL_error(L, "'arg' is not a table");
432*0a6a1f1dSLionel Sambuc n = (int)luaL_len(L, -1);
433*0a6a1f1dSLionel Sambuc luaL_checkstack(L, n + 3, "too many arguments to script");
434*0a6a1f1dSLionel Sambuc for (i = 1; i <= n; i++)
435*0a6a1f1dSLionel Sambuc lua_rawgeti(L, -i, i);
436*0a6a1f1dSLionel Sambuc lua_remove(L, -i); /* remove table from the stack */
437*0a6a1f1dSLionel Sambuc return n;
438*0a6a1f1dSLionel Sambuc }
439*0a6a1f1dSLionel Sambuc
440*0a6a1f1dSLionel Sambuc
handle_script(lua_State * L,char ** argv)441*0a6a1f1dSLionel Sambuc static int handle_script (lua_State *L, char **argv) {
44211be35a1SLionel Sambuc int status;
443*0a6a1f1dSLionel Sambuc const char *fname = argv[0];
444*0a6a1f1dSLionel Sambuc if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0)
44511be35a1SLionel Sambuc fname = NULL; /* stdin */
44611be35a1SLionel Sambuc status = luaL_loadfile(L, fname);
447*0a6a1f1dSLionel Sambuc if (status == LUA_OK) {
448*0a6a1f1dSLionel Sambuc int n = pushargs(L); /* push arguments to script */
449*0a6a1f1dSLionel Sambuc status = docall(L, n, LUA_MULTRET);
450*0a6a1f1dSLionel Sambuc }
45111be35a1SLionel Sambuc return report(L, status);
45211be35a1SLionel Sambuc }
45311be35a1SLionel Sambuc
45411be35a1SLionel Sambuc
45511be35a1SLionel Sambuc
456*0a6a1f1dSLionel Sambuc /* bits of various argument indicators in 'args' */
457*0a6a1f1dSLionel Sambuc #define has_error 1 /* bad option */
458*0a6a1f1dSLionel Sambuc #define has_i 2 /* -i */
459*0a6a1f1dSLionel Sambuc #define has_v 4 /* -v */
460*0a6a1f1dSLionel Sambuc #define has_e 8 /* -e */
461*0a6a1f1dSLionel Sambuc #define has_E 16 /* -E */
46211be35a1SLionel Sambuc
463*0a6a1f1dSLionel Sambuc /*
464*0a6a1f1dSLionel Sambuc ** Traverses all arguments from 'argv', returning a mask with those
465*0a6a1f1dSLionel Sambuc ** needed before running any Lua code (or an error code if it finds
466*0a6a1f1dSLionel Sambuc ** any invalid argument). 'first' returns the first not-handled argument
467*0a6a1f1dSLionel Sambuc ** (either the script name or a bad argument in case of error).
468*0a6a1f1dSLionel Sambuc */
collectargs(char ** argv,int * first)469*0a6a1f1dSLionel Sambuc static int collectargs (char **argv, int *first) {
470*0a6a1f1dSLionel Sambuc int args = 0;
47111be35a1SLionel Sambuc int i;
47211be35a1SLionel Sambuc for (i = 1; argv[i] != NULL; i++) {
473*0a6a1f1dSLionel Sambuc *first = i;
47411be35a1SLionel Sambuc if (argv[i][0] != '-') /* not an option? */
475*0a6a1f1dSLionel Sambuc return args; /* stop handling options */
476*0a6a1f1dSLionel Sambuc switch (argv[i][1]) { /* else check option */
477*0a6a1f1dSLionel Sambuc case '-': /* '--' */
478*0a6a1f1dSLionel Sambuc if (argv[i][2] != '\0') /* extra characters after '--'? */
479*0a6a1f1dSLionel Sambuc return has_error; /* invalid option */
480*0a6a1f1dSLionel Sambuc *first = i + 1;
481*0a6a1f1dSLionel Sambuc return args;
482*0a6a1f1dSLionel Sambuc case '\0': /* '-' */
483*0a6a1f1dSLionel Sambuc return args; /* script "name" is '-' */
484*0a6a1f1dSLionel Sambuc case 'E':
485*0a6a1f1dSLionel Sambuc if (argv[i][2] != '\0') /* extra characters after 1st? */
486*0a6a1f1dSLionel Sambuc return has_error; /* invalid option */
487*0a6a1f1dSLionel Sambuc args |= has_E;
488*0a6a1f1dSLionel Sambuc break;
48911be35a1SLionel Sambuc case 'i':
490*0a6a1f1dSLionel Sambuc args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */
49111be35a1SLionel Sambuc case 'v':
492*0a6a1f1dSLionel Sambuc if (argv[i][2] != '\0') /* extra characters after 1st? */
493*0a6a1f1dSLionel Sambuc return has_error; /* invalid option */
494*0a6a1f1dSLionel Sambuc args |= has_v;
49511be35a1SLionel Sambuc break;
49611be35a1SLionel Sambuc case 'e':
497*0a6a1f1dSLionel Sambuc args |= has_e; /* FALLTHROUGH */
498*0a6a1f1dSLionel Sambuc case 'l': /* both options need an argument */
499*0a6a1f1dSLionel Sambuc if (argv[i][2] == '\0') { /* no concatenated argument? */
500*0a6a1f1dSLionel Sambuc i++; /* try next 'argv' */
501*0a6a1f1dSLionel Sambuc if (argv[i] == NULL || argv[i][0] == '-')
502*0a6a1f1dSLionel Sambuc return has_error; /* no next argument or it is another option */
50311be35a1SLionel Sambuc }
50411be35a1SLionel Sambuc break;
505*0a6a1f1dSLionel Sambuc default: /* invalid option */
506*0a6a1f1dSLionel Sambuc return has_error;
50711be35a1SLionel Sambuc }
50811be35a1SLionel Sambuc }
509*0a6a1f1dSLionel Sambuc *first = i; /* no script name */
510*0a6a1f1dSLionel Sambuc return args;
51111be35a1SLionel Sambuc }
51211be35a1SLionel Sambuc
51311be35a1SLionel Sambuc
514*0a6a1f1dSLionel Sambuc /*
515*0a6a1f1dSLionel Sambuc ** Processes options 'e' and 'l', which involve running Lua code.
516*0a6a1f1dSLionel Sambuc ** Returns 0 if some code raises an error.
517*0a6a1f1dSLionel Sambuc */
runargs(lua_State * L,char ** argv,int n)51811be35a1SLionel Sambuc static int runargs (lua_State *L, char **argv, int n) {
51911be35a1SLionel Sambuc int i;
52011be35a1SLionel Sambuc for (i = 1; i < n; i++) {
521*0a6a1f1dSLionel Sambuc int option = argv[i][1];
522*0a6a1f1dSLionel Sambuc lua_assert(argv[i][0] == '-'); /* already checked */
523*0a6a1f1dSLionel Sambuc if (option == 'e' || option == 'l') {
524*0a6a1f1dSLionel Sambuc int status;
525*0a6a1f1dSLionel Sambuc const char *extra = argv[i] + 2; /* both options need an argument */
526*0a6a1f1dSLionel Sambuc if (*extra == '\0') extra = argv[++i];
527*0a6a1f1dSLionel Sambuc lua_assert(extra != NULL);
528*0a6a1f1dSLionel Sambuc status = (option == 'e')
529*0a6a1f1dSLionel Sambuc ? dostring(L, extra, "=(command line)")
530*0a6a1f1dSLionel Sambuc : dolibrary(L, extra);
531*0a6a1f1dSLionel Sambuc if (status != LUA_OK) return 0;
532*0a6a1f1dSLionel Sambuc }
533*0a6a1f1dSLionel Sambuc }
53411be35a1SLionel Sambuc return 1;
53511be35a1SLionel Sambuc }
53611be35a1SLionel Sambuc
53711be35a1SLionel Sambuc
handle_luainit(lua_State * L)53811be35a1SLionel Sambuc static int handle_luainit (lua_State *L) {
539*0a6a1f1dSLionel Sambuc const char *name = "=" LUA_INITVARVERSION;
540*0a6a1f1dSLionel Sambuc const char *init = getenv(name + 1);
541*0a6a1f1dSLionel Sambuc if (init == NULL) {
542*0a6a1f1dSLionel Sambuc name = "=" LUA_INIT_VAR;
543*0a6a1f1dSLionel Sambuc init = getenv(name + 1); /* try alternative name */
544*0a6a1f1dSLionel Sambuc }
545*0a6a1f1dSLionel Sambuc if (init == NULL) return LUA_OK;
54611be35a1SLionel Sambuc else if (init[0] == '@')
54711be35a1SLionel Sambuc return dofile(L, init+1);
54811be35a1SLionel Sambuc else
549*0a6a1f1dSLionel Sambuc return dostring(L, init, name);
55011be35a1SLionel Sambuc }
55111be35a1SLionel Sambuc
55211be35a1SLionel Sambuc
553*0a6a1f1dSLionel Sambuc /*
554*0a6a1f1dSLionel Sambuc ** Main body of stand-alone interpreter (to be called in protected mode).
555*0a6a1f1dSLionel Sambuc ** Reads the options and handles them all.
556*0a6a1f1dSLionel Sambuc */
pmain(lua_State * L)55711be35a1SLionel Sambuc static int pmain (lua_State *L) {
558*0a6a1f1dSLionel Sambuc int argc = (int)lua_tointeger(L, 1);
559*0a6a1f1dSLionel Sambuc char **argv = (char **)lua_touserdata(L, 2);
56011be35a1SLionel Sambuc int script;
561*0a6a1f1dSLionel Sambuc int args = collectargs(argv, &script);
562*0a6a1f1dSLionel Sambuc luaL_checkversion(L); /* check that interpreter has correct version */
56311be35a1SLionel Sambuc if (argv[0] && argv[0][0]) progname = argv[0];
564*0a6a1f1dSLionel Sambuc if (args == has_error) { /* bad arg? */
565*0a6a1f1dSLionel Sambuc print_usage(argv[script]); /* 'script' has index of bad arg. */
56611be35a1SLionel Sambuc return 0;
56711be35a1SLionel Sambuc }
568*0a6a1f1dSLionel Sambuc if (args & has_v) /* option '-v'? */
56911be35a1SLionel Sambuc print_version();
570*0a6a1f1dSLionel Sambuc if (args & has_E) { /* option '-E'? */
571*0a6a1f1dSLionel Sambuc lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
572*0a6a1f1dSLionel Sambuc lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
573*0a6a1f1dSLionel Sambuc }
574*0a6a1f1dSLionel Sambuc luaL_openlibs(L); /* open standard libraries */
575*0a6a1f1dSLionel Sambuc createargtable(L, argv, argc, script); /* create table 'arg' */
576*0a6a1f1dSLionel Sambuc if (!(args & has_E)) { /* no option '-E'? */
577*0a6a1f1dSLionel Sambuc if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
578*0a6a1f1dSLionel Sambuc return 0; /* error running LUA_INIT */
579*0a6a1f1dSLionel Sambuc }
580*0a6a1f1dSLionel Sambuc if (!runargs(L, argv, script)) /* execute arguments -e and -l */
581*0a6a1f1dSLionel Sambuc return 0; /* something failed */
582*0a6a1f1dSLionel Sambuc if (script < argc && /* execute main script (if there is one) */
583*0a6a1f1dSLionel Sambuc handle_script(L, argv + script) != LUA_OK)
584*0a6a1f1dSLionel Sambuc return 0;
585*0a6a1f1dSLionel Sambuc if (args & has_i) /* -i option? */
586*0a6a1f1dSLionel Sambuc doREPL(L); /* do read-eval-print loop */
587*0a6a1f1dSLionel Sambuc else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */
588*0a6a1f1dSLionel Sambuc if (lua_stdin_is_tty()) { /* running in interactive mode? */
589*0a6a1f1dSLionel Sambuc print_version();
590*0a6a1f1dSLionel Sambuc doREPL(L); /* do read-eval-print loop */
59111be35a1SLionel Sambuc }
59211be35a1SLionel Sambuc else dofile(L, NULL); /* executes stdin as a file */
59311be35a1SLionel Sambuc }
594*0a6a1f1dSLionel Sambuc lua_pushboolean(L, 1); /* signal no errors */
595*0a6a1f1dSLionel Sambuc return 1;
59611be35a1SLionel Sambuc }
59711be35a1SLionel Sambuc
59811be35a1SLionel Sambuc
main(int argc,char ** argv)59911be35a1SLionel Sambuc int main (int argc, char **argv) {
600*0a6a1f1dSLionel Sambuc int status, result;
601*0a6a1f1dSLionel Sambuc lua_State *L = luaL_newstate(); /* create state */
60211be35a1SLionel Sambuc if (L == NULL) {
60311be35a1SLionel Sambuc l_message(argv[0], "cannot create state: not enough memory");
60411be35a1SLionel Sambuc return EXIT_FAILURE;
60511be35a1SLionel Sambuc }
606*0a6a1f1dSLionel Sambuc lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
607*0a6a1f1dSLionel Sambuc lua_pushinteger(L, argc); /* 1st argument */
608*0a6a1f1dSLionel Sambuc lua_pushlightuserdata(L, argv); /* 2nd argument */
609*0a6a1f1dSLionel Sambuc status = lua_pcall(L, 2, 1, 0); /* do the call */
610*0a6a1f1dSLionel Sambuc result = lua_toboolean(L, -1); /* get result */
61111be35a1SLionel Sambuc report(L, status);
61211be35a1SLionel Sambuc lua_close(L);
613*0a6a1f1dSLionel Sambuc return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
61411be35a1SLionel Sambuc }
61511be35a1SLionel Sambuc
616