Imported from ../lua-4.0.1.tar.gz.
[lua.git] / src / lib / ldblib.c
blob636dbe05546a8ff84fbee3c5625d0a75293c16e2
1 /*
2 ** $Id: ldblib.c,v 1.29 2000/11/06 17:58:38 roberto Exp $
3 ** Interface from Lua to its debug API
4 ** See Copyright Notice in lua.h
5 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "lua.h"
14 #include "lauxlib.h"
15 #include "luadebug.h"
16 #include "lualib.h"
20 static void settabss (lua_State *L, const char *i, const char *v) {
21 lua_pushstring(L, i);
22 lua_pushstring(L, v);
23 lua_settable(L, -3);
27 static void settabsi (lua_State *L, const char *i, int v) {
28 lua_pushstring(L, i);
29 lua_pushnumber(L, v);
30 lua_settable(L, -3);
34 static int getinfo (lua_State *L) {
35 lua_Debug ar;
36 const char *options = luaL_opt_string(L, 2, "flnSu");
37 char buff[20];
38 if (lua_isnumber(L, 1)) {
39 if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
40 lua_pushnil(L); /* level out of range */
41 return 1;
44 else if (lua_isfunction(L, 1)) {
45 lua_pushvalue(L, 1);
46 sprintf(buff, ">%.10s", options);
47 options = buff;
49 else
50 luaL_argerror(L, 1, "function or level expected");
51 if (!lua_getinfo(L, options, &ar))
52 luaL_argerror(L, 2, "invalid option");
53 lua_newtable(L);
54 for (; *options; options++) {
55 switch (*options) {
56 case 'S':
57 settabss(L, "source", ar.source);
58 if (ar.source)
59 settabss(L, "short_src", ar.short_src);
60 settabsi(L, "linedefined", ar.linedefined);
61 settabss(L, "what", ar.what);
62 break;
63 case 'l':
64 settabsi(L, "currentline", ar.currentline);
65 break;
66 case 'u':
67 settabsi(L, "nups", ar.nups);
68 break;
69 case 'n':
70 settabss(L, "name", ar.name);
71 settabss(L, "namewhat", ar.namewhat);
72 break;
73 case 'f':
74 lua_pushstring(L, "func");
75 lua_pushvalue(L, -3);
76 lua_settable(L, -3);
77 break;
80 return 1; /* return table */
84 static int getlocal (lua_State *L) {
85 lua_Debug ar;
86 const char *name;
87 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
88 luaL_argerror(L, 1, "level out of range");
89 name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
90 if (name) {
91 lua_pushstring(L, name);
92 lua_pushvalue(L, -2);
93 return 2;
95 else {
96 lua_pushnil(L);
97 return 1;
102 static int setlocal (lua_State *L) {
103 lua_Debug ar;
104 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
105 luaL_argerror(L, 1, "level out of range");
106 luaL_checkany(L, 3);
107 lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
108 return 1;
113 /* dummy variables (to define unique addresses) */
114 static char key1, key2;
115 #define KEY_CALLHOOK (&key1)
116 #define KEY_LINEHOOK (&key2)
119 static void hookf (lua_State *L, void *key) {
120 lua_getregistry(L);
121 lua_pushuserdata(L, key);
122 lua_gettable(L, -2);
123 if (lua_isfunction(L, -1)) {
124 lua_pushvalue(L, 1);
125 lua_rawcall(L, 1, 0);
127 else
128 lua_pop(L, 1); /* pop result from gettable */
129 lua_pop(L, 1); /* pop table */
133 static void callf (lua_State *L, lua_Debug *ar) {
134 lua_pushstring(L, ar->event);
135 hookf(L, KEY_CALLHOOK);
139 static void linef (lua_State *L, lua_Debug *ar) {
140 lua_pushnumber(L, ar->currentline);
141 hookf(L, KEY_LINEHOOK);
145 static void sethook (lua_State *L, void *key, lua_Hook hook,
146 lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
147 lua_settop(L, 1);
148 if (lua_isnil(L, 1))
149 (*sethookf)(L, NULL);
150 else if (lua_isfunction(L, 1))
151 (*sethookf)(L, hook);
152 else
153 luaL_argerror(L, 1, "function expected");
154 lua_getregistry(L);
155 lua_pushuserdata(L, key);
156 lua_pushvalue(L, -1); /* dup key */
157 lua_gettable(L, -3); /* get old value */
158 lua_pushvalue(L, -2); /* key (again) */
159 lua_pushvalue(L, 1);
160 lua_settable(L, -5); /* set new value */
164 static int setcallhook (lua_State *L) {
165 sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
166 return 1;
170 static int setlinehook (lua_State *L) {
171 sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
172 return 1;
176 static const struct luaL_reg dblib[] = {
177 {"getlocal", getlocal},
178 {"getinfo", getinfo},
179 {"setcallhook", setcallhook},
180 {"setlinehook", setlinehook},
181 {"setlocal", setlocal}
185 LUALIB_API void lua_dblibopen (lua_State *L) {
186 luaL_openl(L, dblib);