Browse Source

new library for debbuging

Roberto Ierusalimschy 26 years ago
parent
commit
01772cefa5
4 changed files with 228 additions and 11 deletions
  1. 213 0
      ldblib.c
  2. 4 5
      lua.c
  3. 3 2
      lualib.h
  4. 8 4
      makefile

+ 213 - 0
ldblib.c

@@ -0,0 +1,213 @@
+/*
+** $Id: $
+** Interface from Lua to its debug API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#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])));
+}
+

+ 4 - 5
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);

+ 3 - 2
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 */

+ 8 - 4
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