24#if !defined(LUA_PROGNAME)
25#define LUA_PROGNAME "lua"
28#if !defined(LUA_INIT_VAR)
29#define LUA_INIT_VAR "LUA_INIT"
32#define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX
37static const char *progname = LUA_PROGNAME;
40#if defined(LUA_USE_POSIX)
45static void setsignal (
int sig,
void (*handler)(
int)) {
47 sa.sa_handler = handler;
49 sigemptyset(&sa.sa_mask);
50 sigaction(sig, &sa, NULL);
55#define setsignal signal
65 lua_sethook(L, NULL, 0, 0);
66 luaL_error(L,
"interrupted!");
76static void laction (
int i) {
77 int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
78 setsignal(i, SIG_DFL);
79 lua_sethook(globalL, lstop, flag, 1);
83static void print_usage (
const char *badoption) {
84 lua_writestringerror(
"%s: ", progname);
85 if (badoption[1] ==
'e' || badoption[1] ==
'l')
86 lua_writestringerror(
"'%s' needs argument\n", badoption);
88 lua_writestringerror(
"unrecognized option '%s'\n", badoption);
90 "usage: %s [options] [script [args]]\n"
91 "Available options are:\n"
92 " -e stat execute string 'stat'\n"
93 " -i enter interactive mode after executing 'script'\n"
94 " -l mod require library 'mod' into global 'mod'\n"
95 " -l g=mod require library 'mod' into global 'g'\n"
96 " -v show version information\n"
97 " -E ignore environment variables\n"
98 " -W turn warnings on\n"
99 " -- stop handling options\n"
100 " - stop handling options and execute stdin\n"
110static void l_message (
const char *pname,
const char *msg) {
111 if (pname) lua_writestringerror(
"%s: ", pname);
112 lua_writestringerror(
"%s\n", msg);
121static int report (
lua_State *L,
int status) {
122 if (status != LUA_OK) {
123 const char *msg = lua_tostring(L, -1);
124 l_message(progname, msg);
135 const char *msg = lua_tostring(L, 1);
137 if (luaL_callmeta(L, 1,
"__tostring") &&
138 lua_type(L, -1) == LUA_TSTRING)
141 msg = lua_pushfstring(L,
"(error object is a %s value)",
142 luaL_typename(L, 1));
144 luaL_traceback(L, L, msg, 1);
153static int docall (
lua_State *L,
int narg,
int nres) {
155 int base = lua_gettop(L) - narg;
156 lua_pushcfunction(L, msghandler);
159 setsignal(SIGINT, laction);
160 status = lua_pcall(L, narg, nres, base);
161 setsignal(SIGINT, SIG_DFL);
167static void print_version (
void) {
168 lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
183static void createargtable (
lua_State *L,
char **argv,
int argc,
int script) {
185 narg = argc - (script + 1);
186 lua_createtable(L, narg, script + 1);
187 for (i = 0; i < argc; i++) {
188 lua_pushstring(L, argv[i]);
189 lua_rawseti(L, -2, i - script);
191 lua_setglobal(L,
"arg");
195static int dochunk (
lua_State *L,
int status) {
196 if (status == LUA_OK) status = docall(L, 0, 0);
197 return report(L, status);
201static int dofile (
lua_State *L,
const char *name) {
202 return dochunk(L, luaL_loadfile(L, name));
206static int dostring (
lua_State *L,
const char *s,
const char *name) {
207 return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name));
214static int dolibrary (
lua_State *L,
char *globname) {
216 char *modname = strchr(globname,
'=');
223 lua_getglobal(L,
"require");
224 lua_pushstring(L, modname);
225 status = docall(L, 1, 1);
226 if (status == LUA_OK)
227 lua_setglobal(L, globname);
228 return report(L, status);
237 if (lua_getglobal(L,
"arg") != LUA_TTABLE)
238 luaL_error(L,
"'arg' is not a table");
239 n = (int)luaL_len(L, -1);
240 luaL_checkstack(L, n + 3,
"too many arguments to script");
241 for (i = 1; i <= n; i++)
242 lua_rawgeti(L, -i, i);
248static int handle_script (
lua_State *L,
char **argv) {
250 const char *fname = argv[0];
251 if (strcmp(fname,
"-") == 0 && strcmp(argv[-1],
"--") != 0)
253 status = luaL_loadfile(L, fname);
254 if (status == LUA_OK) {
256 status = docall(L, n, LUA_MULTRET);
258 return report(L, status);
277static int collectargs (
char **argv,
int *first) {
280 if (argv[0] != NULL) {
288 for (i = 1; argv[i] != NULL; i++) {
290 if (argv[i][0] !=
'-')
292 switch (argv[i][1]) {
294 if (argv[i][2] !=
'\0')
301 if (argv[i][2] !=
'\0')
306 if (argv[i][2] !=
'\0')
312 if (argv[i][2] !=
'\0')
319 if (argv[i][2] ==
'\0') {
321 if (argv[i] == NULL || argv[i][0] ==
'-')
339static int runargs (
lua_State *L,
char **argv,
int n) {
341 for (i = 1; i < n; i++) {
342 int option = argv[i][1];
343 lua_assert(argv[i][0] ==
'-');
345 case 'e':
case 'l': {
347 char *extra = argv[i] + 2;
348 if (*extra ==
'\0') extra = argv[++i];
349 lua_assert(extra != NULL);
350 status = (option ==
'e')
351 ? dostring(L, extra,
"=(command line)")
352 : dolibrary(L, extra);
353 if (status != LUA_OK)
return 0;
357 lua_warning(L,
"@on", 0);
365static int handle_luainit (
lua_State *L) {
366 const char *name =
"=" LUA_INITVARVERSION;
367 const char *init = getenv(name + 1);
369 name =
"=" LUA_INIT_VAR;
370 init = getenv(name + 1);
372 if (init == NULL)
return LUA_OK;
373 else if (init[0] ==
'@')
374 return dofile(L, init+1);
376 return dostring(L, init, name);
386#if !defined(LUA_PROMPT)
387#define LUA_PROMPT "> "
388#define LUA_PROMPT2 ">> "
391#if !defined(LUA_MAXINPUT)
392#define LUA_MAXINPUT 512
400#if !defined(lua_stdin_is_tty)
402#if defined(LUA_USE_POSIX)
405#define lua_stdin_is_tty() isatty(0)
407#elif defined(LUA_USE_WINDOWS)
412#define lua_stdin_is_tty() _isatty(_fileno(stdin))
417#define lua_stdin_is_tty() 1
430#if !defined(lua_readline)
432#if defined(LUA_USE_READLINE)
434#include <readline/readline.h>
435#include <readline/history.h>
436#define lua_initreadline(L) ((void)L, rl_readline_name="lua")
437#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
438#define lua_saveline(L,line) ((void)L, add_history(line))
439#define lua_freeline(L,b) ((void)L, free(b))
443#define lua_initreadline(L) ((void)L)
444#define lua_readline(L,b,p) \
445 ((void)L, fputs(p, stdout), fflush(stdout), \
446 fgets(b, LUA_MAXINPUT, stdin) != NULL)
447#define lua_saveline(L,line) { (void)L; (void)line; }
448#define lua_freeline(L,b) { (void)L; (void)b; }
460static const char *get_prompt (
lua_State *L,
int firstline) {
461 if (lua_getglobal(L, firstline ?
"_PROMPT" :
"_PROMPT2") == LUA_TNIL)
462 return (firstline ? LUA_PROMPT : LUA_PROMPT2);
464 const char *p = luaL_tolstring(L, -1, NULL);
471#define EOFMARK "<eof>"
472#define marklen (sizeof(EOFMARK)/sizeof(char) - 1)
480static int incomplete (
lua_State *L,
int status) {
481 if (status == LUA_ERRSYNTAX) {
483 const char *msg = lua_tolstring(L, -1, &lmsg);
484 if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
496static int pushline (
lua_State *L,
int firstline) {
497 char buffer[LUA_MAXINPUT];
500 const char *prmt = get_prompt(L, firstline);
501 int readstatus = lua_readline(L, b, prmt);
506 if (l > 0 && b[l-1] ==
'\n')
508 if (firstline && b[0] ==
'=')
509 lua_pushfstring(L,
"return %s", b + 1);
511 lua_pushlstring(L, b, l);
522 const char *line = lua_tostring(L, -1);
523 const char *retline = lua_pushfstring(L,
"return %s;", line);
524 int status = luaL_loadbuffer(L, retline, strlen(retline),
"=stdin");
525 if (status == LUA_OK) {
528 lua_saveline(L, line);
542 const char *line = lua_tolstring(L, 1, &len);
543 int status = luaL_loadbuffer(L, line, len,
"=stdin");
544 if (!incomplete(L, status) || !pushline(L, 0)) {
545 lua_saveline(L, line);
548 lua_pushliteral(L,
"\n");
566 if ((status = addreturn(L)) != LUA_OK)
567 status = multiline(L);
569 lua_assert(lua_gettop(L) == 1);
578 int n = lua_gettop(L);
580 luaL_checkstack(L, LUA_MINSTACK,
"too many results to print");
581 lua_getglobal(L,
"print");
583 if (lua_pcall(L, n, 0, 0) != LUA_OK)
584 l_message(progname, lua_pushfstring(L,
"error calling 'print' (%s)",
585 lua_tostring(L, -1)));
596 const char *oldprogname = progname;
599 while ((status = loadline(L)) != -1) {
600 if (status == LUA_OK)
601 status = docall(L, 0, LUA_MULTRET);
602 if (status == LUA_OK) l_print(L);
603 else report(L, status);
607 progname = oldprogname;
618 int argc = (int)lua_tointeger(L, 1);
619 char **argv = (
char **)lua_touserdata(L, 2);
621 int args = collectargs(argv, &script);
622 int optlim = (script > 0) ? script : argc;
623 luaL_checkversion(L);
624 if (args == has_error) {
625 print_usage(argv[script]);
631 lua_pushboolean(L, 1);
632 lua_setfield(L, LUA_REGISTRYINDEX,
"LUA_NOENV");
635 createargtable(L, argv, argc, script);
636 lua_gc(L, LUA_GCRESTART);
637 lua_gc(L, LUA_GCGEN, 0, 0);
638 if (!(args & has_E)) {
639 if (handle_luainit(L) != LUA_OK)
642 if (!runargs(L, argv, optlim))
645 if (handle_script(L, argv + script) != LUA_OK)
650 else if (script < 1 && !(args & (has_e | has_v))) {
651 if (lua_stdin_is_tty()) {
655 else dofile(L, NULL);
657 lua_pushboolean(L, 1);
662int main (
int argc,
char **argv) {
666 l_message(argv[0],
"cannot create state: not enough memory");
669 lua_gc(L, LUA_GCSTOP);
670 lua_pushcfunction(L, &pmain);
671 lua_pushinteger(L, argc);
672 lua_pushlightuserdata(L, argv);
673 status = lua_pcall(L, 2, 1, 0);
674 result = lua_toboolean(L, -1);
677 return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;