123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*
- ** $Id: ldblib.c,v 1.4 1999/02/04 17:47:59 roberto Exp roberto $
- ** 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"
- #include "lualib.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 *str;
- int line;
- lua_funcinfo(func, &str, &line);
- if (line == -1) /* C function? */
- settabss(result, "kind", "C");
- else if (line == 0) { /* "main"? */
- settabss(result, "kind", "chunk");
- settabss(result, "source", str);
- }
- else { /* Lua function */
- settabss(result, "kind", "Lua");
- settabsi(result, "def_line", line);
- settabss(result, "source", str);
- }
- if (line != 0) { /* is it not a "main"? */
- char *kind = lua_getobjname(func, &str);
- if (*kind) {
- settabss(result, "name", str);
- 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);
- lua_pushstring("func");
- lua_pushobject(func);
- lua_settable(); /* result.func = func */
- 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_setlinehook(NULL);
- lua_CHFunction oldcallhook = lua_setcallhook(NULL);
- lua_callfunction(lua_getref(ref));
- lua_setlinehook(oldlinehook);
- lua_setcallhook(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_setcallhook(NULL);
- }
- else {
- lua_pushobject(f);
- callhook = lua_ref(1);
- lua_setcallhook(callf);
- }
- }
- static void setlinehook (void) {
- lua_Object f = lua_getparam(1);
- lua_unref(linehook);
- if (f == LUA_NOOBJECT) {
- linehook = -1;
- lua_setlinehook(NULL);
- }
- else {
- lua_pushobject(f);
- linehook = lua_ref(1);
- lua_setlinehook(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])));
- }
|