diff --git a/ldblib.c b/ldblib.c new file mode 100644 index 00000000..952f3cb3 --- /dev/null +++ b/ldblib.c @@ -0,0 +1,213 @@ +/* +** $Id: $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#include "lauxlib.h" +#include "lua.h" +#include "luadebug.h" + + + +static void settabss (lua_Object t, char *i, char *v) { + lua_pushobject(t); + lua_pushstring(i); + lua_pushstring(v); + lua_settable(); +} + + +static void settabsi (lua_Object t, char *i, int v) { + lua_pushobject(t); + lua_pushstring(i); + lua_pushnumber(v); + lua_settable(); +} + + +static lua_Object getfuncinfo (lua_Object func) { + lua_Object result = lua_createtable(); + char *name; + int line; + lua_funcinfo(func, &name, &line); + if (line == -1) /* C function? */ + settabss(result, "kind", "C"); + else if (line == 0) { /* "main"? */ + settabss(result, "kind", "chunk"); + settabss(result, "name", name); + } + else { /* Lua function */ + settabss(result, "kind", "Lua"); + settabsi(result, "def_line", line); + settabss(result, "def_chunk", name); + } + if (line != 0) { /* is it not a "main"? */ + char *kind = lua_getobjname(func, &name); + if (*kind) { + settabss(result, "name", name); + settabss(result, "where", kind); + } + } + return result; +} + + +static void getstack (void) { + lua_Object func = lua_stackedfunction(luaL_check_int(1)); + if (func == LUA_NOOBJECT) /* level out of range? */ + return; + else { + lua_Object result = getfuncinfo(func); + int currline = lua_currentline(func); + if (currline > 0) + settabsi(result, "current", currline); + lua_pushobject(result); + } +} + + +static void funcinfo (void) { + lua_pushobject(getfuncinfo(luaL_functionarg(1))); +} + + +static int findlocal (lua_Object func, int arg) { + lua_Object v = lua_getparam(arg); + if (lua_isnumber(v)) + return (int)lua_getnumber(v); + else { + char *name = luaL_check_string(arg); + int i = 0; + int result = -1; + char *vname; + while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) { + if (strcmp(name, vname) == 0) + result = i; /* keep looping to get the last var with this name */ + } + if (result == -1) + luaL_verror("no local variable `%.50s' at given level", name); + return result; + } +} + + +static void getlocal (void) { + lua_Object func = lua_stackedfunction(luaL_check_int(1)); + lua_Object val; + char *name; + if (func == LUA_NOOBJECT) /* level out of range? */ + return; /* return nil */ + else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */ + if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) { + lua_pushobject(val); + lua_pushstring(name); + } + /* else return nil */ + } + else { /* collect all locals in a table */ + lua_Object result = lua_createtable(); + int i; + for (i=1; ;i++) { + if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT) + break; + lua_pushobject(result); + lua_pushstring(name); + lua_pushobject(val); + lua_settable(); /* result[name] = value */ + } + lua_pushobject(result); + } +} + + +static void setlocal (void) { + lua_Object func = lua_stackedfunction(luaL_check_int(1)); + int numvar; + luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range"); + numvar = findlocal(func, 2); + lua_pushobject(luaL_nonnullarg(3)); + if (!lua_setlocal(func, numvar)) + lua_error("no such local variable"); +} + + + +static int linehook = -1; /* Lua reference to line hook function */ +static int callhook = -1; /* Lua reference to call hook function */ + + +static void dohook (int ref) { + lua_LHFunction oldlinehook = lua_linehook; /* save old hooks */ + lua_CHFunction oldcallhook = lua_callhook; + lua_linehook = NULL; lua_callhook = NULL; /* to avoid recusive calls */ + lua_callfunction(lua_getref(ref)); + lua_linehook = oldlinehook; /* restore old hooks */ + lua_callhook = oldcallhook; +} + + +static void linef (int line) { + lua_pushnumber(line); + dohook(linehook); +} + + +static void callf (lua_Function func, char *file, int line) { + if (func != LUA_NOOBJECT) { + lua_pushobject(func); + lua_pushstring(file); + lua_pushnumber(line); + } + dohook(callhook); +} + + +static void setcallhook (void) { + lua_Object f = lua_getparam(1); + lua_unref(callhook); + if (f == LUA_NOOBJECT) { + callhook = -1; + lua_callhook = NULL; + } + else { + lua_pushobject(f); + callhook = lua_ref(1); + lua_callhook = callf; + } +} + + +static void setlinehook (void) { + lua_Object f = lua_getparam(1); + lua_unref(linehook); + if (f == LUA_NOOBJECT) { + linehook = -1; + lua_linehook = NULL; + } + else { + lua_pushobject(f); + linehook = lua_ref(1); + lua_linehook = linef; + } +} + + +static struct luaL_reg dblib[] = { + {"funcinfo", funcinfo}, + {"getlocal", getlocal}, + {"getstack", getstack}, + {"setcallhook", setcallhook}, + {"setlinehook", setlinehook}, + {"setlocal", setlocal} +}; + + +void lua_dblibopen (void) { + luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0]))); +} + diff --git a/lua.c b/lua.c index 576d34fe..1ab0ac44 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.15 1998/12/28 13:44:54 roberto Exp $ +** $Id: lua.c,v 1.16 1999/01/06 13:12:41 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -131,11 +131,10 @@ static void manual_input (int prompt) { int main (int argc, char *argv[]) { int i; - setlocale(LC_ALL, ""); - lua_iolibopen(); - lua_strlibopen(); - lua_mathlibopen(); + lua_open(); lua_pushstring("> "); lua_setglobal("_PROMPT"); + lua_userinit(); + setlocale(LC_ALL, ""); if (argc < 2) { /* no arguments? */ if (isatty(0)) { printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT); diff --git a/lualib.h b/lualib.h index cf17599a..c6e34b52 100644 --- a/lualib.h +++ b/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.3 1997/12/17 20:48:58 roberto Exp roberto $ +** $Id: lualib.h,v 1.4 1998/06/19 16:14:09 roberto Exp roberto $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -10,12 +10,13 @@ #include "lua.h" - void lua_iolibopen (void); void lua_strlibopen (void); void lua_mathlibopen (void); +void lua_dblibopen (void); +void lua_userinit (void); /* To keep compatibility with old versions */ diff --git a/makefile b/makefile index 8fed9268..a1640b3d 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ # -## $Id: makefile,v 1.12 1998/05/27 13:03:40 roberto Exp roberto $ +## $Id: makefile,v 1.13 1998/06/19 18:52:27 roberto Exp roberto $ ## Makefile ## See Copyright Notice in lua.h # @@ -58,7 +58,9 @@ LUAOBJS = \ LIBOBJS = \ liolib.o \ lmathlib.o \ - lstrlib.o + lstrlib.o \ + ldblib.o \ + linit.o lua : lua.o liblua.a liblualib.a @@ -96,12 +98,14 @@ lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \ ldo.h lstate.h lfunc.h lmem.h lstring.h ltable.h ltm.h lundump.h \ - lzio.h + lzio.h lvm.h +ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \ - lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h + lparser.h lzio.h lstring.h ltm.h luadebug.h lundump.h lvm.h lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \ lstring.h ltable.h ltm.h +linit.o: linit.c lua.h lualib.h liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \ lparser.h lstate.h lstring.h luadebug.h