| /* |
| ** 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.15 1994/12/16 15:55:04 roberto Exp roberto $"; |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "mem.h" |
| #include "opcode.h" |
| #include "hash.h" |
| #include "inout.h" |
| #include "table.h" |
| #include "tree.h" |
| #include "lua.h" |
| |
| /* Exported variables */ |
| Word lua_linenumber; |
| Bool lua_debug; |
| Word lua_debugline = 0; |
| |
| |
| /* Internal variables */ |
| |
| #ifndef MAXFUNCSTACK |
| #define MAXFUNCSTACK 100 |
| #endif |
| |
| typedef struct FuncStackNode { |
| struct FuncStackNode *next; |
| char *file; |
| Word function; |
| Word line; |
| } FuncStackNode; |
| |
| static FuncStackNode *funcStack = NULL; |
| static Word nfuncstack=0; |
| |
| static FILE *fp; |
| static char *st; |
| |
| /* |
| ** Function to get the next character from the input file |
| */ |
| static int fileinput (void) |
| { |
| return fgetc (fp); |
| } |
| |
| /* |
| ** 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 0 on success or error message on error. |
| */ |
| char *lua_openfile (char *fn) |
| { |
| lua_linenumber = 1; |
| lua_setinput (fileinput); |
| fp = fopen (fn, "r"); |
| if (fp == NULL) |
| { |
| static char buff[32]; |
| sprintf(buff, "unable to open file %.10s", fn); |
| return buff; |
| } |
| return lua_addfile (fn); |
| } |
| |
| /* |
| ** Function to close an opened file |
| */ |
| void lua_closefile (void) |
| { |
| if (fp != NULL) |
| { |
| lua_delfile(); |
| fclose (fp); |
| fp = NULL; |
| } |
| } |
| |
| /* |
| ** Function to open a string to be input unit |
| */ |
| char *lua_openstring (char *s) |
| { |
| lua_linenumber = 1; |
| lua_setinput (stringinput); |
| st = s; |
| { |
| char sn[64]; |
| sprintf (sn, "String: %10.10s...", s); |
| return lua_addfile (sn); |
| } |
| } |
| |
| /* |
| ** Function to close an opened string |
| */ |
| void lua_closestring (void) |
| { |
| lua_delfile(); |
| } |
| |
| |
| /* |
| ** Called to execute SETFUNCTION opcode, this function pushs a function into |
| ** function stack. |
| */ |
| void lua_pushfunction (char *file, Word function) |
| { |
| FuncStackNode *newNode; |
| if (nfuncstack++ >= MAXFUNCSTACK) |
| { |
| lua_reportbug("function stack overflow"); |
| } |
| newNode = new(FuncStackNode); |
| newNode->function = function; |
| newNode->file = file; |
| newNode->line= lua_debugline; |
| newNode->next = funcStack; |
| funcStack = newNode; |
| } |
| |
| /* |
| ** Called to execute RESET opcode, this function pops a function from |
| ** function stack. |
| */ |
| void lua_popfunction (void) |
| { |
| FuncStackNode *temp = funcStack; |
| if (temp == NULL) return; |
| --nfuncstack; |
| lua_debugline = temp->line; |
| funcStack = temp->next; |
| luaI_free(temp); |
| } |
| |
| /* |
| ** Report bug building a message and sending it to lua_error function. |
| */ |
| void lua_reportbug (char *s) |
| { |
| char msg[MAXFUNCSTACK*80]; |
| strcpy (msg, s); |
| if (lua_debugline != 0) |
| { |
| if (funcStack) |
| { |
| FuncStackNode *func = funcStack; |
| int line = lua_debugline; |
| sprintf (strchr(msg,0), "\n\tactive stack:\n"); |
| do |
| { |
| sprintf (strchr(msg,0), |
| "\t-> function \"%s\" at file \"%s\":%u\n", |
| lua_constant[func->function]->str, func->file, line); |
| line = func->line; |
| func = func->next; |
| lua_popfunction(); |
| } while (func); |
| } |
| else |
| { |
| sprintf (strchr(msg,0), |
| "\n\tin statement begining at line %u of file \"%s\"", |
| lua_debugline, lua_filename()); |
| } |
| } |
| lua_error (msg); |
| } |
| |
| |
| /* |
| ** Internal function: do a string |
| */ |
| void lua_internaldostring (void) |
| { |
| lua_Object obj = lua_getparam (1); |
| if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) |
| lua_pushnumber(1); |
| else |
| lua_pushnil(); |
| } |
| |
| /* |
| ** Internal function: do a file |
| */ |
| void lua_internaldofile (void) |
| { |
| lua_Object obj = lua_getparam (1); |
| if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) |
| lua_pushnumber(1); |
| else |
| lua_pushnil(); |
| } |
| |
| /* |
| ** Internal function: print object values |
| */ |
| void lua_print (void) |
| { |
| int i=1; |
| lua_Object obj; |
| while ((obj=lua_getparam (i++)) != LUA_NOOBJECT) |
| { |
| if (lua_isnumber(obj)) printf("%g\n",lua_getnumber(obj)); |
| else if (lua_isstring(obj)) printf("%s\n",lua_getstring(obj)); |
| else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(luaI_Address(obj))); |
| else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction(obj) |
| ); |
| else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata(obj)); |
| else if (lua_istable(obj)) printf("table: %p\n",avalue(luaI_Address(obj))); |
| else if (lua_isnil(obj)) printf("nil\n"); |
| else printf("invalid value to print\n"); |
| } |
| } |
| |
| |
| /* |
| ** Internal function: return an object type. |
| */ |
| void luaI_type (void) |
| { |
| lua_Object o = lua_getparam(1); |
| if (o == LUA_NOOBJECT) |
| lua_error("no parameter to function 'type'"); |
| switch (lua_type(o)) |
| { |
| case LUA_T_NIL : |
| lua_pushliteral("nil"); |
| break; |
| case LUA_T_NUMBER : |
| lua_pushliteral("number"); |
| break; |
| case LUA_T_STRING : |
| lua_pushliteral("string"); |
| break; |
| case LUA_T_ARRAY : |
| lua_pushliteral("table"); |
| break; |
| case LUA_T_FUNCTION : |
| lua_pushliteral("function"); |
| break; |
| case LUA_T_CFUNCTION : |
| lua_pushliteral("cfunction"); |
| break; |
| default : |
| lua_pushliteral("userdata"); |
| break; |
| } |
| } |
| |
| /* |
| ** Internal function: convert an object to a number |
| */ |
| void lua_obj2number (void) |
| { |
| lua_Object o = lua_getparam(1); |
| if (lua_isnumber(o)) |
| lua_pushobject(o); |
| else if (lua_isstring(o)) |
| { |
| char c; |
| float f; |
| if (sscanf(lua_getstring(o),"%f %c",&f,&c) == 1) |
| lua_pushnumber(f); |
| else |
| lua_pushnil(); |
| } |
| else |
| lua_pushnil(); |
| } |
| |
| |
| void luaI_error (void) |
| { |
| char *s = lua_getstring(lua_getparam(1)); |
| if (s == NULL) s = "(no message)"; |
| lua_reportbug(s); |
| } |
| |