/* ** 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.56 1997/04/06 14:08:08 roberto Exp roberto $"; #include #include #include "auxlib.h" #include "lex.h" #include "opcode.h" #include "inout.h" #include "table.h" #include "tree.h" #include "lua.h" #include "hash.h" #include "luamem.h" #include "fallback.h" #include "luamem.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 }; static FILE *fp; static char *st; /* ** Function to get the next character from the input file */ static int fileinput (void) { int c = fgetc(fp); return (c == EOF) ? 0 : c; } /* ** Function to get the next character from the input string */ static int stringinput (void) { return *st++; } /* ** Function to open a file to be input unit. ** Return the file. */ FILE *lua_openfile (char *fn) { lua_setinput (fileinput); if (fn == NULL) { fp = stdin; fn = "(stdin)"; } else fp = fopen (fn, "r"); if (fp == NULL) return NULL; lua_parsedfile = luaI_createfixedstring(fn)->str; return fp; } /* ** Function to close an opened file */ void lua_closefile (void) { if (fp != NULL && fp != stdin) { fclose (fp); fp = NULL; } } /* ** Function to open a string to be input unit */ #define SIZE_PREF 20 /* size of string prefix to appear in error messages */ void lua_openstring (char *s) { char buff[SIZE_PREF+25]; lua_setinput(stringinput); st = s; sprintf(buff, "(dostring) >> %.20s%s", s, (strlen(s) > SIZE_PREF) ? "..." : ""); lua_parsedfile = luaI_createfixedstring(buff)->str; } /* ** Function to close an opened string */ void lua_closestring (void) { } static int passresults (void) { int arg = 0; lua_Object obj; while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) lua_pushobject(obj); return arg-1; } /* ** 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(100); int size = o->value.ts->size; int i; strcpy(buff, "userdata: "); if (size > 10) size = 10; for (i=0; ivalue.ts->str[i]); 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))); } #define MAXPARAMS 256 static void luaI_call (void) { lua_Object f = lua_getparam(1); lua_Object arg = lua_getparam(2); lua_Object temp, params[MAXPARAMS]; int narg, i; luaL_arg_check(lua_isfunction(f), 1, "function expected"); luaL_arg_check(lua_istable(arg), 2, "table expected"); /* narg = arg.n */ lua_pushobject(arg); lua_pushstring("n"); temp = lua_getsubscript(); narg = lua_isnumber(temp) ? lua_getnumber(temp) : MAXPARAMS+1; /* read arg[1...n] */ for (i=0; i=MAXPARAMS) lua_error("argument list too long in function `call'"); lua_pushobject(arg); lua_pushnumber(i+1); params[i] = lua_getsubscript(); if (narg == MAXPARAMS+1 && lua_isnil(params[i])) { narg = i; break; } } /* push parameters and do the call */ for (i=0; i