ldblib.c 4.9 KB

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