2 ** $Id: lua.c,v 1.122 2003/04/03 13:34:42 roberto Exp $
3 ** Lua stand-alone interpreter
4 ** See Copyright Notice in lua.h
22 ** generic extra include file
25 #include LUA_USERCONFIG
30 ** definition of `isatty'
32 #ifdef _POSIX_C_SOURCE
34 #define stdin_is_tty() isatty(0)
36 #define stdin_is_tty() 1 /* assume stdin is a tty */
51 #define PROGNAME "lua"
55 #define lua_userinit(L) openstdlibs(L)
60 #define LUA_EXTRALIBS /* empty */
64 static lua_State
*L
= NULL
;
66 static const char *progname
= PROGNAME
;
70 static const luaL_reg lualibs
[] = {
71 {"base", luaopen_base
},
72 {"table", luaopen_table
},
74 {"string", luaopen_string
},
75 {"math", luaopen_math
},
76 {"debug", luaopen_debug
},
77 {"loadlib", luaopen_loadlib
},
78 /* add your libraries here */
85 static void lstop (lua_State
*l
, lua_Debug
*ar
) {
86 (void)ar
; /* unused arg. */
87 lua_sethook(l
, NULL
, 0, 0);
88 luaL_error(l
, "interrupted!");
92 static void laction (int i
) {
93 signal(i
, SIG_DFL
); /* if another SIGINT happens before lstop,
94 terminate process (default action) */
95 lua_sethook(L
, lstop
, LUA_MASKCALL
| LUA_MASKRET
| LUA_MASKCOUNT
, 1);
99 static void print_usage (void) {
101 "usage: %s [options] [script [args]].\n"
102 "Available options are:\n"
103 " - execute stdin as a file\n"
104 " -e stat execute string `stat'\n"
105 " -i enter interactive mode after executing `script'\n"
106 " -l name load and run library `name'\n"
107 " -v show version information\n"
108 " -- stop handling options\n" ,
113 static void l_message (const char *pname
, const char *msg
) {
114 if (pname
) fprintf(stderr
, "%s: ", pname
);
115 fprintf(stderr
, "%s\n", msg
);
119 static int report (int status
) {
122 msg
= lua_tostring(L
, -1);
123 if (msg
== NULL
) msg
= "(error with no message)";
124 l_message(progname
, msg
);
131 static int lcall (int narg
, int clear
) {
133 int base
= lua_gettop(L
) - narg
; /* function index */
134 lua_pushliteral(L
, "_TRACEBACK");
135 lua_rawget(L
, LUA_GLOBALSINDEX
); /* get traceback function */
136 lua_insert(L
, base
); /* put it under chunk and args */
137 signal(SIGINT
, laction
);
138 status
= lua_pcall(L
, narg
, (clear
? 0 : LUA_MULTRET
), base
);
139 signal(SIGINT
, SIG_DFL
);
140 lua_remove(L
, base
); /* remove traceback function */
145 static void print_version (void) {
146 l_message(NULL
, LUA_VERSION
" " LUA_COPYRIGHT
);
150 static void getargs (char *argv
[], int n
) {
153 for (i
=0; argv
[i
]; i
++) {
154 lua_pushnumber(L
, i
- n
);
155 lua_pushstring(L
, argv
[i
]);
158 /* arg.n = maximum index in table `arg' */
159 lua_pushliteral(L
, "n");
160 lua_pushnumber(L
, i
-n
-1);
165 static int docall (int status
) {
166 if (status
== 0) status
= lcall(0, 1);
167 return report(status
);
171 static int file_input (const char *name
) {
172 return docall(luaL_loadfile(L
, name
));
176 static int dostring (const char *s
, const char *name
) {
177 return docall(luaL_loadbuffer(L
, s
, strlen(s
), name
));
181 static int load_file (const char *name
) {
182 lua_pushliteral(L
, "require");
183 lua_rawget(L
, LUA_GLOBALSINDEX
);
184 if (!lua_isfunction(L
, -1)) { /* no `require' defined? */
186 return file_input(name
);
189 lua_pushstring(L
, name
);
190 return report(lcall(1, 1));
196 ** this macro can be used by some `history' system to save lines
197 ** read in manual input
200 #define lua_saveline(L,line) /* empty */
205 ** this macro defines a function to show the prompt and reads the
206 ** next line for manual input
209 #define lua_readline(L,prompt) readline(L,prompt)
211 /* maximum length of an input line */
217 static int readline (lua_State
*l
, const char *prompt
) {
218 static char buffer
[MAXINPUT
];
220 fputs(prompt
, stdout
);
223 if (fgets(buffer
, sizeof(buffer
), stdin
) == NULL
)
224 return 0; /* read fails */
226 lua_pushstring(l
, buffer
);
234 static const char *get_prompt (int firstline
) {
235 const char *p
= NULL
;
236 lua_pushstring(L
, firstline
? "_PROMPT" : "_PROMPT2");
237 lua_rawget(L
, LUA_GLOBALSINDEX
);
238 p
= lua_tostring(L
, -1);
239 if (p
== NULL
) p
= (firstline
? PROMPT
: PROMPT2
);
240 lua_pop(L
, 1); /* remove global */
245 static int incomplete (int status
) {
246 if (status
== LUA_ERRSYNTAX
&&
247 strstr(lua_tostring(L
, -1), "near `<eof>'") != NULL
) {
256 static int load_string (void) {
259 if (lua_readline(L
, get_prompt(1)) == 0) /* no input? */
261 if (lua_tostring(L
, -1)[0] == '=') { /* line starts with `=' ? */
262 lua_pushfstring(L
, "return %s", lua_tostring(L
, -1)+1);/* `=' -> `return' */
263 lua_remove(L
, -2); /* remove original line */
265 for (;;) { /* repeat until gets a complete line */
266 status
= luaL_loadbuffer(L
, lua_tostring(L
, 1), lua_strlen(L
, 1), "=stdin");
267 if (!incomplete(status
)) break; /* cannot try to add lines? */
268 if (lua_readline(L
, get_prompt(0)) == 0) /* no more input? */
270 lua_concat(L
, lua_gettop(L
)); /* join lines */
272 lua_saveline(L
, lua_tostring(L
, 1));
273 lua_remove(L
, 1); /* remove line */
278 static void manual_input (void) {
280 const char *oldprogname
= progname
;
282 while ((status
= load_string()) != -1) {
283 if (status
== 0) status
= lcall(0, 0);
285 if (status
== 0 && lua_gettop(L
) > 0) { /* any result to print? */
286 lua_getglobal(L
, "print");
288 if (lua_pcall(L
, lua_gettop(L
)-1, 0, 0) != 0)
289 l_message(progname
, lua_pushfstring(L
, "error calling `print' (%s)",
290 lua_tostring(L
, -1)));
293 lua_settop(L
, 0); /* clear stack */
295 progname
= oldprogname
;
299 static int handle_argv (char *argv
[], int *interactive
) {
300 if (argv
[1] == NULL
) { /* no more arguments? */
301 if (stdin_is_tty()) {
306 file_input(NULL
); /* executes stdin as a file */
308 else { /* other arguments; loop over them */
310 for (i
= 1; argv
[i
] != NULL
; i
++) {
311 if (argv
[i
][0] != '-') break; /* not an option? */
312 switch (argv
[i
][1]) { /* option */
313 case '-': { /* `--' */
314 if (argv
[i
][2] != '\0') {
318 i
++; /* skip this argument */
319 goto endloop
; /* stop handling arguments */
322 file_input(NULL
); /* executes stdin as a file */
334 const char *chunk
= argv
[i
] + 2;
335 if (*chunk
== '\0') chunk
= argv
[++i
];
340 if (dostring(chunk
, "=<command line>") != 0)
345 const char *filename
= argv
[i
] + 2;
346 if (*filename
== '\0') filename
= argv
[++i
];
347 if (filename
== NULL
) {
351 if (load_file(filename
))
352 return 1; /* stop if file fails */
356 l_message(progname
, "option `-c' is deprecated");
360 l_message(progname
, "option `-s' is deprecated");
369 if (argv
[i
] != NULL
) {
370 const char *filename
= argv
[i
];
371 getargs(argv
, i
); /* collect arguments */
372 lua_setglobal(L
, "arg");
373 return file_input(filename
); /* stop scanning arguments */
380 static void openstdlibs (lua_State
*l
) {
381 const luaL_reg
*lib
= lualibs
;
382 for (; lib
->func
; lib
++) {
383 lib
->func(l
); /* open library */
384 lua_settop(l
, 0); /* discard any results */
389 static int handle_luainit (void) {
390 const char *init
= getenv("LUA_INIT");
391 if (init
== NULL
) return 0; /* status OK */
392 else if (init
[0] == '@')
393 return file_input(init
+1);
395 return dostring(init
, "=LUA_INIT");
406 static int pmain (lua_State
*l
) {
407 struct Smain
*s
= (struct Smain
*)lua_touserdata(l
, 1);
410 if (s
->argv
[0] && s
->argv
[0][0]) progname
= s
->argv
[0];
412 lua_userinit(l
); /* open libraries */
413 status
= handle_luainit();
415 status
= handle_argv(s
->argv
, &interactive
);
416 if (status
== 0 && interactive
) manual_input();
423 int main (int argc
, char *argv
[]) {
426 lua_State
*l
= lua_open(); /* create state */
428 l_message(argv
[0], "cannot create state: not enough memory");
433 status
= lua_cpcall(l
, &pmain
, &s
);
436 return (status
|| s
.status
) ? EXIT_FAILURE
: EXIT_SUCCESS
;