diff options
| -rw-r--r-- | lua.c | 85 |
1 files changed, 47 insertions, 38 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.94 2002/06/26 16:37:39 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.95 2002/07/09 18:19:44 roberto Exp roberto $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -74,14 +74,14 @@ static void print_usage (void) { | |||
| 74 | " -i enter interactive mode after executing `prog'\n" | 74 | " -i enter interactive mode after executing `prog'\n" |
| 75 | " -l name execute file `name'\n" | 75 | " -l name execute file `name'\n" |
| 76 | " -v print version information\n" | 76 | " -v print version information\n" |
| 77 | " -- stop handling arguments\n" , | 77 | " -- stop handling options\n" , |
| 78 | progname); | 78 | progname); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | 81 | ||
| 82 | static void l_message (const char *pname, const char *msg) { | 82 | static void l_message (const char *pname, const char *msg) { |
| 83 | if (pname) fprintf(stderr, "%s: ", pname); | 83 | if (pname) fprintf(stderr, "%s: ", pname); |
| 84 | fprintf(stderr, "%s\n", msg); | 84 | fprintf(stderr, "%s", msg); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | 87 | ||
| @@ -119,13 +119,13 @@ static int lcall (int clear) { | |||
| 119 | 119 | ||
| 120 | static int l_panic (lua_State *l) { | 120 | static int l_panic (lua_State *l) { |
| 121 | (void)l; | 121 | (void)l; |
| 122 | l_message(progname, "unable to recover; exiting"); | 122 | l_message(progname, "unable to recover; exiting\n"); |
| 123 | return 0; | 123 | return 0; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | 126 | ||
| 127 | static void print_version (void) { | 127 | static void print_version (void) { |
| 128 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT); | 128 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT "\n"); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | 131 | ||
| @@ -161,14 +161,13 @@ static int dostring (const char *s, const char *name) { | |||
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | 163 | ||
| 164 | #ifdef USE_READLINE | 164 | #ifndef save_line |
| 165 | #include <readline/readline.h> | 165 | #define save_line(b) /* empty */ |
| 166 | #include <readline/history.h> | 166 | #endif |
| 167 | #define save_line(b) if (strcspn(b, " \t\n") != 0) add_history(b) | 167 | |
| 168 | #define push_line(b) if (incomplete) lua_pushstring(L, "\n"); lua_pushstring(L, b); free(b) | 168 | |
| 169 | #else | 169 | #ifndef read_line |
| 170 | #define save_line(b) | 170 | #define read_line(p) readline(p) |
| 171 | #define push_line(b) lua_pushstring(L, b) | ||
| 172 | 171 | ||
| 173 | /* maximum length of an input line */ | 172 | /* maximum length of an input line */ |
| 174 | #ifndef MAXINPUT | 173 | #ifndef MAXINPUT |
| @@ -176,14 +175,23 @@ static int dostring (const char *s, const char *name) { | |||
| 176 | #endif | 175 | #endif |
| 177 | 176 | ||
| 178 | 177 | ||
| 179 | static char *readline (const char *prompt) { | 178 | static int readline (const char *prompt) { |
| 180 | static char buffer[MAXINPUT]; | 179 | static char buffer[MAXINPUT]; |
| 181 | if (prompt) { | 180 | if (prompt) { |
| 182 | fputs(prompt, stdout); | 181 | fputs(prompt, stdout); |
| 183 | fflush(stdout); | 182 | fflush(stdout); |
| 184 | } | 183 | } |
| 185 | return fgets(buffer, sizeof(buffer), stdin); | 184 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) |
| 185 | return 0; /* read fails */ | ||
| 186 | else { | ||
| 187 | size_t l = strlen(buffer); | ||
| 188 | if (l > 0 && buffer[l-1] == '\n') | ||
| 189 | buffer[l-1] = '\0'; /* remove eventual `\n' */ | ||
| 190 | lua_pushstring(L, buffer); | ||
| 191 | return 1; | ||
| 192 | } | ||
| 186 | } | 193 | } |
| 194 | |||
| 187 | #endif | 195 | #endif |
| 188 | 196 | ||
| 189 | 197 | ||
| @@ -209,35 +217,33 @@ static int incomplete (int status) { | |||
| 209 | 217 | ||
| 210 | 218 | ||
| 211 | static int load_string (void) { | 219 | static int load_string (void) { |
| 212 | int firstline = 1; | ||
| 213 | int status; | 220 | int status; |
| 221 | int moreinput = 1; | ||
| 214 | lua_settop(L, 0); | 222 | lua_settop(L, 0); |
| 215 | do { /* repeat until gets a complete line */ | 223 | if (read_line(get_prompt(1)) == 0) /* no input? */ |
| 216 | char *buffer = readline(get_prompt(firstline)); | 224 | return -1; |
| 217 | if (buffer == NULL) { /* input end? */ | 225 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ |
| 218 | lua_settop(L, 0); | 226 | lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ |
| 219 | return -1; /* input end */ | 227 | lua_remove(L, -2); /* remove original line */ |
| 220 | } | 228 | } |
| 221 | if (firstline && buffer[0] == '=') { | 229 | for (;;) { /* repeat until gets a complete line */ |
| 222 | buffer[0] = ' '; | ||
| 223 | lua_pushstring(L, "return"); | ||
| 224 | } | ||
| 225 | firstline = 0; | ||
| 226 | push_line(buffer); | ||
| 227 | lua_concat(L, lua_gettop(L)); | ||
| 228 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); | 230 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); |
| 229 | } while (incomplete(status)); /* repeat loop to get rest of `line' */ | 231 | if (!moreinput || !incomplete(status)) /* cannot try to add lines? */ |
| 232 | break; | ||
| 233 | lua_pushliteral(L, "\n"); /* no; add line separator */ | ||
| 234 | moreinput = read_line(get_prompt(0)); | ||
| 235 | lua_concat(L, lua_gettop(L)); /* join lines and line separator */ | ||
| 236 | } | ||
| 230 | save_line(lua_tostring(L, 1)); | 237 | save_line(lua_tostring(L, 1)); |
| 231 | lua_remove(L, 1); | 238 | lua_remove(L, 1); /* remove line */ |
| 232 | return status; | 239 | return status; |
| 233 | } | 240 | } |
| 234 | 241 | ||
| 235 | 242 | ||
| 236 | static void manual_input (int version) { | 243 | static void manual_input (void) { |
| 237 | int status; | 244 | int status; |
| 238 | const char *oldprogname = progname; | 245 | const char *oldprogname = progname; |
| 239 | progname = NULL; | 246 | progname = NULL; |
| 240 | if (version) print_version(); | ||
| 241 | while ((status = load_string()) != -1) { | 247 | while ((status = load_string()) != -1) { |
| 242 | if (status == 0) status = lcall(0); | 248 | if (status == 0) status = lcall(0); |
| 243 | report(status, 0); | 249 | report(status, 0); |
| @@ -247,6 +253,7 @@ static void manual_input (int version) { | |||
| 247 | lua_pcall(L, lua_gettop(L)-1, 0); | 253 | lua_pcall(L, lua_gettop(L)-1, 0); |
| 248 | } | 254 | } |
| 249 | } | 255 | } |
| 256 | lua_settop(L, 0); /* clear stack */ | ||
| 250 | fputs("\n", stdout); | 257 | fputs("\n", stdout); |
| 251 | progname = oldprogname; | 258 | progname = oldprogname; |
| 252 | } | 259 | } |
| @@ -255,7 +262,8 @@ static void manual_input (int version) { | |||
| 255 | static int handle_argv (char *argv[], int *interactive) { | 262 | static int handle_argv (char *argv[], int *interactive) { |
| 256 | if (argv[1] == NULL) { /* no more arguments? */ | 263 | if (argv[1] == NULL) { /* no more arguments? */ |
| 257 | if (isatty(0)) { | 264 | if (isatty(0)) { |
| 258 | manual_input(1); | 265 | print_version(); |
| 266 | manual_input(); | ||
| 259 | } | 267 | } |
| 260 | else | 268 | else |
| 261 | file_input(NULL); /* executes stdin as a file */ | 269 | file_input(NULL); /* executes stdin as a file */ |
| @@ -304,11 +312,11 @@ static int handle_argv (char *argv[], int *interactive) { | |||
| 304 | break; | 312 | break; |
| 305 | } | 313 | } |
| 306 | case 'c': { | 314 | case 'c': { |
| 307 | l_message(progname, "option `-c' is deprecated"); | 315 | l_message(progname, "option `-c' is deprecated\n"); |
| 308 | break; | 316 | break; |
| 309 | } | 317 | } |
| 310 | case 's': { | 318 | case 's': { |
| 311 | l_message(progname, "option `-s' is deprecated"); | 319 | l_message(progname, "option `-s' is deprecated\n"); |
| 312 | break; | 320 | break; |
| 313 | } | 321 | } |
| 314 | default: { | 322 | default: { |
| @@ -335,6 +343,7 @@ static int openstdlibs (lua_State *l) { | |||
| 335 | lua_strlibopen(l) + | 343 | lua_strlibopen(l) + |
| 336 | lua_mathlibopen(l) + | 344 | lua_mathlibopen(l) + |
| 337 | lua_dblibopen(l) + | 345 | lua_dblibopen(l) + |
| 346 | /* add your libraries here */ | ||
| 338 | 0; | 347 | 0; |
| 339 | } | 348 | } |
| 340 | 349 | ||
| @@ -356,11 +365,11 @@ int main (int argc, char *argv[]) { | |||
| 356 | progname = argv[0]; | 365 | progname = argv[0]; |
| 357 | L = lua_open(); /* create state */ | 366 | L = lua_open(); /* create state */ |
| 358 | lua_atpanic(L, l_panic); | 367 | lua_atpanic(L, l_panic); |
| 359 | lua_pop(L, LUA_USERINIT(L)); /* open libraries, dischard any results */ | 368 | lua_pop(L, LUA_USERINIT(L)); /* open libraries, discard any results */ |
| 360 | status = handle_luainit(); | 369 | status = handle_luainit(); |
| 361 | if (status != 0) return status; | 370 | if (status != 0) return status; |
| 362 | status = handle_argv(argv, &interactive); | 371 | status = handle_argv(argv, &interactive); |
| 363 | if (status == 0 && interactive) manual_input(0); | 372 | if (status == 0 && interactive) manual_input(); |
| 364 | lua_close(L); | 373 | lua_close(L); |
| 365 | return status; | 374 | return status; |
| 366 | } | 375 | } |
