diff options
author | Philipp Janda <siffiejoe@gmx.net> | 2015-01-13 08:27:20 +0100 |
---|---|---|
committer | Philipp Janda <siffiejoe@gmx.net> | 2015-01-13 08:27:20 +0100 |
commit | 901f1bfdbadc7afa5526ca854a12bdfe8fcb88b3 (patch) | |
tree | 698870c642950c4287c7ab57c2dcab28b3efb6a6 | |
parent | 46bbf75fbea482c19c4eb50bf97ef948f611e26a (diff) | |
download | lua-compat-5.3-901f1bfdbadc7afa5526ca854a12bdfe8fcb88b3.tar.gz lua-compat-5.3-901f1bfdbadc7afa5526ca854a12bdfe8fcb88b3.tar.bz2 lua-compat-5.3-901f1bfdbadc7afa5526ca854a12bdfe8fcb88b3.zip |
add initial implementation of c-api and license
-rw-r--r-- | LICENSE | 20 | ||||
-rw-r--r-- | c-api/compat-5.3.c | 430 | ||||
-rw-r--r-- | c-api/compat-5.3.h | 294 | ||||
-rwxr-xr-x | tests/test.lua | 109 | ||||
-rw-r--r-- | tests/testmod.c | 246 |
5 files changed, 1099 insertions, 0 deletions
@@ -0,0 +1,20 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2015 Kepler Project. | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
6 | this software and associated documentation files (the "Software"), to deal in | ||
7 | the Software without restriction, including without limitation the rights to | ||
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
9 | the Software, and to permit persons to whom the Software is furnished to do so, | ||
10 | subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in all | ||
13 | copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/c-api/compat-5.3.c b/c-api/compat-5.3.c new file mode 100644 index 0000000..9edd5f1 --- /dev/null +++ b/c-api/compat-5.3.c | |||
@@ -0,0 +1,430 @@ | |||
1 | #include <stddef.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <ctype.h> | ||
5 | #include <errno.h> | ||
6 | #include <lua.h> | ||
7 | #include <lauxlib.h> | ||
8 | #include "compat-5.3.h" | ||
9 | |||
10 | /* don't compile it again if it already is included via compat53.h */ | ||
11 | #ifndef COMPAT53_C_ | ||
12 | #define COMPAT53_C_ | ||
13 | |||
14 | |||
15 | |||
16 | /* definitions for Lua 5.1 only */ | ||
17 | #if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM == 501 | ||
18 | |||
19 | |||
20 | COMPAT53_API int lua_absindex (lua_State *L, int i) { | ||
21 | if (i < 0 && i > LUA_REGISTRYINDEX) | ||
22 | i += lua_gettop(L) + 1; | ||
23 | return i; | ||
24 | } | ||
25 | |||
26 | |||
27 | COMPAT53_API void lua_copy (lua_State *L, int from, int to) { | ||
28 | int abs_to = lua_absindex(L, to); | ||
29 | luaL_checkstack(L, 1, "not enough stack slots"); | ||
30 | lua_pushvalue(L, from); | ||
31 | lua_replace(L, abs_to); | ||
32 | } | ||
33 | |||
34 | |||
35 | COMPAT53_API void lua_len (lua_State *L, int i) { | ||
36 | switch (lua_type(L, i)) { | ||
37 | case LUA_TSTRING: /* fall through */ | ||
38 | case LUA_TTABLE: | ||
39 | lua_pushnumber(L, (int)lua_objlen(L, i)); | ||
40 | break; | ||
41 | case LUA_TUSERDATA: | ||
42 | if (luaL_callmeta(L, i, "__len")) | ||
43 | break; | ||
44 | /* maybe fall through */ | ||
45 | default: | ||
46 | luaL_error(L, "attempt to get length of a %s value", | ||
47 | lua_typename(L, lua_type(L, i))); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | |||
52 | COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p) { | ||
53 | int abs_i = lua_absindex(L, i); | ||
54 | lua_pushlightuserdata(L, (void*)p); | ||
55 | lua_rawget(L, abs_i); | ||
56 | return lua_type(L, -1); | ||
57 | } | ||
58 | |||
59 | COMPAT53_API void lua_rawsetp (lua_State *L, int i, const void *p) { | ||
60 | int abs_i = lua_absindex(L, i); | ||
61 | luaL_checkstack(L, 1, "not enough stack slots"); | ||
62 | lua_pushlightuserdata(L, (void*)p); | ||
63 | lua_insert(L, -2); | ||
64 | lua_rawset(L, abs_i); | ||
65 | } | ||
66 | |||
67 | |||
68 | COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) { | ||
69 | lua_Integer n = lua_tointeger(L, i); | ||
70 | if (isnum != NULL) { | ||
71 | *isnum = (n != 0 || lua_isnumber(L, i)); | ||
72 | } | ||
73 | return n; | ||
74 | } | ||
75 | |||
76 | |||
77 | COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum) { | ||
78 | lua_Number n = lua_tonumber(L, i); | ||
79 | if (isnum != NULL) { | ||
80 | *isnum = (n != 0 || lua_isnumber(L, i)); | ||
81 | } | ||
82 | return n; | ||
83 | } | ||
84 | |||
85 | |||
86 | COMPAT53_API void luaL_checkversion (lua_State *L) { | ||
87 | (void)L; | ||
88 | } | ||
89 | |||
90 | |||
91 | COMPAT53_API int luaL_getsubtable (lua_State *L, int i, const char *name) { | ||
92 | int abs_i = lua_absindex(L, i); | ||
93 | luaL_checkstack(L, 3, "not enough stack slots"); | ||
94 | lua_pushstring(L, name); | ||
95 | lua_gettable(L, abs_i); | ||
96 | if (lua_istable(L, -1)) | ||
97 | return 1; | ||
98 | lua_pop(L, 1); | ||
99 | lua_newtable(L); | ||
100 | lua_pushstring(L, name); | ||
101 | lua_pushvalue(L, -2); | ||
102 | lua_settable(L, abs_i); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | |||
107 | COMPAT53_API int luaL_len (lua_State *L, int i) { | ||
108 | int res = 0, isnum = 0; | ||
109 | luaL_checkstack(L, 1, "not enough stack slots"); | ||
110 | lua_len(L, i); | ||
111 | res = (int)lua_tointegerx(L, -1, &isnum); | ||
112 | lua_pop(L, 1); | ||
113 | if (!isnum) | ||
114 | luaL_error(L, "object length is not a number"); | ||
115 | return res; | ||
116 | } | ||
117 | |||
118 | |||
119 | COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { | ||
120 | luaL_checkstack(L, nup+1, "too many upvalues"); | ||
121 | for (; l->name != NULL; l++) { /* fill the table with given functions */ | ||
122 | int i; | ||
123 | lua_pushstring(L, l->name); | ||
124 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | ||
125 | lua_pushvalue(L, -(nup + 1)); | ||
126 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ | ||
127 | lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */ | ||
128 | } | ||
129 | lua_pop(L, nup); /* remove upvalues */ | ||
130 | } | ||
131 | |||
132 | |||
133 | COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname) { | ||
134 | luaL_checkstack(L, 1, "not enough stack slots"); | ||
135 | luaL_getmetatable(L, tname); | ||
136 | lua_setmetatable(L, -2); | ||
137 | } | ||
138 | |||
139 | |||
140 | COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname) { | ||
141 | void *p = lua_touserdata(L, i); | ||
142 | luaL_checkstack(L, 2, "not enough stack slots"); | ||
143 | if (p == NULL || !lua_getmetatable(L, i)) | ||
144 | return NULL; | ||
145 | else { | ||
146 | int res = 0; | ||
147 | luaL_getmetatable(L, tname); | ||
148 | res = lua_rawequal(L, -1, -2); | ||
149 | lua_pop(L, 2); | ||
150 | if (!res) | ||
151 | p = NULL; | ||
152 | } | ||
153 | return p; | ||
154 | } | ||
155 | |||
156 | |||
157 | COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | ||
158 | if (!luaL_callmeta(L, idx, "__tostring")) { | ||
159 | int t = lua_type(L, idx); | ||
160 | switch (t) { | ||
161 | case LUA_TNIL: | ||
162 | lua_pushliteral(L, "nil"); | ||
163 | break; | ||
164 | case LUA_TSTRING: | ||
165 | case LUA_TNUMBER: | ||
166 | lua_pushvalue(L, idx); | ||
167 | break; | ||
168 | case LUA_TBOOLEAN: | ||
169 | if (lua_toboolean(L, idx)) | ||
170 | lua_pushliteral(L, "true"); | ||
171 | else | ||
172 | lua_pushliteral(L, "false"); | ||
173 | break; | ||
174 | default: | ||
175 | lua_pushfstring(L, "%s: %p", lua_typename(L, t), | ||
176 | lua_topointer(L, idx)); | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | return lua_tolstring(L, -1, len); | ||
181 | } | ||
182 | |||
183 | |||
184 | #if !defined(COMPAT53_IS_LUAJIT) | ||
185 | static int compat53_countlevels (lua_State *L) { | ||
186 | lua_Debug ar; | ||
187 | int li = 1, le = 1; | ||
188 | /* find an upper bound */ | ||
189 | while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } | ||
190 | /* do a binary search */ | ||
191 | while (li < le) { | ||
192 | int m = (li + le)/2; | ||
193 | if (lua_getstack(L, m, &ar)) li = m + 1; | ||
194 | else le = m; | ||
195 | } | ||
196 | return le - 1; | ||
197 | } | ||
198 | |||
199 | static int compat53_findfield (lua_State *L, int objidx, int level) { | ||
200 | if (level == 0 || !lua_istable(L, -1)) | ||
201 | return 0; /* not found */ | ||
202 | lua_pushnil(L); /* start 'next' loop */ | ||
203 | while (lua_next(L, -2)) { /* for each pair in table */ | ||
204 | if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ | ||
205 | if (lua_rawequal(L, objidx, -1)) { /* found object? */ | ||
206 | lua_pop(L, 1); /* remove value (but keep name) */ | ||
207 | return 1; | ||
208 | } | ||
209 | else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */ | ||
210 | lua_remove(L, -2); /* remove table (but keep name) */ | ||
211 | lua_pushliteral(L, "."); | ||
212 | lua_insert(L, -2); /* place '.' between the two names */ | ||
213 | lua_concat(L, 3); | ||
214 | return 1; | ||
215 | } | ||
216 | } | ||
217 | lua_pop(L, 1); /* remove value */ | ||
218 | } | ||
219 | return 0; /* not found */ | ||
220 | } | ||
221 | |||
222 | static int compat53_pushglobalfuncname (lua_State *L, lua_Debug *ar) { | ||
223 | int top = lua_gettop(L); | ||
224 | lua_getinfo(L, "f", ar); /* push function */ | ||
225 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
226 | if (compat53_findfield(L, top + 1, 2)) { | ||
227 | lua_copy(L, -1, top + 1); /* move name to proper place */ | ||
228 | lua_pop(L, 2); /* remove pushed values */ | ||
229 | return 1; | ||
230 | } | ||
231 | else { | ||
232 | lua_settop(L, top); /* remove function and global table */ | ||
233 | return 0; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | static void compat53_pushfuncname (lua_State *L, lua_Debug *ar) { | ||
238 | if (*ar->namewhat != '\0') /* is there a name? */ | ||
239 | lua_pushfstring(L, "function " LUA_QS, ar->name); | ||
240 | else if (*ar->what == 'm') /* main? */ | ||
241 | lua_pushliteral(L, "main chunk"); | ||
242 | else if (*ar->what == 'C') { | ||
243 | if (compat53_pushglobalfuncname(L, ar)) { | ||
244 | lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); | ||
245 | lua_remove(L, -2); /* remove name */ | ||
246 | } | ||
247 | else | ||
248 | lua_pushliteral(L, "?"); | ||
249 | } | ||
250 | else | ||
251 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | ||
252 | } | ||
253 | |||
254 | #define COMPAT53_LEVELS1 12 /* size of the first part of the stack */ | ||
255 | #define COMPAT53_LEVELS2 10 /* size of the second part of the stack */ | ||
256 | |||
257 | COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, | ||
258 | const char *msg, int level) { | ||
259 | lua_Debug ar; | ||
260 | int top = lua_gettop(L); | ||
261 | int numlevels = compat53_countlevels(L1); | ||
262 | int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0; | ||
263 | if (msg) lua_pushfstring(L, "%s\n", msg); | ||
264 | lua_pushliteral(L, "stack traceback:"); | ||
265 | while (lua_getstack(L1, level++, &ar)) { | ||
266 | if (level == mark) { /* too many levels? */ | ||
267 | lua_pushliteral(L, "\n\t..."); /* add a '...' */ | ||
268 | level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */ | ||
269 | } | ||
270 | else { | ||
271 | lua_getinfo(L1, "Slnt", &ar); | ||
272 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | ||
273 | if (ar.currentline > 0) | ||
274 | lua_pushfstring(L, "%d:", ar.currentline); | ||
275 | lua_pushliteral(L, " in "); | ||
276 | compat53_pushfuncname(L, &ar); | ||
277 | lua_concat(L, lua_gettop(L) - top); | ||
278 | } | ||
279 | } | ||
280 | lua_concat(L, lua_gettop(L) - top); | ||
281 | } | ||
282 | |||
283 | |||
284 | COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | ||
285 | int en = errno; /* calls to Lua API may change this value */ | ||
286 | if (stat) { | ||
287 | lua_pushboolean(L, 1); | ||
288 | return 1; | ||
289 | } | ||
290 | else { | ||
291 | lua_pushnil(L); | ||
292 | if (fname) | ||
293 | lua_pushfstring(L, "%s: %s", fname, strerror(en)); | ||
294 | else | ||
295 | lua_pushstring(L, strerror(en)); | ||
296 | lua_pushnumber(L, (lua_Number)en); | ||
297 | return 3; | ||
298 | } | ||
299 | } | ||
300 | #endif /* not COMPAT53_IS_LUAJIT */ | ||
301 | |||
302 | |||
303 | #endif /* Lua 5.1 */ | ||
304 | |||
305 | |||
306 | |||
307 | /* definitions for Lua 5.1 and Lua 5.2 */ | ||
308 | #if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM <= 502 | ||
309 | |||
310 | |||
311 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i) { | ||
312 | index = lua_absindex(L, index); | ||
313 | lua_pushinteger(L, i); | ||
314 | lua_gettable(L, index); | ||
315 | return lua_type(L, -1); | ||
316 | } | ||
317 | |||
318 | |||
319 | COMPAT53_API int lua_isinteger (lua_State *L, int index) { | ||
320 | if (lua_type(L, index) == LUA_TNUMBER) { | ||
321 | lua_Number n = lua_tonumber(L, index); | ||
322 | lua_Integer i = lua_tointeger(L, index); | ||
323 | if (i == n) | ||
324 | return 1; | ||
325 | } | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | |||
330 | static void compat53_reverse (lua_State *L, int a, int b) { | ||
331 | for (; a < b; ++a, --b) { | ||
332 | lua_pushvalue(L, a); | ||
333 | lua_pushvalue(L, b); | ||
334 | lua_replace(L, a); | ||
335 | lua_replace(L, b); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | |||
340 | COMPAT53_API void lua_rotate (lua_State *L, int idx, int n) { | ||
341 | int n_elems = 0; | ||
342 | idx = lua_absindex(L, idx); | ||
343 | n_elems = lua_gettop(L)-idx+1; | ||
344 | if (n < 0) | ||
345 | n += n_elems; | ||
346 | if ( n > 0 && n < n_elems) { | ||
347 | luaL_checkstack(L, 2, "not enough stack slots available"); | ||
348 | n = n_elems - n; | ||
349 | compat53_reverse(L, idx, idx+n-1); | ||
350 | compat53_reverse(L, idx+n, idx+n_elems-1); | ||
351 | compat53_reverse(L, idx, idx+n_elems-1); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | |||
356 | COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i) { | ||
357 | luaL_checkstack(L, 1, "not enough stack slots available"); | ||
358 | index = lua_absindex(L, index); | ||
359 | lua_pushinteger(L, i); | ||
360 | lua_insert(L, -2); | ||
361 | lua_settable(L, index); | ||
362 | } | ||
363 | |||
364 | |||
365 | COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s) { | ||
366 | char* endptr; | ||
367 | lua_Number n = lua_str2number(s, &endptr); | ||
368 | if (endptr != s) { | ||
369 | while (*endptr != '\0' && isspace((unsigned char)*endptr)) | ||
370 | ++endptr; | ||
371 | if (*endptr == '\0') { | ||
372 | lua_pushnumber(L, n); | ||
373 | return endptr - s + 1; | ||
374 | } | ||
375 | } | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | |||
380 | COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, | ||
381 | lua_CFunction openf, int glb) { | ||
382 | luaL_checkstack(L, 3, "not enough stack slots available"); | ||
383 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
384 | if (lua_getfield(L, -1, modname) == LUA_TNIL) { | ||
385 | lua_pop(L, 1); | ||
386 | lua_pushcfunction(L, openf); | ||
387 | lua_pushstring(L, modname); | ||
388 | lua_call(L, 1, 1); | ||
389 | lua_pushvalue(L, -1); | ||
390 | lua_setfield(L, -3, modname); | ||
391 | } | ||
392 | if (glb) { | ||
393 | lua_pushvalue(L, -1); | ||
394 | lua_setglobal(L, modname); | ||
395 | } | ||
396 | lua_replace(L, -2); | ||
397 | } | ||
398 | |||
399 | |||
400 | #endif /* Lua 5.1 and 5.2 */ | ||
401 | |||
402 | |||
403 | #endif /* COMPAT53_C_ */ | ||
404 | |||
405 | |||
406 | /********************************************************************* | ||
407 | * This file contains parts of Lua 5.2's and Lua 5.3's source code: | ||
408 | * | ||
409 | * Copyright (C) 1994-2014 Lua.org, PUC-Rio. | ||
410 | * | ||
411 | * Permission is hereby granted, free of charge, to any person obtaining | ||
412 | * a copy of this software and associated documentation files (the | ||
413 | * "Software"), to deal in the Software without restriction, including | ||
414 | * without limitation the rights to use, copy, modify, merge, publish, | ||
415 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
416 | * permit persons to whom the Software is furnished to do so, subject to | ||
417 | * the following conditions: | ||
418 | * | ||
419 | * The above copyright notice and this permission notice shall be | ||
420 | * included in all copies or substantial portions of the Software. | ||
421 | * | ||
422 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
423 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
424 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
425 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
426 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
427 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
428 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
429 | *********************************************************************/ | ||
430 | |||
diff --git a/c-api/compat-5.3.h b/c-api/compat-5.3.h new file mode 100644 index 0000000..b288126 --- /dev/null +++ b/c-api/compat-5.3.h | |||
@@ -0,0 +1,294 @@ | |||
1 | #ifndef COMPAT53_H_ | ||
2 | #define COMPAT53_H_ | ||
3 | |||
4 | #include <stddef.h> | ||
5 | #include <limits.h> | ||
6 | #include <lua.h> | ||
7 | #include <lauxlib.h> | ||
8 | #include <lualib.h> | ||
9 | |||
10 | |||
11 | #if defined(COMPAT53_PREFIX) | ||
12 | /* - change the symbol names of functions to avoid linker conflicts | ||
13 | * - compat-5.3.c needs to be compiled (and linked) separately | ||
14 | */ | ||
15 | # if !defined(COMPAT53_API) | ||
16 | # define COMPAT53_API extern | ||
17 | # endif | ||
18 | # undef COMPAT53_INCLUDE_SOURCE | ||
19 | #else /* COMPAT53_PREFIX */ | ||
20 | /* - make all functions static and include the source. | ||
21 | * - don't mess with the symbol names of functions | ||
22 | * - compat-5.3.c doesn't need to be compiled (and linked) separately | ||
23 | */ | ||
24 | # define COMPAT53_PREFIX lua | ||
25 | # undef COMPAT53_API | ||
26 | # if defined(__GNUC__) || defined(__clang__) | ||
27 | # define COMPAT53_API __attribute__((__unused__)) static | ||
28 | # else | ||
29 | # define COMPAT53_API static | ||
30 | # endif | ||
31 | # define COMPAT53_INCLUDE_SOURCE | ||
32 | #endif /* COMPAT53_PREFIX */ | ||
33 | |||
34 | #define COMPAT53_CONCAT_HELPER(a, b) a##b | ||
35 | #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b) | ||
36 | |||
37 | |||
38 | |||
39 | /* declarations for Lua 5.1 */ | ||
40 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 | ||
41 | |||
42 | /* XXX not implemented: | ||
43 | * lua_arith | ||
44 | * lua_compare | ||
45 | * lua_upvalueid | ||
46 | * lua_upvaluejoin | ||
47 | * lua_version | ||
48 | * lua_yieldk | ||
49 | * luaL_buffinitsize | ||
50 | * luaL_execresult | ||
51 | * luaL_loadbufferx | ||
52 | * luaL_loadfilex | ||
53 | * luaL_prepbuffsize | ||
54 | * luaL_pushresultsize | ||
55 | */ | ||
56 | |||
57 | /* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h, | ||
58 | * LuaJIT uses luaconf_h. If you use PUC-Rio's include files | ||
59 | * but LuaJIT's library, you will need to define the macro | ||
60 | * COMPAT53_IS_LUAJIT yourself! */ | ||
61 | #if !defined(COMPAT53_IS_LUAJIT) && defined(luaconf_h) | ||
62 | # define COMPAT53_IS_LUAJIT | ||
63 | #endif | ||
64 | |||
65 | #define LUA_OK 0 | ||
66 | |||
67 | typedef struct luaL_Stream { | ||
68 | FILE *f; | ||
69 | lua_CFunction closef; | ||
70 | } luaL_Stream; | ||
71 | |||
72 | typedef size_t lua_Unsigned; | ||
73 | |||
74 | #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) | ||
75 | COMPAT53_API int lua_absindex (lua_State *L, int i); | ||
76 | |||
77 | #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) | ||
78 | COMPAT53_API void lua_copy (lua_State *L, int from, int to); | ||
79 | |||
80 | #define lua_getuservalue(L, i) \ | ||
81 | (lua_getfenv(L, i), lua_type(L, -1)) | ||
82 | #define lua_setuservalue(L, i) \ | ||
83 | (luaL_checktype(L, -1, LUA_TTABLE), lua_setfenv(L, i)) | ||
84 | |||
85 | #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len) | ||
86 | COMPAT53_API void lua_len (lua_State *L, int i); | ||
87 | |||
88 | #define luaL_newlibtable(L, l) \ | ||
89 | (lua_createtable(L, 0, sizeof(l)/sizeof(*(l))-1)) | ||
90 | #define luaL_newlib(L, l) \ | ||
91 | (luaL_newlibtable(L, l), luaL_register(L, NULL, l)) | ||
92 | |||
93 | #define lua_pushglobaltable(L) \ | ||
94 | lua_pushvalue(L, LUA_GLOBALSINDEX) | ||
95 | |||
96 | #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp) | ||
97 | COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p); | ||
98 | |||
99 | #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp) | ||
100 | COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p); | ||
101 | |||
102 | #define lua_rawlen(L, i) lua_objlen(L, i) | ||
103 | |||
104 | #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx) | ||
105 | COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum); | ||
106 | |||
107 | #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx) | ||
108 | COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum); | ||
109 | |||
110 | #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion) | ||
111 | COMPAT53_API void luaL_checkversion (lua_State *L); | ||
112 | |||
113 | #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable) | ||
114 | COMPAT53_API int luaL_getsubtable (lua_State* L, int i, const char *name); | ||
115 | |||
116 | #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len) | ||
117 | COMPAT53_API int luaL_len (lua_State *L, int i); | ||
118 | |||
119 | #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs) | ||
120 | COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); | ||
121 | |||
122 | #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable) | ||
123 | COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname); | ||
124 | |||
125 | #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata) | ||
126 | COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname); | ||
127 | |||
128 | #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) | ||
129 | COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); | ||
130 | |||
131 | #if !defined(COMPAT53_IS_LUAJIT) | ||
132 | #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback) | ||
133 | COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level); | ||
134 | |||
135 | #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult) | ||
136 | COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname); | ||
137 | #endif /* COMPAT53_IS_LUAJIT */ | ||
138 | |||
139 | #define lua_callk(L, na, nr, ctx, cont) \ | ||
140 | ((void)(ctx), (void)(cont), lua_call(L, na, nr)) | ||
141 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ | ||
142 | ((void)(ctx), (void)(cont), lua_pcall(L, na, nr, err)) | ||
143 | |||
144 | #if defined(LUA_COMPAT_APIINTCASTS) | ||
145 | #define lua_pushunsigned(L, n) \ | ||
146 | lua_pushinteger(L, (lua_Integer)(n)) | ||
147 | #define lua_tounsignedx(L, i, is) \ | ||
148 | ((lua_Unsigned)lua_tointegerx(L, i, is)) | ||
149 | #define lua_tounsigned(L, i) \ | ||
150 | lua_tounsignedx(L, i, NULL) | ||
151 | #define luaL_checkunsigned(L, a) \ | ||
152 | ((lua_Unsigned)luaL_checkinteger(L, a)) | ||
153 | #define luaL_optunsigned(L, a, d) \ | ||
154 | ((lua_Unsigned)luaL_optinteger(L, a, (lua_Integer)(d))) | ||
155 | #endif | ||
156 | |||
157 | #endif /* Lua 5.1 only */ | ||
158 | |||
159 | |||
160 | |||
161 | /* declarations for Lua 5.1 and 5.2 */ | ||
162 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502 | ||
163 | |||
164 | typedef int lua_KContext; | ||
165 | |||
166 | typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx); | ||
167 | |||
168 | #define lua_dump(L, w, d, s) \ | ||
169 | ((void)(s), lua_dump(L, w, d)) | ||
170 | |||
171 | #define lua_getfield(L, i, k) \ | ||
172 | (lua_getfield(L, i, k), lua_type(L, -1)) | ||
173 | |||
174 | #define lua_gettable(L, i) \ | ||
175 | (lua_gettable(L, i), lua_type(L, -1)) | ||
176 | |||
177 | #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) | ||
178 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); | ||
179 | |||
180 | #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) | ||
181 | COMPAT53_API int lua_isinteger (lua_State *L, int index); | ||
182 | |||
183 | #define lua_numbertointeger(n, p) \ | ||
184 | ((*(p) = (lua_Integer)(n)), 1) | ||
185 | |||
186 | #define lua_rawget(L, i) \ | ||
187 | (lua_rawget(L, i), lua_type(L, -1)) | ||
188 | |||
189 | #define lua_rawgeti(L, i, n) \ | ||
190 | (lua_rawgeti(L, i, n), lua_type(L, -1)) | ||
191 | |||
192 | #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate) | ||
193 | COMPAT53_API void lua_rotate (lua_State *L, int idx, int n); | ||
194 | |||
195 | #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti) | ||
196 | COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i); | ||
197 | |||
198 | #define lua_strtonum COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber) | ||
199 | COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s); | ||
200 | |||
201 | #define luaL_getmetafield(L, o, e) \ | ||
202 | (luaL_getmetafield(L, o, e) ? lua_type(L, -1) : LUA_TNIL) | ||
203 | |||
204 | #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_) | ||
205 | COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, | ||
206 | lua_CFunction openf, int glb ); | ||
207 | |||
208 | #endif /* Lua 5.1 and Lua 5.2 */ | ||
209 | |||
210 | |||
211 | |||
212 | /* declarations for Lua 5.2 */ | ||
213 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502 | ||
214 | |||
215 | /* XXX not implemented: | ||
216 | * lua_isyieldable | ||
217 | * lua_getextraspace | ||
218 | * lua_arith (new operators) | ||
219 | * lua_pushfstring (new formats) | ||
220 | */ | ||
221 | |||
222 | #define lua_getglobal(L, n) \ | ||
223 | (lua_getglobal(L, n), lua_type(L, -1)) | ||
224 | |||
225 | #define lua_getuservalue(L, i) \ | ||
226 | (lua_getuservalue(L, i), lua_type(L, -1)) | ||
227 | |||
228 | #define lua_rawgetp(L, i, p) \ | ||
229 | (lua_rawgetp(L, i, p), lua_type(L, -1)) | ||
230 | |||
231 | #define LUA_KFUNCTION(_name) \ | ||
232 | static int (_name)(lua_State *L, int status, lua_KContext ctx); \ | ||
233 | static int (_name ## _52)(lua_State *L) { \ | ||
234 | luaK_Context ctx; \ | ||
235 | int status = lua_getctx(L, &ctx); \ | ||
236 | return (_name)(L, status, ctx); \ | ||
237 | } \ | ||
238 | static int (_name)(lua_State *L, int status, lua_KContext ctx) | ||
239 | |||
240 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ | ||
241 | lua_pcallk(L, na, nr, err, ctx, cont ## _52) | ||
242 | |||
243 | #define lua_callk(L, na, nr, ctx, cont) \ | ||
244 | lua_callk(L, na, nr, ctx, cont ## _52) | ||
245 | |||
246 | #define lua_yieldk(L, nr, ctx, cont) \ | ||
247 | lua_yieldk(L, nr, ctx, cont ## _52) | ||
248 | |||
249 | #ifdef lua_call | ||
250 | # undef lua_call | ||
251 | # define lua_call(L, na, nr) \ | ||
252 | (lua_callk)(L, na, nr, 0, NULL) | ||
253 | #endif | ||
254 | |||
255 | #ifdef lua_pcall | ||
256 | # undef lua_pcall | ||
257 | # define lua_pcall(L, na, nr, err) \ | ||
258 | (lua_pcallk)(L, na, nr, err, 0, NULL) | ||
259 | #endif | ||
260 | |||
261 | #ifdef lua_yield | ||
262 | # undef lua_yield | ||
263 | # define lua_yield(L, nr) \ | ||
264 | (lua_yieldk)(L, nr, 0, NULL) | ||
265 | #endif | ||
266 | |||
267 | #endif /* Lua 5.2 only */ | ||
268 | |||
269 | |||
270 | |||
271 | /* other Lua versions */ | ||
272 | #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 503 | ||
273 | |||
274 | # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, or 5.3)" | ||
275 | |||
276 | #endif /* other Lua versions except 5.1, 5.2, and 5.3 */ | ||
277 | |||
278 | |||
279 | |||
280 | /* helper macro for defining continuation functions (for every version | ||
281 | * *except* Lua 5.2) */ | ||
282 | #ifndef LUA_KFUNCTION | ||
283 | #define LUA_KFUNCTION(_name) \ | ||
284 | static int (_name)(lua_State *L, int status, lua_KContext ctx) | ||
285 | #endif | ||
286 | |||
287 | |||
288 | #if defined(COMPAT53_INCLUDE_SOURCE) | ||
289 | # include "compat-5.3.c" | ||
290 | #endif | ||
291 | |||
292 | |||
293 | #endif /* COMPAT53_H_ */ | ||
294 | |||
diff --git a/tests/test.lua b/tests/test.lua new file mode 100755 index 0000000..cc07ee8 --- /dev/null +++ b/tests/test.lua | |||
@@ -0,0 +1,109 @@ | |||
1 | #!/usr/bin/env lua | ||
2 | |||
3 | local mod = require( "testmod" ) | ||
4 | local F | ||
5 | do | ||
6 | local type, unpack = type, table.unpack or unpack | ||
7 | function F( ... ) | ||
8 | local args, n = { ... }, select( '#', ... ) | ||
9 | for i = 1, n do | ||
10 | local t = type( args[ i ] ) | ||
11 | if t ~= "string" and t ~= "number" and t ~= "boolean" then | ||
12 | args[ i ] = t | ||
13 | end | ||
14 | end | ||
15 | return unpack( args, 1, n ) | ||
16 | end | ||
17 | end | ||
18 | |||
19 | |||
20 | print( mod.isinteger( 1 ) ) | ||
21 | print( mod.isinteger( 0 ) ) | ||
22 | print( mod.isinteger( 1234567 ) ) | ||
23 | print( mod.isinteger( 12.3 ) ) | ||
24 | print( mod.isinteger( math.huge ) ) | ||
25 | print( mod.isinteger( math.sqrt( -1 ) ) ) | ||
26 | |||
27 | |||
28 | print( mod.rotate( 1, 1, 2, 3, 4, 5, 6 ) ) | ||
29 | print( mod.rotate(-1, 1, 2, 3, 4, 5, 6 ) ) | ||
30 | print( mod.rotate( 4, 1, 2, 3, 4, 5, 6 ) ) | ||
31 | print( mod.rotate( -4, 1, 2, 3, 4, 5, 6 ) ) | ||
32 | |||
33 | |||
34 | print( mod.strtonum( "+123" ) ) | ||
35 | print( mod.strtonum( " 123 " ) ) | ||
36 | print( mod.strtonum( "-1.23" ) ) | ||
37 | print( mod.strtonum( " 123 abc" ) ) | ||
38 | print( mod.strtonum( "jkl" ) ) | ||
39 | |||
40 | |||
41 | local a, b, c = mod.requiref() | ||
42 | print( type( a ), type( b ), type( c ), | ||
43 | a.boolean, b.boolean, c.boolean, | ||
44 | type( requiref1 ), type( requiref2 ), type( requiref3 ) ) | ||
45 | |||
46 | local proxy, backend = {}, {} | ||
47 | setmetatable( proxy, { __index = backend, __newindex = backend } ) | ||
48 | print( rawget( proxy, 1 ), rawget( backend, 1 ) ) | ||
49 | print( mod.getseti( proxy, 1 ) ) | ||
50 | print( rawget( proxy, 1 ), rawget( backend, 1 ) ) | ||
51 | print( mod.getseti( proxy, 1 ) ) | ||
52 | print( rawget( proxy, 1 ), rawget( backend, 1 ) ) | ||
53 | |||
54 | -- tests for Lua 5.1 | ||
55 | print(mod.tonumber(12)) | ||
56 | print(mod.tonumber("12")) | ||
57 | print(mod.tonumber("0")) | ||
58 | print(mod.tonumber(false)) | ||
59 | print(mod.tonumber("error")) | ||
60 | |||
61 | print(mod.tointeger(12)) | ||
62 | print(mod.tointeger("12")) | ||
63 | print(mod.tointeger("0")) | ||
64 | print( "aaa" ) | ||
65 | print(mod.tointeger(math.pi)) | ||
66 | print( "bbb" ) | ||
67 | print(mod.tointeger(false)) | ||
68 | print(mod.tointeger("error")) | ||
69 | |||
70 | print(mod.len("123")) | ||
71 | print(mod.len({ 1, 2, 3})) | ||
72 | print(pcall(mod.len, true)) | ||
73 | local ud, meta = mod.newproxy() | ||
74 | meta.__len = function() return 5 end | ||
75 | print(mod.len(ud)) | ||
76 | meta.__len = function() return true end | ||
77 | print(pcall(mod.len, ud)) | ||
78 | |||
79 | print(mod.copy(true, "string", {}, 1)) | ||
80 | |||
81 | print(mod.rawxetp()) | ||
82 | print(mod.rawxetp("I'm back")) | ||
83 | |||
84 | print(F(mod.globals()), mod.globals() == _G) | ||
85 | |||
86 | local t = {} | ||
87 | print(F(mod.subtable(t))) | ||
88 | local x, msg = mod.subtable(t) | ||
89 | print(F(x, msg, x == t.xxx)) | ||
90 | |||
91 | print(F(mod.udata())) | ||
92 | print(mod.udata("nosuchtype")) | ||
93 | |||
94 | print(F(mod.uservalue())) | ||
95 | |||
96 | print(mod.getupvalues()) | ||
97 | |||
98 | print(mod.absindex("hi", true)) | ||
99 | |||
100 | print(mod.tolstring("string")) | ||
101 | local t = setmetatable({}, { | ||
102 | __tostring = function(v) return "mytable" end | ||
103 | }) | ||
104 | print(mod.tolstring( t ) ) | ||
105 | local t = setmetatable({}, { | ||
106 | __tostring = function(v) return nil end | ||
107 | }) | ||
108 | print(pcall(mod.tolstring, t)) | ||
109 | |||
diff --git a/tests/testmod.c b/tests/testmod.c new file mode 100644 index 0000000..a9c8e8d --- /dev/null +++ b/tests/testmod.c | |||
@@ -0,0 +1,246 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <lua.h> | ||
3 | #include <lauxlib.h> | ||
4 | #include "compat-5.3.h" | ||
5 | |||
6 | |||
7 | static int test_isinteger (lua_State *L) { | ||
8 | lua_pushboolean(L, lua_isinteger(L, 1)); | ||
9 | return 1; | ||
10 | } | ||
11 | |||
12 | |||
13 | static int test_rotate (lua_State *L) { | ||
14 | int r = luaL_checkint(L, 1); | ||
15 | int n = lua_gettop(L)-1; | ||
16 | luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments"); | ||
17 | lua_rotate(L, 2, r); | ||
18 | return n; | ||
19 | } | ||
20 | |||
21 | |||
22 | static int test_str2num (lua_State *L) { | ||
23 | const char *s = luaL_checkstring(L, 1); | ||
24 | size_t len = lua_stringtonumber(L, s); | ||
25 | if (len == 0) | ||
26 | lua_pushnumber(L, 0); | ||
27 | lua_pushinteger(L, (lua_Integer)len); | ||
28 | return 2; | ||
29 | } | ||
30 | |||
31 | |||
32 | static int my_mod (lua_State *L ) { | ||
33 | lua_newtable(L); | ||
34 | lua_pushboolean(L, 1); | ||
35 | lua_setfield(L, -2, "boolean"); | ||
36 | return 1; | ||
37 | } | ||
38 | |||
39 | static int test_requiref (lua_State *L) { | ||
40 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
41 | lua_newtable(L); | ||
42 | lua_pushboolean(L, 0); | ||
43 | lua_setfield(L, -2, "boolean"); | ||
44 | lua_setfield(L, -2, "requiref3"); | ||
45 | lua_pop(L, 1); | ||
46 | luaL_requiref(L, "requiref1", my_mod, 0); | ||
47 | luaL_requiref(L, "requiref2", my_mod, 1); | ||
48 | luaL_requiref(L, "requiref3", my_mod, 1); | ||
49 | return 3; | ||
50 | } | ||
51 | |||
52 | static int test_getseti (lua_State *L) { | ||
53 | lua_Integer k = luaL_checkinteger(L, 2); | ||
54 | lua_Integer n = 0; | ||
55 | if (lua_geti(L, 1, k) == LUA_TNUMBER) { | ||
56 | n = lua_tointeger(L, -1); | ||
57 | } else { | ||
58 | lua_pop(L, 1); | ||
59 | lua_pushinteger(L, n); | ||
60 | } | ||
61 | lua_pushinteger(L, n+1); | ||
62 | lua_seti(L, 1, k); | ||
63 | return 1; | ||
64 | } | ||
65 | |||
66 | |||
67 | /* additional tests for Lua5.1 */ | ||
68 | #define NUP 3 | ||
69 | |||
70 | static int test_newproxy (lua_State *L) { | ||
71 | lua_settop(L, 0); | ||
72 | lua_newuserdata(L, 0); | ||
73 | lua_newtable(L); | ||
74 | lua_pushvalue(L, -1); | ||
75 | lua_pushboolean(L, 1); | ||
76 | lua_setfield(L, -2, "__gc"); | ||
77 | lua_setmetatable(L, -3); | ||
78 | return 2; | ||
79 | } | ||
80 | |||
81 | static int test_absindex (lua_State *L) { | ||
82 | int i = 1; | ||
83 | for (i = 1; i <= NUP; ++i) | ||
84 | lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i))); | ||
85 | lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX)); | ||
86 | lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1)))); | ||
87 | lua_replace(L, lua_absindex(L, -2)); | ||
88 | lua_pushvalue(L, lua_absindex(L, -2)); | ||
89 | lua_pushvalue(L, lua_absindex(L, -4)); | ||
90 | lua_pushvalue(L, lua_absindex(L, -6)); | ||
91 | i += 3; | ||
92 | lua_pushvalue(L, lua_absindex(L, 1)); | ||
93 | lua_pushvalue(L, lua_absindex(L, 2)); | ||
94 | lua_pushvalue(L, lua_absindex(L, 3)); | ||
95 | i += 3; | ||
96 | return i; | ||
97 | } | ||
98 | |||
99 | static int test_globals (lua_State *L) { | ||
100 | lua_pushglobaltable(L); | ||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | static int test_tonumber (lua_State *L) { | ||
105 | int isnum = 0; | ||
106 | lua_Number n = lua_tonumberx(L, 1, &isnum); | ||
107 | if (!isnum) | ||
108 | lua_pushnil(L); | ||
109 | else | ||
110 | lua_pushnumber(L, n); | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | static int test_tointeger (lua_State *L) { | ||
115 | int isnum = 0; | ||
116 | lua_Integer n = lua_tointegerx(L, 1, &isnum); | ||
117 | if (!isnum) | ||
118 | lua_pushnil(L); | ||
119 | else | ||
120 | lua_pushinteger(L, n); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | static int test_len (lua_State *L) { | ||
125 | luaL_checkany(L, 1); | ||
126 | lua_len(L, 1); | ||
127 | lua_pushinteger(L, luaL_len(L, 1)); | ||
128 | return 2; | ||
129 | } | ||
130 | |||
131 | static int test_copy (lua_State *L) { | ||
132 | int args = lua_gettop(L); | ||
133 | if (args >= 2) { | ||
134 | int i = 0; | ||
135 | for (i = args-1; i > 0; --i) | ||
136 | lua_copy(L, args, i); | ||
137 | } | ||
138 | return args; | ||
139 | } | ||
140 | |||
141 | /* need an address */ | ||
142 | static char const dummy = 0; | ||
143 | |||
144 | static int test_rawxetp (lua_State *L) { | ||
145 | if (lua_gettop(L) > 0) | ||
146 | lua_pushvalue(L, 1); | ||
147 | else | ||
148 | lua_pushliteral(L, "hello again"); | ||
149 | lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy); | ||
150 | lua_settop(L, 0); | ||
151 | lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy); | ||
152 | return 1; | ||
153 | } | ||
154 | |||
155 | static int test_udata (lua_State *L) { | ||
156 | const char *tname = luaL_optstring(L, 1, "utype1"); | ||
157 | void *u1 = lua_newuserdata(L, 1); | ||
158 | int u1pos = lua_gettop(L); | ||
159 | void *u2 = lua_newuserdata(L, 1); | ||
160 | int u2pos = lua_gettop(L); | ||
161 | luaL_newmetatable(L, "utype1"); | ||
162 | luaL_newmetatable(L, "utype2"); | ||
163 | lua_pop(L, 2); | ||
164 | luaL_setmetatable(L, "utype2"); | ||
165 | lua_pushvalue(L, u1pos); | ||
166 | luaL_setmetatable(L, "utype1"); | ||
167 | lua_pop(L, 1); | ||
168 | (void)u1; | ||
169 | (void)u2; | ||
170 | lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname)); | ||
171 | lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname)); | ||
172 | return 2; | ||
173 | } | ||
174 | |||
175 | static int test_subtable (lua_State *L) { | ||
176 | luaL_checktype(L, 1, LUA_TTABLE); | ||
177 | lua_settop(L, 1); | ||
178 | if (luaL_getsubtable(L, 1, "xxx")) { | ||
179 | lua_pushliteral(L, "oldtable"); | ||
180 | } else { | ||
181 | lua_pushliteral(L, "newtable"); | ||
182 | } | ||
183 | return 2; | ||
184 | } | ||
185 | |||
186 | static int test_uservalue (lua_State *L) { | ||
187 | void *udata = lua_newuserdata(L, 1); | ||
188 | int ui = lua_gettop(L); | ||
189 | lua_newtable(L); | ||
190 | lua_setuservalue(L, ui); | ||
191 | lua_getuservalue(L, ui); | ||
192 | (void)udata; | ||
193 | return 1; | ||
194 | } | ||
195 | |||
196 | static int test_upvalues (lua_State *L) { | ||
197 | int i = 1; | ||
198 | for (i = 1; i <= NUP; ++i) | ||
199 | lua_pushvalue(L, lua_upvalueindex(i)); | ||
200 | return NUP; | ||
201 | } | ||
202 | |||
203 | static int test_tolstring (lua_State *L) { | ||
204 | size_t len = 0; | ||
205 | luaL_tolstring(L, 1, &len); | ||
206 | lua_pushinteger(L, (int)len); | ||
207 | return 2; | ||
208 | } | ||
209 | |||
210 | |||
211 | static const luaL_Reg funcs[] = { | ||
212 | { "isinteger", test_isinteger }, | ||
213 | { "rotate", test_rotate }, | ||
214 | { "strtonum", test_str2num }, | ||
215 | { "requiref", test_requiref }, | ||
216 | { "getseti", test_getseti }, | ||
217 | { "newproxy", test_newproxy }, | ||
218 | { "tonumber", test_tonumber }, | ||
219 | { "tointeger", test_tointeger }, | ||
220 | { "len", test_len }, | ||
221 | { "copy", test_copy }, | ||
222 | { "rawxetp", test_rawxetp }, | ||
223 | { "subtable", test_subtable }, | ||
224 | { "udata", test_udata }, | ||
225 | { "uservalue", test_uservalue }, | ||
226 | { "globals", test_globals }, | ||
227 | { "tolstring", test_tolstring }, | ||
228 | { NULL, NULL } | ||
229 | }; | ||
230 | |||
231 | static const luaL_Reg more_funcs[] = { | ||
232 | { "getupvalues", test_upvalues }, | ||
233 | { "absindex", test_absindex }, | ||
234 | { NULL, NULL } | ||
235 | }; | ||
236 | |||
237 | |||
238 | int luaopen_testmod (lua_State *L) { | ||
239 | int i = 1; | ||
240 | luaL_newlib(L, funcs); | ||
241 | for (i = 1; i <= NUP; ++i) | ||
242 | lua_pushnumber(L, i); | ||
243 | luaL_setfuncs(L, more_funcs, NUP); | ||
244 | return 1; | ||
245 | } | ||
246 | |||