aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-14 16:31:20 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-14 16:31:20 -0200
commite6d56cd2d844174bd40af4c44c0f68e2115e5876 (patch)
tree0487824699345d8ee59e4af4da493d9b49354ff6
parentc16c63cc592e78f06b5514485c6bd4eb1e7a14b8 (diff)
downloadlua-e6d56cd2d844174bd40af4c44c0f68e2115e5876.tar.gz
lua-e6d56cd2d844174bd40af4c44c0f68e2115e5876.tar.bz2
lua-e6d56cd2d844174bd40af4c44c0f68e2115e5876.zip
module for internal use only, with functions for internal tests
-rw-r--r--ltests.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/ltests.c b/ltests.c
new file mode 100644
index 00000000..547d5c8b
--- /dev/null
+++ b/ltests.c
@@ -0,0 +1,273 @@
1/*
2** $Id: lbuiltin.c,v 1.83 1999/12/07 12:05:34 roberto Exp $
3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <stdlib.h>
10
11#define LUA_REENTRANT
12
13#include "lapi.h"
14#include "lauxlib.h"
15#include "lmem.h"
16#include "lstate.h"
17#include "lstring.h"
18#include "ltable.h"
19#include "lua.h"
20
21
22void luaB_opentests (lua_State *L);
23
24
25/*
26** The whole module only makes sense with DEBUG on
27*/
28#ifdef DEBUG
29
30
31static void mem_query (lua_State *L) {
32 lua_pushnumber(L, totalmem);
33 lua_pushnumber(L, numblocks);
34}
35
36
37static void hash_query (lua_State *L) {
38 lua_Object o = luaL_nonnullarg(L, 1);
39 if (lua_getparam(L, 2) == LUA_NOOBJECT) {
40 luaL_arg_check(L, ttype(o) == LUA_T_STRING, 1, "string expected");
41 lua_pushnumber(L, tsvalue(o)->hash);
42 }
43 else {
44 const Hash *t = avalue(luaL_tablearg(L, 2));
45 lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
46 }
47}
48
49
50static void table_query (lua_State *L) {
51 const Hash *t = avalue(luaL_tablearg(L, 1));
52 int i = luaL_opt_int(L, 2, -1);
53 if (i == -1) {
54 lua_pushnumber(L, t->size);
55 lua_pushnumber(L, t->firstfree - t->node);
56 }
57 else if (i < t->size) {
58 luaA_pushobject(L, &t->node[i].key);
59 luaA_pushobject(L, &t->node[i].val);
60 if (t->node[i].next)
61 lua_pushnumber(L, t->node[i].next - t->node);
62 }
63}
64
65
66static void query_strings (lua_State *L) {
67 int h = luaL_check_int(L, 1) - 1;
68 int s = luaL_opt_int(L, 2, 0) - 1;
69 if (s==-1) {
70 if (h < NUM_HASHS) {
71 lua_pushnumber(L, L->string_root[h].nuse);
72 lua_pushnumber(L, L->string_root[h].size);
73 }
74 }
75 else {
76 TaggedString *ts = L->string_root[h].hash[s];
77 for (ts = L->string_root[h].hash[s]; ts; ts = ts->nexthash) {
78 if (ts->constindex == -1) lua_pushstring(L, "<USERDATA>");
79 else lua_pushstring(L, ts->str);
80 }
81 }
82}
83
84
85static const char *delimits = " \t\n,;";
86
87static void skip (const char **pc) {
88 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
89}
90
91static int getnum (const char **pc) {
92 int res = 0;
93 skip(pc);
94 while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
95 return res;
96}
97
98static int getreg (lua_State *L, const char **pc) {
99 skip(pc);
100 if (*(*pc)++ != 'r') lua_error(L, "`testC' expecting a register");
101 return getnum(pc);
102}
103
104static const char *getname (const char **pc) {
105 static char buff[30];
106 int i = 0;
107 skip(pc);
108 while (**pc != '\0' && !strchr(delimits, **pc))
109 buff[i++] = *(*pc)++;
110 buff[i] = '\0';
111 return buff;
112}
113
114
115#define EQ(s1) (strcmp(s1, inst) == 0)
116
117/*
118** function to test the API with C. It interprets a kind of "assembler"
119** language with calls to the API, so the test can be driven by Lua code
120*/
121static void testC (lua_State *L) {
122 lua_Object reg[10];
123 const char *pc = luaL_check_string(L, 1);
124 for (;;) {
125 const char *inst = getname(&pc);
126 if EQ("") return;
127 else if EQ("pushnum") {
128 lua_pushnumber(L, getnum(&pc));
129 }
130 else if EQ("createtable") {
131 reg[getreg(L, &pc)] = lua_createtable(L);
132 }
133 else if EQ("closure") {
134 lua_CFunction f = lua_getcfunction(L, lua_getglobal(L, getname(&pc)));
135 lua_pushcclosure(L, f, getnum(&pc));
136 }
137 else if EQ("pop") {
138 reg[getreg(L, &pc)] = lua_pop(L);
139 }
140 else if EQ("getglobal") {
141 int n = getreg(L, &pc);
142 reg[n] = lua_getglobal(L, getname(&pc));
143 }
144 else if EQ("rawgetglobal") {
145 int n = getreg(L, &pc);
146 reg[n] = lua_rawgetglobal(L, getname(&pc));
147 }
148 else if EQ("ref") {
149 lua_pushnumber(L, lua_ref(L, 0));
150 reg[getreg(L, &pc)] = lua_pop(L);
151 }
152 else if EQ("reflock") {
153 lua_pushnumber(L, lua_ref(L, 1));
154 reg[getreg(L, &pc)] = lua_pop(L);
155 }
156 else if EQ("getref") {
157 int n = getreg(L, &pc);
158 reg[n] = lua_getref(L, (int)lua_getnumber(L, reg[getreg(L, &pc)]));
159 }
160 else if EQ("unref") {
161 lua_unref(L, (int)lua_getnumber(L, reg[getreg(L, &pc)]));
162 }
163 else if EQ("getparam") {
164 int n = getreg(L, &pc);
165 reg[n] = lua_getparam(L, getnum(&pc)+1); /* skips the commmand itself */
166 }
167 else if EQ("getresult") {
168 int n = getreg(L, &pc);
169 reg[n] = lua_getparam(L, getnum(&pc));
170 }
171 else if EQ("setglobal") {
172 lua_setglobal(L, getname(&pc));
173 }
174 else if EQ("rawsetglobal") {
175 lua_rawsetglobal(L, getname(&pc));
176 }
177 else if EQ("pushstring") {
178 lua_pushstring(L, getname(&pc));
179 }
180 else if EQ("pushreg") {
181 lua_pushobject(L, reg[getreg(L, &pc)]);
182 }
183 else if EQ("call") {
184 lua_call(L, getname(&pc));
185 }
186 else if EQ("gettable") {
187 reg[getreg(L, &pc)] = lua_gettable(L);
188 }
189 else if EQ("rawgettable") {
190 reg[getreg(L, &pc)] = lua_rawgettable(L);
191 }
192 else if EQ("settable") {
193 lua_settable(L);
194 }
195 else if EQ("rawsettable") {
196 lua_rawsettable(L);
197 }
198 else if EQ("nextvar") {
199 lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)])));
200 }
201 else if EQ("next") {
202 int n = getreg(L, &pc);
203 n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)]));
204 lua_pushnumber(L, n);
205 }
206 else if EQ("equal") {
207 int n1 = getreg(L, &pc);
208 int n2 = getreg(L, &pc);
209 lua_pushnumber(L, lua_equal(L, reg[n1], reg[n2]));
210 }
211 else if EQ("pushusertag") {
212 int val = getreg(L, &pc);
213 int tag = getreg(L, &pc);
214 lua_pushusertag(L, (void *)(int)lua_getnumber(L, reg[val]),
215 (int)lua_getnumber(L, reg[tag]));
216 }
217 else if EQ("udataval") {
218 int n = getreg(L, &pc);
219 lua_pushnumber(L, (int)lua_getuserdata(L, reg[getreg(L, &pc)]));
220 reg[n] = lua_pop(L);
221 }
222 else if EQ("settagmethod") {
223 int n = getreg(L, &pc);
224 lua_settagmethod(L, (int)lua_getnumber(L, reg[n]), getname(&pc));
225 }
226 else if EQ("beginblock") {
227 lua_beginblock(L);
228 }
229 else if EQ("endblock") {
230 lua_endblock(L);
231 }
232 else if EQ("newstate") {
233 int stacksize = getnum(&pc);
234 lua_State *L1 = lua_newstate("stack", stacksize,
235 "builtin", getnum(&pc), NULL);
236 lua_pushuserdata(L, L1);
237 }
238 else if EQ("closestate") {
239 lua_close(lua_getuserdata(L, reg[getreg(L, &pc)]));
240 }
241 else if EQ("doremote") {
242 lua_Object ol1 = reg[getreg(L, &pc)];
243 lua_Object str = reg[getreg(L, &pc)];
244 lua_State *L1;
245 lua_Object temp;
246 int i;
247 if (!lua_isuserdata(L, ol1) || !lua_isstring(L, str))
248 lua_error(L, "bad arguments for `doremote'");
249 L1 = lua_getuserdata(L, ol1);
250 lua_dostring(L1, lua_getstring(L, str));
251 i = 1;
252 while ((temp = lua_getresult(L1, i++)) != LUA_NOOBJECT)
253 lua_pushstring(L, lua_getstring(L1, temp));
254 }
255 else luaL_verror(L, "unknown command in `testC': %.20s", inst);
256 }
257}
258
259
260static const struct luaL_reg tests_funcs[] = {
261 {"hash", hash_query},
262 {"querystr", query_strings},
263 {"querytab", table_query},
264 {"testC", testC},
265 {"totalmem", mem_query}
266};
267
268
269void luaB_opentests (lua_State *L) {
270 luaL_openl(L, tests_funcs);
271}
272
273#endif