diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-08 14:47:44 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-08 14:47:44 -0200 |
commit | 01772cefa5217a7840254d1e7ec340dea8f0747a (patch) | |
tree | 01fcf83242542a8ad171a358994b7c4c0cc835dd /ldblib.c | |
parent | dc90d4bce340f987a5048c17699a653f47360711 (diff) | |
download | lua-01772cefa5217a7840254d1e7ec340dea8f0747a.tar.gz lua-01772cefa5217a7840254d1e7ec340dea8f0747a.tar.bz2 lua-01772cefa5217a7840254d1e7ec340dea8f0747a.zip |
new library for debbuging
Diffstat (limited to 'ldblib.c')
-rw-r--r-- | ldblib.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/ldblib.c b/ldblib.c new file mode 100644 index 00000000..952f3cb3 --- /dev/null +++ b/ldblib.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | ** $Id: $ | ||
3 | ** Interface from Lua to its debug API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include "lauxlib.h" | ||
12 | #include "lua.h" | ||
13 | #include "luadebug.h" | ||
14 | |||
15 | |||
16 | |||
17 | static void settabss (lua_Object t, char *i, char *v) { | ||
18 | lua_pushobject(t); | ||
19 | lua_pushstring(i); | ||
20 | lua_pushstring(v); | ||
21 | lua_settable(); | ||
22 | } | ||
23 | |||
24 | |||
25 | static void settabsi (lua_Object t, char *i, int v) { | ||
26 | lua_pushobject(t); | ||
27 | lua_pushstring(i); | ||
28 | lua_pushnumber(v); | ||
29 | lua_settable(); | ||
30 | } | ||
31 | |||
32 | |||
33 | static lua_Object getfuncinfo (lua_Object func) { | ||
34 | lua_Object result = lua_createtable(); | ||
35 | char *name; | ||
36 | int line; | ||
37 | lua_funcinfo(func, &name, &line); | ||
38 | if (line == -1) /* C function? */ | ||
39 | settabss(result, "kind", "C"); | ||
40 | else if (line == 0) { /* "main"? */ | ||
41 | settabss(result, "kind", "chunk"); | ||
42 | settabss(result, "name", name); | ||
43 | } | ||
44 | else { /* Lua function */ | ||
45 | settabss(result, "kind", "Lua"); | ||
46 | settabsi(result, "def_line", line); | ||
47 | settabss(result, "def_chunk", name); | ||
48 | } | ||
49 | if (line != 0) { /* is it not a "main"? */ | ||
50 | char *kind = lua_getobjname(func, &name); | ||
51 | if (*kind) { | ||
52 | settabss(result, "name", name); | ||
53 | settabss(result, "where", kind); | ||
54 | } | ||
55 | } | ||
56 | return result; | ||
57 | } | ||
58 | |||
59 | |||
60 | static void getstack (void) { | ||
61 | lua_Object func = lua_stackedfunction(luaL_check_int(1)); | ||
62 | if (func == LUA_NOOBJECT) /* level out of range? */ | ||
63 | return; | ||
64 | else { | ||
65 | lua_Object result = getfuncinfo(func); | ||
66 | int currline = lua_currentline(func); | ||
67 | if (currline > 0) | ||
68 | settabsi(result, "current", currline); | ||
69 | lua_pushobject(result); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | |||
74 | static void funcinfo (void) { | ||
75 | lua_pushobject(getfuncinfo(luaL_functionarg(1))); | ||
76 | } | ||
77 | |||
78 | |||
79 | static int findlocal (lua_Object func, int arg) { | ||
80 | lua_Object v = lua_getparam(arg); | ||
81 | if (lua_isnumber(v)) | ||
82 | return (int)lua_getnumber(v); | ||
83 | else { | ||
84 | char *name = luaL_check_string(arg); | ||
85 | int i = 0; | ||
86 | int result = -1; | ||
87 | char *vname; | ||
88 | while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) { | ||
89 | if (strcmp(name, vname) == 0) | ||
90 | result = i; /* keep looping to get the last var with this name */ | ||
91 | } | ||
92 | if (result == -1) | ||
93 | luaL_verror("no local variable `%.50s' at given level", name); | ||
94 | return result; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | static void getlocal (void) { | ||
100 | lua_Object func = lua_stackedfunction(luaL_check_int(1)); | ||
101 | lua_Object val; | ||
102 | char *name; | ||
103 | if (func == LUA_NOOBJECT) /* level out of range? */ | ||
104 | return; /* return nil */ | ||
105 | else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */ | ||
106 | if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) { | ||
107 | lua_pushobject(val); | ||
108 | lua_pushstring(name); | ||
109 | } | ||
110 | /* else return nil */ | ||
111 | } | ||
112 | else { /* collect all locals in a table */ | ||
113 | lua_Object result = lua_createtable(); | ||
114 | int i; | ||
115 | for (i=1; ;i++) { | ||
116 | if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT) | ||
117 | break; | ||
118 | lua_pushobject(result); | ||
119 | lua_pushstring(name); | ||
120 | lua_pushobject(val); | ||
121 | lua_settable(); /* result[name] = value */ | ||
122 | } | ||
123 | lua_pushobject(result); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | |||
128 | static void setlocal (void) { | ||
129 | lua_Object func = lua_stackedfunction(luaL_check_int(1)); | ||
130 | int numvar; | ||
131 | luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range"); | ||
132 | numvar = findlocal(func, 2); | ||
133 | lua_pushobject(luaL_nonnullarg(3)); | ||
134 | if (!lua_setlocal(func, numvar)) | ||
135 | lua_error("no such local variable"); | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | static int linehook = -1; /* Lua reference to line hook function */ | ||
141 | static int callhook = -1; /* Lua reference to call hook function */ | ||
142 | |||
143 | |||
144 | static void dohook (int ref) { | ||
145 | lua_LHFunction oldlinehook = lua_linehook; /* save old hooks */ | ||
146 | lua_CHFunction oldcallhook = lua_callhook; | ||
147 | lua_linehook = NULL; lua_callhook = NULL; /* to avoid recusive calls */ | ||
148 | lua_callfunction(lua_getref(ref)); | ||
149 | lua_linehook = oldlinehook; /* restore old hooks */ | ||
150 | lua_callhook = oldcallhook; | ||
151 | } | ||
152 | |||
153 | |||
154 | static void linef (int line) { | ||
155 | lua_pushnumber(line); | ||
156 | dohook(linehook); | ||
157 | } | ||
158 | |||
159 | |||
160 | static void callf (lua_Function func, char *file, int line) { | ||
161 | if (func != LUA_NOOBJECT) { | ||
162 | lua_pushobject(func); | ||
163 | lua_pushstring(file); | ||
164 | lua_pushnumber(line); | ||
165 | } | ||
166 | dohook(callhook); | ||
167 | } | ||
168 | |||
169 | |||
170 | static void setcallhook (void) { | ||
171 | lua_Object f = lua_getparam(1); | ||
172 | lua_unref(callhook); | ||
173 | if (f == LUA_NOOBJECT) { | ||
174 | callhook = -1; | ||
175 | lua_callhook = NULL; | ||
176 | } | ||
177 | else { | ||
178 | lua_pushobject(f); | ||
179 | callhook = lua_ref(1); | ||
180 | lua_callhook = callf; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | |||
185 | static void setlinehook (void) { | ||
186 | lua_Object f = lua_getparam(1); | ||
187 | lua_unref(linehook); | ||
188 | if (f == LUA_NOOBJECT) { | ||
189 | linehook = -1; | ||
190 | lua_linehook = NULL; | ||
191 | } | ||
192 | else { | ||
193 | lua_pushobject(f); | ||
194 | linehook = lua_ref(1); | ||
195 | lua_linehook = linef; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | |||
200 | static struct luaL_reg dblib[] = { | ||
201 | {"funcinfo", funcinfo}, | ||
202 | {"getlocal", getlocal}, | ||
203 | {"getstack", getstack}, | ||
204 | {"setcallhook", setcallhook}, | ||
205 | {"setlinehook", setlinehook}, | ||
206 | {"setlocal", setlocal} | ||
207 | }; | ||
208 | |||
209 | |||
210 | void lua_dblibopen (void) { | ||
211 | luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0]))); | ||
212 | } | ||
213 | |||