116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: lua.c,v 1.206.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Lua stand-alone interpreter 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm*/ 616a5fed65808adf648004b34f98718301d718fa2darylm 716a5fed65808adf648004b34f98718301d718fa2darylm 816a5fed65808adf648004b34f98718301d718fa2darylm#include <signal.h> 916a5fed65808adf648004b34f98718301d718fa2darylm#include <stdio.h> 1016a5fed65808adf648004b34f98718301d718fa2darylm#include <stdlib.h> 1116a5fed65808adf648004b34f98718301d718fa2darylm#include <string.h> 1216a5fed65808adf648004b34f98718301d718fa2darylm 1316a5fed65808adf648004b34f98718301d718fa2darylm#define lua_c 1416a5fed65808adf648004b34f98718301d718fa2darylm 1516a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 1616a5fed65808adf648004b34f98718301d718fa2darylm 1716a5fed65808adf648004b34f98718301d718fa2darylm#include "lauxlib.h" 1816a5fed65808adf648004b34f98718301d718fa2darylm#include "lualib.h" 1916a5fed65808adf648004b34f98718301d718fa2darylm 2016a5fed65808adf648004b34f98718301d718fa2darylm 2116a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_PROMPT) 2216a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PROMPT "> " 2316a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PROMPT2 ">> " 2416a5fed65808adf648004b34f98718301d718fa2darylm#endif 2516a5fed65808adf648004b34f98718301d718fa2darylm 2616a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_PROGNAME) 2716a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PROGNAME "lua" 2816a5fed65808adf648004b34f98718301d718fa2darylm#endif 2916a5fed65808adf648004b34f98718301d718fa2darylm 3016a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_MAXINPUT) 3116a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_MAXINPUT 512 3216a5fed65808adf648004b34f98718301d718fa2darylm#endif 3316a5fed65808adf648004b34f98718301d718fa2darylm 3416a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_INIT) 3516a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_INIT "LUA_INIT" 3616a5fed65808adf648004b34f98718301d718fa2darylm#endif 3716a5fed65808adf648004b34f98718301d718fa2darylm 3816a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_INITVERSION \ 3916a5fed65808adf648004b34f98718301d718fa2darylm LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 4016a5fed65808adf648004b34f98718301d718fa2darylm 4116a5fed65808adf648004b34f98718301d718fa2darylm 4216a5fed65808adf648004b34f98718301d718fa2darylm/* 4316a5fed65808adf648004b34f98718301d718fa2darylm** lua_stdin_is_tty detects whether the standard input is a 'tty' (that 4416a5fed65808adf648004b34f98718301d718fa2darylm** is, whether we're running lua interactively). 4516a5fed65808adf648004b34f98718301d718fa2darylm*/ 4616a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_USE_ISATTY) 4716a5fed65808adf648004b34f98718301d718fa2darylm#include <unistd.h> 4816a5fed65808adf648004b34f98718301d718fa2darylm#define lua_stdin_is_tty() isatty(0) 4916a5fed65808adf648004b34f98718301d718fa2darylm#elif defined(LUA_WIN) 5016a5fed65808adf648004b34f98718301d718fa2darylm#include <io.h> 5116a5fed65808adf648004b34f98718301d718fa2darylm#include <stdio.h> 5216a5fed65808adf648004b34f98718301d718fa2darylm#define lua_stdin_is_tty() _isatty(_fileno(stdin)) 5316a5fed65808adf648004b34f98718301d718fa2darylm#else 5416a5fed65808adf648004b34f98718301d718fa2darylm#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ 5516a5fed65808adf648004b34f98718301d718fa2darylm#endif 5616a5fed65808adf648004b34f98718301d718fa2darylm 5716a5fed65808adf648004b34f98718301d718fa2darylm 5816a5fed65808adf648004b34f98718301d718fa2darylm/* 5916a5fed65808adf648004b34f98718301d718fa2darylm** lua_readline defines how to show a prompt and then read a line from 6016a5fed65808adf648004b34f98718301d718fa2darylm** the standard input. 6116a5fed65808adf648004b34f98718301d718fa2darylm** lua_saveline defines how to "save" a read line in a "history". 6216a5fed65808adf648004b34f98718301d718fa2darylm** lua_freeline defines how to free a line read by lua_readline. 6316a5fed65808adf648004b34f98718301d718fa2darylm*/ 6416a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_USE_READLINE) 6516a5fed65808adf648004b34f98718301d718fa2darylm 6616a5fed65808adf648004b34f98718301d718fa2darylm#include <stdio.h> 6716a5fed65808adf648004b34f98718301d718fa2darylm#include <readline/readline.h> 6816a5fed65808adf648004b34f98718301d718fa2darylm#include <readline/history.h> 6916a5fed65808adf648004b34f98718301d718fa2darylm#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) 7016a5fed65808adf648004b34f98718301d718fa2darylm#define lua_saveline(L,idx) \ 7116a5fed65808adf648004b34f98718301d718fa2darylm if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \ 7216a5fed65808adf648004b34f98718301d718fa2darylm add_history(lua_tostring(L, idx)); /* add it to history */ 7316a5fed65808adf648004b34f98718301d718fa2darylm#define lua_freeline(L,b) ((void)L, free(b)) 7416a5fed65808adf648004b34f98718301d718fa2darylm 7516a5fed65808adf648004b34f98718301d718fa2darylm#elif !defined(lua_readline) 7616a5fed65808adf648004b34f98718301d718fa2darylm 7716a5fed65808adf648004b34f98718301d718fa2darylm#define lua_readline(L,b,p) \ 7816a5fed65808adf648004b34f98718301d718fa2darylm ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ 7916a5fed65808adf648004b34f98718301d718fa2darylm fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ 8016a5fed65808adf648004b34f98718301d718fa2darylm#define lua_saveline(L,idx) { (void)L; (void)idx; } 8116a5fed65808adf648004b34f98718301d718fa2darylm#define lua_freeline(L,b) { (void)L; (void)b; } 8216a5fed65808adf648004b34f98718301d718fa2darylm 8316a5fed65808adf648004b34f98718301d718fa2darylm#endif 8416a5fed65808adf648004b34f98718301d718fa2darylm 8516a5fed65808adf648004b34f98718301d718fa2darylm 8616a5fed65808adf648004b34f98718301d718fa2darylm 8716a5fed65808adf648004b34f98718301d718fa2darylm 8816a5fed65808adf648004b34f98718301d718fa2darylmstatic lua_State *globalL = NULL; 8916a5fed65808adf648004b34f98718301d718fa2darylm 9016a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *progname = LUA_PROGNAME; 9116a5fed65808adf648004b34f98718301d718fa2darylm 9216a5fed65808adf648004b34f98718301d718fa2darylm 9316a5fed65808adf648004b34f98718301d718fa2darylm 9416a5fed65808adf648004b34f98718301d718fa2darylmstatic void lstop (lua_State *L, lua_Debug *ar) { 9516a5fed65808adf648004b34f98718301d718fa2darylm (void)ar; /* unused arg. */ 9616a5fed65808adf648004b34f98718301d718fa2darylm lua_sethook(L, NULL, 0, 0); 9716a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, "interrupted!"); 9816a5fed65808adf648004b34f98718301d718fa2darylm} 9916a5fed65808adf648004b34f98718301d718fa2darylm 10016a5fed65808adf648004b34f98718301d718fa2darylm 10116a5fed65808adf648004b34f98718301d718fa2darylmstatic void laction (int i) { 10216a5fed65808adf648004b34f98718301d718fa2darylm signal(i, SIG_DFL); /* if another SIGINT happens before lstop, 10316a5fed65808adf648004b34f98718301d718fa2darylm terminate process (default action) */ 10416a5fed65808adf648004b34f98718301d718fa2darylm lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); 10516a5fed65808adf648004b34f98718301d718fa2darylm} 10616a5fed65808adf648004b34f98718301d718fa2darylm 10716a5fed65808adf648004b34f98718301d718fa2darylm 10816a5fed65808adf648004b34f98718301d718fa2darylmstatic void print_usage (const char *badoption) { 10916a5fed65808adf648004b34f98718301d718fa2darylm luai_writestringerror("%s: ", progname); 11016a5fed65808adf648004b34f98718301d718fa2darylm if (badoption[1] == 'e' || badoption[1] == 'l') 11116a5fed65808adf648004b34f98718301d718fa2darylm luai_writestringerror("'%s' needs argument\n", badoption); 11216a5fed65808adf648004b34f98718301d718fa2darylm else 11316a5fed65808adf648004b34f98718301d718fa2darylm luai_writestringerror("unrecognized option '%s'\n", badoption); 11416a5fed65808adf648004b34f98718301d718fa2darylm luai_writestringerror( 11516a5fed65808adf648004b34f98718301d718fa2darylm "usage: %s [options] [script [args]]\n" 11616a5fed65808adf648004b34f98718301d718fa2darylm "Available options are:\n" 11716a5fed65808adf648004b34f98718301d718fa2darylm " -e stat execute string " LUA_QL("stat") "\n" 11816a5fed65808adf648004b34f98718301d718fa2darylm " -i enter interactive mode after executing " LUA_QL("script") "\n" 11916a5fed65808adf648004b34f98718301d718fa2darylm " -l name require library " LUA_QL("name") "\n" 12016a5fed65808adf648004b34f98718301d718fa2darylm " -v show version information\n" 12116a5fed65808adf648004b34f98718301d718fa2darylm " -E ignore environment variables\n" 12216a5fed65808adf648004b34f98718301d718fa2darylm " -- stop handling options\n" 12316a5fed65808adf648004b34f98718301d718fa2darylm " - stop handling options and execute stdin\n" 12416a5fed65808adf648004b34f98718301d718fa2darylm , 12516a5fed65808adf648004b34f98718301d718fa2darylm progname); 12616a5fed65808adf648004b34f98718301d718fa2darylm} 12716a5fed65808adf648004b34f98718301d718fa2darylm 12816a5fed65808adf648004b34f98718301d718fa2darylm 12916a5fed65808adf648004b34f98718301d718fa2darylmstatic void l_message (const char *pname, const char *msg) { 13016a5fed65808adf648004b34f98718301d718fa2darylm if (pname) luai_writestringerror("%s: ", pname); 13116a5fed65808adf648004b34f98718301d718fa2darylm luai_writestringerror("%s\n", msg); 13216a5fed65808adf648004b34f98718301d718fa2darylm} 13316a5fed65808adf648004b34f98718301d718fa2darylm 13416a5fed65808adf648004b34f98718301d718fa2darylm 13516a5fed65808adf648004b34f98718301d718fa2darylmstatic int report (lua_State *L, int status) { 13616a5fed65808adf648004b34f98718301d718fa2darylm if (status != LUA_OK && !lua_isnil(L, -1)) { 13716a5fed65808adf648004b34f98718301d718fa2darylm const char *msg = lua_tostring(L, -1); 13816a5fed65808adf648004b34f98718301d718fa2darylm if (msg == NULL) msg = "(error object is not a string)"; 13916a5fed65808adf648004b34f98718301d718fa2darylm l_message(progname, msg); 14016a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); 14116a5fed65808adf648004b34f98718301d718fa2darylm /* force a complete garbage collection in case of errors */ 14216a5fed65808adf648004b34f98718301d718fa2darylm lua_gc(L, LUA_GCCOLLECT, 0); 14316a5fed65808adf648004b34f98718301d718fa2darylm } 14416a5fed65808adf648004b34f98718301d718fa2darylm return status; 14516a5fed65808adf648004b34f98718301d718fa2darylm} 14616a5fed65808adf648004b34f98718301d718fa2darylm 14716a5fed65808adf648004b34f98718301d718fa2darylm 14816a5fed65808adf648004b34f98718301d718fa2darylm/* the next function is called unprotected, so it must avoid errors */ 14916a5fed65808adf648004b34f98718301d718fa2darylmstatic void finalreport (lua_State *L, int status) { 15016a5fed65808adf648004b34f98718301d718fa2darylm if (status != LUA_OK) { 15116a5fed65808adf648004b34f98718301d718fa2darylm const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) 15216a5fed65808adf648004b34f98718301d718fa2darylm : NULL; 15316a5fed65808adf648004b34f98718301d718fa2darylm if (msg == NULL) msg = "(error object is not a string)"; 15416a5fed65808adf648004b34f98718301d718fa2darylm l_message(progname, msg); 15516a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); 15616a5fed65808adf648004b34f98718301d718fa2darylm } 15716a5fed65808adf648004b34f98718301d718fa2darylm} 15816a5fed65808adf648004b34f98718301d718fa2darylm 15916a5fed65808adf648004b34f98718301d718fa2darylm 16016a5fed65808adf648004b34f98718301d718fa2darylmstatic int traceback (lua_State *L) { 16116a5fed65808adf648004b34f98718301d718fa2darylm const char *msg = lua_tostring(L, 1); 16216a5fed65808adf648004b34f98718301d718fa2darylm if (msg) 16316a5fed65808adf648004b34f98718301d718fa2darylm luaL_traceback(L, L, msg, 1); 16416a5fed65808adf648004b34f98718301d718fa2darylm else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */ 16516a5fed65808adf648004b34f98718301d718fa2darylm if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ 16616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, "(no error message)"); 16716a5fed65808adf648004b34f98718301d718fa2darylm } 16816a5fed65808adf648004b34f98718301d718fa2darylm return 1; 16916a5fed65808adf648004b34f98718301d718fa2darylm} 17016a5fed65808adf648004b34f98718301d718fa2darylm 17116a5fed65808adf648004b34f98718301d718fa2darylm 17216a5fed65808adf648004b34f98718301d718fa2darylmstatic int docall (lua_State *L, int narg, int nres) { 17316a5fed65808adf648004b34f98718301d718fa2darylm int status; 17416a5fed65808adf648004b34f98718301d718fa2darylm int base = lua_gettop(L) - narg; /* function index */ 17516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcfunction(L, traceback); /* push traceback function */ 17616a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, base); /* put it under chunk and args */ 17716a5fed65808adf648004b34f98718301d718fa2darylm globalL = L; /* to be available to 'laction' */ 17816a5fed65808adf648004b34f98718301d718fa2darylm signal(SIGINT, laction); 17916a5fed65808adf648004b34f98718301d718fa2darylm status = lua_pcall(L, narg, nres, base); 18016a5fed65808adf648004b34f98718301d718fa2darylm signal(SIGINT, SIG_DFL); 18116a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, base); /* remove traceback function */ 18216a5fed65808adf648004b34f98718301d718fa2darylm return status; 18316a5fed65808adf648004b34f98718301d718fa2darylm} 18416a5fed65808adf648004b34f98718301d718fa2darylm 18516a5fed65808adf648004b34f98718301d718fa2darylm 18616a5fed65808adf648004b34f98718301d718fa2darylmstatic void print_version (void) { 18716a5fed65808adf648004b34f98718301d718fa2darylm luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); 18816a5fed65808adf648004b34f98718301d718fa2darylm luai_writeline(); 18916a5fed65808adf648004b34f98718301d718fa2darylm} 19016a5fed65808adf648004b34f98718301d718fa2darylm 19116a5fed65808adf648004b34f98718301d718fa2darylm 19216a5fed65808adf648004b34f98718301d718fa2darylmstatic int getargs (lua_State *L, char **argv, int n) { 19316a5fed65808adf648004b34f98718301d718fa2darylm int narg; 19416a5fed65808adf648004b34f98718301d718fa2darylm int i; 19516a5fed65808adf648004b34f98718301d718fa2darylm int argc = 0; 19616a5fed65808adf648004b34f98718301d718fa2darylm while (argv[argc]) argc++; /* count total number of arguments */ 19716a5fed65808adf648004b34f98718301d718fa2darylm narg = argc - (n + 1); /* number of arguments to the script */ 19816a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkstack(L, narg + 3, "too many arguments to script"); 19916a5fed65808adf648004b34f98718301d718fa2darylm for (i=n+1; i < argc; i++) 20016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, argv[i]); 20116a5fed65808adf648004b34f98718301d718fa2darylm lua_createtable(L, narg, n + 1); 20216a5fed65808adf648004b34f98718301d718fa2darylm for (i=0; i < argc; i++) { 20316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, argv[i]); 20416a5fed65808adf648004b34f98718301d718fa2darylm lua_rawseti(L, -2, i - n); 20516a5fed65808adf648004b34f98718301d718fa2darylm } 20616a5fed65808adf648004b34f98718301d718fa2darylm return narg; 20716a5fed65808adf648004b34f98718301d718fa2darylm} 20816a5fed65808adf648004b34f98718301d718fa2darylm 20916a5fed65808adf648004b34f98718301d718fa2darylm 21016a5fed65808adf648004b34f98718301d718fa2darylmstatic int dofile (lua_State *L, const char *name) { 21116a5fed65808adf648004b34f98718301d718fa2darylm int status = luaL_loadfile(L, name); 21216a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) status = docall(L, 0, 0); 21316a5fed65808adf648004b34f98718301d718fa2darylm return report(L, status); 21416a5fed65808adf648004b34f98718301d718fa2darylm} 21516a5fed65808adf648004b34f98718301d718fa2darylm 21616a5fed65808adf648004b34f98718301d718fa2darylm 21716a5fed65808adf648004b34f98718301d718fa2darylmstatic int dostring (lua_State *L, const char *s, const char *name) { 21816a5fed65808adf648004b34f98718301d718fa2darylm int status = luaL_loadbuffer(L, s, strlen(s), name); 21916a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) status = docall(L, 0, 0); 22016a5fed65808adf648004b34f98718301d718fa2darylm return report(L, status); 22116a5fed65808adf648004b34f98718301d718fa2darylm} 22216a5fed65808adf648004b34f98718301d718fa2darylm 22316a5fed65808adf648004b34f98718301d718fa2darylm 22416a5fed65808adf648004b34f98718301d718fa2darylmstatic int dolibrary (lua_State *L, const char *name) { 22516a5fed65808adf648004b34f98718301d718fa2darylm int status; 22616a5fed65808adf648004b34f98718301d718fa2darylm lua_getglobal(L, "require"); 22716a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, name); 22816a5fed65808adf648004b34f98718301d718fa2darylm status = docall(L, 1, 1); /* call 'require(name)' */ 22916a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) 23016a5fed65808adf648004b34f98718301d718fa2darylm lua_setglobal(L, name); /* global[name] = require return */ 23116a5fed65808adf648004b34f98718301d718fa2darylm return report(L, status); 23216a5fed65808adf648004b34f98718301d718fa2darylm} 23316a5fed65808adf648004b34f98718301d718fa2darylm 23416a5fed65808adf648004b34f98718301d718fa2darylm 23516a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *get_prompt (lua_State *L, int firstline) { 23616a5fed65808adf648004b34f98718301d718fa2darylm const char *p; 23716a5fed65808adf648004b34f98718301d718fa2darylm lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); 23816a5fed65808adf648004b34f98718301d718fa2darylm p = lua_tostring(L, -1); 23916a5fed65808adf648004b34f98718301d718fa2darylm if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); 24016a5fed65808adf648004b34f98718301d718fa2darylm return p; 24116a5fed65808adf648004b34f98718301d718fa2darylm} 24216a5fed65808adf648004b34f98718301d718fa2darylm 24316a5fed65808adf648004b34f98718301d718fa2darylm/* mark in error messages for incomplete statements */ 24416a5fed65808adf648004b34f98718301d718fa2darylm#define EOFMARK "<eof>" 24516a5fed65808adf648004b34f98718301d718fa2darylm#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) 24616a5fed65808adf648004b34f98718301d718fa2darylm 24716a5fed65808adf648004b34f98718301d718fa2darylmstatic int incomplete (lua_State *L, int status) { 24816a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_ERRSYNTAX) { 24916a5fed65808adf648004b34f98718301d718fa2darylm size_t lmsg; 25016a5fed65808adf648004b34f98718301d718fa2darylm const char *msg = lua_tolstring(L, -1, &lmsg); 25116a5fed65808adf648004b34f98718301d718fa2darylm if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { 25216a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); 25316a5fed65808adf648004b34f98718301d718fa2darylm return 1; 25416a5fed65808adf648004b34f98718301d718fa2darylm } 25516a5fed65808adf648004b34f98718301d718fa2darylm } 25616a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* else... */ 25716a5fed65808adf648004b34f98718301d718fa2darylm} 25816a5fed65808adf648004b34f98718301d718fa2darylm 25916a5fed65808adf648004b34f98718301d718fa2darylm 26016a5fed65808adf648004b34f98718301d718fa2darylmstatic int pushline (lua_State *L, int firstline) { 26116a5fed65808adf648004b34f98718301d718fa2darylm char buffer[LUA_MAXINPUT]; 26216a5fed65808adf648004b34f98718301d718fa2darylm char *b = buffer; 26316a5fed65808adf648004b34f98718301d718fa2darylm size_t l; 26416a5fed65808adf648004b34f98718301d718fa2darylm const char *prmt = get_prompt(L, firstline); 26516a5fed65808adf648004b34f98718301d718fa2darylm int readstatus = lua_readline(L, b, prmt); 26616a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove result from 'get_prompt' */ 26716a5fed65808adf648004b34f98718301d718fa2darylm if (readstatus == 0) 26816a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* no input */ 26916a5fed65808adf648004b34f98718301d718fa2darylm l = strlen(b); 27016a5fed65808adf648004b34f98718301d718fa2darylm if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ 27116a5fed65808adf648004b34f98718301d718fa2darylm b[l-1] = '\0'; /* remove it */ 27216a5fed65808adf648004b34f98718301d718fa2darylm if (firstline && b[0] == '=') /* first line starts with `=' ? */ 27316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ 27416a5fed65808adf648004b34f98718301d718fa2darylm else 27516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, b); 27616a5fed65808adf648004b34f98718301d718fa2darylm lua_freeline(L, b); 27716a5fed65808adf648004b34f98718301d718fa2darylm return 1; 27816a5fed65808adf648004b34f98718301d718fa2darylm} 27916a5fed65808adf648004b34f98718301d718fa2darylm 28016a5fed65808adf648004b34f98718301d718fa2darylm 28116a5fed65808adf648004b34f98718301d718fa2darylmstatic int loadline (lua_State *L) { 28216a5fed65808adf648004b34f98718301d718fa2darylm int status; 28316a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 0); 28416a5fed65808adf648004b34f98718301d718fa2darylm if (!pushline(L, 1)) 28516a5fed65808adf648004b34f98718301d718fa2darylm return -1; /* no input */ 28616a5fed65808adf648004b34f98718301d718fa2darylm for (;;) { /* repeat until gets a complete line */ 28716a5fed65808adf648004b34f98718301d718fa2darylm size_t l; 28816a5fed65808adf648004b34f98718301d718fa2darylm const char *line = lua_tolstring(L, 1, &l); 28916a5fed65808adf648004b34f98718301d718fa2darylm status = luaL_loadbuffer(L, line, l, "=stdin"); 29016a5fed65808adf648004b34f98718301d718fa2darylm if (!incomplete(L, status)) break; /* cannot try to add lines? */ 29116a5fed65808adf648004b34f98718301d718fa2darylm if (!pushline(L, 0)) /* no more input? */ 29216a5fed65808adf648004b34f98718301d718fa2darylm return -1; 29316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, "\n"); /* add a new line... */ 29416a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -2); /* ...between the two lines */ 29516a5fed65808adf648004b34f98718301d718fa2darylm lua_concat(L, 3); /* join them */ 29616a5fed65808adf648004b34f98718301d718fa2darylm } 29716a5fed65808adf648004b34f98718301d718fa2darylm lua_saveline(L, 1); 29816a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, 1); /* remove line */ 29916a5fed65808adf648004b34f98718301d718fa2darylm return status; 30016a5fed65808adf648004b34f98718301d718fa2darylm} 30116a5fed65808adf648004b34f98718301d718fa2darylm 30216a5fed65808adf648004b34f98718301d718fa2darylm 30316a5fed65808adf648004b34f98718301d718fa2darylmstatic void dotty (lua_State *L) { 30416a5fed65808adf648004b34f98718301d718fa2darylm int status; 30516a5fed65808adf648004b34f98718301d718fa2darylm const char *oldprogname = progname; 30616a5fed65808adf648004b34f98718301d718fa2darylm progname = NULL; 30716a5fed65808adf648004b34f98718301d718fa2darylm while ((status = loadline(L)) != -1) { 30816a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); 30916a5fed65808adf648004b34f98718301d718fa2darylm report(L, status); 31016a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ 31116a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); 31216a5fed65808adf648004b34f98718301d718fa2darylm lua_getglobal(L, "print"); 31316a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, 1); 31416a5fed65808adf648004b34f98718301d718fa2darylm if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) 31516a5fed65808adf648004b34f98718301d718fa2darylm l_message(progname, lua_pushfstring(L, 31616a5fed65808adf648004b34f98718301d718fa2darylm "error calling " LUA_QL("print") " (%s)", 31716a5fed65808adf648004b34f98718301d718fa2darylm lua_tostring(L, -1))); 31816a5fed65808adf648004b34f98718301d718fa2darylm } 31916a5fed65808adf648004b34f98718301d718fa2darylm } 32016a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 0); /* clear stack */ 32116a5fed65808adf648004b34f98718301d718fa2darylm luai_writeline(); 32216a5fed65808adf648004b34f98718301d718fa2darylm progname = oldprogname; 32316a5fed65808adf648004b34f98718301d718fa2darylm} 32416a5fed65808adf648004b34f98718301d718fa2darylm 32516a5fed65808adf648004b34f98718301d718fa2darylm 32616a5fed65808adf648004b34f98718301d718fa2darylmstatic int handle_script (lua_State *L, char **argv, int n) { 32716a5fed65808adf648004b34f98718301d718fa2darylm int status; 32816a5fed65808adf648004b34f98718301d718fa2darylm const char *fname; 32916a5fed65808adf648004b34f98718301d718fa2darylm int narg = getargs(L, argv, n); /* collect arguments */ 33016a5fed65808adf648004b34f98718301d718fa2darylm lua_setglobal(L, "arg"); 33116a5fed65808adf648004b34f98718301d718fa2darylm fname = argv[n]; 33216a5fed65808adf648004b34f98718301d718fa2darylm if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) 33316a5fed65808adf648004b34f98718301d718fa2darylm fname = NULL; /* stdin */ 33416a5fed65808adf648004b34f98718301d718fa2darylm status = luaL_loadfile(L, fname); 33516a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -(narg+1)); 33616a5fed65808adf648004b34f98718301d718fa2darylm if (status == LUA_OK) 33716a5fed65808adf648004b34f98718301d718fa2darylm status = docall(L, narg, LUA_MULTRET); 33816a5fed65808adf648004b34f98718301d718fa2darylm else 33916a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, narg); 34016a5fed65808adf648004b34f98718301d718fa2darylm return report(L, status); 34116a5fed65808adf648004b34f98718301d718fa2darylm} 34216a5fed65808adf648004b34f98718301d718fa2darylm 34316a5fed65808adf648004b34f98718301d718fa2darylm 34416a5fed65808adf648004b34f98718301d718fa2darylm/* check that argument has no extra characters at the end */ 34516a5fed65808adf648004b34f98718301d718fa2darylm#define noextrachars(x) {if ((x)[2] != '\0') return -1;} 34616a5fed65808adf648004b34f98718301d718fa2darylm 34716a5fed65808adf648004b34f98718301d718fa2darylm 34816a5fed65808adf648004b34f98718301d718fa2darylm/* indices of various argument indicators in array args */ 34916a5fed65808adf648004b34f98718301d718fa2darylm#define has_i 0 /* -i */ 35016a5fed65808adf648004b34f98718301d718fa2darylm#define has_v 1 /* -v */ 35116a5fed65808adf648004b34f98718301d718fa2darylm#define has_e 2 /* -e */ 35216a5fed65808adf648004b34f98718301d718fa2darylm#define has_E 3 /* -E */ 35316a5fed65808adf648004b34f98718301d718fa2darylm 35416a5fed65808adf648004b34f98718301d718fa2darylm#define num_has 4 /* number of 'has_*' */ 35516a5fed65808adf648004b34f98718301d718fa2darylm 35616a5fed65808adf648004b34f98718301d718fa2darylm 35716a5fed65808adf648004b34f98718301d718fa2darylmstatic int collectargs (char **argv, int *args) { 35816a5fed65808adf648004b34f98718301d718fa2darylm int i; 35916a5fed65808adf648004b34f98718301d718fa2darylm for (i = 1; argv[i] != NULL; i++) { 36016a5fed65808adf648004b34f98718301d718fa2darylm if (argv[i][0] != '-') /* not an option? */ 36116a5fed65808adf648004b34f98718301d718fa2darylm return i; 36216a5fed65808adf648004b34f98718301d718fa2darylm switch (argv[i][1]) { /* option */ 36316a5fed65808adf648004b34f98718301d718fa2darylm case '-': 36416a5fed65808adf648004b34f98718301d718fa2darylm noextrachars(argv[i]); 36516a5fed65808adf648004b34f98718301d718fa2darylm return (argv[i+1] != NULL ? i+1 : 0); 36616a5fed65808adf648004b34f98718301d718fa2darylm case '\0': 36716a5fed65808adf648004b34f98718301d718fa2darylm return i; 36816a5fed65808adf648004b34f98718301d718fa2darylm case 'E': 36916a5fed65808adf648004b34f98718301d718fa2darylm args[has_E] = 1; 37016a5fed65808adf648004b34f98718301d718fa2darylm break; 37116a5fed65808adf648004b34f98718301d718fa2darylm case 'i': 37216a5fed65808adf648004b34f98718301d718fa2darylm noextrachars(argv[i]); 37316a5fed65808adf648004b34f98718301d718fa2darylm args[has_i] = 1; /* go through */ 37416a5fed65808adf648004b34f98718301d718fa2darylm case 'v': 37516a5fed65808adf648004b34f98718301d718fa2darylm noextrachars(argv[i]); 37616a5fed65808adf648004b34f98718301d718fa2darylm args[has_v] = 1; 37716a5fed65808adf648004b34f98718301d718fa2darylm break; 37816a5fed65808adf648004b34f98718301d718fa2darylm case 'e': 37916a5fed65808adf648004b34f98718301d718fa2darylm args[has_e] = 1; /* go through */ 38016a5fed65808adf648004b34f98718301d718fa2darylm case 'l': /* both options need an argument */ 38116a5fed65808adf648004b34f98718301d718fa2darylm if (argv[i][2] == '\0') { /* no concatenated argument? */ 38216a5fed65808adf648004b34f98718301d718fa2darylm i++; /* try next 'argv' */ 38316a5fed65808adf648004b34f98718301d718fa2darylm if (argv[i] == NULL || argv[i][0] == '-') 38416a5fed65808adf648004b34f98718301d718fa2darylm return -(i - 1); /* no next argument or it is another option */ 38516a5fed65808adf648004b34f98718301d718fa2darylm } 38616a5fed65808adf648004b34f98718301d718fa2darylm break; 38716a5fed65808adf648004b34f98718301d718fa2darylm default: /* invalid option; return its index... */ 38816a5fed65808adf648004b34f98718301d718fa2darylm return -i; /* ...as a negative value */ 38916a5fed65808adf648004b34f98718301d718fa2darylm } 39016a5fed65808adf648004b34f98718301d718fa2darylm } 39116a5fed65808adf648004b34f98718301d718fa2darylm return 0; 39216a5fed65808adf648004b34f98718301d718fa2darylm} 39316a5fed65808adf648004b34f98718301d718fa2darylm 39416a5fed65808adf648004b34f98718301d718fa2darylm 39516a5fed65808adf648004b34f98718301d718fa2darylmstatic int runargs (lua_State *L, char **argv, int n) { 39616a5fed65808adf648004b34f98718301d718fa2darylm int i; 39716a5fed65808adf648004b34f98718301d718fa2darylm for (i = 1; i < n; i++) { 39816a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(argv[i][0] == '-'); 39916a5fed65808adf648004b34f98718301d718fa2darylm switch (argv[i][1]) { /* option */ 40016a5fed65808adf648004b34f98718301d718fa2darylm case 'e': { 40116a5fed65808adf648004b34f98718301d718fa2darylm const char *chunk = argv[i] + 2; 40216a5fed65808adf648004b34f98718301d718fa2darylm if (*chunk == '\0') chunk = argv[++i]; 40316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(chunk != NULL); 40416a5fed65808adf648004b34f98718301d718fa2darylm if (dostring(L, chunk, "=(command line)") != LUA_OK) 40516a5fed65808adf648004b34f98718301d718fa2darylm return 0; 40616a5fed65808adf648004b34f98718301d718fa2darylm break; 40716a5fed65808adf648004b34f98718301d718fa2darylm } 40816a5fed65808adf648004b34f98718301d718fa2darylm case 'l': { 40916a5fed65808adf648004b34f98718301d718fa2darylm const char *filename = argv[i] + 2; 41016a5fed65808adf648004b34f98718301d718fa2darylm if (*filename == '\0') filename = argv[++i]; 41116a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(filename != NULL); 41216a5fed65808adf648004b34f98718301d718fa2darylm if (dolibrary(L, filename) != LUA_OK) 41316a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* stop if file fails */ 41416a5fed65808adf648004b34f98718301d718fa2darylm break; 41516a5fed65808adf648004b34f98718301d718fa2darylm } 41616a5fed65808adf648004b34f98718301d718fa2darylm default: break; 41716a5fed65808adf648004b34f98718301d718fa2darylm } 41816a5fed65808adf648004b34f98718301d718fa2darylm } 41916a5fed65808adf648004b34f98718301d718fa2darylm return 1; 42016a5fed65808adf648004b34f98718301d718fa2darylm} 42116a5fed65808adf648004b34f98718301d718fa2darylm 42216a5fed65808adf648004b34f98718301d718fa2darylm 42316a5fed65808adf648004b34f98718301d718fa2darylmstatic int handle_luainit (lua_State *L) { 42416a5fed65808adf648004b34f98718301d718fa2darylm const char *name = "=" LUA_INITVERSION; 42516a5fed65808adf648004b34f98718301d718fa2darylm const char *init = getenv(name + 1); 42616a5fed65808adf648004b34f98718301d718fa2darylm if (init == NULL) { 42716a5fed65808adf648004b34f98718301d718fa2darylm name = "=" LUA_INIT; 42816a5fed65808adf648004b34f98718301d718fa2darylm init = getenv(name + 1); /* try alternative name */ 42916a5fed65808adf648004b34f98718301d718fa2darylm } 43016a5fed65808adf648004b34f98718301d718fa2darylm if (init == NULL) return LUA_OK; 43116a5fed65808adf648004b34f98718301d718fa2darylm else if (init[0] == '@') 43216a5fed65808adf648004b34f98718301d718fa2darylm return dofile(L, init+1); 43316a5fed65808adf648004b34f98718301d718fa2darylm else 43416a5fed65808adf648004b34f98718301d718fa2darylm return dostring(L, init, name); 43516a5fed65808adf648004b34f98718301d718fa2darylm} 43616a5fed65808adf648004b34f98718301d718fa2darylm 43716a5fed65808adf648004b34f98718301d718fa2darylm 43816a5fed65808adf648004b34f98718301d718fa2darylmstatic int pmain (lua_State *L) { 43916a5fed65808adf648004b34f98718301d718fa2darylm int argc = (int)lua_tointeger(L, 1); 44016a5fed65808adf648004b34f98718301d718fa2darylm char **argv = (char **)lua_touserdata(L, 2); 44116a5fed65808adf648004b34f98718301d718fa2darylm int script; 44216a5fed65808adf648004b34f98718301d718fa2darylm int args[num_has]; 44316a5fed65808adf648004b34f98718301d718fa2darylm args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; 44416a5fed65808adf648004b34f98718301d718fa2darylm if (argv[0] && argv[0][0]) progname = argv[0]; 44516a5fed65808adf648004b34f98718301d718fa2darylm script = collectargs(argv, args); 44616a5fed65808adf648004b34f98718301d718fa2darylm if (script < 0) { /* invalid arg? */ 44716a5fed65808adf648004b34f98718301d718fa2darylm print_usage(argv[-script]); 44816a5fed65808adf648004b34f98718301d718fa2darylm return 0; 44916a5fed65808adf648004b34f98718301d718fa2darylm } 45016a5fed65808adf648004b34f98718301d718fa2darylm if (args[has_v]) print_version(); 45116a5fed65808adf648004b34f98718301d718fa2darylm if (args[has_E]) { /* option '-E'? */ 45216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ 45316a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 45416a5fed65808adf648004b34f98718301d718fa2darylm } 45516a5fed65808adf648004b34f98718301d718fa2darylm /* open standard libraries */ 45616a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkversion(L); 45716a5fed65808adf648004b34f98718301d718fa2darylm lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ 45816a5fed65808adf648004b34f98718301d718fa2darylm luaL_openlibs(L); /* open libraries */ 45916a5fed65808adf648004b34f98718301d718fa2darylm lua_gc(L, LUA_GCRESTART, 0); 46016a5fed65808adf648004b34f98718301d718fa2darylm if (!args[has_E] && handle_luainit(L) != LUA_OK) 46116a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* error running LUA_INIT */ 46216a5fed65808adf648004b34f98718301d718fa2darylm /* execute arguments -e and -l */ 46316a5fed65808adf648004b34f98718301d718fa2darylm if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; 46416a5fed65808adf648004b34f98718301d718fa2darylm /* execute main script (if there is one) */ 46516a5fed65808adf648004b34f98718301d718fa2darylm if (script && handle_script(L, argv, script) != LUA_OK) return 0; 46616a5fed65808adf648004b34f98718301d718fa2darylm if (args[has_i]) /* -i option? */ 46716a5fed65808adf648004b34f98718301d718fa2darylm dotty(L); 46816a5fed65808adf648004b34f98718301d718fa2darylm else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */ 46916a5fed65808adf648004b34f98718301d718fa2darylm if (lua_stdin_is_tty()) { 47016a5fed65808adf648004b34f98718301d718fa2darylm print_version(); 47116a5fed65808adf648004b34f98718301d718fa2darylm dotty(L); 47216a5fed65808adf648004b34f98718301d718fa2darylm } 47316a5fed65808adf648004b34f98718301d718fa2darylm else dofile(L, NULL); /* executes stdin as a file */ 47416a5fed65808adf648004b34f98718301d718fa2darylm } 47516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, 1); /* signal no errors */ 47616a5fed65808adf648004b34f98718301d718fa2darylm return 1; 47716a5fed65808adf648004b34f98718301d718fa2darylm} 47816a5fed65808adf648004b34f98718301d718fa2darylm 47916a5fed65808adf648004b34f98718301d718fa2darylm 48016a5fed65808adf648004b34f98718301d718fa2darylmint main (int argc, char **argv) { 48116a5fed65808adf648004b34f98718301d718fa2darylm int status, result; 48216a5fed65808adf648004b34f98718301d718fa2darylm lua_State *L = luaL_newstate(); /* create state */ 48316a5fed65808adf648004b34f98718301d718fa2darylm if (L == NULL) { 48416a5fed65808adf648004b34f98718301d718fa2darylm l_message(argv[0], "cannot create state: not enough memory"); 48516a5fed65808adf648004b34f98718301d718fa2darylm return EXIT_FAILURE; 48616a5fed65808adf648004b34f98718301d718fa2darylm } 48716a5fed65808adf648004b34f98718301d718fa2darylm /* call 'pmain' in protected mode */ 48816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcfunction(L, &pmain); 48916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushinteger(L, argc); /* 1st argument */ 49016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushlightuserdata(L, argv); /* 2nd argument */ 49116a5fed65808adf648004b34f98718301d718fa2darylm status = lua_pcall(L, 2, 1, 0); 49216a5fed65808adf648004b34f98718301d718fa2darylm result = lua_toboolean(L, -1); /* get result */ 49316a5fed65808adf648004b34f98718301d718fa2darylm finalreport(L, status); 49416a5fed65808adf648004b34f98718301d718fa2darylm lua_close(L); 49516a5fed65808adf648004b34f98718301d718fa2darylm return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; 49616a5fed65808adf648004b34f98718301d718fa2darylm} 49716a5fed65808adf648004b34f98718301d718fa2darylm 498