dub 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/.gitignore +8 -0
  2. data/History.txt +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +53 -0
  5. data/Rakefile +58 -0
  6. data/dub.gemspec +194 -0
  7. data/lib/dub/argument.rb +261 -0
  8. data/lib/dub/entities_unescape.rb +16 -0
  9. data/lib/dub/function.rb +111 -0
  10. data/lib/dub/function_group.rb +74 -0
  11. data/lib/dub/generator.rb +15 -0
  12. data/lib/dub/group.rb +10 -0
  13. data/lib/dub/klass.rb +231 -0
  14. data/lib/dub/lua/class.cpp.erb +75 -0
  15. data/lib/dub/lua/class_gen.rb +78 -0
  16. data/lib/dub/lua/function.cpp.erb +4 -0
  17. data/lib/dub/lua/function_gen.rb +223 -0
  18. data/lib/dub/lua/group.cpp.erb +10 -0
  19. data/lib/dub/lua/lua_cpp_helper.h +141 -0
  20. data/lib/dub/lua/namespace.cpp.erb +35 -0
  21. data/lib/dub/lua/namespace_gen.rb +86 -0
  22. data/lib/dub/lua.rb +24 -0
  23. data/lib/dub/member_extraction.rb +88 -0
  24. data/lib/dub/namespace.rb +276 -0
  25. data/lib/dub/parser.rb +46 -0
  26. data/lib/dub/templates/lua_template.erb +21 -0
  27. data/lib/dub/version.rb +3 -0
  28. data/lib/dub.rb +26 -0
  29. data/test/argument_test.rb +423 -0
  30. data/test/fixtures/app/CMakeLists.txt +54 -0
  31. data/test/fixtures/app/Doxyfile +1600 -0
  32. data/test/fixtures/app/bindings/all_lua.cpp +299 -0
  33. data/test/fixtures/app/include/matrix.h +123 -0
  34. data/test/fixtures/app/make_lua_bindings.rb +13 -0
  35. data/test/fixtures/app/vendor/lua/CMakeLists.txt +25 -0
  36. data/test/fixtures/app/vendor/lua/COPYRIGHT +34 -0
  37. data/test/fixtures/app/vendor/lua/HISTORY +183 -0
  38. data/test/fixtures/app/vendor/lua/INSTALL +99 -0
  39. data/test/fixtures/app/vendor/lua/Makefile +183 -0
  40. data/test/fixtures/app/vendor/lua/README +37 -0
  41. data/test/fixtures/app/vendor/lua/lapi.c +1080 -0
  42. data/test/fixtures/app/vendor/lua/lapi.h +16 -0
  43. data/test/fixtures/app/vendor/lua/lauxlib.c +653 -0
  44. data/test/fixtures/app/vendor/lua/lauxlib.h +174 -0
  45. data/test/fixtures/app/vendor/lua/lbaselib.c +643 -0
  46. data/test/fixtures/app/vendor/lua/lcode.c +839 -0
  47. data/test/fixtures/app/vendor/lua/lcode.h +76 -0
  48. data/test/fixtures/app/vendor/lua/ldblib.c +397 -0
  49. data/test/fixtures/app/vendor/lua/ldebug.c +622 -0
  50. data/test/fixtures/app/vendor/lua/ldebug.h +33 -0
  51. data/test/fixtures/app/vendor/lua/ldo.c +516 -0
  52. data/test/fixtures/app/vendor/lua/ldo.h +57 -0
  53. data/test/fixtures/app/vendor/lua/ldump.c +164 -0
  54. data/test/fixtures/app/vendor/lua/lfunc.c +174 -0
  55. data/test/fixtures/app/vendor/lua/lfunc.h +34 -0
  56. data/test/fixtures/app/vendor/lua/lgc.c +711 -0
  57. data/test/fixtures/app/vendor/lua/lgc.h +110 -0
  58. data/test/fixtures/app/vendor/lua/liblua.a +0 -0
  59. data/test/fixtures/app/vendor/lua/linit.c +38 -0
  60. data/test/fixtures/app/vendor/lua/liolib.c +532 -0
  61. data/test/fixtures/app/vendor/lua/llex.c +461 -0
  62. data/test/fixtures/app/vendor/lua/llex.h +81 -0
  63. data/test/fixtures/app/vendor/lua/llimits.h +128 -0
  64. data/test/fixtures/app/vendor/lua/lmathlib.c +263 -0
  65. data/test/fixtures/app/vendor/lua/lmem.c +86 -0
  66. data/test/fixtures/app/vendor/lua/lmem.h +49 -0
  67. data/test/fixtures/app/vendor/lua/loadlib.c +664 -0
  68. data/test/fixtures/app/vendor/lua/lobject.c +214 -0
  69. data/test/fixtures/app/vendor/lua/lobject.h +381 -0
  70. data/test/fixtures/app/vendor/lua/lopcodes.c +102 -0
  71. data/test/fixtures/app/vendor/lua/lopcodes.h +268 -0
  72. data/test/fixtures/app/vendor/lua/loslib.c +244 -0
  73. data/test/fixtures/app/vendor/lua/lparser.c +1337 -0
  74. data/test/fixtures/app/vendor/lua/lparser.h +82 -0
  75. data/test/fixtures/app/vendor/lua/lstate.c +214 -0
  76. data/test/fixtures/app/vendor/lua/lstate.h +168 -0
  77. data/test/fixtures/app/vendor/lua/lstring.c +111 -0
  78. data/test/fixtures/app/vendor/lua/lstring.h +31 -0
  79. data/test/fixtures/app/vendor/lua/lstrlib.c +868 -0
  80. data/test/fixtures/app/vendor/lua/ltable.c +588 -0
  81. data/test/fixtures/app/vendor/lua/ltable.h +40 -0
  82. data/test/fixtures/app/vendor/lua/ltablib.c +278 -0
  83. data/test/fixtures/app/vendor/lua/ltm.c +75 -0
  84. data/test/fixtures/app/vendor/lua/ltm.h +54 -0
  85. data/test/fixtures/app/vendor/lua/lua.c +695 -0
  86. data/test/fixtures/app/vendor/lua/lua.h +385 -0
  87. data/test/fixtures/app/vendor/lua/lua_dub_helper.h +77 -0
  88. data/test/fixtures/app/vendor/lua/luac +0 -0
  89. data/test/fixtures/app/vendor/lua/luac.c +200 -0
  90. data/test/fixtures/app/vendor/lua/luaconf.h +762 -0
  91. data/test/fixtures/app/vendor/lua/lualib.h +53 -0
  92. data/test/fixtures/app/vendor/lua/lundump.c +223 -0
  93. data/test/fixtures/app/vendor/lua/lundump.h +36 -0
  94. data/test/fixtures/app/vendor/lua/lvm.c +765 -0
  95. data/test/fixtures/app/vendor/lua/lvm.h +36 -0
  96. data/test/fixtures/app/vendor/lua/lzio.c +82 -0
  97. data/test/fixtures/app/vendor/lua/lzio.h +67 -0
  98. data/test/fixtures/app/vendor/lua/matrix.h +102 -0
  99. data/test/fixtures/app/vendor/lua/print.c +227 -0
  100. data/test/fixtures/app/vendor/lua/test/README +26 -0
  101. data/test/fixtures/app/vendor/lua/test/bisect.lua +27 -0
  102. data/test/fixtures/app/vendor/lua/test/cf.lua +16 -0
  103. data/test/fixtures/app/vendor/lua/test/echo.lua +5 -0
  104. data/test/fixtures/app/vendor/lua/test/env.lua +7 -0
  105. data/test/fixtures/app/vendor/lua/test/factorial.lua +32 -0
  106. data/test/fixtures/app/vendor/lua/test/fib.lua +40 -0
  107. data/test/fixtures/app/vendor/lua/test/fibfor.lua +13 -0
  108. data/test/fixtures/app/vendor/lua/test/globals.lua +13 -0
  109. data/test/fixtures/app/vendor/lua/test/hello.lua +3 -0
  110. data/test/fixtures/app/vendor/lua/test/life.lua +111 -0
  111. data/test/fixtures/app/vendor/lua/test/luac.lua +7 -0
  112. data/test/fixtures/app/vendor/lua/test/printf.lua +7 -0
  113. data/test/fixtures/app/vendor/lua/test/readonly.lua +12 -0
  114. data/test/fixtures/app/vendor/lua/test/sieve.lua +29 -0
  115. data/test/fixtures/app/vendor/lua/test/sort.lua +66 -0
  116. data/test/fixtures/app/vendor/lua/test/table.lua +12 -0
  117. data/test/fixtures/app/vendor/lua/test/trace-calls.lua +32 -0
  118. data/test/fixtures/app/vendor/lua/test/trace-globals.lua +38 -0
  119. data/test/fixtures/app/vendor/lua/test/xd.lua +14 -0
  120. data/test/fixtures/app/xml/classdub_1_1_matrix.xml +239 -0
  121. data/test/fixtures/app/xml/classdub_1_1_t_mat.xml +233 -0
  122. data/test/fixtures/app/xml/combine.xslt +15 -0
  123. data/test/fixtures/app/xml/compound.xsd +814 -0
  124. data/test/fixtures/app/xml/dir_53661a2bdeb1d55e60581a7e15deb763.xml +12 -0
  125. data/test/fixtures/app/xml/index.xml +42 -0
  126. data/test/fixtures/app/xml/index.xsd +66 -0
  127. data/test/fixtures/app/xml/matrix_8h.xml +149 -0
  128. data/test/fixtures/app/xml/namespacedub.xml +41 -0
  129. data/test/fixtures/classcv_1_1_mat.xml +1996 -0
  130. data/test/fixtures/classcv_1_1_point__.xml +341 -0
  131. data/test/fixtures/classcv_1_1_size__.xml +270 -0
  132. data/test/fixtures/group___magic_type.xml +406 -0
  133. data/test/fixtures/namespacecv.xml +12659 -0
  134. data/test/function_group_test.rb +15 -0
  135. data/test/function_test.rb +252 -0
  136. data/test/group_test.rb +155 -0
  137. data/test/helper.rb +34 -0
  138. data/test/klass_test.rb +297 -0
  139. data/test/lua_function_gen_test.rb +179 -0
  140. data/test/namespace_test.rb +220 -0
  141. data/test/parser_test.rb +36 -0
  142. metadata +216 -0
@@ -0,0 +1,76 @@
1
+ /*
2
+ ** $Id: lcode.h,v 1.48 2006/03/21 19:28:03 roberto Exp $
3
+ ** Code generator for Lua
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+ #ifndef lcode_h
8
+ #define lcode_h
9
+
10
+ #include "llex.h"
11
+ #include "lobject.h"
12
+ #include "lopcodes.h"
13
+ #include "lparser.h"
14
+
15
+
16
+ /*
17
+ ** Marks the end of a patch list. It is an invalid value both as an absolute
18
+ ** address, and as a list link (would link an element to itself).
19
+ */
20
+ #define NO_JUMP (-1)
21
+
22
+
23
+ /*
24
+ ** grep "ORDER OPR" if you change these enums
25
+ */
26
+ typedef enum BinOpr {
27
+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28
+ OPR_CONCAT,
29
+ OPR_NE, OPR_EQ,
30
+ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
31
+ OPR_AND, OPR_OR,
32
+ OPR_NOBINOPR
33
+ } BinOpr;
34
+
35
+
36
+ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37
+
38
+
39
+ #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
40
+
41
+ #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42
+
43
+ #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
44
+
45
+ LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46
+ LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
47
+ LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
48
+ LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
49
+ LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
50
+ LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
51
+ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
52
+ LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
53
+ LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
54
+ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
55
+ LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56
+ LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
57
+ LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
58
+ LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59
+ LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60
+ LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
61
+ LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
62
+ LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
63
+ LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
64
+ LUAI_FUNC int luaK_jump (FuncState *fs);
65
+ LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
66
+ LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
67
+ LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
68
+ LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
69
+ LUAI_FUNC int luaK_getlabel (FuncState *fs);
70
+ LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
71
+ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
72
+ LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
73
+ LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
74
+
75
+
76
+ #endif
@@ -0,0 +1,397 @@
1
+ /*
2
+ ** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp $
3
+ ** Interface from Lua to its debug API
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ #define ldblib_c
13
+ #define LUA_LIB
14
+
15
+ #include "lua.h"
16
+
17
+ #include "lauxlib.h"
18
+ #include "lualib.h"
19
+
20
+
21
+
22
+ static int db_getregistry (lua_State *L) {
23
+ lua_pushvalue(L, LUA_REGISTRYINDEX);
24
+ return 1;
25
+ }
26
+
27
+
28
+ static int db_getmetatable (lua_State *L) {
29
+ luaL_checkany(L, 1);
30
+ if (!lua_getmetatable(L, 1)) {
31
+ lua_pushnil(L); /* no metatable */
32
+ }
33
+ return 1;
34
+ }
35
+
36
+
37
+ static int db_setmetatable (lua_State *L) {
38
+ int t = lua_type(L, 2);
39
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
40
+ "nil or table expected");
41
+ lua_settop(L, 2);
42
+ lua_pushboolean(L, lua_setmetatable(L, 1));
43
+ return 1;
44
+ }
45
+
46
+
47
+ static int db_getfenv (lua_State *L) {
48
+ lua_getfenv(L, 1);
49
+ return 1;
50
+ }
51
+
52
+
53
+ static int db_setfenv (lua_State *L) {
54
+ luaL_checktype(L, 2, LUA_TTABLE);
55
+ lua_settop(L, 2);
56
+ if (lua_setfenv(L, 1) == 0)
57
+ luaL_error(L, LUA_QL("setfenv")
58
+ " cannot change environment of given object");
59
+ return 1;
60
+ }
61
+
62
+
63
+ static void settabss (lua_State *L, const char *i, const char *v) {
64
+ lua_pushstring(L, v);
65
+ lua_setfield(L, -2, i);
66
+ }
67
+
68
+
69
+ static void settabsi (lua_State *L, const char *i, int v) {
70
+ lua_pushinteger(L, v);
71
+ lua_setfield(L, -2, i);
72
+ }
73
+
74
+
75
+ static lua_State *getthread (lua_State *L, int *arg) {
76
+ if (lua_isthread(L, 1)) {
77
+ *arg = 1;
78
+ return lua_tothread(L, 1);
79
+ }
80
+ else {
81
+ *arg = 0;
82
+ return L;
83
+ }
84
+ }
85
+
86
+
87
+ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
88
+ if (L == L1) {
89
+ lua_pushvalue(L, -2);
90
+ lua_remove(L, -3);
91
+ }
92
+ else
93
+ lua_xmove(L1, L, 1);
94
+ lua_setfield(L, -2, fname);
95
+ }
96
+
97
+
98
+ static int db_getinfo (lua_State *L) {
99
+ lua_Debug ar;
100
+ int arg;
101
+ lua_State *L1 = getthread(L, &arg);
102
+ const char *options = luaL_optstring(L, arg+2, "flnSu");
103
+ if (lua_isnumber(L, arg+1)) {
104
+ if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
105
+ lua_pushnil(L); /* level out of range */
106
+ return 1;
107
+ }
108
+ }
109
+ else if (lua_isfunction(L, arg+1)) {
110
+ lua_pushfstring(L, ">%s", options);
111
+ options = lua_tostring(L, -1);
112
+ lua_pushvalue(L, arg+1);
113
+ lua_xmove(L, L1, 1);
114
+ }
115
+ else
116
+ return luaL_argerror(L, arg+1, "function or level expected");
117
+ if (!lua_getinfo(L1, options, &ar))
118
+ return luaL_argerror(L, arg+2, "invalid option");
119
+ lua_createtable(L, 0, 2);
120
+ if (strchr(options, 'S')) {
121
+ settabss(L, "source", ar.source);
122
+ settabss(L, "short_src", ar.short_src);
123
+ settabsi(L, "linedefined", ar.linedefined);
124
+ settabsi(L, "lastlinedefined", ar.lastlinedefined);
125
+ settabss(L, "what", ar.what);
126
+ }
127
+ if (strchr(options, 'l'))
128
+ settabsi(L, "currentline", ar.currentline);
129
+ if (strchr(options, 'u'))
130
+ settabsi(L, "nups", ar.nups);
131
+ if (strchr(options, 'n')) {
132
+ settabss(L, "name", ar.name);
133
+ settabss(L, "namewhat", ar.namewhat);
134
+ }
135
+ if (strchr(options, 'L'))
136
+ treatstackoption(L, L1, "activelines");
137
+ if (strchr(options, 'f'))
138
+ treatstackoption(L, L1, "func");
139
+ return 1; /* return table */
140
+ }
141
+
142
+
143
+ static int db_getlocal (lua_State *L) {
144
+ int arg;
145
+ lua_State *L1 = getthread(L, &arg);
146
+ lua_Debug ar;
147
+ const char *name;
148
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
149
+ return luaL_argerror(L, arg+1, "level out of range");
150
+ name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
151
+ if (name) {
152
+ lua_xmove(L1, L, 1);
153
+ lua_pushstring(L, name);
154
+ lua_pushvalue(L, -2);
155
+ return 2;
156
+ }
157
+ else {
158
+ lua_pushnil(L);
159
+ return 1;
160
+ }
161
+ }
162
+
163
+
164
+ static int db_setlocal (lua_State *L) {
165
+ int arg;
166
+ lua_State *L1 = getthread(L, &arg);
167
+ lua_Debug ar;
168
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
169
+ return luaL_argerror(L, arg+1, "level out of range");
170
+ luaL_checkany(L, arg+3);
171
+ lua_settop(L, arg+3);
172
+ lua_xmove(L, L1, 1);
173
+ lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
174
+ return 1;
175
+ }
176
+
177
+
178
+ static int auxupvalue (lua_State *L, int get) {
179
+ const char *name;
180
+ int n = luaL_checkint(L, 2);
181
+ luaL_checktype(L, 1, LUA_TFUNCTION);
182
+ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
183
+ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
184
+ if (name == NULL) return 0;
185
+ lua_pushstring(L, name);
186
+ lua_insert(L, -(get+1));
187
+ return get + 1;
188
+ }
189
+
190
+
191
+ static int db_getupvalue (lua_State *L) {
192
+ return auxupvalue(L, 1);
193
+ }
194
+
195
+
196
+ static int db_setupvalue (lua_State *L) {
197
+ luaL_checkany(L, 3);
198
+ return auxupvalue(L, 0);
199
+ }
200
+
201
+
202
+
203
+ static const char KEY_HOOK = 'h';
204
+
205
+
206
+ static void hookf (lua_State *L, lua_Debug *ar) {
207
+ static const char *const hooknames[] =
208
+ {"call", "return", "line", "count", "tail return"};
209
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
210
+ lua_rawget(L, LUA_REGISTRYINDEX);
211
+ lua_pushlightuserdata(L, L);
212
+ lua_rawget(L, -2);
213
+ if (lua_isfunction(L, -1)) {
214
+ lua_pushstring(L, hooknames[(int)ar->event]);
215
+ if (ar->currentline >= 0)
216
+ lua_pushinteger(L, ar->currentline);
217
+ else lua_pushnil(L);
218
+ lua_assert(lua_getinfo(L, "lS", ar));
219
+ lua_call(L, 2, 0);
220
+ }
221
+ }
222
+
223
+
224
+ static int makemask (const char *smask, int count) {
225
+ int mask = 0;
226
+ if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
227
+ if (strchr(smask, 'r')) mask |= LUA_MASKRET;
228
+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
229
+ if (count > 0) mask |= LUA_MASKCOUNT;
230
+ return mask;
231
+ }
232
+
233
+
234
+ static char *unmakemask (int mask, char *smask) {
235
+ int i = 0;
236
+ if (mask & LUA_MASKCALL) smask[i++] = 'c';
237
+ if (mask & LUA_MASKRET) smask[i++] = 'r';
238
+ if (mask & LUA_MASKLINE) smask[i++] = 'l';
239
+ smask[i] = '\0';
240
+ return smask;
241
+ }
242
+
243
+
244
+ static void gethooktable (lua_State *L) {
245
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
246
+ lua_rawget(L, LUA_REGISTRYINDEX);
247
+ if (!lua_istable(L, -1)) {
248
+ lua_pop(L, 1);
249
+ lua_createtable(L, 0, 1);
250
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
251
+ lua_pushvalue(L, -2);
252
+ lua_rawset(L, LUA_REGISTRYINDEX);
253
+ }
254
+ }
255
+
256
+
257
+ static int db_sethook (lua_State *L) {
258
+ int arg;
259
+ lua_State *L1 = getthread(L, &arg);
260
+ if (lua_isnoneornil(L, arg+1)) {
261
+ lua_settop(L, arg+1);
262
+ lua_sethook(L1, NULL, 0, 0); /* turn off hooks */
263
+ }
264
+ else {
265
+ const char *smask = luaL_checkstring(L, arg+2);
266
+ int count = luaL_optint(L, arg+3, 0);
267
+ luaL_checktype(L, arg+1, LUA_TFUNCTION);
268
+ lua_sethook(L1, hookf, makemask(smask, count), count);
269
+ }
270
+ gethooktable(L1);
271
+ lua_pushlightuserdata(L1, L1);
272
+ lua_pushvalue(L, arg+1);
273
+ lua_xmove(L, L1, 1);
274
+ lua_rawset(L1, -3); /* set new hook */
275
+ lua_pop(L1, 1); /* remove hook table */
276
+ return 0;
277
+ }
278
+
279
+
280
+ static int db_gethook (lua_State *L) {
281
+ int arg;
282
+ lua_State *L1 = getthread(L, &arg);
283
+ char buff[5];
284
+ int mask = lua_gethookmask(L1);
285
+ lua_Hook hook = lua_gethook(L1);
286
+ if (hook != NULL && hook != hookf) /* external hook? */
287
+ lua_pushliteral(L, "external hook");
288
+ else {
289
+ gethooktable(L1);
290
+ lua_pushlightuserdata(L1, L1);
291
+ lua_rawget(L1, -2); /* get hook */
292
+ lua_remove(L1, -2); /* remove hook table */
293
+ lua_xmove(L1, L, 1);
294
+ }
295
+ lua_pushstring(L, unmakemask(mask, buff));
296
+ lua_pushinteger(L, lua_gethookcount(L1));
297
+ return 3;
298
+ }
299
+
300
+
301
+ static int db_debug (lua_State *L) {
302
+ for (;;) {
303
+ char buffer[250];
304
+ fputs("lua_debug> ", stderr);
305
+ if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
306
+ strcmp(buffer, "cont\n") == 0)
307
+ return 0;
308
+ if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
309
+ lua_pcall(L, 0, 0, 0)) {
310
+ fputs(lua_tostring(L, -1), stderr);
311
+ fputs("\n", stderr);
312
+ }
313
+ lua_settop(L, 0); /* remove eventual returns */
314
+ }
315
+ }
316
+
317
+
318
+ #define LEVELS1 12 /* size of the first part of the stack */
319
+ #define LEVELS2 10 /* size of the second part of the stack */
320
+
321
+ static int db_errorfb (lua_State *L) {
322
+ int level;
323
+ int firstpart = 1; /* still before eventual `...' */
324
+ int arg;
325
+ lua_State *L1 = getthread(L, &arg);
326
+ lua_Debug ar;
327
+ if (lua_isnumber(L, arg+2)) {
328
+ level = (int)lua_tointeger(L, arg+2);
329
+ lua_pop(L, 1);
330
+ }
331
+ else
332
+ level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
333
+ if (lua_gettop(L) == arg)
334
+ lua_pushliteral(L, "");
335
+ else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
336
+ else lua_pushliteral(L, "\n");
337
+ lua_pushliteral(L, "stack traceback:");
338
+ while (lua_getstack(L1, level++, &ar)) {
339
+ if (level > LEVELS1 && firstpart) {
340
+ /* no more than `LEVELS2' more levels? */
341
+ if (!lua_getstack(L1, level+LEVELS2, &ar))
342
+ level--; /* keep going */
343
+ else {
344
+ lua_pushliteral(L, "\n\t..."); /* too many levels */
345
+ while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
346
+ level++;
347
+ }
348
+ firstpart = 0;
349
+ continue;
350
+ }
351
+ lua_pushliteral(L, "\n\t");
352
+ lua_getinfo(L1, "Snl", &ar);
353
+ lua_pushfstring(L, "%s:", ar.short_src);
354
+ if (ar.currentline > 0)
355
+ lua_pushfstring(L, "%d:", ar.currentline);
356
+ if (*ar.namewhat != '\0') /* is there a name? */
357
+ lua_pushfstring(L, " in function " LUA_QS, ar.name);
358
+ else {
359
+ if (*ar.what == 'm') /* main? */
360
+ lua_pushfstring(L, " in main chunk");
361
+ else if (*ar.what == 'C' || *ar.what == 't')
362
+ lua_pushliteral(L, " ?"); /* C function or tail call */
363
+ else
364
+ lua_pushfstring(L, " in function <%s:%d>",
365
+ ar.short_src, ar.linedefined);
366
+ }
367
+ lua_concat(L, lua_gettop(L) - arg);
368
+ }
369
+ lua_concat(L, lua_gettop(L) - arg);
370
+ return 1;
371
+ }
372
+
373
+
374
+ static const luaL_Reg dblib[] = {
375
+ {"debug", db_debug},
376
+ {"getfenv", db_getfenv},
377
+ {"gethook", db_gethook},
378
+ {"getinfo", db_getinfo},
379
+ {"getlocal", db_getlocal},
380
+ {"getregistry", db_getregistry},
381
+ {"getmetatable", db_getmetatable},
382
+ {"getupvalue", db_getupvalue},
383
+ {"setfenv", db_setfenv},
384
+ {"sethook", db_sethook},
385
+ {"setlocal", db_setlocal},
386
+ {"setmetatable", db_setmetatable},
387
+ {"setupvalue", db_setupvalue},
388
+ {"traceback", db_errorfb},
389
+ {NULL, NULL}
390
+ };
391
+
392
+
393
+ LUALIB_API int luaopen_debug (lua_State *L) {
394
+ luaL_register(L, LUA_DBLIBNAME, dblib);
395
+ return 1;
396
+ }
397
+