ldblib.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:4k
源码类别:

模拟服务器

开发平台:

C/C++

  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. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "../lua.h"
  10. #include "../lauxlib.h"
  11. #include "../luadebug.h"
  12. #include "../lualib.h"
  13. static void settabss (lua_State *L, const char *i, const char *v) {
  14.   lua_pushstring(L, i);
  15.   lua_pushstring(L, v);
  16.   lua_settable(L, -3);
  17. }
  18. static void settabsi (lua_State *L, const char *i, int v) {
  19.   lua_pushstring(L, i);
  20.   lua_pushnumber(L, v);
  21.   lua_settable(L, -3);
  22. }
  23. static int getinfo (lua_State *L) {
  24.   lua_Debug ar;
  25.   const char *options = luaL_opt_string(L, 2, "flnSu");
  26.   char buff[20];
  27.   if (lua_isnumber(L, 1)) {
  28.     if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
  29.       lua_pushnil(L);  /* level out of range */
  30.       return 1;
  31.     }
  32.   }
  33.   else if (lua_isfunction(L, 1)) {
  34.     lua_pushvalue(L, 1);
  35.     sprintf(buff, ">%.10s", options);
  36.     options = buff;
  37.   }
  38.   else
  39.     luaL_argerror(L, 1, "function or level expected");
  40.   if (!lua_getinfo(L, options, &ar))
  41.     luaL_argerror(L, 2, "invalid option");
  42.   lua_newtable(L);
  43.   for (; *options; options++) {
  44.     switch (*options) {
  45.       case 'S':
  46.         settabss(L, "source", ar.source);
  47.         if (ar.source)
  48.           settabss(L, "short_src", ar.short_src);
  49.         settabsi(L, "linedefined", ar.linedefined);
  50.         settabss(L, "what", ar.what);
  51.         break;
  52.       case 'l':
  53.         settabsi(L, "currentline", ar.currentline);
  54.         break;
  55.       case 'u':
  56.         settabsi(L, "nups", ar.nups);
  57.         break;
  58.       case 'n':
  59.         settabss(L, "name", ar.name);
  60.         settabss(L, "namewhat", ar.namewhat);
  61.         break;
  62.       case 'f':
  63.         lua_pushstring(L, "func");
  64.         lua_pushvalue(L, -3);
  65.         lua_settable(L, -3);
  66.         break;
  67.     }
  68.   }
  69.   return 1;  /* return table */
  70. }
  71.     
  72. static int getlocal (lua_State *L) {
  73.   lua_Debug ar;
  74.   const char *name;
  75.   if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
  76.     luaL_argerror(L, 1, "level out of range");
  77.   name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
  78.   if (name) {
  79.     lua_pushstring(L, name);
  80.     lua_pushvalue(L, -2);
  81.     return 2;
  82.   }
  83.   else {
  84.     lua_pushnil(L);
  85.     return 1;
  86.   }
  87. }
  88. static int setlocal (lua_State *L) {
  89.   lua_Debug ar;
  90.   if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
  91.     luaL_argerror(L, 1, "level out of range");
  92.   luaL_checkany(L, 3);
  93.   lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
  94.   return 1;
  95. }
  96. /* dummy variables (to define unique addresses) */
  97. static char key1, key2;
  98. #define KEY_CALLHOOK (&key1)
  99. #define KEY_LINEHOOK (&key2)
  100. static void hookf (lua_State *L, void *key) {
  101.   lua_getregistry(L);
  102.   lua_pushuserdata(L, key);
  103.   lua_gettable(L, -2);
  104.   if (lua_isfunction(L, -1)) {
  105.     lua_pushvalue(L, 1);
  106.     lua_rawcall(L, 1, 0);
  107.   }
  108.   else
  109.     lua_pop(L, 1);  /* pop result from gettable */
  110.   lua_pop(L, 1);  /* pop table */
  111. }
  112. static void callf (lua_State *L, lua_Debug *ar) {
  113.   lua_pushstring(L, ar->event);
  114.   hookf(L, KEY_CALLHOOK);
  115. }
  116. static void linef (lua_State *L, lua_Debug *ar) {
  117.   lua_pushnumber(L, ar->currentline);
  118.   hookf(L, KEY_LINEHOOK);
  119. }
  120. static void sethook (lua_State *L, void *key, lua_Hook hook,
  121.                      lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
  122.   lua_settop(L, 1);
  123.   if (lua_isnil(L, 1))
  124.     (*sethookf)(L, NULL);
  125.   else if (lua_isfunction(L, 1))
  126.     (*sethookf)(L, hook);
  127.   else
  128.     luaL_argerror(L, 1, "function expected");
  129.   lua_getregistry(L);
  130.   lua_pushuserdata(L, key);
  131.   lua_pushvalue(L, -1);  /* dup key */
  132.   lua_gettable(L, -3);   /* get old value */
  133.   lua_pushvalue(L, -2);  /* key (again) */
  134.   lua_pushvalue(L, 1);
  135.   lua_settable(L, -5);  /* set new value */
  136. }
  137. static int setcallhook (lua_State *L) {
  138.   sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
  139.   return 1;
  140. }
  141. static int setlinehook (lua_State *L) {
  142.   sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
  143.   return 1;
  144. }
  145. static const struct luaL_reg dblib[] = {
  146.   {"getlocal", getlocal},
  147.   {"getinfo", getinfo},
  148.   {"setcallhook", setcallhook},
  149.   {"setlinehook", setlinehook},
  150.   {"setlocal", setlocal}
  151. };
  152. LUALIB_API void lua_dblibopen (lua_State *L) {
  153.   luaL_openl(L, dblib);
  154. }