diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/test.lua | 789 | ||||
-rw-r--r-- | tests/testmod.c | 318 |
2 files changed, 1107 insertions, 0 deletions
diff --git a/tests/test.lua b/tests/test.lua new file mode 100755 index 0000000..582f55e --- /dev/null +++ b/tests/test.lua | |||
@@ -0,0 +1,789 @@ | |||
1 | #!/usr/bin/env lua | ||
2 | |||
3 | local F, tproxy, writefile, noprint, ___ | ||
4 | do | ||
5 | local type, unpack = type, table.unpack or unpack | ||
6 | local assert, io = assert, io | ||
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 | function tproxy(t) | ||
18 | return setmetatable({}, { | ||
19 | __index = t, | ||
20 | __newindex = t, | ||
21 | __len = function() return #t end, | ||
22 | }), t | ||
23 | end | ||
24 | function writefile(name, contents, bin) | ||
25 | local f = assert(io.open(name, bin and "wb" or "w")) | ||
26 | f:write(contents) | ||
27 | f:close() | ||
28 | end | ||
29 | function noprint() end | ||
30 | local sep = ("="):rep(70) | ||
31 | function ___() | ||
32 | print(sep) | ||
33 | end | ||
34 | end | ||
35 | |||
36 | local V = _VERSION:gsub("^.*(%d+)%.(%d+)$", "%1%2") | ||
37 | if jit then V = "jit" end | ||
38 | |||
39 | local mode = "global" | ||
40 | if arg[1] == "module" then | ||
41 | mode = "module" | ||
42 | end | ||
43 | |||
44 | |||
45 | package.path = "../?.lua;../?/init.lua" | ||
46 | package.cpath = "./?-"..V..".so;./?-"..V..".dll;./?.so;./?.dll" | ||
47 | if mode == "module" then | ||
48 | print("testing Lua API using `compat53.module` ...") | ||
49 | _ENV = require("compat53.module") | ||
50 | if setfenv then setfenv(1, _ENV) end | ||
51 | else | ||
52 | print("testing Lua API using `compat53` ...") | ||
53 | require("compat53") | ||
54 | end | ||
55 | |||
56 | |||
57 | ___'' | ||
58 | do | ||
59 | print("assert", F(pcall(assert, false))) | ||
60 | print("assert", F(pcall(assert, false, nil))) | ||
61 | print("assert", F(pcall(assert, false, "error msg"))) | ||
62 | print("assert", F(pcall(assert, nil, {}))) | ||
63 | print("assert", F(pcall(assert, 1, 2, 3))) | ||
64 | end | ||
65 | |||
66 | |||
67 | ___'' | ||
68 | do | ||
69 | local t = setmetatable({}, { __index = { 1, false, "three" } }) | ||
70 | for i,v in ipairs(t) do | ||
71 | print("ipairs", i, v) | ||
72 | end | ||
73 | end | ||
74 | |||
75 | |||
76 | ___'' | ||
77 | do | ||
78 | local p, t = tproxy{ "a", "b", "c" } | ||
79 | print("table.concat", table.concat(p)) | ||
80 | print("table.concat", table.concat(p, ",", 2)) | ||
81 | print("table.concat", table.concat(p, ".", 1, 2)) | ||
82 | print("table.concat", table.concat(t)) | ||
83 | print("table.concat", table.concat(t, ",", 2)) | ||
84 | print("table.concat", table.concat(t, ".", 1, 2)) | ||
85 | end | ||
86 | |||
87 | |||
88 | ___'' | ||
89 | do | ||
90 | local p, t = tproxy{ "a", "b", "c" } | ||
91 | table.insert(p, "d") | ||
92 | print("table.insert", next(p), t[4]) | ||
93 | table.insert(p, 1, "z") | ||
94 | print("table.insert", next(p), t[1], t[2]) | ||
95 | table.insert(p, 2, "y") | ||
96 | print("table.insert", next(p), t[1], t[2], p[3]) | ||
97 | t = { "a", "b", "c" } | ||
98 | table.insert(t, "d") | ||
99 | print("table.insert", t[1], t[2], t[3], t[4]) | ||
100 | table.insert(t, 1, "z") | ||
101 | print("table.insert", t[1], t[2], t[3], t[4], t[5]) | ||
102 | table.insert(t, 2, "y") | ||
103 | print("table.insert", t[1], t[2], t[3], t[4], t[5]) | ||
104 | end | ||
105 | |||
106 | |||
107 | ___'' | ||
108 | do | ||
109 | local ps, s = tproxy{ "a", "b", "c", "d" } | ||
110 | local pd, d = tproxy{ "A", "B", "C", "D" } | ||
111 | table.move(ps, 1, 4, 1, pd) | ||
112 | print("table.move", next(pd), d[1], d[2], d[3], d[4]) | ||
113 | pd, d = tproxy{ "A", "B", "C", "D" } | ||
114 | table.move(ps, 2, 4, 1, pd) | ||
115 | print("table.move", next(pd), d[1], d[2], d[3], d[4]) | ||
116 | pd, d = tproxy{ "A", "B", "C", "D" } | ||
117 | table.move(ps, 2, 3, 4, pd) | ||
118 | print("table.move", next(pd), d[1], d[2], d[3], d[4], d[5]) | ||
119 | table.move(ps, 2, 4, 1) | ||
120 | print("table.move", next(ps), s[1], s[2], s[3], s[4]) | ||
121 | ps, s = tproxy{ "a", "b", "c", "d" } | ||
122 | table.move(ps, 2, 3, 4) | ||
123 | print("table.move", next(ps), s[1], s[2], s[3], s[4], s[5]) | ||
124 | s = { "a", "b", "c", "d" } | ||
125 | d = { "A", "B", "C", "D" } | ||
126 | table.move(s, 1, 4, 1, d) | ||
127 | print("table.move", d[1], d[2], d[3], d[4]) | ||
128 | d = { "A", "B", "C", "D" } | ||
129 | table.move(s, 2, 4, 1, d) | ||
130 | print("table.move", d[1], d[2], d[3], d[4]) | ||
131 | d = { "A", "B", "C", "D" } | ||
132 | table.move(s, 2, 3, 4, d) | ||
133 | print("table.move", d[1], d[2], d[3], d[4], d[5]) | ||
134 | table.move(s, 2, 4, 1) | ||
135 | print("table.move", s[1], s[2], s[3], s[4]) | ||
136 | s = { "a", "b", "c", "d" } | ||
137 | table.move(s, 2, 3, 4) | ||
138 | print("table.move", s[1], s[2], s[3], s[4], s[5]) | ||
139 | end | ||
140 | |||
141 | |||
142 | ___'' | ||
143 | do | ||
144 | local p, t = tproxy{ "a", "b", "c", "d", "e" } | ||
145 | print("table.remove", table.remove(p)) | ||
146 | print("table.remove", next(p), t[1], t[2], t[3], t[4], t[5]) | ||
147 | print("table.remove", table.remove(p, 1)) | ||
148 | print("table.remove", next(p), t[1], t[2], t[3], t[4]) | ||
149 | print("table.remove", table.remove(p, 2)) | ||
150 | print("table.remove", next(p), t[1], t[2], t[3]) | ||
151 | print("table.remove", table.remove(p, 3)) | ||
152 | print("table.remove", next(p), t[1], t[2], t[3]) | ||
153 | p, t = tproxy{} | ||
154 | print("table.remove", table.remove(p)) | ||
155 | print("table.remove", next(p), next(t)) | ||
156 | t = { "a", "b", "c", "d", "e" } | ||
157 | print("table.remove", table.remove(t)) | ||
158 | print("table.remove", t[1], t[2], t[3], t[4], t[5]) | ||
159 | print("table.remove", table.remove(t, 1)) | ||
160 | print("table.remove", t[1], t[2], t[3], t[4]) | ||
161 | print("table.remove", table.remove(t, 2)) | ||
162 | print("table.remove", t[1], t[2], t[3]) | ||
163 | print("table.remove", table.remove(t, 3)) | ||
164 | print("table.remove", t[1], t[2], t[3]) | ||
165 | t = {} | ||
166 | print("table.remove", table.remove(t)) | ||
167 | print("table.remove", next(t)) | ||
168 | end | ||
169 | |||
170 | ___'' | ||
171 | do | ||
172 | local p, t = tproxy{ 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } | ||
173 | table.sort(p) | ||
174 | print("table.sort", next(p)) | ||
175 | for i,v in ipairs(t) do | ||
176 | print("table.sort", i, v) | ||
177 | end | ||
178 | table.sort(p) | ||
179 | print("table.sort", next(p)) | ||
180 | for i,v in ipairs(t) do | ||
181 | print("table.sort", i, v) | ||
182 | end | ||
183 | p, t = tproxy{ 9, 8, 7, 6, 5, 4, 3, 2, 1 } | ||
184 | table.sort(p) | ||
185 | print("table.sort", next(p)) | ||
186 | for i,v in ipairs(t) do | ||
187 | print("table.sort", i, v) | ||
188 | end | ||
189 | table.sort(p, function(a, b) return a > b end) | ||
190 | print("table.sort", next(p)) | ||
191 | for i,v in ipairs(t) do | ||
192 | print("table.sort", i, v) | ||
193 | end | ||
194 | p, t = tproxy{ 1, 1, 1, 1, 1 } | ||
195 | print("table.sort", next(p)) | ||
196 | for i,v in ipairs(t) do | ||
197 | print("table.sort", i, v) | ||
198 | end | ||
199 | t = { 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } | ||
200 | table.sort(t) | ||
201 | for i,v in ipairs(t) do | ||
202 | print("table.sort", i, v) | ||
203 | end | ||
204 | table.sort(t, function(a, b) return a > b end) | ||
205 | for i,v in ipairs(t) do | ||
206 | print("table.sort", i, v) | ||
207 | end | ||
208 | end | ||
209 | |||
210 | |||
211 | ___'' | ||
212 | do | ||
213 | local p, t = tproxy{ "a", "b", "c" } | ||
214 | print("table.unpack", table.unpack(p)) | ||
215 | print("table.unpack", table.unpack(p, 2)) | ||
216 | print("table.unpack", table.unpack(p, 1, 2)) | ||
217 | print("table.unpack", table.unpack(t)) | ||
218 | print("table.unpack", table.unpack(t, 2)) | ||
219 | print("table.unpack", table.unpack(t, 1, 2)) | ||
220 | end | ||
221 | |||
222 | |||
223 | ___'' | ||
224 | print("math.maxinteger", math.maxinteger+1 > math.maxinteger) | ||
225 | print("math.mininteger", math.mininteger-1 < math.mininteger) | ||
226 | |||
227 | |||
228 | ___'' | ||
229 | print("math.tointeger", math.tointeger(0)) | ||
230 | print("math.tointeger", math.tointeger(math.pi)) | ||
231 | print("math.tointeger", math.tointeger("hello")) | ||
232 | print("math.tointeger", math.tointeger(math.maxinteger+2.0)) | ||
233 | print("math.tointeger", math.tointeger(math.mininteger*2.0)) | ||
234 | |||
235 | |||
236 | ___'' | ||
237 | print("math.type", math.type(0)) | ||
238 | print("math.type", math.type(math.pi)) | ||
239 | print("math.type", math.type("hello")) | ||
240 | |||
241 | |||
242 | ___'' | ||
243 | print("math.ult", math.ult(1, 2), math.ult(2, 1)) | ||
244 | print("math.ult", math.ult(-1, 2), math.ult(2, -1)) | ||
245 | print("math.ult", math.ult(-1, -2), math.ult(-2, -1)) | ||
246 | print("math.ult", pcall(math.ult, "x", 2)) | ||
247 | print("math.ult", pcall(math.ult, 1, 2.1)) | ||
248 | ___'' | ||
249 | |||
250 | |||
251 | if utf8.len then | ||
252 | local unpack = table.unpack or unpack | ||
253 | local function utf8rt(s) | ||
254 | local t = { utf8.codepoint(s, 1, #s) } | ||
255 | local ps, cs = {}, {} | ||
256 | for p,c in utf8.codes(s) do | ||
257 | ps[#ps+1], cs[#cs+1] = p, c | ||
258 | end | ||
259 | print("utf8.codes", unpack(ps)) | ||
260 | print("utf8.codes", unpack(cs)) | ||
261 | print("utf8.codepoint", unpack(t)) | ||
262 | print("utf8.len", utf8.len(s), #t, #s) | ||
263 | print("utf8.char", utf8.char(unpack(t))) | ||
264 | end | ||
265 | utf8rt("äöüßÄÖÜ") | ||
266 | utf8rt("abcdefg") | ||
267 | ___'' | ||
268 | local s = "äöüßÄÖÜ" | ||
269 | print("utf8.offset", utf8.offset(s, 1, 1)) | ||
270 | print("utf8.offset", utf8.offset(s, 2, 1)) | ||
271 | print("utf8.offset", utf8.offset(s, 3, 1)) | ||
272 | print("utf8.offset", pcall(utf8.offset, s, 3, 2)) | ||
273 | print("utf8.offset", utf8.offset(s, 3, 3)) | ||
274 | print("utf8.offset", utf8.offset(s, -1, 7)) | ||
275 | print("utf8.offset", utf8.offset(s, -2, 7)) | ||
276 | print("utf8.offset", utf8.offset(s, -3, 7)) | ||
277 | print("utf8.offset", utf8.offset(s, -1)) | ||
278 | ___'' | ||
279 | else | ||
280 | print("XXX: utf8 module not available") | ||
281 | end | ||
282 | |||
283 | |||
284 | if string.pack then | ||
285 | local format = "bBhHlLjJdc3z" | ||
286 | local s = string.pack(format, -128, 255, -32768, 65535, -2147483648, 4294967295, -32768, 65536, 1.25, "abc", "defgh") | ||
287 | print("string.unpack", string.unpack(format, s)) | ||
288 | ___'' | ||
289 | else | ||
290 | print("XXX: string packing not available") | ||
291 | end | ||
292 | |||
293 | |||
294 | print("testing Lua API for Lua 5.1 ...") | ||
295 | |||
296 | ___'' | ||
297 | print("debug.getuservalue()", F(debug.getuservalue(false))) | ||
298 | print("debug.setuservalue()", pcall(function() | ||
299 | debug.setuservalue(false, {}) | ||
300 | end)) | ||
301 | print("debug.setmetatable()", F(debug.setmetatable({}, {}))) | ||
302 | |||
303 | |||
304 | ___'' | ||
305 | do | ||
306 | local t = setmetatable({}, { | ||
307 | __pairs = function() return pairs({ a = "a" }) end, | ||
308 | }) | ||
309 | for k,v in pairs(t) do | ||
310 | print("pairs()", k, v) | ||
311 | end | ||
312 | end | ||
313 | |||
314 | |||
315 | ___'' | ||
316 | do | ||
317 | local code = "print('hello world')\n" | ||
318 | local badcode = "print('blub\n" | ||
319 | print("load()", pcall(function() load(true) end)) | ||
320 | print("load()", F(load(badcode))) | ||
321 | print("load()", F(load(code))) | ||
322 | print("load()", F(load(code, "[L]"))) | ||
323 | print("load()", F(load(code, "[L]", "b"))) | ||
324 | print("load()", F(load(code, "[L]", "t"))) | ||
325 | print("load()", F(load(code, "[L]", "bt"))) | ||
326 | local f = load(code, "[L]", "bt", {}) | ||
327 | print("load()", pcall(f)) | ||
328 | f = load(code, "[L]", "bt", { print = noprint }) | ||
329 | print("load()", pcall(f)) | ||
330 | local bytecode = string.dump(f) | ||
331 | print("load()", F(load(bytecode))) | ||
332 | print("load()", F(load(bytecode, "[L]"))) | ||
333 | print("load()", F(load(bytecode, "[L]", "b"))) | ||
334 | print("load()", F(load(bytecode, "[L]", "t"))) | ||
335 | print("load()", F(load(bytecode, "[L]", "bt"))) | ||
336 | f = load(bytecode, "[L]", "bt", {}) | ||
337 | print("load()", pcall(f)) | ||
338 | f = load(bytecode, "[L]", "bt", { print = noprint }) | ||
339 | print("load()", pcall(f)) | ||
340 | local function make_loader(code) | ||
341 | local mid = math.floor( #code/2 ) | ||
342 | local array = { code:sub(1, mid), code:sub(mid+1) } | ||
343 | local i = 0 | ||
344 | return function() | ||
345 | i = i + 1 | ||
346 | return array[i] | ||
347 | end | ||
348 | end | ||
349 | print("load()", F(load(make_loader(badcode)))) | ||
350 | print("load()", F(load(make_loader(code)))) | ||
351 | print("load()", F(load(make_loader(code), "[L]"))) | ||
352 | print("load()", F(load(make_loader(code), "[L]", "b"))) | ||
353 | print("load()", F(load(make_loader(code), "[L]", "t"))) | ||
354 | print("load()", F(load(make_loader(code), "[L]", "bt"))) | ||
355 | f = load(make_loader(code), "[L]", "bt", {}) | ||
356 | print("load()", pcall(f)) | ||
357 | f = load(make_loader(code), "[L]", "bt", { print = noprint }) | ||
358 | print("load()", pcall(f)) | ||
359 | print("load()", F(load(make_loader(bytecode)))) | ||
360 | print("load()", F(load(make_loader(bytecode), "[L]"))) | ||
361 | print("load()", F(load(make_loader(bytecode), "[L]", "b"))) | ||
362 | print("load()", F(load(make_loader(bytecode), "[L]", "t"))) | ||
363 | print("load()", F(load(make_loader(bytecode), "[L]", "bt"))) | ||
364 | f = load(make_loader(bytecode), "[L]", "bt", {}) | ||
365 | print("load()", pcall(f)) | ||
366 | f = load(make_loader(bytecode), "[L]", "bt", { print = noprint }) | ||
367 | print("load()", pcall(f)) | ||
368 | writefile("good.lua", code) | ||
369 | writefile("bad.lua", badcode) | ||
370 | writefile("good.luac", bytecode, true) | ||
371 | print("loadfile()", F(loadfile("bad.lua"))) | ||
372 | print("loadfile()", F(loadfile("good.lua"))) | ||
373 | print("loadfile()", F(loadfile("good.lua", "b"))) | ||
374 | print("loadfile()", F(loadfile("good.lua", "t"))) | ||
375 | print("loadfile()", F(loadfile("good.lua", "bt"))) | ||
376 | f = loadfile("good.lua", "bt", {}) | ||
377 | print("loadfile()", pcall(f)) | ||
378 | f = loadfile("good.lua", "bt", { print = noprint }) | ||
379 | print("loadfile()", pcall(f)) | ||
380 | print("loadfile()", F(loadfile("good.luac"))) | ||
381 | print("loadfile()", F(loadfile("good.luac", "b"))) | ||
382 | print("loadfile()", F(loadfile("good.luac", "t"))) | ||
383 | print("loadfile()", F(loadfile("good.luac", "bt"))) | ||
384 | f = loadfile("good.luac", "bt", {}) | ||
385 | print("loadfile()", pcall(f)) | ||
386 | f = loadfile("good.luac", "bt", { print = noprint }) | ||
387 | print("loadfile()", pcall(f)) | ||
388 | os.remove("good.lua") | ||
389 | os.remove("bad.lua") | ||
390 | os.remove("good.luac") | ||
391 | end | ||
392 | |||
393 | |||
394 | ___'' | ||
395 | do | ||
396 | local function func(throw) | ||
397 | if throw then | ||
398 | error("argh") | ||
399 | else | ||
400 | return 1, 2, 3 | ||
401 | end | ||
402 | end | ||
403 | local function tb(err) return "|"..err.."|" end | ||
404 | print("xpcall()", xpcall(func, debug.traceback, false)) | ||
405 | print("xpcall()", xpcall(func, debug.traceback, true)) | ||
406 | print("xpcall()", xpcall(func, tb, true)) | ||
407 | if mode ~= "module" then | ||
408 | local function func2(cb) | ||
409 | print("xpcall()", xpcall(cb, debug.traceback, "str")) | ||
410 | end | ||
411 | local function func3(cb) | ||
412 | print("pcall()", pcall(cb, "str")) | ||
413 | end | ||
414 | local function cb(arg) | ||
415 | coroutine.yield(2) | ||
416 | return arg | ||
417 | end | ||
418 | local c = coroutine.wrap(func2) | ||
419 | print("xpcall()", c(cb)) | ||
420 | print("xpcall()", c()) | ||
421 | local c = coroutine.wrap(func3) | ||
422 | print("pcall()", c(cb)) | ||
423 | print("pcall()", c()) | ||
424 | end | ||
425 | end | ||
426 | |||
427 | |||
428 | ___'' | ||
429 | do | ||
430 | local t = setmetatable({ 1 }, { __len = function() return 5 end }) | ||
431 | print("rawlen()", rawlen(t), rawlen("123")) | ||
432 | end | ||
433 | |||
434 | |||
435 | ___'' | ||
436 | print("os.execute()", os.execute("exit 1")) | ||
437 | io.flush() | ||
438 | print("os.execute()", os.execute("echo 'hello world!'")) | ||
439 | io.flush() | ||
440 | print("os.execute()", os.execute("no_such_file")) | ||
441 | |||
442 | |||
443 | ___'' | ||
444 | do | ||
445 | local t = table.pack("a", nil, "b", nil) | ||
446 | print("table.(un)pack()", t.n, table.unpack(t, 1, t.n)) | ||
447 | end | ||
448 | |||
449 | |||
450 | ___'' | ||
451 | do | ||
452 | print("coroutine.running()", F(coroutine.wrap(function() | ||
453 | return coroutine.running() | ||
454 | end)())) | ||
455 | print("coroutine.running()", F(coroutine.running())) | ||
456 | local main_co, co1, co2 = coroutine.running() | ||
457 | -- coroutine.yield | ||
458 | if mode ~= "module" then | ||
459 | print("coroutine.yield()", pcall(function() | ||
460 | coroutine.yield(1, 2, 3) | ||
461 | end)) | ||
462 | end | ||
463 | print("coroutine.yield()", coroutine.wrap(function() | ||
464 | coroutine.yield(1, 2, 3) | ||
465 | end)()) | ||
466 | print("coroutine.resume()", coroutine.resume(main_co, 1, 2, 3)) | ||
467 | co1 = coroutine.create(function(a, b, c) | ||
468 | print("coroutine.resume()", a, b, c) | ||
469 | return a, b, c | ||
470 | end) | ||
471 | print("coroutine.resume()", coroutine.resume(co1, 1, 2, 3)) | ||
472 | co1 = coroutine.create(function() | ||
473 | print("coroutine.status()", "[co1] main is", coroutine.status(main_co)) | ||
474 | print("coroutine.status()", "[co1] co2 is", coroutine.status(co2)) | ||
475 | end) | ||
476 | co2 = coroutine.create(function() | ||
477 | print("coroutine.status()", "[co2] main is", coroutine.status(main_co)) | ||
478 | print("coroutine.status()", "[co2] co2 is", coroutine.status(co2)) | ||
479 | coroutine.yield() | ||
480 | coroutine.resume(co1) | ||
481 | end) | ||
482 | print("coroutine.status()", coroutine.status(main_co)) | ||
483 | print("coroutine.status()", coroutine.status(co2)) | ||
484 | coroutine.resume(co2) | ||
485 | print("coroutine.status()", F(coroutine.status(co2))) | ||
486 | coroutine.resume(co2) | ||
487 | print("coroutine.status()", F(coroutine.status(co2))) | ||
488 | end | ||
489 | |||
490 | |||
491 | ___'' | ||
492 | print("math.log()", math.log(1000)) | ||
493 | print("math.log()", math.log(1000, 10)) | ||
494 | |||
495 | |||
496 | ___'' | ||
497 | do | ||
498 | local path, prefix = "./?.lua;?/init.lua;../?.lua", "package.searchpath()" | ||
499 | print(prefix, package.searchpath("no.such.module", path)) | ||
500 | print(prefix, package.searchpath("no.such.module", "")) | ||
501 | print(prefix, package.searchpath("compat53", path)) | ||
502 | print(prefix, package.searchpath("no:such:module", path, ":", "|")) | ||
503 | end | ||
504 | |||
505 | |||
506 | ___'' | ||
507 | if mode ~= "module" then | ||
508 | local function mod_func() return {} end | ||
509 | local function my_searcher(name) | ||
510 | if name == "my.module" then | ||
511 | print("package.searchers", "my.module found") | ||
512 | return mod_func | ||
513 | end | ||
514 | end | ||
515 | local function my_searcher2(name) | ||
516 | if name == "my.module" then | ||
517 | print("package.searchers", "my.module found 2") | ||
518 | return mod_func | ||
519 | end | ||
520 | end | ||
521 | table.insert(package.searchers, my_searcher) | ||
522 | require("my.module") | ||
523 | package.loaded["my.module"] = nil | ||
524 | local new_s = { my_searcher2 } | ||
525 | for i,f in ipairs(package.searchers) do | ||
526 | new_s[i+1] = f | ||
527 | end | ||
528 | package.searchers = new_s | ||
529 | require("my.module") | ||
530 | end | ||
531 | |||
532 | |||
533 | ___'' | ||
534 | do | ||
535 | print("string.find()", string.find("abc\0abc\0abc", "[^a\0]+")) | ||
536 | print("string.find()", string.find("abc\0abc\0abc", "%w+\0", 5)) | ||
537 | for x in string.gmatch("abc\0def\0ghi", "[^\0]+") do | ||
538 | print("string.gmatch()", x) | ||
539 | end | ||
540 | for x in string.gmatch("abc\0def\0ghi", "%w*\0") do | ||
541 | print("string.gmatch()", #x) | ||
542 | end | ||
543 | print("string.gsub()", string.gsub("abc\0def\0ghi", "[\0]", "X")) | ||
544 | print("string.gsub()", string.gsub("abc\0def\0ghi", "%w*\0", "X")) | ||
545 | print("string.gsub()", string.gsub("abc\0def\0ghi", "%A", "X")) | ||
546 | print("string.match()", string.match("abc\0abc\0abc", "([^\0a]+)")) | ||
547 | print("string.match()", #string.match("abc\0abc\0abc", ".*\0")) | ||
548 | print("string.rep()", string.rep("a", 0)) | ||
549 | print("string.rep()", string.rep("b", 1)) | ||
550 | print("string.rep()", string.rep("c", 4)) | ||
551 | print("string.rep()", string.rep("a", 0, "|")) | ||
552 | print("string.rep()", string.rep("b", 1, "|")) | ||
553 | print("string.rep()", string.rep("c", 4, "|")) | ||
554 | local _tostring = tostring | ||
555 | function tostring(v) | ||
556 | if type(v) == "number" then | ||
557 | return "(".._tostring(v)..")" | ||
558 | else | ||
559 | return _tostring(v) | ||
560 | end | ||
561 | end | ||
562 | print("string.format()", string.format("%q", "\"\\\0000\0010\002\r\n0\t0\"")) | ||
563 | print("string.format()", string.format("%12.3fx%%sxx%.6s", 3.1, {})) | ||
564 | print("string.format()", string.format("%-3f %%%s %%s", 3.1, true)) | ||
565 | print("string.format()", string.format("% 3.2g %%d %%%s", 3.1, nil)) | ||
566 | print("string.format()", string.format("%+3d %%d %%%%%10.6s", 3, io.stdout)) | ||
567 | print("string.format()", pcall(function() | ||
568 | print("string.format()", string.format("%d %%s", {})) | ||
569 | end)) | ||
570 | tostring = _tostring | ||
571 | end | ||
572 | |||
573 | |||
574 | ___'' | ||
575 | do | ||
576 | print("io.write()", io.type(io.write("hello world\n"))) | ||
577 | local f = assert(io.tmpfile()) | ||
578 | print("file:write()", io.type(f:write("hello world\n"))) | ||
579 | f:close() | ||
580 | end | ||
581 | |||
582 | |||
583 | ___'' | ||
584 | do | ||
585 | writefile("data.txt", "123 18.8 hello world\ni'm here\n") | ||
586 | io.input("data.txt") | ||
587 | print("io.read()", io.read("*n", "*number", "*l", "*a")) | ||
588 | io.input("data.txt") | ||
589 | print("io.read()", io.read("n", "number", "l", "a")) | ||
590 | io.input(io.stdin) | ||
591 | if mode ~= "module" then | ||
592 | local f = assert(io.open("data.txt", "r")) | ||
593 | print("file:read()", f:read("*n", "*number", "*l", "*a")) | ||
594 | f:close() | ||
595 | f = assert(io.open("data.txt", "r")) | ||
596 | print("file:read()", f:read("n", "number", "l", "a")) | ||
597 | f:close() | ||
598 | end | ||
599 | os.remove("data.txt") | ||
600 | end | ||
601 | |||
602 | |||
603 | ___'' | ||
604 | do | ||
605 | writefile("data.txt", "123 18.8 hello world\ni'm here\n") | ||
606 | for a,b in io.lines("test.lua", 2, "*l") do | ||
607 | print("io.lines()", a, b) | ||
608 | break | ||
609 | end | ||
610 | for l in io.lines("test.lua") do | ||
611 | print("io.lines()", l) | ||
612 | break | ||
613 | end | ||
614 | for n1,n2,rest in io.lines("data.txt", "*n", "n", "*a") do | ||
615 | print("io.lines()", n1, n2, rest) | ||
616 | end | ||
617 | for l in io.lines("data.txt") do | ||
618 | print("io.lines()", l) | ||
619 | end | ||
620 | print("io.lines()", pcall(function() | ||
621 | for l in io.lines("data.txt", "*x") do print(l) end | ||
622 | end)) | ||
623 | print("io.lines()", pcall(function() | ||
624 | for l in io.lines("no_such_file.txt") do print(l) end | ||
625 | end)) | ||
626 | if mode ~= "module" then | ||
627 | local f = assert(io.open("test.lua", "r")) | ||
628 | for a,b in f:lines(2, "*l") do | ||
629 | print("file:lines()", a, b) | ||
630 | break | ||
631 | end | ||
632 | f:close() | ||
633 | f = assert(io.open("data.txt", "r")) | ||
634 | for n1,n2,rest in f:lines("*n", "n", "*a") do | ||
635 | print("file:lines()", n1, n2, rest) | ||
636 | end | ||
637 | f:close() | ||
638 | f = assert(io.open("data.txt", "r")) | ||
639 | for l in f:lines() do | ||
640 | print("file:lines()", l) | ||
641 | end | ||
642 | f:close() | ||
643 | print("file:lines()", pcall(function() | ||
644 | for l in f:lines() do print(l) end | ||
645 | end)) | ||
646 | print("file:lines()", pcall(function() | ||
647 | local f = assert(io.open("data.txt", "r")) | ||
648 | for l in f:lines("*l", "*x") do print(l) end | ||
649 | f:close() | ||
650 | end)) | ||
651 | end | ||
652 | os.remove("data.txt") | ||
653 | end | ||
654 | ___'' | ||
655 | |||
656 | |||
657 | print("testing C API ...") | ||
658 | local mod = require("testmod") | ||
659 | ___'' | ||
660 | print(mod.isinteger(1)) | ||
661 | print(mod.isinteger(0)) | ||
662 | print(mod.isinteger(1234567)) | ||
663 | print(mod.isinteger(12.3)) | ||
664 | print(mod.isinteger(math.huge)) | ||
665 | print(mod.isinteger(math.sqrt(-1))) | ||
666 | |||
667 | |||
668 | ___'' | ||
669 | print(mod.rotate(1, 1, 2, 3, 4, 5, 6)) | ||
670 | print(mod.rotate(-1, 1, 2, 3, 4, 5, 6)) | ||
671 | print(mod.rotate(4, 1, 2, 3, 4, 5, 6)) | ||
672 | print(mod.rotate(-4, 1, 2, 3, 4, 5, 6)) | ||
673 | |||
674 | |||
675 | ___'' | ||
676 | print(mod.strtonum("+123")) | ||
677 | print(mod.strtonum(" 123 ")) | ||
678 | print(mod.strtonum("-1.23")) | ||
679 | print(mod.strtonum(" 123 abc")) | ||
680 | print(mod.strtonum("jkl")) | ||
681 | |||
682 | |||
683 | ___'' | ||
684 | local a, b, c = mod.requiref() | ||
685 | print( type(a), type(b), type(c), | ||
686 | a.boolean, b.boolean, c.boolean, | ||
687 | type(requiref1), type(requiref2), type(requiref3)) | ||
688 | |||
689 | ___'' | ||
690 | local proxy, backend = {}, {} | ||
691 | setmetatable(proxy, { __index = backend, __newindex = backend }) | ||
692 | print(rawget(proxy, 1), rawget(backend, 1)) | ||
693 | print(mod.getseti(proxy, 1)) | ||
694 | print(rawget(proxy, 1), rawget(backend, 1)) | ||
695 | print(mod.getseti(proxy, 1)) | ||
696 | print(rawget(proxy, 1), rawget(backend, 1)) | ||
697 | |||
698 | -- tests for Lua 5.1 | ||
699 | ___'' | ||
700 | print(mod.tonumber(12)) | ||
701 | print(mod.tonumber("12")) | ||
702 | print(mod.tonumber("0")) | ||
703 | print(mod.tonumber(false)) | ||
704 | print(mod.tonumber("error")) | ||
705 | |||
706 | ___'' | ||
707 | print(mod.tointeger(12)) | ||
708 | print(mod.tointeger("12")) | ||
709 | print(mod.tointeger("0")) | ||
710 | print( "aaa" ) | ||
711 | print(mod.tointeger(math.pi)) | ||
712 | print( "bbb" ) | ||
713 | print(mod.tointeger(false)) | ||
714 | print(mod.tointeger("error")) | ||
715 | |||
716 | ___'' | ||
717 | print(mod.len("123")) | ||
718 | print(mod.len({ 1, 2, 3})) | ||
719 | print(pcall(mod.len, true)) | ||
720 | local ud, meta = mod.newproxy() | ||
721 | meta.__len = function() return 5 end | ||
722 | print(mod.len(ud)) | ||
723 | meta.__len = function() return true end | ||
724 | print(pcall(mod.len, ud)) | ||
725 | |||
726 | ___'' | ||
727 | print(mod.copy(true, "string", {}, 1)) | ||
728 | |||
729 | ___'' | ||
730 | print(mod.rawxetp()) | ||
731 | print(mod.rawxetp("I'm back")) | ||
732 | |||
733 | ___'' | ||
734 | print(F(mod.globals()), mod.globals() == _G) | ||
735 | |||
736 | ___'' | ||
737 | local t = {} | ||
738 | print(F(mod.subtable(t))) | ||
739 | local x, msg = mod.subtable(t) | ||
740 | print(F(x, msg, x == t.xxx)) | ||
741 | |||
742 | ___'' | ||
743 | print(F(mod.udata())) | ||
744 | print(mod.udata("nosuchtype")) | ||
745 | |||
746 | ___'' | ||
747 | print(F(mod.uservalue())) | ||
748 | |||
749 | ___'' | ||
750 | print(mod.getupvalues()) | ||
751 | |||
752 | ___'' | ||
753 | print(mod.absindex("hi", true)) | ||
754 | |||
755 | ___'' | ||
756 | print(mod.arith(2, 1)) | ||
757 | print(mod.arith(3, 5)) | ||
758 | |||
759 | ___'' | ||
760 | print(mod.compare(1, 1)) | ||
761 | print(mod.compare(2, 1)) | ||
762 | print(mod.compare(1, 2)) | ||
763 | |||
764 | ___'' | ||
765 | print(mod.tolstring("string")) | ||
766 | local t = setmetatable({}, { | ||
767 | __tostring = function(v) return "mytable" end | ||
768 | }) | ||
769 | print(mod.tolstring(t)) | ||
770 | local t = setmetatable({}, { | ||
771 | __tostring = function(v) return nil end | ||
772 | }) | ||
773 | print(pcall(mod.tolstring, t)) | ||
774 | local ud, meta = mod.newproxy() | ||
775 | meta.__name = "XXX" | ||
776 | print(mod.tolstring(ud):gsub(":.*$", ": yyy")) | ||
777 | |||
778 | ___'' | ||
779 | print(mod.pushstring()) | ||
780 | |||
781 | ___'' | ||
782 | print(mod.buffer()) | ||
783 | |||
784 | ___'' | ||
785 | print(mod.exec("exit 0")) | ||
786 | print(mod.exec("exit 1")) | ||
787 | print(mod.exec("exit 25")) | ||
788 | ___'' | ||
789 | |||
diff --git a/tests/testmod.c b/tests/testmod.c new file mode 100644 index 0000000..868136b --- /dev/null +++ b/tests/testmod.c | |||
@@ -0,0 +1,318 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <lua.h> | ||
4 | #include <lauxlib.h> | ||
5 | #include "compat-5.3.h" | ||
6 | |||
7 | |||
8 | static int test_isinteger (lua_State *L) { | ||
9 | lua_pushboolean(L, lua_isinteger(L, 1)); | ||
10 | return 1; | ||
11 | } | ||
12 | |||
13 | |||
14 | static int test_rotate (lua_State *L) { | ||
15 | int r = luaL_checkint(L, 1); | ||
16 | int n = lua_gettop(L)-1; | ||
17 | luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments"); | ||
18 | lua_rotate(L, 2, r); | ||
19 | return n; | ||
20 | } | ||
21 | |||
22 | |||
23 | static int test_str2num (lua_State *L) { | ||
24 | const char *s = luaL_checkstring(L, 1); | ||
25 | size_t len = lua_stringtonumber(L, s); | ||
26 | if (len == 0) | ||
27 | lua_pushnumber(L, 0); | ||
28 | lua_pushinteger(L, (lua_Integer)len); | ||
29 | return 2; | ||
30 | } | ||
31 | |||
32 | |||
33 | static int my_mod (lua_State *L ) { | ||
34 | lua_newtable(L); | ||
35 | lua_pushboolean(L, 1); | ||
36 | lua_setfield(L, -2, "boolean"); | ||
37 | return 1; | ||
38 | } | ||
39 | |||
40 | static int test_requiref (lua_State *L) { | ||
41 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
42 | lua_newtable(L); | ||
43 | lua_pushboolean(L, 0); | ||
44 | lua_setfield(L, -2, "boolean"); | ||
45 | lua_setfield(L, -2, "requiref3"); | ||
46 | lua_pop(L, 1); | ||
47 | luaL_requiref(L, "requiref1", my_mod, 0); | ||
48 | luaL_requiref(L, "requiref2", my_mod, 1); | ||
49 | luaL_requiref(L, "requiref3", my_mod, 1); | ||
50 | return 3; | ||
51 | } | ||
52 | |||
53 | static int test_getseti (lua_State *L) { | ||
54 | lua_Integer k = luaL_checkinteger(L, 2); | ||
55 | lua_Integer n = 0; | ||
56 | if (lua_geti(L, 1, k) == LUA_TNUMBER) { | ||
57 | n = lua_tointeger(L, -1); | ||
58 | } else { | ||
59 | lua_pop(L, 1); | ||
60 | lua_pushinteger(L, n); | ||
61 | } | ||
62 | lua_pushinteger(L, n+1); | ||
63 | lua_seti(L, 1, k); | ||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | |||
68 | /* additional tests for Lua5.1 */ | ||
69 | #define NUP 3 | ||
70 | |||
71 | static int test_newproxy (lua_State *L) { | ||
72 | lua_settop(L, 0); | ||
73 | lua_newuserdata(L, 0); | ||
74 | lua_newtable(L); | ||
75 | lua_pushvalue(L, -1); | ||
76 | lua_pushboolean(L, 1); | ||
77 | lua_setfield(L, -2, "__gc"); | ||
78 | lua_setmetatable(L, -3); | ||
79 | return 2; | ||
80 | } | ||
81 | |||
82 | static int test_absindex (lua_State *L) { | ||
83 | int i = 1; | ||
84 | for (i = 1; i <= NUP; ++i) | ||
85 | lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i))); | ||
86 | lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX)); | ||
87 | lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1)))); | ||
88 | lua_replace(L, lua_absindex(L, -2)); | ||
89 | lua_pushvalue(L, lua_absindex(L, -2)); | ||
90 | lua_pushvalue(L, lua_absindex(L, -4)); | ||
91 | lua_pushvalue(L, lua_absindex(L, -6)); | ||
92 | i += 3; | ||
93 | lua_pushvalue(L, lua_absindex(L, 1)); | ||
94 | lua_pushvalue(L, lua_absindex(L, 2)); | ||
95 | lua_pushvalue(L, lua_absindex(L, 3)); | ||
96 | i += 3; | ||
97 | return i; | ||
98 | } | ||
99 | |||
100 | static int test_arith (lua_State *L) { | ||
101 | lua_settop(L, 2); | ||
102 | lua_pushvalue(L, 1); | ||
103 | lua_pushvalue(L, 2); | ||
104 | lua_arith(L, LUA_OPADD); | ||
105 | lua_pushvalue(L, 1); | ||
106 | lua_pushvalue(L, 2); | ||
107 | lua_arith(L, LUA_OPSUB); | ||
108 | lua_pushvalue(L, 1); | ||
109 | lua_pushvalue(L, 2); | ||
110 | lua_arith(L, LUA_OPMUL); | ||
111 | lua_pushvalue(L, 1); | ||
112 | lua_pushvalue(L, 2); | ||
113 | lua_arith(L, LUA_OPDIV); | ||
114 | lua_pushvalue(L, 1); | ||
115 | lua_pushvalue(L, 2); | ||
116 | lua_arith(L, LUA_OPMOD); | ||
117 | lua_pushvalue(L, 1); | ||
118 | lua_pushvalue(L, 2); | ||
119 | lua_arith(L, LUA_OPPOW); | ||
120 | lua_pushvalue(L, 1); | ||
121 | lua_arith(L, LUA_OPUNM); | ||
122 | return lua_gettop(L)-2; | ||
123 | } | ||
124 | |||
125 | static int test_compare (lua_State *L) { | ||
126 | luaL_checknumber(L, 1); | ||
127 | luaL_checknumber(L, 2); | ||
128 | lua_settop(L, 2); | ||
129 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ)); | ||
130 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT)); | ||
131 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE)); | ||
132 | return 3; | ||
133 | } | ||
134 | |||
135 | static int test_globals (lua_State *L) { | ||
136 | lua_pushglobaltable(L); | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | static int test_tonumber (lua_State *L) { | ||
141 | int isnum = 0; | ||
142 | lua_Number n = lua_tonumberx(L, 1, &isnum); | ||
143 | if (!isnum) | ||
144 | lua_pushnil(L); | ||
145 | else | ||
146 | lua_pushnumber(L, n); | ||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | static int test_tointeger (lua_State *L) { | ||
151 | int isnum = 0; | ||
152 | lua_Integer n = lua_tointegerx(L, 1, &isnum); | ||
153 | if (!isnum) | ||
154 | lua_pushnil(L); | ||
155 | else | ||
156 | lua_pushinteger(L, n); | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | static int test_len (lua_State *L) { | ||
161 | luaL_checkany(L, 1); | ||
162 | lua_len(L, 1); | ||
163 | lua_pushinteger(L, luaL_len(L, 1)); | ||
164 | return 2; | ||
165 | } | ||
166 | |||
167 | static int test_copy (lua_State *L) { | ||
168 | int args = lua_gettop(L); | ||
169 | if (args >= 2) { | ||
170 | int i = 0; | ||
171 | for (i = args-1; i > 0; --i) | ||
172 | lua_copy(L, args, i); | ||
173 | } | ||
174 | return args; | ||
175 | } | ||
176 | |||
177 | /* need an address */ | ||
178 | static char const dummy = 0; | ||
179 | |||
180 | static int test_rawxetp (lua_State *L) { | ||
181 | if (lua_gettop(L) > 0) | ||
182 | lua_pushvalue(L, 1); | ||
183 | else | ||
184 | lua_pushliteral(L, "hello again"); | ||
185 | lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy); | ||
186 | lua_settop(L, 0); | ||
187 | lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy); | ||
188 | return 1; | ||
189 | } | ||
190 | |||
191 | static int test_udata (lua_State *L) { | ||
192 | const char *tname = luaL_optstring(L, 1, "utype1"); | ||
193 | void *u1 = lua_newuserdata(L, 1); | ||
194 | int u1pos = lua_gettop(L); | ||
195 | void *u2 = lua_newuserdata(L, 1); | ||
196 | int u2pos = lua_gettop(L); | ||
197 | luaL_newmetatable(L, "utype1"); | ||
198 | luaL_newmetatable(L, "utype2"); | ||
199 | lua_pop(L, 2); | ||
200 | luaL_setmetatable(L, "utype2"); | ||
201 | lua_pushvalue(L, u1pos); | ||
202 | luaL_setmetatable(L, "utype1"); | ||
203 | lua_pop(L, 1); | ||
204 | (void)u1; | ||
205 | (void)u2; | ||
206 | lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname)); | ||
207 | lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname)); | ||
208 | luaL_getmetatable(L, "utype1"); | ||
209 | lua_getfield(L, -1, "__name"); | ||
210 | lua_replace(L, -2); | ||
211 | return 3; | ||
212 | } | ||
213 | |||
214 | static int test_subtable (lua_State *L) { | ||
215 | luaL_checktype(L, 1, LUA_TTABLE); | ||
216 | lua_settop(L, 1); | ||
217 | if (luaL_getsubtable(L, 1, "xxx")) { | ||
218 | lua_pushliteral(L, "oldtable"); | ||
219 | } else { | ||
220 | lua_pushliteral(L, "newtable"); | ||
221 | } | ||
222 | return 2; | ||
223 | } | ||
224 | |||
225 | static int test_uservalue (lua_State *L) { | ||
226 | void *udata = lua_newuserdata(L, 1); | ||
227 | int ui = lua_gettop(L); | ||
228 | lua_newtable(L); | ||
229 | lua_setuservalue(L, ui); | ||
230 | lua_getuservalue(L, ui); | ||
231 | (void)udata; | ||
232 | return 1; | ||
233 | } | ||
234 | |||
235 | static int test_upvalues (lua_State *L) { | ||
236 | int i = 1; | ||
237 | for (i = 1; i <= NUP; ++i) | ||
238 | lua_pushvalue(L, lua_upvalueindex(i)); | ||
239 | return NUP; | ||
240 | } | ||
241 | |||
242 | static int test_tolstring (lua_State *L) { | ||
243 | size_t len = 0; | ||
244 | luaL_tolstring(L, 1, &len); | ||
245 | lua_pushinteger(L, (int)len); | ||
246 | return 2; | ||
247 | } | ||
248 | |||
249 | static int test_pushstring (lua_State *L) { | ||
250 | lua_pushstring(L, lua_pushliteral(L, "abc")); | ||
251 | lua_pushstring(L, lua_pushlstring(L, "abc", 2)); | ||
252 | lua_pushstring(L, lua_pushlstring(L, NULL, 0)); | ||
253 | lua_pushstring(L, lua_pushstring(L, "abc")); | ||
254 | lua_pushboolean(L, NULL == lua_pushstring(L, NULL)); | ||
255 | return 10; | ||
256 | } | ||
257 | |||
258 | static int test_buffer (lua_State *L) { | ||
259 | luaL_Buffer b; | ||
260 | char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1); | ||
261 | p[0] = 'a'; | ||
262 | p[1] = 'b'; | ||
263 | luaL_addsize(&b, 2); | ||
264 | luaL_addstring(&b, "c"); | ||
265 | lua_pushliteral(L, "d"); | ||
266 | luaL_addvalue(&b); | ||
267 | luaL_addchar(&b, 'e'); | ||
268 | luaL_pushresult(&b); | ||
269 | return 1; | ||
270 | } | ||
271 | |||
272 | static int test_exec (lua_State *L) { | ||
273 | const char *cmd = luaL_checkstring(L, 1); | ||
274 | return luaL_execresult(L, system(cmd)); | ||
275 | } | ||
276 | |||
277 | |||
278 | static const luaL_Reg funcs[] = { | ||
279 | { "isinteger", test_isinteger }, | ||
280 | { "rotate", test_rotate }, | ||
281 | { "strtonum", test_str2num }, | ||
282 | { "requiref", test_requiref }, | ||
283 | { "getseti", test_getseti }, | ||
284 | { "newproxy", test_newproxy }, | ||
285 | { "arith", test_arith }, | ||
286 | { "compare", test_compare }, | ||
287 | { "tonumber", test_tonumber }, | ||
288 | { "tointeger", test_tointeger }, | ||
289 | { "len", test_len }, | ||
290 | { "copy", test_copy }, | ||
291 | { "rawxetp", test_rawxetp }, | ||
292 | { "subtable", test_subtable }, | ||
293 | { "udata", test_udata }, | ||
294 | { "uservalue", test_uservalue }, | ||
295 | { "globals", test_globals }, | ||
296 | { "tolstring", test_tolstring }, | ||
297 | { "pushstring", test_pushstring }, | ||
298 | { "buffer", test_buffer }, | ||
299 | { "exec", test_exec }, | ||
300 | { NULL, NULL } | ||
301 | }; | ||
302 | |||
303 | static const luaL_Reg more_funcs[] = { | ||
304 | { "getupvalues", test_upvalues }, | ||
305 | { "absindex", test_absindex }, | ||
306 | { NULL, NULL } | ||
307 | }; | ||
308 | |||
309 | |||
310 | int luaopen_testmod (lua_State *L) { | ||
311 | int i = 1; | ||
312 | luaL_newlib(L, funcs); | ||
313 | for (i = 1; i <= NUP; ++i) | ||
314 | lua_pushnumber(L, i); | ||
315 | luaL_setfuncs(L, more_funcs, NUP); | ||
316 | return 1; | ||
317 | } | ||
318 | |||