/* ** inout.c ** Provide function to realise the input/output function and debugger ** facilities. ** Also provides some predefined lua functions. */ char *rcs_inout="$Id: inout.c,v 2.60 1997/06/09 17:28:14 roberto Exp roberto $"; #include #include #include "auxlib.h" #include "fallback.h" #include "hash.h" #include "inout.h" #include "lex.h" #include "lua.h" #include "luamem.h" #include "luamem.h" #include "opcode.h" #include "table.h" #include "tree.h" #include "undump.h" #include "zio.h" /* Exported variables */ Word lua_linenumber; char *lua_parsedfile; char *luaI_typenames[] = { /* ORDER LUA_T */ "userdata", "line", "cmark", "mark", "function", "function", "table", "string", "number", "nil", NULL }; int lua_dofile (char *filename) { int status; int c; FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); if (f == NULL) return 2; lua_parsedfile = luaI_createfixedstring(filename?filename:"(stdin)")->str; c = fgetc(f); ungetc(c, f); if (c == ID_CHUNK) { ZIO z; f = freopen(filename, "rb", f); /* set binary mode */ zFopen(&z, f); lua_setinput(&z); status = luaI_undump(&z); zclose(&z); } else { ZIO z; if (c == '#') while ((c=fgetc(f)) != '\n') /* skip first line */; zFopen(&z, f); lua_setinput(&z); status = lua_domain(); zclose(&z); } return status; } #define SIZE_PREF 20 /* size of string prefix to appear in error messages */ int lua_dostring (char *str) { int status; char buff[SIZE_PREF+25]; ZIO z; if (str == NULL) return 1; sprintf(buff, "(dostring) >> %.20s%s", str, (strlen(str) > SIZE_PREF) ? "..." : ""); lua_parsedfile = luaI_createfixedstring(buff)->str; zsopen(&z, str); lua_setinput(&z); status = lua_domain(); zclose(&z); return status; } static int passresults (void) { int arg = 0; lua_Object obj; while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) lua_pushobject(obj); return arg-1; } static void packresults (void) { int arg = 0; lua_Object obj; lua_Object table = lua_createtable(); while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) { lua_pushobject(table); lua_pushnumber(arg); lua_pushobject(obj); lua_rawsettable(); } lua_pushobject(table); lua_pushstring("n"); lua_pushnumber(arg-1); lua_rawsettable(); lua_pushobject(table); /* final result */ } /* ** Internal function: do a string */ static void lua_internaldostring (void) { if (lua_dostring(luaL_check_string(1)) == 0) if (passresults() == 0) lua_pushuserdata(NULL); /* at least one result to signal no errors */ } /* ** Internal function: do a file */ static void lua_internaldofile (void) { char *fname = luaL_opt_string(1, NULL); if (lua_dofile(fname) == 0) if (passresults() == 0) lua_pushuserdata(NULL); /* at least one result to signal no errors */ } static char *tostring (lua_Object obj) { TObject *o = luaI_Address(obj); switch (ttype(o)) { case LUA_T_NUMBER: case LUA_T_STRING: return lua_getstring(obj); case LUA_T_ARRAY: case LUA_T_FUNCTION: case LUA_T_CFUNCTION: case LUA_T_NIL: return luaI_typenames[-ttype(o)]; case LUA_T_USERDATA: { char *buff = luaI_buffer(30); sprintf(buff, "userdata: %p", o->value.ts->u.v); return buff; } default: return ""; } } static void luaI_tostring (void) { lua_pushstring(tostring(lua_getparam(1))); } static void luaI_print (void) { int i = 1; lua_Object obj; while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) printf("%s\n", tostring(obj)); } static void luaI_type (void) { lua_Object o = lua_getparam(1); luaL_arg_check(o != LUA_NOOBJECT, 1, "no argument"); lua_pushstring(luaI_typenames[-ttype(luaI_Address(o))]); lua_pushnumber(lua_tag(o)); } /* ** Internal function: convert an object to a number */ static void lua_obj2number (void) { lua_Object o = lua_getparam(1); if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o)); } static void luaI_error (void) { char *s = lua_getstring(lua_getparam(1)); if (s == NULL) s = "(no message)"; lua_error(s); } static void luaI_assert (void) { lua_Object p = lua_getparam(1); if (p == LUA_NOOBJECT || lua_isnil(p)) lua_error("assertion failed!"); } static void luaI_setglobal (void) { lua_Object value = lua_getparam(2); luaL_arg_check(value != LUA_NOOBJECT, 2, NULL); lua_pushobject(value); lua_setglobal(luaL_check_string(1)); lua_pushobject(value); /* return given value */ } static void luaI_rawsetglobal (void) { lua_Object value = lua_getparam(2); luaL_arg_check(value != LUA_NOOBJECT, 2, NULL); lua_pushobject(value); lua_rawsetglobal(luaL_check_string(1)); lua_pushobject(value); /* return given value */ } static void luaI_getglobal (void) { lua_pushobject(lua_getglobal(luaL_check_string(1))); } static void luaI_rawgetglobal (void) { lua_pushobject(lua_rawgetglobal(luaL_check_string(1))); } static void luatag (void) { lua_pushnumber(lua_tag(lua_getparam(1))); } static int getnarg (lua_Object table) { lua_Object temp; /* temp = table.n */ lua_pushobject(table); lua_pushstring("n"); temp = lua_gettable(); return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_WORD); } static void luaI_call (void) { lua_Object f = lua_getparam(1); lua_Object arg = lua_getparam(2); int withtable = (luaL_opt_string(3, NULL) != NULL); int narg, i; luaL_arg_check(lua_isfunction(f), 1, "function expected"); luaL_arg_check(lua_istable(arg), 2, "table expected"); narg = getnarg(arg); /* push arg[1...n] */ for (i=0; i