1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "compat-5.3.h"
4 
5 
test_isinteger(lua_State * L)6 static int test_isinteger (lua_State *L) {
7   lua_pushboolean(L, lua_isinteger(L, 1));
8   return 1;
9 }
10 
11 
test_rotate(lua_State * L)12 static int test_rotate (lua_State *L) {
13   int r = (int)luaL_checkinteger(L, 1);
14   int n = lua_gettop(L)-1;
15   luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments");
16   lua_rotate(L, 2, r);
17   return n;
18 }
19 
20 
test_str2num(lua_State * L)21 static int test_str2num (lua_State *L) {
22   const char *s = luaL_checkstring(L, 1);
23   size_t len = lua_stringtonumber(L, s);
24   if (len == 0)
25     lua_pushnumber(L, 0);
26   lua_pushinteger(L, (lua_Integer)len);
27   return 2;
28 }
29 
30 
my_mod(lua_State * L)31 static int my_mod (lua_State *L ) {
32   lua_newtable(L);
33   lua_pushboolean(L, 1);
34   lua_setfield(L, -2, "boolean");
35   return 1;
36 }
37 
test_requiref(lua_State * L)38 static int test_requiref (lua_State *L) {
39   lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
40   lua_newtable(L);
41   lua_pushboolean(L, 0);
42   lua_setfield(L, -2, "boolean");
43   lua_setfield(L, -2, "requiref3");
44   lua_pop(L, 1);
45   luaL_requiref(L, "requiref1", my_mod, 0);
46   luaL_requiref(L, "requiref2", my_mod, 1);
47   luaL_requiref(L, "requiref3", my_mod, 1);
48   return 3;
49 }
50 
test_getseti(lua_State * L)51 static int test_getseti (lua_State *L) {
52   lua_Integer k = luaL_checkinteger(L, 2);
53   lua_Integer n = 0;
54   if (lua_geti(L, 1, k) == LUA_TNUMBER) {
55     n = lua_tointeger(L, -1);
56   } else {
57     lua_pop(L, 1);
58     lua_pushinteger(L, n);
59   }
60   lua_pushinteger(L, n+1);
61   lua_seti(L, 1, k);
62   return 1;
63 }
64 
65 
66 /* additional tests for Lua5.1 */
67 #define NUP 3
68 
test_newproxy(lua_State * L)69 static int test_newproxy (lua_State *L) {
70   lua_settop(L, 0);
71   lua_newuserdata(L, 0);
72   lua_newtable(L);
73   lua_pushvalue(L, -1);
74   lua_pushboolean(L, 1);
75   lua_setfield(L, -2, "__gc");
76   lua_setmetatable(L, -3);
77   return 2;
78 }
79 
test_absindex(lua_State * L)80 static int test_absindex (lua_State *L) {
81   int i = 1;
82   for (i = 1; i <= NUP; ++i)
83     lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i)));
84   lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX));
85   lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1))));
86   lua_replace(L, lua_absindex(L, -2));
87   lua_pushvalue(L, lua_absindex(L, -2));
88   lua_pushvalue(L, lua_absindex(L, -4));
89   lua_pushvalue(L, lua_absindex(L, -6));
90   i += 3;
91   lua_pushvalue(L, lua_absindex(L, 1));
92   lua_pushvalue(L, lua_absindex(L, 2));
93   lua_pushvalue(L, lua_absindex(L, 3));
94   i += 3;
95   return i;
96 }
97 
test_arith(lua_State * L)98 static int test_arith (lua_State *L) {
99   lua_settop(L, 2);
100   lua_pushvalue(L, 1);
101   lua_pushvalue(L, 2);
102   lua_arith(L, LUA_OPADD);
103   lua_pushvalue(L, 1);
104   lua_pushvalue(L, 2);
105   lua_arith(L, LUA_OPSUB);
106   lua_pushvalue(L, 1);
107   lua_pushvalue(L, 2);
108   lua_arith(L, LUA_OPMUL);
109   lua_pushvalue(L, 1);
110   lua_pushvalue(L, 2);
111   lua_arith(L, LUA_OPDIV);
112   lua_pushvalue(L, 1);
113   lua_pushvalue(L, 2);
114   lua_arith(L, LUA_OPMOD);
115   lua_pushvalue(L, 1);
116   lua_pushvalue(L, 2);
117   lua_arith(L, LUA_OPPOW);
118   lua_pushvalue(L, 1);
119   lua_arith(L, LUA_OPUNM);
120   return lua_gettop(L)-2;
121 }
122 
test_compare(lua_State * L)123 static int test_compare (lua_State *L) {
124   luaL_checknumber(L, 1);
125   luaL_checknumber(L, 2);
126   lua_settop(L, 2);
127   lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ));
128   lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT));
129   lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE));
130   return 3;
131 }
132 
test_globals(lua_State * L)133 static int test_globals (lua_State *L) {
134   lua_pushglobaltable(L);
135   return 1;
136 }
137 
test_tonumber(lua_State * L)138 static int test_tonumber (lua_State *L) {
139   int isnum = 0;
140   lua_Number n = lua_tonumberx(L, 1, &isnum);
141   if (!isnum)
142     lua_pushnil(L);
143   else
144     lua_pushnumber(L, n);
145   return 1;
146 }
147 
test_tointeger(lua_State * L)148 static int test_tointeger (lua_State *L) {
149   int isnum = 0;
150   lua_Integer n = lua_tointegerx(L, 1, &isnum);
151   if (!isnum)
152     lua_pushnil(L);
153   else
154     lua_pushinteger(L, n);
155   return 1;
156 }
157 
test_len(lua_State * L)158 static int test_len (lua_State *L) {
159   luaL_checkany(L, 1);
160   lua_len(L, 1);
161   lua_pushinteger(L, luaL_len(L, 1));
162   return 2;
163 }
164 
test_copy(lua_State * L)165 static int test_copy (lua_State *L) {
166   int args = lua_gettop(L);
167   if (args >= 2) {
168     int i = 0;
169     for (i = args-1; i > 0; --i)
170       lua_copy(L, args, i);
171   }
172   return args;
173 }
174 
175 /* need an address */
176 static char const dummy = 0;
177 
test_rawxetp(lua_State * L)178 static int test_rawxetp (lua_State *L) {
179   if (lua_gettop(L) > 0)
180     lua_pushvalue(L, 1);
181   else
182     lua_pushliteral(L, "hello again");
183   lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy);
184   lua_settop(L, 0);
185   lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy);
186   return 1;
187 }
188 
test_udata(lua_State * L)189 static int test_udata (lua_State *L) {
190   const char *tname = luaL_optstring(L, 1, "utype1");
191   void *u1 = lua_newuserdata(L, 1);
192   int u1pos = lua_gettop(L);
193   void *u2 = lua_newuserdata(L, 1);
194   int u2pos = lua_gettop(L);
195   luaL_newmetatable(L, "utype1");
196   luaL_newmetatable(L, "utype2");
197   lua_pop(L, 2);
198   luaL_setmetatable(L, "utype2");
199   lua_pushvalue(L, u1pos);
200   luaL_setmetatable(L, "utype1");
201   lua_pop(L, 1);
202   (void)u1;
203   (void)u2;
204   lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname));
205   lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname));
206   luaL_getmetatable(L, "utype1");
207   lua_getfield(L, -1, "__name");
208   lua_replace(L, -2);
209   return 3;
210 }
211 
test_subtable(lua_State * L)212 static int test_subtable (lua_State *L) {
213   luaL_checktype(L, 1, LUA_TTABLE);
214   lua_settop(L, 1);
215   if (luaL_getsubtable(L, 1, "xxx")) {
216     lua_pushliteral(L, "oldtable");
217   } else {
218     lua_pushliteral(L, "newtable");
219   }
220   return 2;
221 }
222 
test_uservalue(lua_State * L)223 static int test_uservalue (lua_State *L) {
224   void *udata = lua_newuserdata(L, 1);
225   int ui = lua_gettop(L);
226   lua_newtable(L);
227   lua_setuservalue(L, ui);
228   lua_getuservalue(L, ui);
229   (void)udata;
230   return 1;
231 }
232 
test_upvalues(lua_State * L)233 static int test_upvalues (lua_State *L) {
234   int i = 1;
235   for (i = 1; i <= NUP; ++i)
236     lua_pushvalue(L, lua_upvalueindex(i));
237   return NUP;
238 }
239 
test_tolstring(lua_State * L)240 static int test_tolstring (lua_State *L) {
241   size_t len = 0;
242   luaL_tolstring(L, 1, &len);
243   lua_pushinteger(L, (int)len);
244   return 2;
245 }
246 
test_pushstring(lua_State * L)247 static int test_pushstring (lua_State *L) {
248   lua_pushstring(L, lua_pushliteral(L, "abc"));
249   lua_pushstring(L, lua_pushlstring(L, "abc", 2));
250   lua_pushstring(L, lua_pushlstring(L, NULL, 0));
251   lua_pushstring(L, lua_pushstring(L, "abc"));
252   lua_pushboolean(L, NULL == lua_pushstring(L, NULL));
253   return 10;
254 }
255 
test_buffer(lua_State * L)256 static int test_buffer (lua_State *L) {
257   luaL_Buffer b;
258   char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1);
259   p[0] = 'a';
260   p[1] = 'b';
261   luaL_addsize(&b, 2);
262   luaL_addstring(&b, "c");
263   lua_pushliteral(L, "d");
264   luaL_addvalue(&b);
265   luaL_addchar(&b, 'e');
266   luaL_pushresult(&b);
267   return 1;
268 }
269 
test_exec(lua_State * L)270 static int test_exec (lua_State *L) {
271   const char *cmd = luaL_checkstring(L, 1);
272   return luaL_execresult(L, system(cmd));
273 }
274 
test_loadstring(lua_State * L)275 static int test_loadstring (lua_State *L) {
276   size_t len = 0;
277   char const* s = luaL_checklstring(L, 1, &len);
278   char const* mode = luaL_optstring(L, 2, "bt");
279   lua_pushinteger(L, luaL_loadbufferx(L, s, len, s, mode));
280   return 2;
281 }
282 
test_loadfile(lua_State * L)283 static int test_loadfile (lua_State *L) {
284   char filename[L_tmpnam+1] = { 0 };
285   size_t len = 0;
286   char const* s = luaL_checklstring(L, 1, &len);
287   char const* mode = luaL_optstring(L, 2, "bt");
288   if (tmpnam(filename)) {
289     FILE* f = fopen(filename, "wb");
290     if (f) {
291       fwrite(s, 1, len, f);
292       fclose(f);
293       lua_pushinteger(L, luaL_loadfilex(L, filename, mode));
294       remove(filename);
295       return 2;
296     } else
297       remove(filename);
298   }
299   return 0;
300 }
301 
302 
303 static const luaL_Reg funcs[] = {
304   { "isinteger", test_isinteger },
305   { "rotate", test_rotate },
306   { "strtonum", test_str2num },
307   { "requiref", test_requiref },
308   { "getseti", test_getseti },
309   { "newproxy", test_newproxy },
310   { "arith", test_arith },
311   { "compare", test_compare },
312   { "tonumber", test_tonumber },
313   { "tointeger", test_tointeger },
314   { "len", test_len },
315   { "copy", test_copy },
316   { "rawxetp", test_rawxetp },
317   { "subtable", test_subtable },
318   { "udata", test_udata },
319   { "uservalue", test_uservalue },
320   { "globals", test_globals },
321   { "tolstring", test_tolstring },
322   { "pushstring", test_pushstring },
323   { "buffer", test_buffer },
324   { "exec", test_exec },
325   { "loadstring", test_loadstring },
326   { "loadfile", test_loadfile },
327   { NULL, NULL }
328 };
329 
330 static const luaL_Reg more_funcs[] = {
331   { "getupvalues", test_upvalues },
332   { "absindex", test_absindex },
333   { NULL, NULL }
334 };
335 
336 
337 #ifdef __cplusplus
338 extern "C" {
339 #endif
luaopen_testmod(lua_State * L)340 int luaopen_testmod (lua_State *L) {
341   int i = 1;
342   luaL_newlib(L, funcs);
343   for (i = 1; i <= NUP; ++i)
344     lua_pushnumber(L, i);
345   luaL_setfuncs(L, more_funcs, NUP);
346   return 1;
347 }
348 #ifdef __cplusplus
349 }
350 #endif
351 
352