lua/ldblib.c

220 lines
5.3 KiB
C
Raw Normal View History

1999-01-09 00:47:44 +08:00
/*
1999-11-23 01:39:51 +08:00
** $Id: ldblib.c,v 1.7 1999/11/22 13:12:07 roberto Exp roberto $
1999-01-09 00:47:44 +08:00
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#define LUA_REENTRANT
1999-01-09 00:47:44 +08:00
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
1999-01-12 02:57:35 +08:00
#include "lualib.h"
1999-01-09 00:47:44 +08:00
static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) {
lua_pushobject(L, t);
lua_pushstring(L, i);
lua_pushstring(L, v);
lua_settable(L);
1999-01-09 00:47:44 +08:00
}
static void settabsi (lua_State *L, lua_Object t, const char *i, int v) {
lua_pushobject(L, t);
lua_pushstring(L, i);
lua_pushnumber(L, v);
lua_settable(L);
1999-01-09 00:47:44 +08:00
}
static lua_Object getfuncinfo (lua_State *L, lua_Object func) {
lua_Object result = lua_createtable(L);
1999-08-17 04:52:00 +08:00
const char *str;
1999-01-09 00:47:44 +08:00
int line;
lua_funcinfo(L, func, &str, &line);
1999-01-09 00:47:44 +08:00
if (line == -1) /* C function? */
settabss(L, result, "kind", "C");
1999-01-09 00:47:44 +08:00
else if (line == 0) { /* "main"? */
settabss(L, result, "kind", "chunk");
settabss(L, result, "source", str);
1999-01-09 00:47:44 +08:00
}
else { /* Lua function */
settabss(L, result, "kind", "Lua");
settabsi(L, result, "def_line", line);
settabss(L, result, "source", str);
1999-01-09 00:47:44 +08:00
}
if (line != 0) { /* is it not a "main"? */
const char *kind = lua_getobjname(L, func, &str);
1999-01-09 00:47:44 +08:00
if (*kind) {
settabss(L, result, "name", str);
settabss(L, result, "where", kind);
1999-01-09 00:47:44 +08:00
}
}
return result;
}
static void getstack (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
1999-01-09 00:47:44 +08:00
if (func == LUA_NOOBJECT) /* level out of range? */
return;
else {
lua_Object result = getfuncinfo(L, func);
int currline = lua_currentline(L, func);
1999-01-09 00:47:44 +08:00
if (currline > 0)
settabsi(L, result, "current", currline);
lua_pushobject(L, result);
lua_pushstring(L, "func");
lua_pushobject(L, func);
lua_settable(L); /* result.func = func */
lua_pushobject(L, result);
1999-01-09 00:47:44 +08:00
}
}
static void funcinfo (lua_State *L) {
lua_pushobject(L, getfuncinfo(L, luaL_functionarg(L, 1)));
1999-01-09 00:47:44 +08:00
}
static int findlocal (lua_State *L, lua_Object func, int arg) {
lua_Object v = lua_getparam(L, arg);
if (lua_isnumber(L, v))
return (int)lua_getnumber(L, v);
1999-01-09 00:47:44 +08:00
else {
const char *name = luaL_check_string(L, arg);
1999-01-09 00:47:44 +08:00
int i = 0;
int result = -1;
1999-08-17 04:52:00 +08:00
const char *vname;
while (lua_getlocal(L, func, ++i, &vname) != LUA_NOOBJECT) {
1999-01-09 00:47:44 +08:00
if (strcmp(name, vname) == 0)
result = i; /* keep looping to get the last var with this name */
}
if (result == -1)
luaL_verror(L, "no local variable `%.50s' at given level", name);
1999-01-09 00:47:44 +08:00
return result;
}
}
static void getlocal (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
1999-01-09 00:47:44 +08:00
lua_Object val;
1999-08-17 04:52:00 +08:00
const char *name;
1999-01-09 00:47:44 +08:00
if (func == LUA_NOOBJECT) /* level out of range? */
return; /* return nil */
else if (lua_getparam(L, 2) != LUA_NOOBJECT) { /* 2nd argument? */
if ((val = lua_getlocal(L, func, findlocal(L, func, 2), &name)) != LUA_NOOBJECT) {
lua_pushobject(L, val);
lua_pushstring(L, name);
1999-01-09 00:47:44 +08:00
}
/* else return nil */
}
else { /* collect all locals in a table */
lua_Object result = lua_createtable(L);
1999-01-09 00:47:44 +08:00
int i;
for (i=1; ;i++) {
if ((val = lua_getlocal(L, func, i, &name)) == LUA_NOOBJECT)
1999-01-09 00:47:44 +08:00
break;
lua_pushobject(L, result);
lua_pushstring(L, name);
lua_pushobject(L, val);
lua_settable(L); /* result[name] = value */
1999-01-09 00:47:44 +08:00
}
lua_pushobject(L, result);
1999-01-09 00:47:44 +08:00
}
}
static void setlocal (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
1999-01-09 00:47:44 +08:00
int numvar;
luaL_arg_check(L, func != LUA_NOOBJECT, 1, "level out of range");
numvar = findlocal(L, func, 2);
lua_pushobject(L, luaL_nonnullarg(L, 3));
if (!lua_setlocal(L, func, numvar))
lua_error(L, "no such local variable");
1999-01-09 00:47:44 +08:00
}
static int linehook = -1; /* Lua reference to line hook function */
static int callhook = -1; /* Lua reference to call hook function */
static void dohook (lua_State *L, int ref) {
lua_LHFunction oldlinehook = lua_setlinehook(L, NULL);
lua_CHFunction oldcallhook = lua_setcallhook(L, NULL);
lua_callfunction(L, lua_getref(L, ref));
lua_setlinehook(L, oldlinehook);
lua_setcallhook(L, oldcallhook);
1999-01-09 00:47:44 +08:00
}
static void linef (lua_State *L, int line) {
lua_pushnumber(L, line);
dohook(L, linehook);
1999-01-09 00:47:44 +08:00
}
static void callf (lua_State *L, lua_Function func, const char *file, int line) {
1999-01-09 00:47:44 +08:00
if (func != LUA_NOOBJECT) {
lua_pushobject(L, func);
lua_pushstring(L, file);
lua_pushnumber(L, line);
1999-01-09 00:47:44 +08:00
}
dohook(L, callhook);
1999-01-09 00:47:44 +08:00
}
static void setcallhook (lua_State *L) {
lua_Object f = lua_getparam(L, 1);
lua_unref(L, callhook);
1999-01-09 00:47:44 +08:00
if (f == LUA_NOOBJECT) {
callhook = -1;
lua_setcallhook(L, NULL);
1999-01-09 00:47:44 +08:00
}
else {
lua_pushobject(L, f);
callhook = lua_ref(L, 1);
lua_setcallhook(L, callf);
1999-01-09 00:47:44 +08:00
}
}
static void setlinehook (lua_State *L) {
lua_Object f = lua_getparam(L, 1);
lua_unref(L, linehook);
1999-01-09 00:47:44 +08:00
if (f == LUA_NOOBJECT) {
linehook = -1;
lua_setlinehook(L, NULL);
1999-01-09 00:47:44 +08:00
}
else {
lua_pushobject(L, f);
linehook = lua_ref(L, 1);
lua_setlinehook(L, linef);
1999-01-09 00:47:44 +08:00
}
}
1999-08-17 04:52:00 +08:00
static const struct luaL_reg dblib[] = {
1999-01-09 00:47:44 +08:00
{"funcinfo", funcinfo},
{"getlocal", getlocal},
{"getstack", getstack},
{"setcallhook", setcallhook},
{"setlinehook", setlinehook},
{"setlocal", setlocal}
};
void lua_dblibopen (lua_State *L) {
1999-11-23 01:39:51 +08:00
luaL_openl(L, dblib);
1999-01-09 00:47:44 +08:00
}