Imported from ../lua-4.0.tar.gz.
[lua.git] / src / lua / lua.c
blob2da857e1cb02192dcb4ec10760660c373951d97b
1 /*
2 ** $Id: lua.c,v 1.55 2000/10/20 16:36:32 roberto Exp $
3 ** Lua stand-alone interpreter
4 ** See Copyright Notice in lua.h
5 */
8 #include <signal.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "lua.h"
15 #include "luadebug.h"
16 #include "lualib.h"
19 static lua_State *L = NULL;
22 #ifndef PROMPT
23 #define PROMPT "> "
24 #endif
26 #ifdef _POSIX_SOURCE
27 #include <unistd.h>
28 #else
29 static int isatty (int x) { return x==0; } /* assume stdin is a tty */
30 #endif
34 ** global options
36 struct Options {
37 int toclose;
38 int stacksize;
42 typedef void (*handler)(int); /* type for signal actions */
44 static void laction (int i);
47 static lua_Hook old_linehook = NULL;
48 static lua_Hook old_callhook = NULL;
51 static void userinit (void) {
52 lua_baselibopen(L);
53 lua_iolibopen(L);
54 lua_strlibopen(L);
55 lua_mathlibopen(L);
56 lua_dblibopen(L);
57 /* add your libraries here */
61 static handler lreset (void) {
62 return signal(SIGINT, laction);
66 static void lstop (void) {
67 lua_setlinehook(L, old_linehook);
68 lua_setcallhook(L, old_callhook);
69 lreset();
70 lua_error(L, "interrupted!");
74 static void laction (int i) {
75 (void)i; /* to avoid warnings */
76 signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
77 terminate process (default action) */
78 old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
79 old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
83 static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
84 int res;
85 handler h = lreset();
86 int top = lua_gettop(L);
87 res = f(L, name); /* dostring | dofile */
88 lua_settop(L, top); /* remove eventual results */
89 signal(SIGINT, h); /* restore old action */
90 /* Lua gives no message in such cases, so lua.c provides one */
91 if (res == LUA_ERRMEM) {
92 fprintf(stderr, "lua: memory allocation error\n");
94 else if (res == LUA_ERRERR)
95 fprintf(stderr, "lua: error in error message\n");
96 return res;
100 static void print_message (void) {
101 fprintf(stderr,
102 "usage: lua [options]. Available options are:\n"
103 " - execute stdin as a file\n"
104 " -c close Lua when exiting\n"
105 " -e stat execute string `stat'\n"
106 " -f name execute file `name' with remaining arguments in table `arg'\n"
107 " -i enter interactive mode with prompt\n"
108 " -q enter interactive mode without prompt\n"
109 " -sNUM set stack size to NUM (must be the first option)\n"
110 " -v print version information\n"
111 " a=b set global `a' to string `b'\n"
112 " name execute file `name'\n"
117 static void print_version (void) {
118 printf("%.80s %.80s\n", LUA_VERSION, LUA_COPYRIGHT);
122 static void assign (char *arg) {
123 char *eq = strchr(arg, '=');
124 *eq = '\0'; /* spilt `arg' in two strings (name & value) */
125 lua_pushstring(L, eq+1);
126 lua_setglobal(L, arg);
130 static void getargs (char *argv[]) {
131 int i;
132 lua_newtable(L);
133 for (i=0; argv[i]; i++) {
134 /* arg[i] = argv[i] */
135 lua_pushnumber(L, i);
136 lua_pushstring(L, argv[i]);
137 lua_settable(L, -3);
139 /* arg.n = maximum index in table `arg' */
140 lua_pushstring(L, "n");
141 lua_pushnumber(L, i-1);
142 lua_settable(L, -3);
146 static int l_getargs (lua_State *l) {
147 char **argv = (char **)lua_touserdata(l, -1);
148 getargs(argv);
149 return 1;
153 static int file_input (const char *argv) {
154 int result = ldo(lua_dofile, argv);
155 if (result) {
156 if (result == LUA_ERRFILE) {
157 fprintf(stderr, "lua: cannot execute file ");
158 perror(argv);
160 return EXIT_FAILURE;
162 else
163 return EXIT_SUCCESS;
167 /* maximum length of an input string */
168 #ifndef MAXINPUT
169 #define MAXINPUT BUFSIZ
170 #endif
172 static void manual_input (int version, int prompt) {
173 int cont = 1;
174 if (version) print_version();
175 while (cont) {
176 char buffer[MAXINPUT];
177 int i = 0;
178 if (prompt) {
179 const char *s;
180 lua_getglobal(L, "_PROMPT");
181 s = lua_tostring(L, -1);
182 if (!s) s = PROMPT;
183 fputs(s, stdout);
184 lua_pop(L, 1); /* remove global */
186 for(;;) {
187 int c = getchar();
188 if (c == EOF) {
189 cont = 0;
190 break;
192 else if (c == '\n') {
193 if (i>0 && buffer[i-1] == '\\')
194 buffer[i-1] = '\n';
195 else break;
197 else if (i >= MAXINPUT-1) {
198 fprintf(stderr, "lua: input line too long\n");
199 break;
201 else buffer[i++] = (char)c;
203 buffer[i] = '\0';
204 ldo(lua_dostring, buffer);
205 lua_settop(L, 0); /* remove eventual results */
207 printf("\n");
211 static int handle_argv (char *argv[], struct Options *opt) {
212 if (opt->stacksize > 0) argv++; /* skip option `-s' (if present) */
213 if (*argv == NULL) { /* no more arguments? */
214 if (isatty(0)) {
215 manual_input(1, 1);
217 else
218 ldo(lua_dofile, NULL); /* executes stdin as a file */
220 else { /* other arguments; loop over them */
221 int i;
222 for (i = 0; argv[i] != NULL; i++) {
223 if (argv[i][0] != '-') { /* not an option? */
224 if (strchr(argv[i], '='))
225 assign(argv[i]);
226 else
227 if (file_input(argv[i]) != EXIT_SUCCESS)
228 return EXIT_FAILURE; /* stop if file fails */
230 else switch (argv[i][1]) { /* option */
231 case 0: {
232 ldo(lua_dofile, NULL); /* executes stdin as a file */
233 break;
235 case 'i': {
236 manual_input(0, 1);
237 break;
239 case 'q': {
240 manual_input(0, 0);
241 break;
243 case 'c': {
244 opt->toclose = 1;
245 break;
247 case 'v': {
248 print_version();
249 break;
251 case 'e': {
252 i++;
253 if (argv[i] == NULL) {
254 print_message();
255 return EXIT_FAILURE;
257 if (ldo(lua_dostring, argv[i]) != 0) {
258 fprintf(stderr, "lua: error running argument `%.99s'\n", argv[i]);
259 return EXIT_FAILURE;
261 break;
263 case 'f': {
264 i++;
265 if (argv[i] == NULL) {
266 print_message();
267 return EXIT_FAILURE;
269 getargs(argv+i); /* collect remaining arguments */
270 lua_setglobal(L, "arg");
271 return file_input(argv[i]); /* stop scanning arguments */
273 case 's': {
274 fprintf(stderr, "lua: stack size (`-s') must be the first option\n");
275 return EXIT_FAILURE;
277 default: {
278 print_message();
279 return EXIT_FAILURE;
284 return EXIT_SUCCESS;
288 static void getstacksize (int argc, char *argv[], struct Options *opt) {
289 if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 's') {
290 int stacksize = atoi(&argv[1][2]);
291 if (stacksize <= 0) {
292 fprintf(stderr, "lua: invalid stack size ('%.20s')\n", &argv[1][2]);
293 exit(EXIT_FAILURE);
295 opt->stacksize = stacksize;
297 else
298 opt->stacksize = 0; /* no stack size */
302 static void register_getargs (char *argv[]) {
303 lua_pushuserdata(L, argv);
304 lua_pushcclosure(L, l_getargs, 1);
305 lua_setglobal(L, "getargs");
309 int main (int argc, char *argv[]) {
310 struct Options opt;
311 int status;
312 opt.toclose = 0;
313 getstacksize(argc, argv, &opt); /* handle option `-s' */
314 L = lua_open(opt.stacksize); /* create state */
315 userinit(); /* open libraries */
316 register_getargs(argv); /* create `getargs' function */
317 status = handle_argv(argv+1, &opt);
318 if (opt.toclose)
319 lua_close(L);
320 return status;