diff options
Diffstat (limited to 'ldblib.c')
-rw-r--r-- | ldblib.c | 157 |
1 files changed, 56 insertions, 101 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.8 1999/11/22 17:39:51 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.9 1999/12/21 18:04:41 roberto Exp roberto $ |
3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -33,113 +33,73 @@ static void settabsi (lua_State *L, lua_Object t, const char *i, int v) { | |||
33 | } | 33 | } |
34 | 34 | ||
35 | 35 | ||
36 | static lua_Object getfuncinfo (lua_State *L, lua_Object func) { | 36 | static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) { |
37 | lua_Object result = lua_createtable(L); | 37 | lua_pushobject(L, t); |
38 | const char *str; | 38 | lua_pushstring(L, i); |
39 | int line; | 39 | lua_pushobject(L, v); |
40 | lua_funcinfo(L, func, &str, &line); | 40 | lua_settable(L); |
41 | if (line == -1) /* C function? */ | ||
42 | settabss(L, result, "kind", "C"); | ||
43 | else if (line == 0) { /* "main"? */ | ||
44 | settabss(L, result, "kind", "chunk"); | ||
45 | settabss(L, result, "source", str); | ||
46 | } | ||
47 | else { /* Lua function */ | ||
48 | settabss(L, result, "kind", "Lua"); | ||
49 | settabsi(L, result, "def_line", line); | ||
50 | settabss(L, result, "source", str); | ||
51 | } | ||
52 | if (line != 0) { /* is it not a "main"? */ | ||
53 | const char *kind = lua_getobjname(L, func, &str); | ||
54 | if (*kind) { | ||
55 | settabss(L, result, "name", str); | ||
56 | settabss(L, result, "where", kind); | ||
57 | } | ||
58 | } | ||
59 | return result; | ||
60 | } | 41 | } |
61 | 42 | ||
62 | 43 | ||
63 | static void getstack (lua_State *L) { | 44 | static void getstack (lua_State *L) { |
64 | lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1)); | 45 | lua_Dbgactreg ar; |
65 | if (func == LUA_NOOBJECT) /* level out of range? */ | 46 | if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ |
66 | return; | 47 | return; |
67 | else { | 48 | else { |
68 | lua_Object result = getfuncinfo(L, func); | 49 | const char *options = luaL_check_string(L, 2); |
69 | int currline = lua_currentline(L, func); | 50 | lua_Object res = lua_createtable(L); |
70 | if (currline > 0) | 51 | if (!lua_getinfo(L, options, &ar)) |
71 | settabsi(L, result, "current", currline); | 52 | luaL_argerror(L, 2, "invalid option"); |
72 | lua_pushobject(L, result); | 53 | for ( ;*options; options++) { |
73 | lua_pushstring(L, "func"); | 54 | switch (*options) { |
74 | lua_pushobject(L, func); | 55 | case 'S': |
75 | lua_settable(L); /* result.func = func */ | 56 | settabss(L, res, "source", ar.source); |
76 | lua_pushobject(L, result); | 57 | settabsi(L, res, "linedefined", ar.linedefined); |
77 | } | 58 | settabss(L, res, "what", ar.what); |
78 | } | 59 | break; |
79 | 60 | case 'l': | |
80 | 61 | settabsi(L, res, "currentline", ar.currentline); | |
81 | static void funcinfo (lua_State *L) { | 62 | break; |
82 | lua_pushobject(L, getfuncinfo(L, luaL_functionarg(L, 1))); | 63 | case 'u': |
83 | } | 64 | settabsi(L, res, "nups", ar.nups); |
84 | 65 | break; | |
85 | 66 | case 'n': | |
86 | static int findlocal (lua_State *L, lua_Object func, int arg) { | 67 | settabss(L, res, "name", ar.name); |
87 | lua_Object v = lua_getparam(L, arg); | 68 | settabss(L, res, "namewhat", ar.namewhat); |
88 | if (lua_isnumber(L, v)) | 69 | break; |
89 | return (int)lua_getnumber(L, v); | 70 | case 'f': |
90 | else { | 71 | settabso(L, res, "func", ar.func); |
91 | const char *name = luaL_check_string(L, arg); | 72 | break; |
92 | int i = 0; | 73 | |
93 | int result = -1; | 74 | } |
94 | const char *vname; | ||
95 | while (lua_getlocal(L, func, ++i, &vname) != LUA_NOOBJECT) { | ||
96 | if (strcmp(name, vname) == 0) | ||
97 | result = i; /* keep looping to get the last var with this name */ | ||
98 | } | 75 | } |
99 | if (result == -1) | 76 | lua_pushobject(L, res); |
100 | luaL_verror(L, "no local variable `%.50s' at given level", name); | ||
101 | return result; | ||
102 | } | 77 | } |
103 | } | 78 | } |
104 | 79 | ||
105 | 80 | ||
106 | static void getlocal (lua_State *L) { | 81 | static void getlocal (lua_State *L) { |
107 | lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1)); | 82 | lua_Dbgactreg ar; |
108 | lua_Object val; | 83 | lua_Dbglocvar lvar; |
109 | const char *name; | 84 | if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ |
110 | if (func == LUA_NOOBJECT) /* level out of range? */ | 85 | luaL_argerror(L, 1, "level out of range"); |
111 | return; /* return nil */ | 86 | lvar.index = luaL_check_int(L, 2); |
112 | else if (lua_getparam(L, 2) != LUA_NOOBJECT) { /* 2nd argument? */ | 87 | if (lua_getlocal(L, &ar, &lvar)) { |
113 | if ((val = lua_getlocal(L, func, findlocal(L, func, 2), &name)) != LUA_NOOBJECT) { | 88 | lua_pushstring(L, lvar.name); |
114 | lua_pushobject(L, val); | 89 | lua_pushobject(L, lvar.value); |
115 | lua_pushstring(L, name); | ||
116 | } | ||
117 | /* else return nil */ | ||
118 | } | ||
119 | else { /* collect all locals in a table */ | ||
120 | lua_Object result = lua_createtable(L); | ||
121 | int i; | ||
122 | for (i=1; ;i++) { | ||
123 | if ((val = lua_getlocal(L, func, i, &name)) == LUA_NOOBJECT) | ||
124 | break; | ||
125 | lua_pushobject(L, result); | ||
126 | lua_pushstring(L, name); | ||
127 | lua_pushobject(L, val); | ||
128 | lua_settable(L); /* result[name] = value */ | ||
129 | } | ||
130 | lua_pushobject(L, result); | ||
131 | } | 90 | } |
132 | } | 91 | } |
133 | 92 | ||
134 | 93 | ||
135 | static void setlocal (lua_State *L) { | 94 | static void setlocal (lua_State *L) { |
136 | lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1)); | 95 | lua_Dbgactreg ar; |
137 | int numvar; | 96 | lua_Dbglocvar lvar; |
138 | luaL_arg_check(L, func != LUA_NOOBJECT, 1, "level out of range"); | 97 | if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ |
139 | numvar = findlocal(L, func, 2); | 98 | luaL_argerror(L, 1, "level out of range"); |
140 | lua_pushobject(L, luaL_nonnullarg(L, 3)); | 99 | lvar.index = luaL_check_int(L, 2); |
141 | if (!lua_setlocal(L, func, numvar)) | 100 | lvar.value = luaL_nonnullarg(L, 3); |
142 | lua_error(L, "no such local variable"); | 101 | if (lua_setlocal(L, &ar, &lvar)) |
102 | lua_pushstring(L, lvar.name); | ||
143 | } | 103 | } |
144 | 104 | ||
145 | 105 | ||
@@ -149,21 +109,17 @@ static int callhook = LUA_NOREF; /* Lua reference to call hook function */ | |||
149 | 109 | ||
150 | 110 | ||
151 | 111 | ||
152 | static void linef (lua_State *L, int line) { | 112 | static void linef (lua_State *L, lua_Dbgactreg *ar) { |
153 | if (linehook != LUA_NOREF) { | 113 | if (linehook != LUA_NOREF) { |
154 | lua_pushnumber(L, line); | 114 | lua_pushnumber(L, ar->currentline); |
155 | lua_callfunction(L, lua_getref(L, linehook)); | 115 | lua_callfunction(L, lua_getref(L, linehook)); |
156 | } | 116 | } |
157 | } | 117 | } |
158 | 118 | ||
159 | 119 | ||
160 | static void callf (lua_State *L, lua_Function f, const char *file, int line) { | 120 | static void callf (lua_State *L, lua_Dbgactreg *ar) { |
161 | if (callhook != LUA_NOREF) { | 121 | if (callhook != LUA_NOREF) { |
162 | if (f != LUA_NOOBJECT) { | 122 | lua_pushstring(L, ar->event); |
163 | lua_pushobject(L, f); | ||
164 | lua_pushstring(L, file); | ||
165 | lua_pushnumber(L, line); | ||
166 | } | ||
167 | lua_callfunction(L, lua_getref(L, callhook)); | 123 | lua_callfunction(L, lua_getref(L, callhook)); |
168 | } | 124 | } |
169 | } | 125 | } |
@@ -200,7 +156,6 @@ static void setlinehook (lua_State *L) { | |||
200 | 156 | ||
201 | 157 | ||
202 | static const struct luaL_reg dblib[] = { | 158 | static const struct luaL_reg dblib[] = { |
203 | {"funcinfo", funcinfo}, | ||
204 | {"getlocal", getlocal}, | 159 | {"getlocal", getlocal}, |
205 | {"getstack", getstack}, | 160 | {"getstack", getstack}, |
206 | {"setcallhook", setcallhook}, | 161 | {"setcallhook", setcallhook}, |