ldblib.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. ** $Id: ldblib.c,v 1.7 1999/11/22 13:12:07 roberto Exp roberto $
  3. ** Interface from Lua to its debug API
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #define LUA_REENTRANT
  9. #include "lauxlib.h"
  10. #include "lua.h"
  11. #include "luadebug.h"
  12. #include "lualib.h"
  13. static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) {
  14. lua_pushobject(L, t);
  15. lua_pushstring(L, i);
  16. lua_pushstring(L, v);
  17. lua_settable(L);
  18. }
  19. static void settabsi (lua_State *L, lua_Object t, const char *i, int v) {
  20. lua_pushobject(L, t);
  21. lua_pushstring(L, i);
  22. lua_pushnumber(L, v);
  23. lua_settable(L);
  24. }
  25. static lua_Object getfuncinfo (lua_State *L, lua_Object func) {
  26. lua_Object result = lua_createtable(L);
  27. const char *str;
  28. int line;
  29. lua_funcinfo(L, func, &str, &line);
  30. if (line == -1) /* C function? */
  31. settabss(L, result, "kind", "C");
  32. else if (line == 0) { /* "main"? */
  33. settabss(L, result, "kind", "chunk");
  34. settabss(L, result, "source", str);
  35. }
  36. else { /* Lua function */
  37. settabss(L, result, "kind", "Lua");
  38. settabsi(L, result, "def_line", line);
  39. settabss(L, result, "source", str);
  40. }
  41. if (line != 0) { /* is it not a "main"? */
  42. const char *kind = lua_getobjname(L, func, &str);
  43. if (*kind) {
  44. settabss(L, result, "name", str);
  45. settabss(L, result, "where", kind);
  46. }
  47. }
  48. return result;
  49. }
  50. static void getstack (lua_State *L) {
  51. lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
  52. if (func == LUA_NOOBJECT) /* level out of range? */
  53. return;
  54. else {
  55. lua_Object result = getfuncinfo(L, func);
  56. int currline = lua_currentline(L, func);
  57. if (currline > 0)
  58. settabsi(L, result, "current", currline);
  59. lua_pushobject(L, result);
  60. lua_pushstring(L, "func");
  61. lua_pushobject(L, func);
  62. lua_settable(L); /* result.func = func */
  63. lua_pushobject(L, result);
  64. }
  65. }
  66. static void funcinfo (lua_State *L) {
  67. lua_pushobject(L, getfuncinfo(L, luaL_functionarg(L, 1)));
  68. }
  69. static int findlocal (lua_State *L, lua_Object func, int arg) {
  70. lua_Object v = lua_getparam(L, arg);
  71. if (lua_isnumber(L, v))
  72. return (int)lua_getnumber(L, v);
  73. else {
  74. const char *name = luaL_check_string(L, arg);
  75. int i = 0;
  76. int result = -1;
  77. const char *vname;
  78. while (lua_getlocal(L, func, ++i, &vname) != LUA_NOOBJECT) {
  79. if (strcmp(name, vname) == 0)
  80. result = i; /* keep looping to get the last var with this name */
  81. }
  82. if (result == -1)
  83. luaL_verror(L, "no local variable `%.50s' at given level", name);
  84. return result;
  85. }
  86. }
  87. static void getlocal (lua_State *L) {
  88. lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
  89. lua_Object val;
  90. const char *name;
  91. if (func == LUA_NOOBJECT) /* level out of range? */
  92. return; /* return nil */
  93. else if (lua_getparam(L, 2) != LUA_NOOBJECT) { /* 2nd argument? */
  94. if ((val = lua_getlocal(L, func, findlocal(L, func, 2), &name)) != LUA_NOOBJECT) {
  95. lua_pushobject(L, val);
  96. lua_pushstring(L, name);
  97. }
  98. /* else return nil */
  99. }
  100. else { /* collect all locals in a table */
  101. lua_Object result = lua_createtable(L);
  102. int i;
  103. for (i=1; ;i++) {
  104. if ((val = lua_getlocal(L, func, i, &name)) == LUA_NOOBJECT)
  105. break;
  106. lua_pushobject(L, result);
  107. lua_pushstring(L, name);
  108. lua_pushobject(L, val);
  109. lua_settable(L); /* result[name] = value */
  110. }
  111. lua_pushobject(L, result);
  112. }
  113. }
  114. static void setlocal (lua_State *L) {
  115. lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
  116. int numvar;
  117. luaL_arg_check(L, func != LUA_NOOBJECT, 1, "level out of range");
  118. numvar = findlocal(L, func, 2);
  119. lua_pushobject(L, luaL_nonnullarg(L, 3));
  120. if (!lua_setlocal(L, func, numvar))
  121. lua_error(L, "no such local variable");
  122. }
  123. static int linehook = -1; /* Lua reference to line hook function */
  124. static int callhook = -1; /* Lua reference to call hook function */
  125. static void dohook (lua_State *L, int ref) {
  126. lua_LHFunction oldlinehook = lua_setlinehook(L, NULL);
  127. lua_CHFunction oldcallhook = lua_setcallhook(L, NULL);
  128. lua_callfunction(L, lua_getref(L, ref));
  129. lua_setlinehook(L, oldlinehook);
  130. lua_setcallhook(L, oldcallhook);
  131. }
  132. static void linef (lua_State *L, int line) {
  133. lua_pushnumber(L, line);
  134. dohook(L, linehook);
  135. }
  136. static void callf (lua_State *L, lua_Function func, const char *file, int line) {
  137. if (func != LUA_NOOBJECT) {
  138. lua_pushobject(L, func);
  139. lua_pushstring(L, file);
  140. lua_pushnumber(L, line);
  141. }
  142. dohook(L, callhook);
  143. }
  144. static void setcallhook (lua_State *L) {
  145. lua_Object f = lua_getparam(L, 1);
  146. lua_unref(L, callhook);
  147. if (f == LUA_NOOBJECT) {
  148. callhook = -1;
  149. lua_setcallhook(L, NULL);
  150. }
  151. else {
  152. lua_pushobject(L, f);
  153. callhook = lua_ref(L, 1);
  154. lua_setcallhook(L, callf);
  155. }
  156. }
  157. static void setlinehook (lua_State *L) {
  158. lua_Object f = lua_getparam(L, 1);
  159. lua_unref(L, linehook);
  160. if (f == LUA_NOOBJECT) {
  161. linehook = -1;
  162. lua_setlinehook(L, NULL);
  163. }
  164. else {
  165. lua_pushobject(L, f);
  166. linehook = lua_ref(L, 1);
  167. lua_setlinehook(L, linef);
  168. }
  169. }
  170. static const struct luaL_reg dblib[] = {
  171. {"funcinfo", funcinfo},
  172. {"getlocal", getlocal},
  173. {"getstack", getstack},
  174. {"setcallhook", setcallhook},
  175. {"setlinehook", setlinehook},
  176. {"setlocal", setlocal}
  177. };
  178. void lua_dblibopen (lua_State *L) {
  179. luaL_openl(L, dblib);
  180. }