From: Sergey Ostanevich via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: Sergey Kaplun <skaplun@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite Date: Fri, 26 Mar 2021 13:14:05 +0300 [thread overview] Message-ID: <D71B8C6B-3AFC-4989-B866-27547A85C790@tarantool.org> (raw) In-Reply-To: <99ce4b411ab34067105f6f7c58b7a736c32a05f7.1616743343.git.skaplun@tarantool.org> Hi! Thanks for the patch, verified with $ for i in `find . -type f` ; do ii=`basename $i`; \ > diff -iwhite $i `find ../../test/PUC-Lua-5.1-tests/ -name $ii` ; done diff: missing operand after `./libs/makefile' diff: Try `diff --help' for more information. $ LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test > suite. Source code taken verbatim (except trailing whitespaces) from > https://www.lua.org/tests/lua5.1-tests.tar.gz. > > Some tests may fail after this commit. They will be disabled > or adapted in the next patches. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > .luacheckrc | 5 +- > test/CMakeLists.txt | 2 + > test/PUC-Lua-5.1-tests/CMakeLists.txt | 45 + > test/PUC-Lua-5.1-tests/README | 41 + > test/PUC-Lua-5.1-tests/all.lua | 137 +++ > test/PUC-Lua-5.1-tests/api.lua | 711 ++++++++++++ > test/PUC-Lua-5.1-tests/attrib.lua | 339 ++++++ > test/PUC-Lua-5.1-tests/big.lua | 381 +++++++ > test/PUC-Lua-5.1-tests/calls.lua | 294 +++++ > test/PUC-Lua-5.1-tests/checktable.lua | 77 ++ > test/PUC-Lua-5.1-tests/closure.lua | 422 +++++++ > test/PUC-Lua-5.1-tests/code.lua | 143 +++ > test/PUC-Lua-5.1-tests/constructs.lua | 240 ++++ > test/PUC-Lua-5.1-tests/db.lua | 499 +++++++++ > test/PUC-Lua-5.1-tests/errors.lua | 250 +++++ > test/PUC-Lua-5.1-tests/etc/ltests.c | 1147 ++++++++++++++++++++ > test/PUC-Lua-5.1-tests/etc/ltests.h | 92 ++ > test/PUC-Lua-5.1-tests/events.lua | 360 ++++++ > test/PUC-Lua-5.1-tests/files.lua | 324 ++++++ > test/PUC-Lua-5.1-tests/gc.lua | 312 ++++++ > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 18 + > test/PUC-Lua-5.1-tests/libs/lib1.c | 40 + > test/PUC-Lua-5.1-tests/libs/lib11.c | 18 + > test/PUC-Lua-5.1-tests/libs/lib2.c | 28 + > test/PUC-Lua-5.1-tests/libs/lib21.c | 18 + > test/PUC-Lua-5.1-tests/literals.lua | 176 +++ > test/PUC-Lua-5.1-tests/locals.lua | 127 +++ > test/PUC-Lua-5.1-tests/main.lua | 159 +++ > test/PUC-Lua-5.1-tests/math.lua | 208 ++++ > test/PUC-Lua-5.1-tests/nextvar.lua | 396 +++++++ > test/PUC-Lua-5.1-tests/pm.lua | 273 +++++ > test/PUC-Lua-5.1-tests/sort.lua | 74 ++ > test/PUC-Lua-5.1-tests/strings.lua | 176 +++ > test/PUC-Lua-5.1-tests/vararg.lua | 126 +++ > test/PUC-Lua-5.1-tests/verybig.lua | 100 ++ > 35 files changed, 7756 insertions(+), 2 deletions(-) > create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/README > create mode 100755 test/PUC-Lua-5.1-tests/all.lua > create mode 100644 test/PUC-Lua-5.1-tests/api.lua > create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua > create mode 100644 test/PUC-Lua-5.1-tests/big.lua > create mode 100644 test/PUC-Lua-5.1-tests/calls.lua > create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua > create mode 100644 test/PUC-Lua-5.1-tests/closure.lua > create mode 100644 test/PUC-Lua-5.1-tests/code.lua > create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua > create mode 100644 test/PUC-Lua-5.1-tests/db.lua > create mode 100644 test/PUC-Lua-5.1-tests/errors.lua > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h > create mode 100644 test/PUC-Lua-5.1-tests/events.lua > create mode 100644 test/PUC-Lua-5.1-tests/files.lua > create mode 100644 test/PUC-Lua-5.1-tests/gc.lua > create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c > create mode 100644 test/PUC-Lua-5.1-tests/literals.lua > create mode 100644 test/PUC-Lua-5.1-tests/locals.lua > create mode 100644 test/PUC-Lua-5.1-tests/main.lua > create mode 100644 test/PUC-Lua-5.1-tests/math.lua > create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua > create mode 100644 test/PUC-Lua-5.1-tests/pm.lua > create mode 100644 test/PUC-Lua-5.1-tests/sort.lua > create mode 100644 test/PUC-Lua-5.1-tests/strings.lua > create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua > create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua > > diff --git a/.luacheckrc b/.luacheckrc > index 4e5dbdf..fd5583b 100644 > --- a/.luacheckrc > +++ b/.luacheckrc > @@ -3,11 +3,12 @@ std = 'luajit' > -- This fork also introduces a new global for misc API namespace. > read_globals = { 'misc' } > > --- These files are inherited from the vanilla LuaJIT and need to > --- be coherent with the upstream. > +-- These files are inherited from the vanilla LuaJIT or different > +-- test suites and need to be coherent with the upstream. > exclude_files = { > 'dynasm/', > 'src/', > 'test/LuaJIT-tests/', > + 'test/PUC-Lua-5.1-tests/', > 'test/lua-Harness-tests/', > } > diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt > index 02fb2ed..30cbf87 100644 > --- a/test/CMakeLists.txt > +++ b/test/CMakeLists.txt > @@ -44,11 +44,13 @@ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]" > separate_arguments(LUAJIT_TEST_COMMAND) > > add_subdirectory(LuaJIT-tests) > +add_subdirectory(PUC-Lua-5.1-tests) > add_subdirectory(lua-Harness-tests) > add_subdirectory(tarantool-tests) > > add_custom_target(${PROJECT_NAME}-test DEPENDS > LuaJIT-tests > + PUC-Lua-5.1-tests > lua-Harness-tests > tarantool-tests > ) > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > new file mode 100644 > index 0000000..773db0d > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -0,0 +1,45 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +# XXX: There are two ways to set up the proper environment > +# described in the suite's README: > +# * set LUA_PATH to "?;./?.lua" > +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to > +# "package.path = '?;'..package.path" > +# Unfortunately, Tarantool doesn't support LUA_INIT and most > +# likely it never will. For more info, see > +# https://github.com/tarantool/tarantool/issues/5744 > +# Hence, there is no way other than set LUA_PATH environment > +# variable as proposed in the first case. > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > + > +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> > +# subdirectory. > +add_subdirectory(libs) > + > +# TODO: PUC-Rio Lua 5.1 test suite also has special header > +# <ltests.h> and <ltests.c> translation unit to check some > +# internal behaviour of the Lua implementation (see etc/ > +# directory). It modifies realloc function to check memory > +# consistency and also contains tests for yield in hooks > +# and for the Lua C API. > +# But, unfortunately, <ltests.c> depends on specific PUC-Rio > +# Lua 5.1 internal headers and should be adapted for LuaJIT. > + > +add_custom_target(PUC-Lua-5.1-tests > + DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare > +) > + > +add_custom_command(TARGET PUC-Lua-5.1-tests > + COMMENT "Running PUC-Rio Lua 5.1 tests" > + COMMAND > + env > + LUA_PATH="${LUA_PATH}\;\;" > + ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 > diff --git a/test/PUC-Lua-5.1-tests/README b/test/PUC-Lua-5.1-tests/README > new file mode 100644 > index 0000000..e2d4b28 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/README > @@ -0,0 +1,41 @@ > +This tarball contains the official test scripts for Lua 5.1. > +Unlike Lua itself, these tests do not aim portability, small footprint, > +or easy of use. (Their main goal is to try to crash Lua.) They are not > +intended for general use. You are wellcome to use them, but expect to > +have to "dirt your hands". > + > +The tarball should expand in the following contents: > + - several .lua scripts with the tests > + - a main "all.lua" Lua script that invokes all the other scripts > + - a subdirectory "libs" with an empty subdirectory "libs/P1", > + to be used by the scripts > + - a subdirectory "etc" with some extra files > + > +To run the tests, do as follows: > + > +- go to the test directory > + > +- set LUA_PATH to "?;./?.lua" (or, better yet, set LUA_PATH to "./?.lua;;" > + and LUA_INIT to "package.path = '?;'..package.path") > + > +- run "lua all.lua" > + > + > +-------------------------------------------- > +Internal tests > +-------------------------------------------- > + > +Some tests need a special library, "testC", that gives access to > +several internal structures in Lua. > +This library is only available when Lua is compiled in debug mode. > +The scripts automatically detect its absence and skip those tests. > + > +If you want to run these tests, move etc/ltests.c and etc/ltests.h to > +the directory with the source Lua files, and recompile Lua with > +the option -DLUA_USER_H='"ltests.h"' (or its equivalent to define > +LUA_USER_H as the string "ltests.h", including the quotes). This > +option not only adds the testC library, but it adds several other > +internal tests as well. After the recompilation, run the tests > +as before. > + > + > diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua > new file mode 100755 > index 0000000..8c4afac > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/all.lua > @@ -0,0 +1,137 @@ > +#!../lua > + > +math.randomseed(0) > + > +collectgarbage("setstepmul", 180) > +collectgarbage("setpause", 190) > + > + > +--[=[ > + example of a long [comment], > + [[spanning several [lines]]] > + > +]=] > + > +print("current path:\n " .. string.gsub(package.path, ";", "\n ")) > + > + > +local msgs = {} > +function Message (m) > + print(m) > + msgs[#msgs+1] = string.sub(m, 3, -3) > +end > + > + > +local c = os.clock() > + > +assert(os.setlocale"C") > + > +local T,print,gcinfo,format,write,assert,type = > + T,print,gcinfo,string.format,io.write,assert,type > + > +local function formatmem (m) > + if m < 1024 then return m > + else > + m = m/1024 - m/1024%1 > + if m < 1024 then return m.."K" > + else > + m = m/1024 - m/1024%1 > + return m.."M" > + end > + end > +end > + > +local showmem = function () > + if not T then > + print(format(" ---- total memory: %s ----\n", formatmem(gcinfo()))) > + else > + T.checkmemory() > + local a,b,c = T.totalmem() > + local d,e = gcinfo() > + print(format( > + "\n ---- total memory: %s (%dK), max use: %s, blocks: %d\n", > + formatmem(a), d, formatmem(c), b)) > + end > +end > + > + > +-- > +-- redefine dofile to run files through dump/undump > +-- > +dofile = function (n) > + showmem() > + local f = assert(loadfile(n)) > + local b = string.dump(f) > + f = assert(loadstring(b)) > + return f() > +end > + > +dofile('main.lua') > + > +do > + local u = newproxy(true) > + local newproxy, stderr = newproxy, io.stderr > + getmetatable(u).__gc = function (o) > + stderr:write'.' > + newproxy(o) > + end > +end > + > +local f = assert(loadfile('gc.lua')) > +f() > +dofile('db.lua') > +assert(dofile('calls.lua') == deep and deep) > +dofile('strings.lua') > +dofile('literals.lua') > +assert(dofile('attrib.lua') == 27) > +assert(dofile('locals.lua') == 5) > +dofile('constructs.lua') > +dofile('code.lua') > +do > + local f = coroutine.wrap(assert(loadfile('big.lua'))) > + assert(f() == 'b') > + assert(f() == 'a') > +end > +dofile('nextvar.lua') > +dofile('pm.lua') > +dofile('api.lua') > +assert(dofile('events.lua') == 12) > +dofile('vararg.lua') > +dofile('closure.lua') > +dofile('errors.lua') > +dofile('math.lua') > +dofile('sort.lua') > +assert(dofile('verybig.lua') == 10); collectgarbage() > +dofile('files.lua') > + > +if #msgs > 0 then > + print("\ntests not performed:") > + for i=1,#msgs do > + print(msgs[i]) > + end > + print() > +end > + > +print("final OK !!!") > +print('cleaning all!!!!') > + > +debug.sethook(function (a) assert(type(a) == 'string') end, "cr") > + > +local _G, collectgarbage, showmem, print, format, clock = > + _G, collectgarbage, showmem, print, format, os.clock > + > +local a={} > +for n in pairs(_G) do a[n] = 1 end > +a.tostring = nil > +a.___Glob = nil > +for n in pairs(a) do _G[n] = nil end > + > +a = nil > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage();showmem() > + > +print(format("\n\ntotal time: %.2f\n", clock()-c)) > diff --git a/test/PUC-Lua-5.1-tests/api.lua b/test/PUC-Lua-5.1-tests/api.lua > new file mode 100644 > index 0000000..c955ebf > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/api.lua > @@ -0,0 +1,711 @@ > + > +if T==nil then > + (Message or print)('\a\n >>> testC not active: skipping API tests <<<\n\a') > + return > +end > + > + > + > +function tcheck (t1, t2) > + table.remove(t1, 1) -- remove code > + assert(table.getn(t1) == table.getn(t2)) > + for i=1,table.getn(t1) do assert(t1[i] == t2[i]) end > +end > + > +function pack(...) return arg end > + > + > +print('testing C API') > + > +-- testing allignment > +a = T.d2s(12458954321123) > +assert(string.len(a) == 8) -- sizeof(double) > +assert(T.s2d(a) == 12458954321123) > + > +a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2") > +assert(a == 2 and b == 3 and not c) > + > +-- test that all trues are equal > +a,b,c = T.testC("pushbool 1; pushbool 2; pushbool 0; return 3") > +assert(a == b and a == true and c == false) > +a,b,c = T.testC"pushbool 0; pushbool 10; pushnil;\ > + tobool -3; tobool -3; tobool -3; return 3" > +assert(a==0 and b==1 and c==0) > + > + > +a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40) > +assert(a == 40 and b == 5 and not c) > + > +t = pack(T.testC("settop 5; gettop; return .", 2, 3)) > +tcheck(t, {n=4,2,3}) > + > +t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23)) > +assert(t.n == 10 and t[1] == nil and t[10] == nil) > + > +t = pack(T.testC("remove -2; gettop; return .", 2, 3, 4)) > +tcheck(t, {n=2,2,4}) > + > +t = pack(T.testC("insert -1; gettop; return .", 2, 3)) > +tcheck(t, {n=2,2,3}) > + > +t = pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=4,2,5,3,4}) > + > +t = pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,5,3,4}) > + > +t = pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,2,3,5}) > + > +t = pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,2,4,5}) > + > +t = pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2; \ > + insert 2; pushvalue 1; remove 1; insert 1; \ > + insert -2; pushvalue -2; remove -3; gettop; return .", > + 2, 3, 4, 5, 10, 40, 90)) > +tcheck(t, {n=7,2,3,4,5,10,40,90}) > + > +t = pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", 12)) > +tcheck(t, {n=1,"alo23joao12"}) > + > +-- testing MULTRET > +t = pack(T.testC("rawcall 2,-1; gettop; return .", > + function (a,b) return 1,2,3,4,a,b end, "alo", "joao")) > +tcheck(t, {n=6,1,2,3,4,"alo", "joao"}) > + > +do -- test returning more results than fit in the caller stack > + local a = {} > + for i=1,1000 do a[i] = true end; a[999] = 10 > + local b = T.testC([[call 1 -1; pop 1; tostring -1; return 1]], unpack, a) > + assert(b == "10") > +end > + > + > +-- testing lessthan > +assert(T.testC("lessthan 2 5, return 1", 3, 2, 2, 4, 2, 2)) > +assert(T.testC("lessthan 5 2, return 1", 4, 2, 2, 3, 2, 2)) > +assert(not T.testC("lessthan 2 -3, return 1", "4", "2", "2", "3", "2", "2")) > +assert(not T.testC("lessthan -3 2, return 1", "3", "2", "2", "4", "2", "2")) > + > +local b = {__lt = function (a,b) return a[1] < b[1] end} > +local a1,a3,a4 = setmetatable({1}, b), > + setmetatable({3}, b), > + setmetatable({4}, b) > +assert(T.testC("lessthan 2 5, return 1", a3, 2, 2, a4, 2, 2)) > +assert(T.testC("lessthan 5 -6, return 1", a4, 2, 2, a3, 2, 2)) > +a,b = T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20) > +assert(a == 20 and b == false) > + > + > +-- testing lua_is > + > +function count (x, n) > + n = n or 2 > + local prog = [[ > + isnumber %d; > + isstring %d; > + isfunction %d; > + iscfunction %d; > + istable %d; > + isuserdata %d; > + isnil %d; > + isnull %d; > + return 8 > + ]] > + prog = string.format(prog, n, n, n, n, n, n, n, n) > + local a,b,c,d,e,f,g,h = T.testC(prog, x) > + return a+b+c+d+e+f+g+(100*h) > +end > + > +assert(count(3) == 2) > +assert(count('alo') == 1) > +assert(count('32') == 2) > +assert(count({}) == 1) > +assert(count(print) == 2) > +assert(count(function () end) == 1) > +assert(count(nil) == 1) > +assert(count(io.stdin) == 1) > +assert(count(nil, 15) == 100) > + > +-- testing lua_to... > + > +function to (s, x, n) > + n = n or 2 > + return T.testC(string.format("%s %d; return 1", s, n), x) > +end > + > +assert(to("tostring", {}) == nil) > +assert(to("tostring", "alo") == "alo") > +assert(to("tostring", 12) == "12") > +assert(to("tostring", 12, 3) == nil) > +assert(to("objsize", {}) == 0) > +assert(to("objsize", "alo\0\0a") == 6) > +assert(to("objsize", T.newuserdata(0)) == 0) > +assert(to("objsize", T.newuserdata(101)) == 101) > +assert(to("objsize", 12) == 2) > +assert(to("objsize", 12, 3) == 0) > +assert(to("tonumber", {}) == 0) > +assert(to("tonumber", "12") == 12) > +assert(to("tonumber", "s2") == 0) > +assert(to("tonumber", 1, 20) == 0) > +a = to("tocfunction", math.deg) > +assert(a(3) == math.deg(3) and a ~= math.deg) > + > + > +-- testing errors > + > +a = T.testC([[ > + loadstring 2; call 0,1; > + pushvalue 3; insert -2; call 1, 1; > + call 0, 0; > + return 1 > +]], "x=150", function (a) assert(a==nil); return 3 end) > + > +assert(type(a) == 'string' and x == 150) > + > +function check3(p, ...) > + assert(arg.n == 3) > + assert(string.find(arg[3], p)) > +end > +check3(":1:", T.testC("loadstring 2; gettop; return .", "x=")) > +check3("cannot read", T.testC("loadfile 2; gettop; return .", ".")) > +check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", "xxxx")) > + > +-- testing table access > + > +a = {x=0, y=12} > +x, y = T.testC("gettable 2; pushvalue 4; gettable 2; return 2", > + a, 3, "y", 4, "x") > +assert(x == 0 and y == 12) > +T.testC("settable -5", a, 3, 4, "x", 15) > +assert(a.x == 15) > +a[a] = print > +x = T.testC("gettable 2; return 1", a) -- table and key are the same object! > +assert(x == print) > +T.testC("settable 2", a, "x") -- table and key are the same object! > +assert(a[a] == "x") > + > +b = setmetatable({p = a}, {}) > +getmetatable(b).__index = function (t, i) return t.p[i] end > +k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x") > +assert(x == 15 and k == 35) > +getmetatable(b).__index = function (t, i) return a[i] end > +getmetatable(b).__newindex = function (t, i,v ) a[i] = v end > +y = T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b) > +assert(y == 12) > +k = T.testC("settable -5, return 1", b, 3, 4, "x", 16) > +assert(a.x == 16 and k == 4) > +a[b] = 'xuxu' > +y = T.testC("gettable 2, return 1", b) > +assert(y == 'xuxu') > +T.testC("settable 2", b, 19) > +assert(a[b] == 19) > + > +-- testing next > +a = {} > +t = pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=1,a}) > +a = {a=3} > +t = pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=3,a,'a',3}) > +t = pack(T.testC("next; pop 1; next; gettop; return .", a, nil)) > +tcheck(t, {n=1,a}) > + > + > + > +-- testing upvalues > + > +do > + local A = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] > + t, b, c = A([[pushvalue U0; pushvalue U1; pushvalue U2; return 3]]) > + assert(b == 10 and c == 20 and type(t) == 'table') > + a, b = A([[tostring U3; tonumber U4; return 2]]) > + assert(a == nil and b == 0) > + A([[pushnum 100; pushnum 200; replace U2; replace U1]]) > + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b == 100 and c == 200) > + A([[replace U2; replace U1]], {x=1}, {x=2}) > + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b.x == 1 and c.x == 2) > + T.checkmemory() > +end > + > +local f = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] > +assert(T.upvalue(f, 1) == 10 and > + T.upvalue(f, 2) == 20 and > + T.upvalue(f, 3) == nil) > +T.upvalue(f, 2, "xuxu") > +assert(T.upvalue(f, 2) == "xuxu") > + > + > +-- testing environments > + > +assert(T.testC"pushvalue G; return 1" == _G) > +assert(T.testC"pushvalue E; return 1" == _G) > +local a = {} > +T.testC("replace E; return 1", a) > +assert(T.testC"pushvalue G; return 1" == _G) > +assert(T.testC"pushvalue E; return 1" == a) > +assert(debug.getfenv(T.testC) == a) > +assert(debug.getfenv(T.upvalue) == _G) > +-- userdata inherit environment > +local u = T.testC"newuserdata 0; return 1" > +assert(debug.getfenv(u) == a) > +-- functions inherit environment > +u = T.testC"pushcclosure 0; return 1" > +assert(debug.getfenv(u) == a) > +debug.setfenv(T.testC, _G) > +assert(T.testC"pushvalue E; return 1" == _G) > + > +local b = newproxy() > +assert(debug.getfenv(b) == _G) > +assert(debug.setfenv(b, a)) > +assert(debug.getfenv(b) == a) > + > + > + > +-- testing locks (refs) > + > +-- reuse of references > +local i = T.ref{} > +T.unref(i) > +assert(T.ref{} == i) > + > +Arr = {} > +Lim = 100 > +for i=1,Lim do -- lock many objects > + Arr[i] = T.ref({}) > +end > + > +assert(T.ref(nil) == -1 and T.getref(-1) == nil) > +T.unref(-1); T.unref(-1) > + > +for i=1,Lim do -- unlock all them > + T.unref(Arr[i]) > +end > + > +function printlocks () > + local n = T.testC("gettable R; return 1", "n") > + print("n", n) > + for i=0,n do > + print(i, T.testC("gettable R; return 1", i)) > + end > +end > + > + > +for i=1,Lim do -- lock many objects > + Arr[i] = T.ref({}) > +end > + > +for i=1,Lim,2 do -- unlock half of them > + T.unref(Arr[i]) > +end > + > +assert(type(T.getref(Arr[2])) == 'table') > + > + > +assert(T.getref(-1) == nil) > + > + > +a = T.ref({}) > + > +collectgarbage() > + > +assert(type(T.getref(a)) == 'table') > + > + > +-- colect in cl the `val' of all collected userdata > +tt = {} > +cl = {n=0} > +A = nil; B = nil > +local F > +F = function (x) > + local udval = T.udataval(x) > + table.insert(cl, udval) > + local d = T.newuserdata(100) -- cria lixo > + d = nil > + assert(debug.getmetatable(x).__gc == F) > + loadstring("table.insert({}, {})")() -- cria mais lixo > + collectgarbage() -- forca coleta de lixo durante coleta! > + assert(debug.getmetatable(x).__gc == F) -- coleta anterior nao melou isso? > + local dummy = {} -- cria lixo durante coleta > + if A ~= nil then > + assert(type(A) == "userdata") > + assert(T.udataval(A) == B) > + debug.getmetatable(A) -- just acess it > + end > + A = x -- ressucita userdata > + B = udval > + return 1,2,3 > +end > +tt.__gc = F > + > +-- test whether udate collection frees memory in the right time > +do > + collectgarbage(); > + collectgarbage(); > + local x = collectgarbage("count"); > + local a = T.newuserdata(5001) > + assert(T.testC("objsize 2; return 1", a) == 5001) > + assert(collectgarbage("count") >= x+4) > + a = nil > + collectgarbage(); > + assert(collectgarbage("count") <= x+1) > + -- udata without finalizer > + x = collectgarbage("count") > + collectgarbage("stop") > + for i=1,1000 do newproxy(false) end > + assert(collectgarbage("count") > x+10) > + collectgarbage() > + assert(collectgarbage("count") <= x+1) > + -- udata with finalizer > + x = collectgarbage("count") > + collectgarbage() > + collectgarbage("stop") > + a = newproxy(true) > + getmetatable(a).__gc = function () end > + for i=1,1000 do newproxy(a) end > + assert(collectgarbage("count") >= x+10) > + collectgarbage() -- this collection only calls TM, without freeing memory > + assert(collectgarbage("count") >= x+10) > + collectgarbage() -- now frees memory > + assert(collectgarbage("count") <= x+1) > +end > + > + > +collectgarbage("stop") > + > +-- create 3 userdatas with tag `tt' > +a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a) > +b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b) > +c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c) > + > +-- create userdata without meta table > +x = T.newuserdata(4) > +y = T.newuserdata(0) > + > +assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil) > + > +d=T.ref(a); > +e=T.ref(b); > +f=T.ref(c); > +t = {T.getref(d), T.getref(e), T.getref(f)} > +assert(t[1] == a and t[2] == b and t[3] == c) > + > +t=nil; a=nil; c=nil; > +T.unref(e); T.unref(f) > + > +collectgarbage() > + > +-- check that unref objects have been collected > +assert(table.getn(cl) == 1 and cl[1] == nc) > + > +x = T.getref(d) > +assert(type(x) == 'userdata' and debug.getmetatable(x) == tt) > +x =nil > +tt.b = b -- create cycle > +tt=nil -- frees tt for GC > +A = nil > +b = nil > +T.unref(d); > +n5 = T.newuserdata(0) > +debug.setmetatable(n5, {__gc=F}) > +n5 = T.udataval(n5) > +collectgarbage() > +assert(table.getn(cl) == 4) > +-- check order of collection > +assert(cl[2] == n5 and cl[3] == nb and cl[4] == na) > + > + > +a, na = {}, {} > +for i=30,1,-1 do > + a[i] = T.newuserdata(0) > + debug.setmetatable(a[i], {__gc=F}) > + na[i] = T.udataval(a[i]) > +end > +cl = {} > +a = nil; collectgarbage() > +assert(table.getn(cl) == 30) > +for i=1,30 do assert(cl[i] == na[i]) end > +na = nil > + > + > +for i=2,Lim,2 do -- unlock the other half > + T.unref(Arr[i]) > +end > + > +x = T.newuserdata(41); debug.setmetatable(x, {__gc=F}) > +assert(T.testC("objsize 2; return 1", x) == 41) > +cl = {} > +a = {[x] = 1} > +x = T.udataval(x) > +collectgarbage() > +-- old `x' cannot be collected (`a' still uses it) > +assert(table.getn(cl) == 0) > +for n in pairs(a) do a[n] = nil end > +collectgarbage() > +assert(table.getn(cl) == 1 and cl[1] == x) -- old `x' must be collected > + > +-- testing lua_equal > +assert(T.testC("equal 2 4; return 1", print, 1, print, 20)) > +assert(T.testC("equal 3 2; return 1", 'alo', "alo")) > +assert(T.testC("equal 2 3; return 1", nil, nil)) > +assert(not T.testC("equal 2 3; return 1", {}, {})) > +assert(not T.testC("equal 2 3; return 1")) > +assert(not T.testC("equal 2 3; return 1", 3)) > + > +-- testing lua_equal with fallbacks > +do > + local map = {} > + local t = {__eq = function (a,b) return map[a] == map[b] end} > + local function f(x) > + local u = T.newuserdata(0) > + debug.setmetatable(u, t) > + map[u] = x > + return u > + end > + assert(f(10) == f(10)) > + assert(f(10) ~= f(11)) > + assert(T.testC("equal 2 3; return 1", f(10), f(10))) > + assert(not T.testC("equal 2 3; return 1", f(10), f(20))) > + t.__eq = nil > + assert(f(10) ~= f(10)) > +end > + > +print'+' > + > + > + > +------------------------------------------------------------------------- > +do -- testing errors during GC > + local a = {} > + for i=1,20 do > + a[i] = T.newuserdata(i) -- creates several udata > + end > + for i=1,20,2 do -- mark half of them to raise error during GC > + debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end}) > + end > + for i=2,20,2 do -- mark the other half to count and to create more garbage > + debug.setmetatable(a[i], {__gc = function (x) loadstring("A=A+1")() end}) > + end > + _G.A = 0 > + a = 0 > + while 1 do > + if xpcall(collectgarbage, function (s) a=a+1 end) then > + break -- stop if no more errors > + end > + end > + assert(a == 10) -- number of errors > + assert(A == 10) -- number of normal collections > +end > +------------------------------------------------------------------------- > +-- test for userdata vals > +do > + local a = {}; local lim = 30 > + for i=0,lim do a[i] = T.pushuserdata(i) end > + for i=0,lim do assert(T.udataval(a[i]) == i) end > + for i=0,lim do assert(T.pushuserdata(i) == a[i]) end > + for i=0,lim do a[a[i]] = i end > + for i=0,lim do a[T.pushuserdata(i)] = i end > + assert(type(tostring(a[1])) == "string") > +end > + > + > +------------------------------------------------------------------------- > +-- testing multiple states > +T.closestate(T.newstate()); > +L1 = T.newstate() > +assert(L1) > +assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; f()")).n == 0) > + > +a, b = T.doremote(L1, "return f()") > +assert(a == 'alo' and b == '3') > + > +T.doremote(L1, "_ERRORMESSAGE = nil") > +-- error: `sin' is not defined > +a, b = T.doremote(L1, "return sin(1)") > +assert(a == nil and b == 2) -- 2 == run-time error > + > +-- error: syntax error > +a, b, c = T.doremote(L1, "return a+") > +assert(a == nil and b == 3 and type(c) == "string") -- 3 == syntax error > + > +T.loadlib(L1) > +a, b = T.doremote(L1, [[ > + a = strlibopen() > + a = packageopen() > + a = baselibopen(); assert(a == _G and require("_G") == a) > + a = iolibopen(); assert(type(a.read) == "function") > + assert(require("io") == a) > + a = tablibopen(); assert(type(a.insert) == "function") > + a = dblibopen(); assert(type(a.getlocal) == "function") > + a = mathlibopen(); assert(type(a.sin) == "function") > + return string.sub('okinama', 1, 2) > +]]) > +assert(a == "ok") > + > +T.closestate(L1); > + > +L1 = T.newstate() > +T.loadlib(L1) > +T.doremote(L1, "a = {}") > +T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1; > + settable -3]]) > +assert(T.doremote(L1, "return a.x") == "1") > + > +T.closestate(L1) > + > +L1 = nil > + > +print('+') > + > +------------------------------------------------------------------------- > +-- testing memory limits > +------------------------------------------------------------------------- > +collectgarbage() > +T.totalmem(T.totalmem()+5000) -- set low memory limit (+5k) > +assert(not pcall(loadstring"local a={}; for i=1,100000 do a[i]=i end")) > +T.totalmem(1000000000) -- restore high limit > + > + > +local function stack(x) if x>0 then stack(x-1) end end > + > +-- test memory errors; increase memory limit in small steps, so that > +-- we get memory errors in different parts of a given task, up to there > +-- is enough memory to complete the task without errors > +function testamem (s, f) > + collectgarbage() > + stack(10) -- ensure minimum stack size > + local M = T.totalmem() > + local oldM = M > + local a,b = nil > + while 1 do > + M = M+3 -- increase memory limit in small steps > + T.totalmem(M) > + a, b = pcall(f) > + if a and b then break end -- stop when no more errors > + collectgarbage() > + if not a and not string.find(b, "memory") then -- `real' error? > + T.totalmem(1000000000) -- restore high limit > + error(b, 0) > + end > + end > + T.totalmem(1000000000) -- restore high limit > + print("\nlimit for " .. s .. ": " .. M-oldM) > + return b > +end > + > + > +-- testing memory errors when creating a new state > + > +b = testamem("state creation", T.newstate) > +T.closestate(b); -- close new state > + > + > +-- testing threads > + > +function expand (n,s) > + if n==0 then return "" end > + local e = string.rep("=", n) > + return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n", > + e, s, expand(n-1,s), e) > +end > + > +G=0; collectgarbage(); a =collectgarbage("count") > +loadstring(expand(20,"G=G+1"))() > +assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1) > + > +testamem("thread creation", function () > + return T.doonnewstack("x=1") == 0 -- try to create thread > +end) > + > + > +-- testing memory x compiler > + > +testamem("loadstring", function () > + return loadstring("x=1") -- try to do a loadstring > +end) > + > + > +local testprog = [[ > +local function foo () return end > +local t = {"x"} > +a = "aaa" > +for _, v in ipairs(t) do a=a..v end > +return true > +]] > + > +-- testing memory x dofile > +_G.a = nil > +local t =os.tmpname() > +local f = assert(io.open(t, "w")) > +f:write(testprog) > +f:close() > +testamem("dofile", function () > + local a = loadfile(t) > + return a and a() > +end) > +assert(os.remove(t)) > +assert(_G.a == "aaax") > + > + > +-- other generic tests > + > +testamem("string creation", function () > + local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end) > + return (a == 'ablo ablo') > +end) > + > +testamem("dump/undump", function () > + local a = loadstring(testprog) > + local b = a and string.dump(a) > + a = b and loadstring(b) > + return a and a() > +end) > + > +local t = os.tmpname() > +testamem("file creation", function () > + local f = assert(io.open(t, 'w')) > + assert (not io.open"nomenaoexistente") > + io.close(f); > + return not loadfile'nomenaoexistente' > +end) > +assert(os.remove(t)) > + > +testamem("table creation", function () > + local a, lim = {}, 10 > + for i=1,lim do a[i] = i; a[i..'a'] = {} end > + return (type(a[lim..'a']) == 'table' and a[lim] == lim) > +end) > + > +local a = 1 > +close = nil > +testamem("closure creation", function () > + function close (b,c) > + return function (x) return a+b+c+x end > + end > + return (close(2,3)(4) == 10) > +end) > + > +testamem("coroutines", function () > + local a = coroutine.wrap(function () > + coroutine.yield(string.rep("a", 10)) > + return {} > + end) > + assert(string.len(a()) == 10) > + return a() > +end) > + > +print'+' > + > +-- testing some auxlib functions > +assert(T.gsub("alo.alo.uhuh.", ".", "//") == "alo//alo//uhuh//") > +assert(T.gsub("alo.alo.uhuh.", "alo", "//") == "//.//.uhuh.") > +assert(T.gsub("", "alo", "//") == "") > +assert(T.gsub("...", ".", "/.") == "/././.") > +assert(T.gsub("...", "...", "") == "") > + > + > +print'OK' > + > diff --git a/test/PUC-Lua-5.1-tests/attrib.lua b/test/PUC-Lua-5.1-tests/attrib.lua > new file mode 100644 > index 0000000..655669b > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/attrib.lua > @@ -0,0 +1,339 @@ > +do --[ > + > +print "testing require" > + > +assert(require"string" == string) > +assert(require"math" == math) > +assert(require"table" == table) > +assert(require"io" == io) > +assert(require"os" == os) > +assert(require"debug" == debug) > +assert(require"coroutine" == coroutine) > + > +assert(type(package.path) == "string") > +assert(type(package.cpath) == "string") > +assert(type(package.loaded) == "table") > +assert(type(package.preload) == "table") > + > + > +local DIR = "libs/" > + > +local function createfiles (files, preextras, posextras) > + for n,c in pairs(files) do > + io.output(DIR..n) > + io.write(string.format(preextras, n)) > + io.write(c) > + io.write(string.format(posextras, n)) > + io.close(io.output()) > + end > +end > + > +function removefiles (files) > + for n in pairs(files) do > + os.remove(DIR..n) > + end > +end > + > +local files = { > + ["A.lua"] = "", > + ["B.lua"] = "assert(...=='B');require 'A'", > + ["A.lc"] = "", > + ["A"] = "", > + ["L"] = "", > + ["XXxX"] = "", > + ["C.lua"] = "package.loaded[...] = 25; require'C'" > +} > + > +AA = nil > +local extras = [[ > +NAME = '%s' > +REQUIRED = ... > +return AA]] > + > +createfiles(files, "", extras) > + > + > +local oldpath = package.path > + > +package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR) > + > +local try = function (p, n, r) > + NAME = nil > + local rr = require(p) > + assert(NAME == n) > + assert(REQUIRED == p) > + assert(rr == r) > +end > + > +assert(require"C" == 25) > +assert(require"C" == 25) > +AA = nil > +try('B', 'B.lua', true) > +assert(package.loaded.B) > +assert(require"B" == true) > +assert(package.loaded.A) > +package.loaded.A = nil > +try('B', nil, true) -- should not reload package > +try('A', 'A.lua', true) > +package.loaded.A = nil > +os.remove(DIR..'A.lua') > +AA = {} > +try('A', 'A.lc', AA) -- now must find second option > +assert(require("A") == AA) > +AA = false > +try('K', 'L', false) -- default option > +try('K', 'L', false) -- default option (should reload it) > +assert(rawget(_G, "_REQUIREDNAME") == nil) > + > +AA = "x" > +try("X", "XXxX", AA) > + > + > +removefiles(files) > + > + > +-- testing require of sub-packages > + > +package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) > + > +files = { > + ["P1/init.lua"] = "AA = 10", > + ["P1/xuxu.lua"] = "AA = 20", > +} > + > +createfiles(files, "module(..., package.seeall)\n", "") > +AA = 0 > + > +local m = assert(require"P1") > +assert(m == P1 and m._NAME == "P1" and AA == 0 and m.AA == 10) > +assert(require"P1" == P1 and P1 == m) > +assert(require"P1" == P1) > +assert(P1._PACKAGE == "") > + > +local m = assert(require"P1.xuxu") > +assert(m == P1.xuxu and m._NAME == "P1.xuxu" and AA == 0 and m.AA == 20) > +assert(require"P1.xuxu" == P1.xuxu and P1.xuxu == m) > +assert(require"P1.xuxu" == P1.xuxu) > +assert(require"P1" == P1) > +assert(P1.xuxu._PACKAGE == "P1.") > +assert(P1.AA == 10 and P1._PACKAGE == "") > +assert(P1._G == _G and P1.xuxu._G == _G) > + > + > + > +removefiles(files) > + > + > +package.path = "" > +assert(not pcall(require, "file_does_not_exist")) > +package.path = "??\0?" > +assert(not pcall(require, "file_does_not_exist1")) > + > +package.path = oldpath > + > +-- check 'require' error message > +local fname = "file_does_not_exist2" > +local m, err = pcall(require, fname) > +for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do > + t = string.gsub(t, "?", fname) > + assert(string.find(err, t, 1, true)) > +end > + > + > +local function import(...) > + local f = {...} > + return function (m) > + for i=1, #f do m[f[i]] = _G[f[i]] end > + end > +end > + > +local assert, module, package = assert, module, package > +X = nil; x = 0; assert(_G.x == 0) -- `x' must be a global variable > +module"X"; x = 1; assert(_M.x == 1) > +module"X.a.b.c"; x = 2; assert(_M.x == 2) > +module("X.a.b", package.seeall); x = 3 > +assert(X._NAME == "X" and X.a.b.c._NAME == "X.a.b.c" and X.a.b._NAME == "X.a.b") > +assert(X._M == X and X.a.b.c._M == X.a.b.c and X.a.b._M == X.a.b) > +assert(X.x == 1 and X.a.b.c.x == 2 and X.a.b.x == 3) > +assert(X._PACKAGE == "" and X.a.b.c._PACKAGE == "X.a.b." and > + X.a.b._PACKAGE == "X.a.") > +assert(_PACKAGE.."c" == "X.a.c") > +assert(X.a._NAME == nil and X.a._M == nil) > +module("X.a", import("X")) ; x = 4 > +assert(X.a._NAME == "X.a" and X.a.x == 4 and X.a._M == X.a) > +module("X.a.b", package.seeall); assert(x == 3); x = 5 > +assert(_NAME == "X.a.b" and X.a.b.x == 5) > + > +assert(X._G == nil and X.a._G == nil and X.a.b._G == _G and X.a.b.c._G == nil) > + > +setfenv(1, _G) > +assert(x == 0) > + > +assert(not pcall(module, "x")) > +assert(not pcall(module, "math.sin")) > + > + > +-- testing C libraries > + > + > +local p = "" -- On Mac OS X, redefine this to "_" > + > +-- assert(loadlib == package.loadlib) -- only for compatibility > +local f, err, when = package.loadlib("libs/lib1.so", p.."luaopen_lib1") > +if not f then > + (Message or print)('\a\n >>> cannot load dynamic library <<<\n\a') > + print(err, when) > +else > + f() -- open library > + assert(require("lib1") == lib1) > + collectgarbage() > + assert(lib1.id("x") == "x") > + f = assert(package.loadlib("libs/lib1.so", p.."anotherfunc")) > + assert(f(10, 20) == "1020\n") > + f, err, when = package.loadlib("libs/lib1.so", p.."xuxu") > + assert(not f and type(err) == "string" and when == "init") > + package.cpath = "libs/?.so" > + require"lib2" > + assert(lib2.id("x") == "x") > + local fs = require"lib1.sub" > + assert(fs == lib1.sub and next(lib1.sub) == nil) > + module("lib2", package.seeall) > + f = require"-lib2" > + assert(f.id("x") == "x" and _M == f and _NAME == "lib2") > + module("lib1.sub", package.seeall) > + assert(_M == fs) > + setfenv(1, _G) > + > +end > +f, err, when = package.loadlib("donotexist", p.."xuxu") > +assert(not f and type(err) == "string" and (when == "open" or when == "absent")) > + > + > +-- testing preload > + > +do > + local p = package > + package = {} > + p.preload.pl = function (...) > + module(...) > + function xuxu (x) return x+20 end > + end > + > + require"pl" > + assert(require"pl" == pl) > + assert(pl.xuxu(10) == 30) > + > + package = p > + assert(type(package.path) == "string") > +end > + > + > + > +end --] > + > +print('+') > + > +print("testing assignments, logical operators, and constructors") > + > +local res, res2 = 27 > + > +a, b = 1, 2+3 > +assert(a==1 and b==5) > +a={} > +function f() return 10, 11, 12 end > +a.x, b, a[1] = 1, 2, f() > +assert(a.x==1 and b==2 and a[1]==10) > +a[f()], b, a[f()+3] = f(), a, 'x' > +assert(a[10] == 10 and b == a and a[13] == 'x') > + > +do > + local f = function (n) local x = {}; for i=1,n do x[i]=i end; > + return unpack(x) end; > + local a,b,c > + a,b = 0, f(1) > + assert(a == 0 and b == 1) > + A,b = 0, f(1) > + assert(A == 0 and b == 1) > + a,b,c = 0,5,f(4) > + assert(a==0 and b==5 and c==1) > + a,b,c = 0,5,f(0) > + assert(a==0 and b==5 and c==nil) > +end > + > + > +a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6 > +assert(not a and b and c and d==6) > + > +d = 20 > +a, b, c, d = f() > +assert(a==10 and b==11 and c==12 and d==nil) > +a,b = f(), 1, 2, 3, f() > +assert(a==10 and b==1) > + > +assert(a<b == false and a>b == true) > +assert((10 and 2) == 2) > +assert((10 or 2) == 10) > +assert((10 or assert(nil)) == 10) > +assert(not (nil and assert(nil))) > +assert((nil or "alo") == "alo") > +assert((nil and 10) == nil) > +assert((false and 10) == false) > +assert((true or 10) == true) > +assert((false or 10) == 10) > +assert(false ~= nil) > +assert(nil ~= false) > +assert(not nil == true) > +assert(not not nil == false) > +assert(not not 1 == true) > +assert(not not a == true) > +assert(not not (6 or nil) == true) > +assert(not not (nil and 56) == false) > +assert(not not (nil and true) == false) > +print('+') > + > +a = {} > +a[true] = 20 > +a[false] = 10 > +assert(a[1<2] == 20 and a[1>2] == 10) > + > +function f(a) return a end > + > +local a = {} > +for i=3000,-3000,-1 do a[i] = i; end > +a[10e30] = "alo"; a[true] = 10; a[false] = 20 > +assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10) > +for i=3000,-3000,-1 do assert(a[i] == i); end > +a[print] = assert > +a[f] = print > +a[a] = a > +assert(a[a][a][a][a][print] == assert) > +a[print](a[a[f]] == a[print]) > +a = nil > + > +a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'} > +a, a.x, a.y = a, a[-3] > +assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y) > +a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 > +a[1].alo(a[2]==10 and b==10 and c==print) > + > +a[2^31] = 10; a[2^31+1] = 11; a[-2^31] = 12; > +a[2^32] = 13; a[-2^32] = 14; a[2^32+1] = 15; a[10^33] = 16; > + > +assert(a[2^31] == 10 and a[2^31+1] == 11 and a[-2^31] == 12 and > + a[2^32] == 13 and a[-2^32] == 14 and a[2^32+1] == 15 and > + a[10^33] == 16) > + > +a = nil > + > + > +do > + local a,i,j,b > + a = {'a', 'b'}; i=1; j=2; b=a > + i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i > + assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and > + b[3] == 1) > +end > + > +print('OK') > + > +return res > diff --git a/test/PUC-Lua-5.1-tests/big.lua b/test/PUC-Lua-5.1-tests/big.lua > new file mode 100644 > index 0000000..9261288 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/big.lua > @@ -0,0 +1,381 @@ > +print "testing string length overflow" > + > +local longs = string.rep("\0", 2^25) > +local function catter (i) > + return assert(loadstring( > + string.format("return function(a) return a%s end", > + string.rep("..a", i-1))))() > +end > +rep129 = catter(129) > +local a, b = pcall(rep129, longs) > +assert(not a and string.find(b, "overflow")) > +print('+') > + > + > +require "checktable" > + > +--[[ lots of empty lines (to force SETLINEW) > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > +--]] > + > + > +a,b = nil,nil > +while not b do > +if a then > +b = { -- lots of strings (to force JMPW and PUSHCONSTANTW) > +"n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10", > +"n11", "n12", "j301", "j302", "j303", "j304", "j305", "j306", "j307", "j308", > +"j309", "a310", "n311", "n312", "n313", "n314", "n315", "n316", "n317", "n318", > +"n319", "n320", "n321", "n322", "n323", "n324", "n325", "n326", "n327", "n328", > +"a329", "n330", "n331", "n332", "n333", "n334", "n335", "n336", "n337", "n338", > +"n339", "n340", "n341", "z342", "n343", "n344", "n345", "n346", "n347", "n348", > +"n349", "n350", "n351", "n352", "r353", "n354", "n355", "n356", "n357", "n358", > +"n359", "n360", "n361", "n362", "n363", "n364", "n365", "n366", "z367", "n368", > +"n369", "n370", "n371", "n372", "n373", "n374", "n375", "a376", "n377", "n378", > +"n379", "n380", "n381", "n382", "n383", "n384", "n385", "n386", "n387", "n388", > +"n389", "n390", "n391", "n392", "n393", "n394", "n395", "n396", "n397", "n398", > +"n399", "n400", "n13", "n14", "n15", "n16", "n17", "n18", "n19", "n20", > +"n21", "n22", "n23", "a24", "n25", "n26", "n27", "n28", "n29", "j30", > +"n31", "n32", "n33", "n34", "n35", "n36", "n37", "n38", "n39", "n40", > +"n41", "n42", "n43", "n44", "n45", "n46", "n47", "n48", "n49", "n50", > +"n51", "n52", "n53", "n54", "n55", "n56", "n57", "n58", "n59", "n60", > +"n61", "n62", "n63", "n64", "n65", "a66", "z67", "n68", "n69", "n70", > +"n71", "n72", "n73", "n74", "n75", "n76", "n77", "n78", "n79", "n80", > +"n81", "n82", "n83", "n84", "n85", "n86", "n87", "n88", "n89", "n90", > +"n91", "n92", "n93", "n94", "n95", "n96", "n97", "n98", "n99", "n100", > +"n201", "n202", "n203", "n204", "n205", "n206", "n207", "n208", "n209", "n210", > +"n211", "n212", "n213", "n214", "n215", "n216", "n217", "n218", "n219", "n220", > +"n221", "n222", "n223", "n224", "n225", "n226", "n227", "n228", "n229", "n230", > +"n231", "n232", "n233", "n234", "n235", "n236", "n237", "n238", "n239", "a240", > +"a241", "a242", "a243", "a244", "a245", "a246", "a247", "a248", "a249", "n250", > +"n251", "n252", "n253", "n254", "n255", "n256", "n257", "n258", "n259", "n260", > +"n261", "n262", "n263", "n264", "n265", "n266", "n267", "n268", "n269", "n270", > +"n271", "n272", "n273", "n274", "n275", "n276", "n277", "n278", "n279", "n280", > +"n281", "n282", "n283", "n284", "n285", "n286", "n287", "n288", "n289", "n290", > +"n291", "n292", "n293", "n294", "n295", "n296", "n297", "n298", "n299" > +; x=23} > +else a = 1 end > + > + > +end > + > +assert(b.x == 23) > +print('+') > + > +stat(b) > + > +repeat > +a = { > +n1 = 1.5, n2 = 2.5, n3 = 3.5, n4 = 4.5, n5 = 5.5, n6 = 6.5, n7 = 7.5, > +n8 = 8.5, n9 = 9.5, n10 = 10.5, n11 = 11.5, n12 = 12.5, > +j301 = 301.5, j302 = 302.5, j303 = 303.5, j304 = 304.5, j305 = 305.5, > +j306 = 306.5, j307 = 307.5, j308 = 308.5, j309 = 309.5, a310 = 310.5, > +n311 = 311.5, n312 = 312.5, n313 = 313.5, n314 = 314.5, n315 = 315.5, > +n316 = 316.5, n317 = 317.5, n318 = 318.5, n319 = 319.5, n320 = 320.5, > +n321 = 321.5, n322 = 322.5, n323 = 323.5, n324 = 324.5, n325 = 325.5, > +n326 = 326.5, n327 = 327.5, n328 = 328.5, a329 = 329.5, n330 = 330.5, > +n331 = 331.5, n332 = 332.5, n333 = 333.5, n334 = 334.5, n335 = 335.5, > +n336 = 336.5, n337 = 337.5, n338 = 338.5, n339 = 339.5, n340 = 340.5, > +n341 = 341.5, z342 = 342.5, n343 = 343.5, n344 = 344.5, n345 = 345.5, > +n346 = 346.5, n347 = 347.5, n348 = 348.5, n349 = 349.5, n350 = 350.5, > +n351 = 351.5, n352 = 352.5, r353 = 353.5, n354 = 354.5, n355 = 355.5, > +n356 = 356.5, n357 = 357.5, n358 = 358.5, n359 = 359.5, n360 = 360.5, > +n361 = 361.5, n362 = 362.5, n363 = 363.5, n364 = 364.5, n365 = 365.5, > +n366 = 366.5, z367 = 367.5, n368 = 368.5, n369 = 369.5, n370 = 370.5, > +n371 = 371.5, n372 = 372.5, n373 = 373.5, n374 = 374.5, n375 = 375.5, > +a376 = 376.5, n377 = 377.5, n378 = 378.5, n379 = 379.5, n380 = 380.5, > +n381 = 381.5, n382 = 382.5, n383 = 383.5, n384 = 384.5, n385 = 385.5, > +n386 = 386.5, n387 = 387.5, n388 = 388.5, n389 = 389.5, n390 = 390.5, > +n391 = 391.5, n392 = 392.5, n393 = 393.5, n394 = 394.5, n395 = 395.5, > +n396 = 396.5, n397 = 397.5, n398 = 398.5, n399 = 399.5, n400 = 400.5, > +n13 = 13.5, n14 = 14.5, n15 = 15.5, n16 = 16.5, n17 = 17.5, > +n18 = 18.5, n19 = 19.5, n20 = 20.5, n21 = 21.5, n22 = 22.5, > +n23 = 23.5, a24 = 24.5, n25 = 25.5, n26 = 26.5, n27 = 27.5, > +n28 = 28.5, n29 = 29.5, j30 = 30.5, n31 = 31.5, n32 = 32.5, > +n33 = 33.5, n34 = 34.5, n35 = 35.5, n36 = 36.5, n37 = 37.5, > +n38 = 38.5, n39 = 39.5, n40 = 40.5, n41 = 41.5, n42 = 42.5, > +n43 = 43.5, n44 = 44.5, n45 = 45.5, n46 = 46.5, n47 = 47.5, > +n48 = 48.5, n49 = 49.5, n50 = 50.5, n51 = 51.5, n52 = 52.5, > +n53 = 53.5, n54 = 54.5, n55 = 55.5, n56 = 56.5, n57 = 57.5, > +n58 = 58.5, n59 = 59.5, n60 = 60.5, n61 = 61.5, n62 = 62.5, > +n63 = 63.5, n64 = 64.5, n65 = 65.5, a66 = 66.5, z67 = 67.5, > +n68 = 68.5, n69 = 69.5, n70 = 70.5, n71 = 71.5, n72 = 72.5, > +n73 = 73.5, n74 = 74.5, n75 = 75.5, n76 = 76.5, n77 = 77.5, > +n78 = 78.5, n79 = 79.5, n80 = 80.5, n81 = 81.5, n82 = 82.5, > +n83 = 83.5, n84 = 84.5, n85 = 85.5, n86 = 86.5, n87 = 87.5, > +n88 = 88.5, n89 = 89.5, n90 = 90.5, n91 = 91.5, n92 = 92.5, > +n93 = 93.5, n94 = 94.5, n95 = 95.5, n96 = 96.5, n97 = 97.5, > +n98 = 98.5, n99 = 99.5, n100 = 100.5, n201 = 201.5, n202 = 202.5, > +n203 = 203.5, n204 = 204.5, n205 = 205.5, n206 = 206.5, n207 = 207.5, > +n208 = 208.5, n209 = 209.5, n210 = 210.5, n211 = 211.5, n212 = 212.5, > +n213 = 213.5, n214 = 214.5, n215 = 215.5, n216 = 216.5, n217 = 217.5, > +n218 = 218.5, n219 = 219.5, n220 = 220.5, n221 = 221.5, n222 = 222.5, > +n223 = 223.5, n224 = 224.5, n225 = 225.5, n226 = 226.5, n227 = 227.5, > +n228 = 228.5, n229 = 229.5, n230 = 230.5, n231 = 231.5, n232 = 232.5, > +n233 = 233.5, n234 = 234.5, n235 = 235.5, n236 = 236.5, n237 = 237.5, > +n238 = 238.5, n239 = 239.5, a240 = 240.5, a241 = 241.5, a242 = 242.5, > +a243 = 243.5, a244 = 244.5, a245 = 245.5, a246 = 246.5, a247 = 247.5, > +a248 = 248.5, a249 = 249.5, n250 = 250.5, n251 = 251.5, n252 = 252.5, > +n253 = 253.5, n254 = 254.5, n255 = 255.5, n256 = 256.5, n257 = 257.5, > +n258 = 258.5, n259 = 259.5, n260 = 260.5, n261 = 261.5, n262 = 262.5, > +n263 = 263.5, n264 = 264.5, n265 = 265.5, n266 = 266.5, n267 = 267.5, > +n268 = 268.5, n269 = 269.5, n270 = 270.5, n271 = 271.5, n272 = 272.5, > +n273 = 273.5, n274 = 274.5, n275 = 275.5, n276 = 276.5, n277 = 277.5, > +n278 = 278.5, n279 = 279.5, n280 = 280.5, n281 = 281.5, n282 = 282.5, > +n283 = 283.5, n284 = 284.5, n285 = 285.5, n286 = 286.5, n287 = 287.5, > +n288 = 288.5, n289 = 289.5, n290 = 290.5, n291 = 291.5, n292 = 292.5, > +n293 = 293.5, n294 = 294.5, n295 = 295.5, n296 = 296.5, n297 = 297.5, > +n298 = 298.5, n299 = 299.5, j300 = 300} or 1 > +until 1 > + > +assert(a.n299 == 299.5) > +xxx = 1 > +assert(xxx == 1) > + > +stat(a) > + > +function a:findfield (f) > + local i,v = next(self, nil) > + while i ~= f do > + if not i then return end > + i,v = next(self, i) > + end > + return v > +end > + > +local ii = 0 > +i = 1 > +while b[i] do > + local r = a:findfield(b[i]); > + assert(a[b[i]] == r) > + ii = math.max(ii,i) > + i = i+1 > +end > + > +assert(ii == 299) > + > +function xxxx (x) coroutine.yield('b'); return ii+x end > + > +assert(xxxx(10) == 309) > + > +a = nil > +b = nil > +a1 = nil > + > +print("tables with table indices:") > +i = 1; a={} > +while i <= 1023 do a[{}] = i; i=i+1 end > +stat(a) > +a = nil > + > +print("tables with function indices:") > +a={} > +for i=1,511 do local x; a[function () return x end] = i end > +stat(a) > +a = nil > + > +print'OK' > + > +return 'a' > diff --git a/test/PUC-Lua-5.1-tests/calls.lua b/test/PUC-Lua-5.1-tests/calls.lua > new file mode 100644 > index 0000000..788f9a1 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/calls.lua > @@ -0,0 +1,294 @@ > +print("testing functions and calls") > + > +-- get the opportunity to test 'type' too ;) > + > +assert(type(1<2) == 'boolean') > +assert(type(true) == 'boolean' and type(false) == 'boolean') > +assert(type(nil) == 'nil' and type(-3) == 'number' and type'x' == 'string' and > + type{} == 'table' and type(type) == 'function') > + > +assert(type(assert) == type(print)) > +f = nil > +function f (x) return a:x (x) end > +assert(type(f) == 'function') > + > + > +-- testing local-function recursion > +fact = false > +do > + local res = 1 > + local function fact (n) > + if n==0 then return res > + else return n*fact(n-1) > + end > + end > + assert(fact(5) == 120) > +end > +assert(fact == false) > + > +-- testing declarations > +a = {i = 10} > +self = 20 > +function a:x (x) return x+self.i end > +function a.y (x) return x+self end > + > +assert(a:x(1)+10 == a.y(1)) > + > +a.t = {i=-100} > +a["t"].x = function (self, a,b) return self.i+a+b end > + > +assert(a.t:x(2,3) == -95) > + > +do > + local a = {x=0} > + function a:add (x) self.x, a.y = self.x+x, 20; return self end > + assert(a:add(10):add(20):add(30).x == 60 and a.y == 20) > +end > + > +local a = {b={c={}}} > + > +function a.b.c.f1 (x) return x+1 end > +function a.b.c:f2 (x,y) self[x] = y end > +assert(a.b.c.f1(4) == 5) > +a.b.c:f2('k', 12); assert(a.b.c.k == 12) > + > +print('+') > + > +t = nil -- 'declare' t > +function f(a,b,c) local d = 'a'; t={a,b,c,d} end > + > +f( -- this line change must be valid > + 1,2) > +assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a') > +f(1,2, -- this one too > + 3,4) > +assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') > + > +function fat(x) > + if x <= 1 then return 1 > + else return x*loadstring("return fat(" .. x-1 .. ")")() > + end > +end > + > +assert(loadstring "loadstring 'assert(fat(6)==720)' () ")() > +a = loadstring('return fat(5), 3') > +a,b = a() > +assert(a == 120 and b == 3) > +print('+') > + > +function err_on_n (n) > + if n==0 then error(); exit(1); > + else err_on_n (n-1); exit(1); > + end > +end > + > +do > + function dummy (n) > + if n > 0 then > + assert(not pcall(err_on_n, n)) > + dummy(n-1) > + end > + end > +end > + > +dummy(10) > + > +function deep (n) > + if n>0 then deep(n-1) end > +end > +deep(10) > +deep(200) > + > +-- testing tail call > +function deep (n) if n>0 then return deep(n-1) else return 101 end end > +assert(deep(30000) == 101) > +a = {} > +function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end > +assert(a:deep(30000) == 101) > + > +print('+') > + > + > +a = nil > +(function (x) a=x end)(23) > +assert(a == 23 and (function (x) return x*2 end)(20) == 40) > + > + > +local x,y,z,a > +a = {}; lim = 2000 > +for i=1, lim do a[i]=i end > +assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) > +x = unpack(a) > +assert(x == 1) > +x = {unpack(a)} > +assert(table.getn(x) == lim and x[1] == 1 and x[lim] == lim) > +x = {unpack(a, lim-2)} > +assert(table.getn(x) == 3 and x[1] == lim-2 and x[3] == lim) > +x = {unpack(a, 10, 6)} > +assert(next(x) == nil) -- no elements > +x = {unpack(a, 11, 10)} > +assert(next(x) == nil) -- no elements > +x,y = unpack(a, 10, 10) > +assert(x == 10 and y == nil) > +x,y,z = unpack(a, 10, 11) > +assert(x == 10 and y == 11 and z == nil) > +a,x = unpack{1} > +assert(a==1 and x==nil) > +a,x = unpack({1,2}, 1, 1) > +assert(a==1 and x==nil) > + > + > +-- testing closures > + > +-- fixed-point operator > +Y = function (le) > + local function a (f) > + return le(function (x) return f(f)(x) end) > + end > + return a(a) > + end > + > + > +-- non-recursive factorial > + > +F = function (f) > + return function (n) > + if n == 0 then return 1 > + else return n*f(n-1) end > + end > + end > + > +fat = Y(F) > + > +assert(fat(0) == 1 and fat(4) == 24 and Y(F)(5)==5*Y(F)(4)) > + > +local function g (z) > + local function f (a,b,c,d) > + return function (x,y) return a+b+c+d+a+x+y+z end > + end > + return f(z,z+1,z+2,z+3) > +end > + > +f = g(10) > +assert(f(9, 16) == 10+11+12+13+10+9+16+10) > + > +Y, F, f = nil > +print('+') > + > +-- testing multiple returns > + > +function unlpack (t, i) > + i = i or 1 > + if (i <= table.getn(t)) then > + return t[i], unlpack(t, i+1) > + end > +end > + > +function equaltab (t1, t2) > + assert(table.getn(t1) == table.getn(t2)) > + for i,v1 in ipairs(t1) do > + assert(v1 == t2[i]) > + end > +end > + > +local function pack (...) > + local x = {...} > + x.n = select('#', ...) > + return x > +end > + > +function f() return 1,2,30,4 end > +function ret2 (a,b) return a,b end > + > +local a,b,c,d = unlpack{1,2,3} > +assert(a==1 and b==2 and c==3 and d==nil) > +a = {1,2,3,4,false,10,'alo',false,assert} > +equaltab(pack(unlpack(a)), a) > +equaltab(pack(unlpack(a), -1), {1,-1}) > +a,b,c,d = ret2(f()), ret2(f()) > +assert(a==1 and b==1 and c==2 and d==nil) > +a,b,c,d = unlpack(pack(ret2(f()), ret2(f()))) > +assert(a==1 and b==1 and c==2 and d==nil) > +a,b,c,d = unlpack(pack(ret2(f()), (ret2(f())))) > +assert(a==1 and b==1 and c==nil and d==nil) > + > +a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} > +assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") > + > + > +-- testing calls with 'incorrect' arguments > +rawget({}, "x", 1) > +rawset({}, "x", 1, 2) > +assert(math.sin(1,2) == math.sin(1)) > +table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg") > + > + > +-- test for generic load > +x = "-- a comment\0\0\0\n x = 10 + \n23; \ > + local a = function () x = 'hi' end; \ > + return '\0'" > +local i = 0 > +function read1 (x) > + return function () > + collectgarbage() > + i=i+1 > + return string.sub(x, i, i) > + end > +end > + > +a = assert(load(read1(x), "modname")) > +assert(a() == "\0" and _G.x == 33) > +assert(debug.getinfo(a).source == "modname") > + > +x = string.dump(loadstring("x = 1; return x")) > +i = 0 > +a = assert(load(read1(x))) > +assert(a() == 1 and _G.x == 1) > + > +i = 0 > +local a, b = load(read1("*a = 123")) > +assert(not a and type(b) == "string" and i == 2) > + > +a, b = load(function () error("hhi") end) > +assert(not a and string.find(b, "hhi")) > + > +-- test generic load with nested functions > +x = [[ > + return function (x) > + return function (y) > + return function (z) > + return x+y+z > + end > + end > + end > +]] > + > +a = assert(load(read1(x))) > +assert(a()(2)(3)(10) == 15) > + > + > +-- test for dump/undump with upvalues > +local a, b = 20, 30 > +x = loadstring(string.dump(function (x) > + if x == "set" then a = 10+b; b = b+1 else > + return a > + end > +end)) > +assert(x() == nil) > +assert(debug.setupvalue(x, 1, "hi") == "a") > +assert(x() == "hi") > +assert(debug.setupvalue(x, 2, 13) == "b") > +assert(not debug.setupvalue(x, 3, 10)) -- only 2 upvalues > +x("set") > +assert(x() == 23) > +x("set") > +assert(x() == 24) > + > + > +-- test for bug in parameter adjustment > +assert((function () return nil end)(4) == nil) > +assert((function () local a; return a end)(4) == nil) > +assert((function (a) return a end)() == nil) > + > +print('OK') > +return deep > diff --git a/test/PUC-Lua-5.1-tests/checktable.lua b/test/PUC-Lua-5.1-tests/checktable.lua > new file mode 100644 > index 0000000..f0938be > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/checktable.lua > @@ -0,0 +1,77 @@ > + > +assert(rawget(_G, "stat") == nil) -- module not loaded before > + > +if T == nil then > + stat = function () print"`querytab' nao ativo" end > + return > +end > + > + > +function checktable (t) > + local asize, hsize, ff = T.querytab(t) > + local l = {} > + for i=0,hsize-1 do > + local key,val,next = T.querytab(t, i + asize) > + if key == nil then > + assert(l[i] == nil and val==nil and next==nil) > + elseif key == "<undef>" then > + assert(val==nil) > + else > + assert(t[key] == val) > + local mp = T.hash(key, t) > + if l[i] then > + assert(l[i] == mp) > + elseif mp ~= i then > + l[i] = mp > + else -- list head > + l[mp] = {mp} -- first element > + while next do > + assert(ff <= next and next < hsize) > + if l[next] then assert(l[next] == mp) else l[next] = mp end > + table.insert(l[mp], next) > + key,val,next = T.querytab(t, next) > + assert(key) > + end > + end > + end > + end > + l.asize = asize; l.hsize = hsize; l.ff = ff > + return l > +end > + > +function mostra (t) > + local asize, hsize, ff = T.querytab(t) > + print(asize, hsize, ff) > + print'------' > + for i=0,asize-1 do > + local _, v = T.querytab(t, i) > + print(string.format("[%d] -", i), v) > + end > + print'------' > + for i=0,hsize-1 do > + print(i, T.querytab(t, i+asize)) > + end > + print'-------------' > +end > + > +function stat (t) > + t = checktable(t) > + local nelem, nlist = 0, 0 > + local maxlist = {} > + for i=0,t.hsize-1 do > + if type(t[i]) == 'table' then > + local n = table.getn(t[i]) > + nlist = nlist+1 > + nelem = nelem + n > + if not maxlist[n] then maxlist[n] = 0 end > + maxlist[n] = maxlist[n]+1 > + end > + end > + print(string.format("hsize=%d elements=%d load=%.2f med.len=%.2f (asize=%d)", > + t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize)) > + for i=1,table.getn(maxlist) do > + local n = maxlist[i] or 0 > + print(string.format("%5d %10d %.2f%%", i, n, n*100/nlist)) > + end > +end > + > diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua > new file mode 100644 > index 0000000..27ca0ad > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/closure.lua > @@ -0,0 +1,422 @@ > +print "testing closures and coroutines" > + > +local A,B = 0,{g=10} > +function f(x) > + local a = {} > + for i=1,1000 do > + local y = 0 > + do > + a[i] = function () B.g = B.g+1; y = y+x; return y+A end > + end > + end > + local dummy = function () return a[A] end > + collectgarbage() > + A = 1; assert(dummy() == a[1]); A = 0; > + assert(a[1]() == x) > + assert(a[3]() == x) > + collectgarbage() > + assert(B.g == 12) > + return a > +end > + > +a = f(10) > +-- force a GC in this level > +local x = {[1] = {}} -- to detect a GC > +setmetatable(x, {__mode = 'kv'}) > +while x[1] do -- repeat until GC > + local a = A..A..A..A -- create garbage > + A = A+1 > +end > +assert(a[1]() == 20+A) > +assert(a[1]() == 30+A) > +assert(a[2]() == 10+A) > +collectgarbage() > +assert(a[2]() == 20+A) > +assert(a[2]() == 30+A) > +assert(a[3]() == 20+A) > +assert(a[8]() == 10+A) > +assert(getmetatable(x).__mode == 'kv') > +assert(B.g == 19) > + > +-- testing closures with 'for' control variable > +a = {} > +for i=1,10 do > + a[i] = {set = function(x) i=x end, get = function () return i end} > + if i == 3 then break end > +end > +assert(a[4] == nil) > +a[1].set(10) > +assert(a[2].get() == 2) > +a[2].set('a') > +assert(a[3].get() == 3) > +assert(a[2].get() == 'a') > + > +a = {} > +for i, k in pairs{'a', 'b'} do > + a[i] = {set = function(x, y) i=x; k=y end, > + get = function () return i, k end} > + if i == 2 then break end > +end > +a[1].set(10, 20) > +local r,s = a[2].get() > +assert(r == 2 and s == 'b') > +r,s = a[1].get() > +assert(r == 10 and s == 20) > +a[2].set('a', 'b') > +r,s = a[2].get() > +assert(r == "a" and s == "b") > + > + > +-- testing closures with 'for' control variable x break > +for i=1,3 do > + f = function () return i end > + break > +end > +assert(f() == 1) > + > +for k, v in pairs{"a", "b"} do > + f = function () return k, v end > + break > +end > +assert(({f()})[1] == 1) > +assert(({f()})[2] == "a") > + > + > +-- testing closure x break x return x errors > + > +local b > +function f(x) > + local first = 1 > + while 1 do > + if x == 3 and not first then return end > + local a = 'xuxu' > + b = function (op, y) > + if op == 'set' then > + a = x+y > + else > + return a > + end > + end > + if x == 1 then do break end > + elseif x == 2 then return > + else if x ~= 3 then error() end > + end > + first = nil > + end > +end > + > +for i=1,3 do > + f(i) > + assert(b('get') == 'xuxu') > + b('set', 10); assert(b('get') == 10+i) > + b = nil > +end > + > +pcall(f, 4); > +assert(b('get') == 'xuxu') > +b('set', 10); assert(b('get') == 14) > + > + > +local w > +-- testing multi-level closure > +function f(x) > + return function (y) > + return function (z) return w+x+y+z end > + end > +end > + > +y = f(10) > +w = 1.345 > +assert(y(20)(30) == 60+w) > + > +-- testing closures x repeat-until > + > +local a = {} > +local i = 1 > +repeat > + local x = i > + a[i] = function () i = x+1; return x end > +until i > 10 or a[i]() ~= x > +assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) > + > +print'+' > + > + > +-- test for correctly closing upvalues in tail calls of vararg functions > +local function t () > + local function c(a,b) assert(a=="test" and b=="OK") end > + local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end > + local x = 1 > + return v(function() return x end) > +end > +t() > + > + > +-- coroutine tests > + > +local f > + > +assert(coroutine.running() == nil) > + > + > +-- tests for global environment > + > +local function foo (a) > + setfenv(0, a) > + coroutine.yield(getfenv()) > + assert(getfenv(0) == a) > + assert(getfenv(1) == _G) > + assert(getfenv(loadstring"") == a) > + return getfenv() > +end > + > +f = coroutine.wrap(foo) > +local a = {} > +assert(f(a) == _G) > +local a,b = pcall(f) > +assert(a and b == _G) > + > + > +-- tests for multiple yield/resume arguments > + > +local function eqtab (t1, t2) > + assert(table.getn(t1) == table.getn(t2)) > + for i,v in ipairs(t1) do > + assert(t2[i] == v) > + end > +end > + > +_G.x = nil -- declare x > +function foo (a, ...) > + assert(coroutine.running() == f) > + assert(coroutine.status(f) == "running") > + local arg = {...} > + for i=1,table.getn(arg) do > + _G.x = {coroutine.yield(unpack(arg[i]))} > + end > + return unpack(a) > +end > + > +f = coroutine.create(foo) > +assert(type(f) == "thread" and coroutine.status(f) == "suspended") > +assert(string.find(tostring(f), "thread")) > +local s,a,b,c,d > +s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'}) > +assert(s and a == nil and coroutine.status(f) == "suspended") > +s,a,b,c,d = coroutine.resume(f) > +eqtab(_G.x, {}) > +assert(s and a == 1 and b == nil) > +s,a,b,c,d = coroutine.resume(f, 1, 2, 3) > +eqtab(_G.x, {1, 2, 3}) > +assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil) > +s,a,b,c,d = coroutine.resume(f, "xuxu") > +eqtab(_G.x, {"xuxu"}) > +assert(s and a == 1 and b == 2 and c == 3 and d == nil) > +assert(coroutine.status(f) == "dead") > +s, a = coroutine.resume(f, "xuxu") > +assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") > + > + > +-- yields in tail calls > +local function foo (i) return coroutine.yield(i) end > +f = coroutine.wrap(function () > + for i=1,10 do > + assert(foo(i) == _G.x) > + end > + return 'a' > +end) > +for i=1,10 do _G.x = i; assert(f(i) == i) end > +_G.x = 'xuxu'; assert(f('xuxu') == 'a') > + > +-- recursive > +function pf (n, i) > + coroutine.yield(n) > + pf(n*i, i+1) > +end > + > +f = coroutine.wrap(pf) > +local s=1 > +for i=1,10 do > + assert(f(1, 1) == s) > + s = s*i > +end > + > +-- sieve > +function gen (n) > + return coroutine.wrap(function () > + for i=2,n do coroutine.yield(i) end > + end) > +end > + > + > +function filter (p, g) > + return coroutine.wrap(function () > + while 1 do > + local n = g() > + if n == nil then return end > + if math.mod(n, p) ~= 0 then coroutine.yield(n) end > + end > + end) > +end > + > +local x = gen(100) > +local a = {} > +while 1 do > + local n = x() > + if n == nil then break end > + table.insert(a, n) > + x = filter(n, x) > +end > + > +assert(table.getn(a) == 25 and a[table.getn(a)] == 97) > + > + > +-- errors in coroutines > +function foo () > + assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1) > + assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined) > + coroutine.yield(3) > + error(foo) > +end > + > +function goo() foo() end > +x = coroutine.wrap(goo) > +assert(x() == 3) > +local a,b = pcall(x) > +assert(not a and b == foo) > + > +x = coroutine.create(goo) > +a,b = coroutine.resume(x) > +assert(a and b == 3) > +a,b = coroutine.resume(x) > +assert(not a and b == foo and coroutine.status(x) == "dead") > +a,b = coroutine.resume(x) > +assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") > + > + > +-- co-routines x for loop > +function all (a, n, k) > + if k == 0 then coroutine.yield(a) > + else > + for i=1,n do > + a[k] = i > + all(a, n, k-1) > + end > + end > +end > + > +local a = 0 > +for t in coroutine.wrap(function () all({}, 5, 4) end) do > + a = a+1 > +end > +assert(a == 5^4) > + > + > +-- access to locals of collected corroutines > +local C = {}; setmetatable(C, {__mode = "kv"}) > +local x = coroutine.wrap (function () > + local a = 10 > + local function f () a = a+10; return a end > + while true do > + a = a+1 > + coroutine.yield(f) > + end > + end) > + > +C[1] = x; > + > +local f = x() > +assert(f() == 21 and x()() == 32 and x() == f) > +x = nil > +collectgarbage() > +assert(C[1] == nil) > +assert(f() == 43 and f() == 53) > + > + > +-- old bug: attempt to resume itself > + > +function co_func (current_co) > + assert(coroutine.running() == current_co) > + assert(coroutine.resume(current_co) == false) > + assert(coroutine.resume(current_co) == false) > + return 10 > +end > + > +local co = coroutine.create(co_func) > +local a,b = coroutine.resume(co, co) > +assert(a == true and b == 10) > +assert(coroutine.resume(co, co) == false) > +assert(coroutine.resume(co, co) == false) > + > +-- access to locals of erroneous coroutines > +local x = coroutine.create (function () > + local a = 10 > + _G.f = function () a=a+1; return a end > + error('x') > + end) > + > +assert(not coroutine.resume(x)) > +-- overwrite previous position of local `a' > +assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) > +assert(_G.f() == 11) > +assert(_G.f() == 12) > + > + > +if not T then > + (Message or print)('\a\n >>> testC not active: skipping yield/hook tests <<<\n\a') > +else > + > + local turn > + > + function fact (t, x) > + assert(turn == t) > + if x == 0 then return 1 > + else return x*fact(t, x-1) > + end > + end > + > + local A,B,a,b = 0,0,0,0 > + > + local x = coroutine.create(function () > + T.setyhook("", 2) > + A = fact("A", 10) > + end) > + > + local y = coroutine.create(function () > + T.setyhook("", 3) > + B = fact("B", 11) > + end) > + > + while A==0 or B==0 do > + if A==0 then turn = "A"; T.resume(x) end > + if B==0 then turn = "B"; T.resume(y) end > + end > + > + assert(B/A == 11) > +end > + > + > +-- leaving a pending coroutine open > +_X = coroutine.wrap(function () > + local a = 10 > + local x = function () a = a+1 end > + coroutine.yield() > + end) > + > +_X() > + > + > +-- coroutine environments > +co = coroutine.create(function () > + coroutine.yield(getfenv(0)) > + return loadstring("return a")() > + end) > + > +a = {a = 15} > +debug.setfenv(co, a) > +assert(debug.getfenv(co) == a) > +assert(select(2, coroutine.resume(co)) == a) > +assert(select(2, coroutine.resume(co)) == a.a) > + > + > +print'OK' > diff --git a/test/PUC-Lua-5.1-tests/code.lua b/test/PUC-Lua-5.1-tests/code.lua > new file mode 100644 > index 0000000..875d488 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/code.lua > @@ -0,0 +1,143 @@ > + > +if T==nil then > + (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a') > + return > +end > +print "testing code generation and optimizations" > + > + > +-- this code gave an error for the code checker > +do > + local function f (a) > + for k,v,w in a do end > + end > +end > + > + > +function check (f, ...) > + local c = T.listcode(f) > + for i=1, arg.n do > + -- print(arg[i], c[i]) > + assert(string.find(c[i], '- '..arg[i]..' *%d')) > + end > + assert(c[arg.n+2] == nil) > +end > + > + > +function checkequal (a, b) > + a = T.listcode(a) > + b = T.listcode(b) > + for i = 1, table.getn(a) do > + a[i] = string.gsub(a[i], '%b()', '') -- remove line number > + b[i] = string.gsub(b[i], '%b()', '') -- remove line number > + assert(a[i] == b[i]) > + end > +end > + > + > +-- some basic instructions > +check(function () > + (function () end){f()} > +end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN') > + > + > +-- sequence of LOADNILs > +check(function () > + local a,b,c > + local d; local e; > + a = nil; d=nil > +end, 'RETURN') > + > + > +-- single return > +check (function (a,b,c) return a end, 'RETURN') > + > + > +-- infinite loops > +check(function () while true do local a = -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () while 1 do local a = -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x = 1 until false end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x until nil end, > +'LOADNIL', 'JMP', 'RETURN') > + > +check(function () repeat local x = 1 until true end, > +'LOADK', 'RETURN') > + > + > +-- concat optimization > +check(function (a,b,c,d) return a..b..c..d end, > + 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') > + > +-- not > +check(function () return not not nil end, 'LOADBOOL', 'RETURN') > +check(function () return not not false end, 'LOADBOOL', 'RETURN') > +check(function () return not not true end, 'LOADBOOL', 'RETURN') > +check(function () return not not 1 end, 'LOADBOOL', 'RETURN') > + > +-- direct access to locals > +check(function () > + local a,b,c,d > + a = b*2 > + c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b > +end, > + 'MUL', > + 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', > + 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') > + > + > +-- direct access to constants > +check(function () > + local a,b > + a.x = 0 > + a.x = b > + a[b] = 'y' > + a = 1 - a > + b = 1/a > + b = 5+4 > + a[true] = false > +end, > + 'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK', > + 'SETTABLE', 'RETURN') > + > +local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end > + > +check(f, 'LOADK', 'RETURN') > +assert(f() == -5) > + > +check(function () > + local a,b,c > + b[c], a = c, b > + b[a], a = c, b > + a, b = c, a > + a = a > +end, > + 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', > + -- no code for a = a > + 'RETURN') > + > + > +-- x == nil , x ~= nil > +checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end, > + function () if (a==9) then a=1 end; if a~=9 then a=1 end end) > + > +check(function () if a==nil then a=1 end end, > +'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN') > + > +-- de morgan > +checkequal(function () local a; if not (a or b) then b=a end end, > + function () local a; if (not a and not b) then b=a end end) > + > +checkequal(function (l) local a; return 0 <= a and a <= l end, > + function (l) local a; return not (not(a >= 0) or not(a <= l)) end) > + > + > +print 'OK' > + > diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua > new file mode 100644 > index 0000000..5fb3798 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/constructs.lua > @@ -0,0 +1,240 @@ > +print "testing syntax" > + > +-- testing priorities > + > +assert(2^3^2 == 2^(3^2)); > +assert(2^3*4 == (2^3)*4); > +assert(2^-2 == 1/4 and -2^- -2 == - - -4); > +assert(not nil and 2 and not(2>3 or 3<2)); > +assert(-3-1-5 == 0+0-9); > +assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0); > +assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33"); > +assert(not(2+1 > 3*1) and "a".."b" > "a"); > + > +assert(not ((true or false) and nil)) > +assert( true or false and nil) > + > +local a,b = 1,nil; > +assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75); > +x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x); > +x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x); > + > +x,y=1,2; > +assert((x>y) and x or y == 2); > +x,y=2,1; > +assert((x>y) and x or y == 2); > + > +assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) > + > + > +-- silly loops > +repeat until 1; repeat until true; > +while false do end; while nil do end; > + > +do -- test old bug (first name could not be an `upvalue') > + local a; function f(x) x={a=1}; x={x=1}; x={G=1} end > +end > + > +function f (i) > + if type(i) ~= 'number' then return i,'jojo'; end; > + if i > 0 then return i, f(i-1); end; > +end > + > +x = {f(3), f(5), f(10);}; > +assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1); > +assert(x[nil] == nil) > +x = {f'alo', f'xixi', nil}; > +assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil); > +x = {f'alo'..'xixi'}; > +assert(x[1] == 'aloxixi') > +x = {f{}} > +assert(x[2] == 'jojo' and type(x[1]) == 'table') > + > + > +local f = function (i) > + if i < 10 then return 'a'; > + elseif i < 20 then return 'b'; > + elseif i < 30 then return 'c'; > + end; > +end > + > +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil) > + > +for i=1,1000 do break; end; > +n=100; > +i=3; > +t = {}; > +a=nil > +while not a do > + a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end; > +end > +assert(a == n*(n+1)/2 and i==3); > +assert(t[1] and t[n] and not t[0] and not t[n+1]) > + > +function f(b) > + local x = 1; > + repeat > + local a; > + if b==1 then local b=1; x=10; break > + elseif b==2 then x=20; break; > + elseif b==3 then x=30; > + else local a,b,c,d=math.sin(1); x=x+1; > + end > + until x>=12; > + return x; > +end; > + > +assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12) > + > + > +local f = function (i) > + if i < 10 then return 'a' > + elseif i < 20 then return 'b' > + elseif i < 30 then return 'c' > + else return 8 > + end > +end > + > +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8) > + > +local a, b = nil, 23 > +x = {f(100)*2+3 or a, a or b+2} > +assert(x[1] == 19 and x[2] == 25) > +x = {f=2+3 or a, a = b+2} > +assert(x.f == 5 and x.a == 25) > + > +a={y=1} > +x = {a.y} > +assert(x[1] == 1) > + > +function f(i) > + while 1 do > + if i>0 then i=i-1; > + else return; end; > + end; > +end; > + > +function g(i) > + while 1 do > + if i>0 then i=i-1 > + else return end > + end > +end > + > +f(10); g(10); > + > +do > + function f () return 1,2,3; end > + local a, b, c = f(); > + assert(a==1 and b==2 and c==3) > + a, b, c = (f()); > + assert(a==1 and b==nil and c==nil) > +end > + > +local a,b = 3 and f(); > +assert(a==1 and b==nil) > + > +function g() f(); return; end; > +assert(g() == nil) > +function g() return nil or f() end > +a,b = g() > +assert(a==1 and b==nil) > + > +print'+'; > + > + > +f = [[ > +return function ( a , b , c , d , e ) > + local x = a >= b or c or ( d and e ) or nil > + return x > +end , { a = 1 , b = 2 >= 1 , } or { 1 }; > +]] > +f = string.gsub(f, "%s+", "\n"); -- force a SETLINE between opcodes > +f,a = loadstring(f)(); > +assert(a.a == 1 and a.b) > + > +function g (a,b,c,d,e) > + if not (a>=b or c or d and e or nil) then return 0; else return 1; end; > +end > + > +function h (a,b,c,d,e) > + while (a>=b or c or (d and e) or nil) do return 1; end; > + return 0; > +end; > + > +assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1) > +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) > +assert(f(1,2,'a') > +~= -- force SETLINE before nil > +nil, "") > +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) > +assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and > + h(1,2,nil,1,'x') == 1) > +assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and > + h(1,2,nil,nil,'x') == 0) > +assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and > + h(1,2,nil,1,nil) == 0) > + > +assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true) > +x = 2<3 and not 3; assert(x==false) > +x = 2<1 or (2>1 and 'a'); assert(x=='a') > + > + > +do > + local a; if nil then a=1; else a=2; end; -- this nil comes as PUSHNIL 2 > + assert(a==2) > +end > + > +function F(a) > + assert(debug.getinfo(1, "n").name == 'F') > + return a,2,3 > +end > + > +a,b = F(1)~=nil; assert(a == true and b == nil); > +a,b = F(nil)==nil; assert(a == true and b == nil) > + > +---------------------------------------------------------------- > +-- creates all combinations of > +-- [not] ([not] arg op [not] (arg op [not] arg )) > +-- and tests each one > + > +function ID(x) return x end > + > +function f(t, i) > + local b = t.n > + local res = math.mod(math.floor(i/c), b)+1 > + c = c*b > + return t[res] > +end > + > +local arg = {" ( 1 < 2 ) ", " ( 1 >= 2 ) ", " F ( ) ", " nil "; n=4} > + > +local op = {" and ", " or ", " == ", " ~= "; n=4} > + > +local neg = {" ", " not "; n=2} > + > +local i = 0 > +repeat > + c = 1 > + local s = f(neg, i)..'ID('..f(neg, i)..f(arg, i)..f(op, i).. > + f(neg, i)..'ID('..f(arg, i)..f(op, i)..f(neg, i)..f(arg, i)..'))' > + local s1 = string.gsub(s, 'ID', '') > + K,X,NX,WX1,WX2 = nil > + s = string.format([[ > + local a = %s > + local b = not %s > + K = b > + local xxx; > + if %s then X = a else X = b end > + if %s then NX = b else NX = a end > + while %s do WX1 = a; break end > + while %s do WX2 = a; break end > + repeat if (%s) then break end; assert(b) until not(%s) > + ]], s1, s, s1, s, s1, s, s1, s, s) > + assert(loadstring(s))() > + assert(X and not NX and not WX1 == K and not WX2 == K) > + if math.mod(i,4000) == 0 then print('+') end > + i = i+1 > +until i==c > + > +print'OK' > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > new file mode 100644 > index 0000000..9d2c86f > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -0,0 +1,499 @@ > +-- testing debug library > + > +local function dostring(s) return assert(loadstring(s))() end > + > +print"testing debug library and debug information" > + > +do > +local a=1 > +end > + > +function test (s, l, p) > + collectgarbage() -- avoid gc during trace > + local function f (event, line) > + assert(event == 'line') > + local l = table.remove(l, 1) > + if p then print(l, line) end > + assert(l == line, "wrong trace!!") > + end > + debug.sethook(f,"l"); loadstring(s)(); debug.sethook() > + assert(table.getn(l) == 0) > +end > + > + > +do > + local a = debug.getinfo(print) > + assert(a.what == "C" and a.short_src == "[C]") > + local b = debug.getinfo(test, "SfL") > + assert(b.name == nil and b.what == "Lua" and b.linedefined == 11 and > + b.lastlinedefined == b.linedefined + 10 and > + b.func == test and not string.find(b.short_src, "%[")) > + assert(b.activelines[b.linedefined + 1] and > + b.activelines[b.lastlinedefined]) > + assert(not b.activelines[b.linedefined] and > + not b.activelines[b.lastlinedefined + 1]) > +end > + > + > +-- test file and string names truncation > +a = "function f () end" > +local function dostring (s, x) return loadstring(s, x)() end > +dostring(a) > +assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a)) > +dostring(a..string.format("; %s\n=1", string.rep('p', 400))) > +assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$')) > +dostring("\n"..a) > +assert(debug.getinfo(f).short_src == '[string "..."]') > +dostring(a, "") > +assert(debug.getinfo(f).short_src == '[string ""]') > +dostring(a, "@xuxu") > +assert(debug.getinfo(f).short_src == "xuxu") > +dostring(a, "@"..string.rep('p', 1000)..'t') > +assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$")) > +dostring(a, "=xuxu") > +assert(debug.getinfo(f).short_src == "xuxu") > +dostring(a, string.format("=%s", string.rep('x', 500))) > +assert(string.find(debug.getinfo(f).short_src, "^x*")) > +dostring(a, "=") > +assert(debug.getinfo(f).short_src == "") > +a = nil; f = nil; > + > + > +repeat > + local g = {x = function () > + local a = debug.getinfo(2) > + assert(a.name == 'f' and a.namewhat == 'local') > + a = debug.getinfo(1) > + assert(a.name == 'x' and a.namewhat == 'field') > + return 'xixi' > + end} > + local f = function () return 1+1 and (not 1 or g.x()) end > + assert(f() == 'xixi') > + g = debug.getinfo(f) > + assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name) > + > + function f (x, name) -- local! > + name = name or 'f' > + local a = debug.getinfo(1) > + assert(a.name == name and a.namewhat == 'local') > + return x > + end > + > + -- breaks in different conditions > + if 3>4 then break end; f() > + if 3<4 then a=1 else break end; f() > + while 1 do local x=10; break end; f() > + local b = 1 > + if 3>4 then return math.sin(1) end; f() > + a = 3<4; f() > + a = 3<4 or 1; f() > + repeat local x=20; if 4>3 then f() else break end; f() until 1 > + g = {} > + f(g).x = f(2) and f(10)+f(9) > + assert(g.x == f(19)) > + function g(x) if not x then return 3 end return (x('a', 'x')) end > + assert(g(f) == 'a') > +until 1 > + > +test([[if > +math.sin(1) > +then > + a=1 > +else > + a=2 > +end > +]], {2,4,7}) > + > +test([[-- > +if nil then > + a=1 > +else > + a=2 > +end > +]], {2,5,6}) > + > +test([[a=1 > +repeat > + a=a+1 > +until a==3 > +]], {1,3,4,3,4}) > + > +test([[ do > + return > +end > +]], {2}) > + > +test([[local a > +a=1 > +while a<=3 do > + a=a+1 > +end > +]], {2,3,4,3,4,3,4,3,5}) > + > +test([[while math.sin(1) do > + if math.sin(1) > + then > + break > + end > +end > +a=1]], {1,2,4,7}) > + > +test([[for i=1,3 do > + a=i > +end > +]], {1,2,1,2,1,2,1,3}) > + > +test([[for i,v in pairs{'a','b'} do > + a=i..v > +end > +]], {1,2,1,2,1,3}) > + > +test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > + > + > + > +print'+' > + > +a = {}; L = nil > +local glob = 1 > +local oldglob = glob > +debug.sethook(function (e,l) > + collectgarbage() -- force GC during a hook > + local f, m, c = debug.gethook() > + assert(m == 'crl' and c == 0) > + if e == "line" then > + if glob ~= oldglob then > + L = l-1 -- get the first line where "glob" has changed > + oldglob = glob > + end > + elseif e == "call" then > + local f = debug.getinfo(2, "f").func > + a[f] = 1 > + else assert(e == "return") > + end > +end, "crl") > + > +function f(a,b) > + collectgarbage() > + local _, x = debug.getlocal(1, 1) > + local _, y = debug.getlocal(1, 2) > + assert(x == a and y == b) > + assert(debug.setlocal(2, 3, "pera") == "AA".."AA") > + assert(debug.setlocal(2, 4, "ma��") == "B") > + x = debug.getinfo(2) > + assert(x.func == g and x.what == "Lua" and x.name == 'g' and > + x.nups == 0 and string.find(x.source, "^@.*db%.lua")) > + glob = glob+1 > + assert(debug.getinfo(1, "l").currentline == L+1) > + assert(debug.getinfo(1, "l").currentline == L+2) > +end > + > +function foo() > + glob = glob+1 > + assert(debug.getinfo(1, "l").currentline == L+1) > +end; foo() -- set L > +-- check line counting inside strings and empty lines > + > +_ = 'alo\ > +alo' .. [[ > + > +]] > +--[[ > +]] > +assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines > + > + > +function g(...) > + do local a,b,c; a=math.sin(40); end > + local feijao > + local AAAA,B = "xuxu", "mam�o" > + f(AAAA,B) > + assert(AAAA == "pera" and B == "ma��") > + do > + local B = 13 > + local x,y = debug.getlocal(1,5) > + assert(x == 'B' and y == 13) > + end > +end > + > +g() > + > + > +assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print]) > + > + > +-- tests for manipulating non-registered locals (C and Lua temporaries) > + > +local n, v = debug.getlocal(0, 1) > +assert(v == 0 and n == "(*temporary)") > +local n, v = debug.getlocal(0, 2) > +assert(v == 2 and n == "(*temporary)") > +assert(not debug.getlocal(0, 3)) > +assert(not debug.getlocal(0, 0)) > + > +function f() > + assert(select(2, debug.getlocal(2,3)) == 1) > + assert(not debug.getlocal(2,4)) > + debug.setlocal(2, 3, 10) > + return 20 > +end > + > +function g(a,b) return (a+1) + f() end > + > +assert(g(0,0) == 30) > + > + > +debug.sethook(nil); > +assert(debug.gethook() == nil) > + > + > +-- testing access to function arguments > + > +X = nil > +a = {} > +function a:f (a, b, ...) local c = 13 end > +debug.sethook(function (e) > + assert(e == "call") > + dostring("XX = 12") -- test dostring inside hooks > + -- testing errors inside hooks > + assert(not pcall(loadstring("a='joao'+1"))) > + debug.sethook(function (e, l) > + assert(debug.getinfo(2, "l").currentline == l) > + local f,m,c = debug.gethook() > + assert(e == "line") > + assert(m == 'l' and c == 0) > + debug.sethook(nil) -- hook is called only once > + assert(not X) -- check that > + X = {}; local i = 1 > + local x,y > + while 1 do > + x,y = debug.getlocal(2, i) > + if x==nil then break end > + X[x] = y > + i = i+1 > + end > + end, "l") > +end, "c") > + > +a:f(1,2,3,4,5) > +assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) > +assert(XX == 12) > +assert(debug.gethook() == nil) > + > + > +-- testing upvalue access > +local function getupvalues (f) > + local t = {} > + local i = 1 > + while true do > + local name, value = debug.getupvalue(f, i) > + if not name then break end > + assert(not t[name]) > + t[name] = value > + i = i + 1 > + end > + return t > +end > + > +local a,b,c = 1,2,3 > +local function foo1 (a) b = a; return c end > +local function foo2 (x) a = x; return c+b end > +assert(debug.getupvalue(foo1, 3) == nil) > +assert(debug.getupvalue(foo1, 0) == nil) > +assert(debug.setupvalue(foo1, 3, "xuxu") == nil) > +local t = getupvalues(foo1) > +assert(t.a == nil and t.b == 2 and t.c == 3) > +t = getupvalues(foo2) > +assert(t.a == 1 and t.b == 2 and t.c == 3) > +assert(debug.setupvalue(foo1, 1, "xuxu") == "b") > +assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu") > +-- cannot manipulate C upvalues from Lua > +assert(debug.getupvalue(io.read, 1) == nil) > +assert(debug.setupvalue(io.read, 1, 10) == nil) > + > + > +-- testing count hooks > +local a=0 > +debug.sethook(function (e) a=a+1 end, "", 1) > +a=0; for i=1,1000 do end; assert(1000 < a and a < 1012) > +debug.sethook(function (e) a=a+1 end, "", 4) > +a=0; for i=1,1000 do end; assert(250 < a and a < 255) > +local f,m,c = debug.gethook() > +assert(m == "" and c == 4) > +debug.sethook(function (e) a=a+1 end, "", 4000) > +a=0; for i=1,1000 do end; assert(a == 0) > +debug.sethook(print, "", 2^24 - 1) -- count upperbound > +local f,m,c = debug.gethook() > +assert(({debug.gethook()})[3] == 2^24 - 1) > +debug.sethook() > + > + > +-- tests for tail calls > +local function f (x) > + if x then > + assert(debug.getinfo(1, "S").what == "Lua") > + local tail = debug.getinfo(2) > + assert(not pcall(getfenv, 3)) > + assert(tail.what == "tail" and tail.short_src == "(tail call)" and > + tail.linedefined == -1 and tail.func == nil) > + assert(debug.getinfo(3, "f").func == g1) > + assert(getfenv(3)) > + assert(debug.getinfo(4, "S").what == "tail") > + assert(not pcall(getfenv, 5)) > + assert(debug.getinfo(5, "S").what == "main") > + assert(getfenv(5)) > + print"+" > + end > +end > + > +function g(x) return f(x) end > + > +function g1(x) g(x) end > + > +local function h (x) local f=g1; return f(x) end > + > +h(true) > + > +local b = {} > +debug.sethook(function (e) table.insert(b, e) end, "cr") > +h(false) > +debug.sethook() > +local res = {"return", -- first return (from sethook) > + "call", "call", "call", "call", > + "return", "tail return", "return", "tail return", > + "call", -- last call (to sethook) > +} > +for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > + > + > +lim = 30000 > +local function foo (x) > + if x==0 then > + assert(debug.getinfo(lim+2).what == "main") > + for i=2,lim do assert(debug.getinfo(i, "S").what == "tail") end > + else return foo(x-1) > + end > +end > + > +foo(lim) > + > + > +print"+" > + > + > +-- testing traceback > + > +assert(debug.traceback(print) == print) > +assert(debug.traceback(print, 4) == print) > +assert(string.find(debug.traceback("hi", 4), "^hi\n")) > +assert(string.find(debug.traceback("hi"), "^hi\n")) > +assert(not string.find(debug.traceback("hi"), "'traceback'")) > +assert(string.find(debug.traceback("hi", 0), "'traceback'")) > +assert(string.find(debug.traceback(), "^stack traceback:\n")) > + > +-- testing debugging of coroutines > + > +local function checktraceback (co, p) > + local tb = debug.traceback(co) > + local i = 0 > + for l in string.gmatch(tb, "[^\n]+\n?") do > + assert(i == 0 or string.find(l, p[i])) > + i = i+1 > + end > + assert(p[i] == nil) > +end > + > + > +local function f (n) > + if n > 0 then return f(n-1) > + else coroutine.yield() end > +end > + > +local co = coroutine.create(f) > +coroutine.resume(co, 3) > +checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) > + > + > +co = coroutine.create(function (x) > + local a = 1 > + coroutine.yield(debug.getinfo(1, "l")) > + coroutine.yield(debug.getinfo(1, "l").currentline) > + return a > + end) > + > +local tr = {} > +local foo = function (e, l) table.insert(tr, l) end > +debug.sethook(co, foo, "l") > + > +local _, l = coroutine.resume(co, 10) > +local x = debug.getinfo(co, 1, "lfLS") > +assert(x.currentline == l.currentline and x.activelines[x.currentline]) > +assert(type(x.func) == "function") > +for i=x.linedefined + 1, x.lastlinedefined do > + assert(x.activelines[i]) > + x.activelines[i] = nil > +end > +assert(next(x.activelines) == nil) -- no 'extra' elements > +assert(debug.getinfo(co, 2) == nil) > +local a,b = debug.getlocal(co, 1, 1) > +assert(a == "x" and b == 10) > +a,b = debug.getlocal(co, 1, 2) > +assert(a == "a" and b == 1) > +debug.setlocal(co, 1, 2, "hi") > +assert(debug.gethook(co) == foo) > +assert(table.getn(tr) == 2 and > + tr[1] == l.currentline-1 and tr[2] == l.currentline) > + > +a,b,c = pcall(coroutine.resume, co) > +assert(a and b and c == l.currentline+1) > +checktraceback(co, {"yield", "in function <"}) > + > +a,b = coroutine.resume(co) > +assert(a and b == "hi") > +assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) > +assert(debug.gethook(co) == foo) > +assert(debug.gethook() == nil) > +checktraceback(co, {}) > + > + > +-- check traceback of suspended (or dead with error) coroutines > + > +function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end > + > +co = coroutine.create(function (x) f(x) end) > +a, b = coroutine.resume(co, 3) > +t = {"'yield'", "'f'", "in function <"} > +while coroutine.status(co) == "suspended" do > + checktraceback(co, t) > + a, b = coroutine.resume(co) > + table.insert(t, 2, "'f'") -- one more recursive call to 'f' > +end > +t[1] = "'error'" > +checktraceback(co, t) > + > + > +-- test acessing line numbers of a coroutine from a resume inside > +-- a C function (this is a known bug in Lua 5.0) > + > +local function g(x) > + coroutine.yield(x) > +end > + > +local function f (i) > + debug.sethook(function () end, "l") > + for j=1,1000 do > + g(i+j) > + end > +end > + > +local co = coroutine.wrap(f) > +co(10) > +pcall(co) > +pcall(co) > + > + > +assert(type(debug.getregistry()) == "table") > + > + > +print"OK" > + > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > new file mode 100644 > index 0000000..e881211 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -0,0 +1,250 @@ > +print("testing errors") > + > +function doit (s) > + local f, msg = loadstring(s) > + if f == nil then return msg end > + local cond, msg = pcall(f) > + return (not cond) and msg > +end > + > + > +function checkmessage (prog, msg) > + assert(string.find(doit(prog), msg, 1, true)) > +end > + > +function checksyntax (prog, extra, token, line) > + local msg = doit(prog) > + token = string.gsub(token, "(%p)", "%%%1") > + local pt = string.format([[^%%[string ".*"%%]:%d: .- near '%s'$]], > + line, token) > + assert(string.find(msg, pt)) > + assert(string.find(msg, msg, 1, true)) > +end > + > + > +-- test error message with no extra info > +assert(doit("error('hi', 0)") == 'hi') > + > +-- test error message with no info > +assert(doit("error()") == nil) > + > + > +-- test common errors/errors that crashed in the past > +assert(doit("unpack({}, 1, n=2^30)")) > +assert(doit("a=math.sin()")) > +assert(not doit("tostring(1)") and doit("tostring()")) > +assert(doit"tonumber()") > +assert(doit"repeat until 1; a") > +checksyntax("break label", "", "label", 1) > +assert(doit";") > +assert(doit"a=1;;") > +assert(doit"return;;") > +assert(doit"assert(false)") > +assert(doit"assert(nil)") > +assert(doit"a=math.sin\n(3)") > +assert(doit("function a (... , ...) end")) > +assert(doit("function a (, ...) end")) > + > +checksyntax([[ > + local a = {4 > + > +]], "'}' expected (to close '{' at line 1)", "<eof>", 3) > + > + > +-- tests for better error messages > + > +checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'") > +checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)", > + "local 'bbbb'") > +checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'") > +checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'") > +assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'")) > +checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number") > + > +aaa = nil > +checkmessage("aaa.bbb:ddd(9)", "global 'aaa'") > +checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'") > +checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'") > +checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'") > +assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)") > + > +checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > +checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > +checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > +checkmessage("aaa={}; x=-aaa", "global 'aaa'") > +assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > +assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > + > +checkmessage([[aaa=9 > +repeat until 3==3 > +local x=math.sin(math.cos(3)) > +if math.sin(1) == x then return math.sin(1) end -- tail call > +local a,b = 1, { > + {x='a'..'b'..'c', y='b', z=x}, > + {1,2,3,4,5} or 3+3<=3+3, > + 3+1>3+1, > + {d = x and aaa[x or y]}} > +]], "global 'aaa'") > + > +checkmessage([[ > +local x,y = {},1 > +if math.sin(1) == 0 then return 3 end -- return > +x.a()]], "field 'a'") > + > +checkmessage([[ > +prefix = nil > +insert = nil > +while 1 do > + local a > + if nil then break end > + insert(prefix, a) > +end]], "global 'insert'") > + > +checkmessage([[ -- tail call > + return math.sin("a") > +]], "'sin'") > + > +checkmessage([[collectgarbage("nooption")]], "invalid option") > + > +checkmessage([[x = print .. "a"]], "concatenate") > + > +checkmessage("getmetatable(io.stdin).__gc()", "no value") > + > +print'+' > + > + > +-- testing line error > + > +function lineerror (s) > + local err,msg = pcall(loadstring(s)) > + local line = string.match(msg, ":(%d+):") > + return line and line+0 > +end > + > +assert(lineerror"local a\n for i=1,'a' do \n print(i) \n end" == 2) > +assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" == 3) > +assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" == 4) > +assert(lineerror"function a.x.y ()\na=a+1\nend" == 1) > + > +local p = [[ > +function g() f() end > +function f(x) error('a', X) end > +g() > +]] > +X=3;assert(lineerror(p) == 3) > +X=0;assert(lineerror(p) == nil) > +X=1;assert(lineerror(p) == 2) > +X=2;assert(lineerror(p) == 1) > + > +lineerror = nil > + > +C = 0 > +local l = debug.getinfo(1, "l").currentline; function y () C=C+1; y() end > + > +local function checkstackmessage (m) > + return (string.find(m, "^.-:%d+: stack overflow")) > +end > +assert(checkstackmessage(doit('y()'))) > +assert(checkstackmessage(doit('y()'))) > +assert(checkstackmessage(doit('y()'))) > +-- teste de linhas em erro > +C = 0 > +local l1 > +local function g() > + l1 = debug.getinfo(1, "l").currentline; y() > +end > +local _, stackmsg = xpcall(g, debug.traceback) > +local stack = {} > +for line in string.gmatch(stackmsg, "[^\n]*") do > + local curr = string.match(line, ":(%d+):") > + if curr then table.insert(stack, tonumber(curr)) end > +end > +local i=1 > +while stack[i] ~= l1 do > + assert(stack[i] == l) > + i = i+1 > +end > +assert(i > 15) > + > + > +-- error in error handling > +local res, msg = xpcall(error, error) > +assert(not res and type(msg) == 'string') > + > +local function f (x) > + if x==0 then error('a\n') > + else > + local aux = function () return f(x-1) end > + local a,b = xpcall(aux, aux) > + return a,b > + end > +end > +f(3) > + > +-- non string messages > +function f() error{msg='x'} end > +res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) > +assert(msg.msg == 'xy') > + > +print('+') > +checksyntax("syntax error", "", "error", 1) > +checksyntax("1.000", "", "1.000", 1) > +checksyntax("[[a]]", "", "[[a]]", 1) > +checksyntax("'aa'", "", "'aa'", 1) > + > +-- test 255 as first char in a chunk > +checksyntax("\255a = 1", "", "\255", 1) > + > +doit('I = loadstring("a=9+"); a=3') > +assert(a==3 and I == nil) > +print('+') > + > +lim = 1000 > +if rawget(_G, "_soft") then lim = 100 end > +for i=1,lim do > + doit('a = ') > + doit('a = 4+nil') > +end > + > + > +-- testing syntax limits > +local function testrep (init, rep) > + local s = "local a; "..init .. string.rep(rep, 400) > + local a,b = loadstring(s) > + assert(not a and string.find(b, "syntax levels")) > +end > +testrep("a=", "{") > +testrep("a=", "(") > +testrep("", "a(") > +testrep("", "do ") > +testrep("", "while a do ") > +testrep("", "if a then else ") > +testrep("", "function foo () ") > +testrep("a=", "a..") > +testrep("a=", "a^") > + > + > +-- testing other limits > +-- upvalues > +local s = "function foo ()\n local " > +for j = 1,70 do > + s = s.."a"..j..", " > +end > +s = s.."b\n" > +for j = 1,70 do > + s = s.."function foo"..j.." ()\n a"..j.."=3\n" > +end > +local a,b = loadstring(s) > +assert(string.find(b, "line 3")) > + > +-- local variables > +s = "\nfunction foo ()\n local " > +for j = 1,300 do > + s = s.."a"..j..", " > +end > +s = s.."b\n" > +local a,b = loadstring(s) > +assert(string.find(b, "line 2")) > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.c b/test/PUC-Lua-5.1-tests/etc/ltests.c > new file mode 100644 > index 0000000..be949e5 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/etc/ltests.c > @@ -0,0 +1,1147 @@ > +/* > +** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp $ > +** Internal Module for Debugging of the Lua Implementation > +** See Copyright Notice in lua.h > +*/ > + > + > +#include <ctype.h> > +#include <limits.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > + > +#define ltests_c > +#define LUA_CORE > + > +#include "lua.h" > + > +#include "lapi.h" > +#include "lauxlib.h" > +#include "lcode.h" > +#include "ldebug.h" > +#include "ldo.h" > +#include "lfunc.h" > +#include "lmem.h" > +#include "lopcodes.h" > +#include "lstate.h" > +#include "lstring.h" > +#include "ltable.h" > +#include "lualib.h" > + > + > + > +/* > +** The whole module only makes sense with LUA_DEBUG on > +*/ > +#if defined(LUA_DEBUG) > + > + > +int Trick = 0; > + > + > +static lua_State *lua_state = NULL; > + > +int islocked = 0; > + > + > +#define obj_at(L,k) (L->ci->base+(k) - 1) > + > + > +static void setnameval (lua_State *L, const char *name, int val) { > + lua_pushstring(L, name); > + lua_pushinteger(L, val); > + lua_settable(L, -3); > +} > + > + > +/* > +** {====================================================================== > +** Controlled version for realloc. > +** ======================================================================= > +*/ > + > +#define MARK 0x55 /* 01010101 (a nice pattern) */ > + > +#ifndef EXTERNMEMCHECK > +/* full memory check */ > +#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ > +#define MARKSIZE 16 /* size of marks after each block */ > +#define blockhead(b) (cast(char *, b) - HEADER) > +#define setsize(newblock, size) (*cast(size_t *, newblock) = size) > +#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) > +#define fillmem(mem,size) memset(mem, -MARK, size) > +#else > +/* external memory check: don't do it twice */ > +#define HEADER 0 > +#define MARKSIZE 0 > +#define blockhead(b) (b) > +#define setsize(newblock, size) /* empty */ > +#define checkblocksize(b,size) (1) > +#define fillmem(mem,size) /* empty */ > +#endif > + > + > +Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX}; > + > + > +static void *checkblock (void *block, size_t size) { > + void *b = blockhead(block); > + int i; > + for (i=0;i<MARKSIZE;i++) > + lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ > + return b; > +} > + > + > +static void freeblock (Memcontrol *mc, void *block, size_t size) { > + if (block) { > + lua_assert(checkblocksize(block, size)); > + block = checkblock(block, size); > + fillmem(block, size+HEADER+MARKSIZE); /* erase block */ > + free(block); /* free original block */ > + mc->numblocks--; > + mc->total -= size; > + } > +} > + > + > +void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { > + Memcontrol *mc = cast(Memcontrol *, ud); > + lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); > + if (size == 0) { > + freeblock(mc, block, oldsize); > + return NULL; > + } > + else if (size > oldsize && mc->total+size-oldsize > mc->memlimit) > + return NULL; /* to test memory allocation errors */ > + else { > + void *newblock; > + int i; > + size_t realsize = HEADER+size+MARKSIZE; > + size_t commonsize = (oldsize < size) ? oldsize : size; > + if (realsize < size) return NULL; /* overflow! */ > + newblock = malloc(realsize); /* alloc a new block */ > + if (newblock == NULL) return NULL; > + if (block) { > + memcpy(cast(char *, newblock)+HEADER, block, commonsize); > + freeblock(mc, block, oldsize); /* erase (and check) old copy */ > + } > + /* initialize new part of the block with something `weird' */ > + fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); > + mc->total += size; > + if (mc->total > mc->maxmem) > + mc->maxmem = mc->total; > + mc->numblocks++; > + setsize(newblock, size); > + for (i=0;i<MARKSIZE;i++) > + *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); > + return cast(char *, newblock)+HEADER; > + } > +} > + > + > +/* }====================================================================== */ > + > + > + > +/* > +** {====================================================== > +** Functions to check memory consistency > +** ======================================================= > +*/ > + > +static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { > + if (isdead(g,t)) return 0; > + if (g->gcstate == GCSpropagate) > + return !isblack(f) || !iswhite(t); > + else if (g->gcstate == GCSfinalize) > + return iswhite(f); > + else > + return 1; > +} > + > + > +static void printobj (global_State *g, GCObject *o) { > + int i = 0; > + GCObject *p; > + for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++; > + if (p == NULL) i = -1; > + printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o, > + isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked); > +} > + > + > +static int testobjref (global_State *g, GCObject *f, GCObject *t) { > + int r = testobjref1(g,f,t); > + if (!r) { > + printf("%d(%02X) - ", g->gcstate, g->currentwhite); > + printobj(g, f); > + printf("\t-> "); > + printobj(g, t); > + printf("\n"); > + } > + return r; > +} > + > +#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) > + > +#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \ > + ((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t)))) > + > + > + > +static void checktable (global_State *g, Table *h) { > + int i; > + int weakkey = 0; > + int weakvalue = 0; > + const TValue *mode; > + GCObject *hgc = obj2gco(h); > + if (h->metatable) > + checkobjref(g, hgc, h->metatable); > + mode = gfasttm(g, h->metatable, TM_MODE); > + if (mode && ttisstring(mode)) { /* is there a weak mode? */ > + weakkey = (strchr(svalue(mode), 'k') != NULL); > + weakvalue = (strchr(svalue(mode), 'v') != NULL); > + } > + i = h->sizearray; > + while (i--) > + checkvalref(g, hgc, &h->array[i]); > + i = sizenode(h); > + while (i--) { > + Node *n = gnode(h, i); > + if (!ttisnil(gval(n))) { > + lua_assert(!ttisnil(gkey(n))); > + checkvalref(g, hgc, gkey(n)); > + checkvalref(g, hgc, gval(n)); > + } > + } > +} > + > + > +/* > +** All marks are conditional because a GC may happen while the > +** prototype is still being created > +*/ > +static void checkproto (global_State *g, Proto *f) { > + int i; > + GCObject *fgc = obj2gco(f); > + if (f->source) checkobjref(g, fgc, f->source); > + for (i=0; i<f->sizek; i++) { > + if (ttisstring(f->k+i)) > + checkobjref(g, fgc, rawtsvalue(f->k+i)); > + } > + for (i=0; i<f->sizeupvalues; i++) { > + if (f->upvalues[i]) > + checkobjref(g, fgc, f->upvalues[i]); > + } > + for (i=0; i<f->sizep; i++) { > + if (f->p[i]) > + checkobjref(g, fgc, f->p[i]); > + } > + for (i=0; i<f->sizelocvars; i++) { > + if (f->locvars[i].varname) > + checkobjref(g, fgc, f->locvars[i].varname); > + } > +} > + > + > + > +static void checkclosure (global_State *g, Closure *cl) { > + GCObject *clgc = obj2gco(cl); > + checkobjref(g, clgc, cl->l.env); > + if (cl->c.isC) { > + int i; > + for (i=0; i<cl->c.nupvalues; i++) > + checkvalref(g, clgc, &cl->c.upvalue[i]); > + } > + else { > + int i; > + lua_assert(cl->l.nupvalues == cl->l.p->nups); > + checkobjref(g, clgc, cl->l.p); > + for (i=0; i<cl->l.nupvalues; i++) { > + if (cl->l.upvals[i]) { > + lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL); > + checkobjref(g, clgc, cl->l.upvals[i]); > + } > + } > + } > +} > + > + > +static void checkstack (global_State *g, lua_State *L1) { > + StkId o; > + CallInfo *ci; > + GCObject *uvo; > + lua_assert(!isdead(g, obj2gco(L1))); > + for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) { > + UpVal *uv = gco2uv(uvo); > + lua_assert(uv->v != &uv->u.value); /* must be open */ > + lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ > + } > + checkliveness(g, gt(L1)); > + if (L1->base_ci) { > + for (ci = L1->base_ci; ci <= L1->ci; ci++) { > + lua_assert(ci->top <= L1->stack_last); > + lua_assert(lua_checkpc(L1, ci)); > + } > + } > + else lua_assert(L1->size_ci == 0); > + if (L1->stack) { > + for (o = L1->stack; o < L1->top; o++) > + checkliveness(g, o); > + } > + else lua_assert(L1->stacksize == 0); > +} > + > + > +static void checkobject (global_State *g, GCObject *o) { > + if (isdead(g, o)) > +/* lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/ > +{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep)) > +printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked); > +} > + else { > + if (g->gcstate == GCSfinalize) > + lua_assert(iswhite(o)); > + switch (o->gch.tt) { > + case LUA_TUPVAL: { > + UpVal *uv = gco2uv(o); > + lua_assert(uv->v == &uv->u.value); /* must be closed */ > + lua_assert(!isgray(o)); /* closed upvalues are never gray */ > + checkvalref(g, o, uv->v); > + break; > + } > + case LUA_TUSERDATA: { > + Table *mt = gco2u(o)->metatable; > + if (mt) checkobjref(g, o, mt); > + break; > + } > + case LUA_TTABLE: { > + checktable(g, gco2h(o)); > + break; > + } > + case LUA_TTHREAD: { > + checkstack(g, gco2th(o)); > + break; > + } > + case LUA_TFUNCTION: { > + checkclosure(g, gco2cl(o)); > + break; > + } > + case LUA_TPROTO: { > + checkproto(g, gco2p(o)); > + break; > + } > + default: lua_assert(0); > + } > + } > +} > + > + > +int lua_checkpc (lua_State *L, pCallInfo ci) { > + if (ci == L->base_ci || !f_isLua(ci)) return 1; > + else { > + Proto *p = ci_func(ci)->l.p; > + if (ci < L->ci) > + return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; > + else > + return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; > + } > +} > + > + > +int lua_checkmemory (lua_State *L) { > + global_State *g = G(L); > + GCObject *o; > + UpVal *uv; > + checkstack(g, g->mainthread); > + for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next) > + checkobject(g, o); > + for (o = o->gch.next; o != NULL; o = o->gch.next) { > + lua_assert(o->gch.tt == LUA_TUSERDATA); > + checkobject(g, o); > + } > + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { > + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); > + lua_assert(uv->v != &uv->u.value); /* must be open */ > + lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */ > + checkvalref(g, obj2gco(uv), uv->v); > + } > + return 0; > +} > + > +/* }====================================================== */ > + > + > + > +/* > +** {====================================================== > +** Disassembler > +** ======================================================= > +*/ > + > + > +static char *buildop (Proto *p, int pc, char *buff) { > + Instruction i = p->code[pc]; > + OpCode o = GET_OPCODE(i); > + const char *name = luaP_opnames[o]; > + int line = getline(p, pc); > + sprintf(buff, "(%4d) %4d - ", line, pc); > + switch (getOpMode(o)) { > + case iABC: > + sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, > + GETARG_A(i), GETARG_B(i), GETARG_C(i)); > + break; > + case iABx: > + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); > + break; > + case iAsBx: > + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); > + break; > + } > + return buff; > +} > + > + > +#if 0 > +void luaI_printcode (Proto *pt, int size) { > + int pc; > + for (pc=0; pc<size; pc++) { > + char buff[100]; > + printf("%s\n", buildop(pt, pc, buff)); > + } > + printf("-------\n"); > +} > +#endif > + > + > +static int listcode (lua_State *L) { > + int pc; > + Proto *p; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + lua_newtable(L); > + setnameval(L, "maxstack", p->maxstacksize); > + setnameval(L, "numparams", p->numparams); > + for (pc=0; pc<p->sizecode; pc++) { > + char buff[100]; > + lua_pushinteger(L, pc+1); > + lua_pushstring(L, buildop(p, pc, buff)); > + lua_settable(L, -3); > + } > + return 1; > +} > + > + > +static int listk (lua_State *L) { > + Proto *p; > + int i; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + lua_createtable(L, p->sizek, 0); > + for (i=0; i<p->sizek; i++) { > + luaA_pushobject(L, p->k+i); > + lua_rawseti(L, -2, i+1); > + } > + return 1; > +} > + > + > +static int listlocals (lua_State *L) { > + Proto *p; > + int pc = luaL_checkint(L, 2) - 1; > + int i = 0; > + const char *name; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) > + lua_pushstring(L, name); > + return i-1; > +} > + > +/* }====================================================== */ > + > + > + > + > +static int get_limits (lua_State *L) { > + lua_createtable(L, 0, 5); > + setnameval(L, "BITS_INT", LUAI_BITSINT); > + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); > + setnameval(L, "MAXVARS", LUAI_MAXVARS); > + setnameval(L, "MAXSTACK", MAXSTACK); > + setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES); > + setnameval(L, "NUM_OPCODES", NUM_OPCODES); > + return 1; > +} > + > + > +static int mem_query (lua_State *L) { > + if (lua_isnone(L, 1)) { > + lua_pushinteger(L, memcontrol.total); > + lua_pushinteger(L, memcontrol.numblocks); > + lua_pushinteger(L, memcontrol.maxmem); > + return 3; > + } > + else { > + memcontrol.memlimit = luaL_checkint(L, 1); > + return 0; > + } > +} > + > + > +static int settrick (lua_State *L) { > + Trick = lua_tointeger(L, 1); > + return 0; > +} > + > + > +/*static int set_gcstate (lua_State *L) { > + static const char *const state[] = {"propagate", "sweep", "finalize"}; > + return 0; > +}*/ > + > + > +static int get_gccolor (lua_State *L) { > + TValue *o; > + luaL_checkany(L, 1); > + o = obj_at(L, 1); > + if (!iscollectable(o)) > + lua_pushstring(L, "no collectable"); > + else > + lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : > + isblack(gcvalue(o)) ? "black" : "grey"); > + return 1; > +} > + > + > +static int gcstate (lua_State *L) { > + switch(G(L)->gcstate) { > + case GCSpropagate: lua_pushstring(L, "propagate"); break; > + case GCSsweepstring: lua_pushstring(L, "sweep strings"); break; > + case GCSsweep: lua_pushstring(L, "sweep"); break; > + case GCSfinalize: lua_pushstring(L, "finalize"); break; > + } > + return 1; > +} > + > + > +static int hash_query (lua_State *L) { > + if (lua_isnone(L, 2)) { > + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); > + lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash); > + } > + else { > + TValue *o = obj_at(L, 1); > + Table *t; > + luaL_checktype(L, 2, LUA_TTABLE); > + t = hvalue(obj_at(L, 2)); > + lua_pushinteger(L, luaH_mainposition(t, o) - t->node); > + } > + return 1; > +} > + > + > +static int stacklevel (lua_State *L) { > + unsigned long a = 0; > + lua_pushinteger(L, (L->top - L->stack)); > + lua_pushinteger(L, (L->stack_last - L->stack)); > + lua_pushinteger(L, (L->ci - L->base_ci)); > + lua_pushinteger(L, (L->end_ci - L->base_ci)); > + lua_pushinteger(L, (unsigned long)&a); > + return 5; > +} > + > + > +static int table_query (lua_State *L) { > + const Table *t; > + int i = luaL_optint(L, 2, -1); > + luaL_checktype(L, 1, LUA_TTABLE); > + t = hvalue(obj_at(L, 1)); > + if (i == -1) { > + lua_pushinteger(L, t->sizearray); > + lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t)); > + lua_pushinteger(L, t->lastfree - t->node); > + } > + else if (i < t->sizearray) { > + lua_pushinteger(L, i); > + luaA_pushobject(L, &t->array[i]); > + lua_pushnil(L); > + } > + else if ((i -= t->sizearray) < sizenode(t)) { > + if (!ttisnil(gval(gnode(t, i))) || > + ttisnil(gkey(gnode(t, i))) || > + ttisnumber(gkey(gnode(t, i)))) { > + luaA_pushobject(L, key2tval(gnode(t, i))); > + } > + else > + lua_pushliteral(L, "<undef>"); > + luaA_pushobject(L, gval(gnode(t, i))); > + if (gnext(&t->node[i])) > + lua_pushinteger(L, gnext(&t->node[i]) - t->node); > + else > + lua_pushnil(L); > + } > + return 3; > +} > + > + > +static int string_query (lua_State *L) { > + stringtable *tb = &G(L)->strt; > + int s = luaL_optint(L, 2, 0) - 1; > + if (s==-1) { > + lua_pushinteger(L ,tb->nuse); > + lua_pushinteger(L ,tb->size); > + return 2; > + } > + else if (s < tb->size) { > + GCObject *ts; > + int n = 0; > + for (ts = tb->hash[s]; ts; ts = ts->gch.next) { > + setsvalue2s(L, L->top, gco2ts(ts)); > + incr_top(L); > + n++; > + } > + return n; > + } > + return 0; > +} > + > + > +static int tref (lua_State *L) { > + int level = lua_gettop(L); > + int lock = luaL_optint(L, 2, 1); > + luaL_checkany(L, 1); > + lua_pushvalue(L, 1); > + lua_pushinteger(L, lua_ref(L, lock)); > + lua_assert(lua_gettop(L) == level+1); /* +1 for result */ > + return 1; > +} > + > +static int getref (lua_State *L) { > + int level = lua_gettop(L); > + lua_getref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) == level+1); > + return 1; > +} > + > +static int unref (lua_State *L) { > + int level = lua_gettop(L); > + lua_unref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) == level); > + return 0; > +} > + > + > +static int upvalue (lua_State *L) { > + int n = luaL_checkint(L, 2); > + luaL_checktype(L, 1, LUA_TFUNCTION); > + if (lua_isnone(L, 3)) { > + const char *name = lua_getupvalue(L, 1, n); > + if (name == NULL) return 0; > + lua_pushstring(L, name); > + return 2; > + } > + else { > + const char *name = lua_setupvalue(L, 1, n); > + lua_pushstring(L, name); > + return 1; > + } > +} > + > + > +static int newuserdata (lua_State *L) { > + size_t size = luaL_checkint(L, 1); > + char *p = cast(char *, lua_newuserdata(L, size)); > + while (size--) *p++ = '\0'; > + return 1; > +} > + > + > +static int pushuserdata (lua_State *L) { > + lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); > + return 1; > +} > + > + > +static int udataval (lua_State *L) { > + lua_pushinteger(L, cast(long, lua_touserdata(L, 1))); > + return 1; > +} > + > + > +static int doonnewstack (lua_State *L) { > + lua_State *L1 = lua_newthread(L); > + size_t l; > + const char *s = luaL_checklstring(L, 1, &l); > + int status = luaL_loadbuffer(L1, s, l, s); > + if (status == 0) > + status = lua_pcall(L1, 0, 0, 0); > + lua_pushinteger(L, status); > + return 1; > +} > + > + > +static int s2d (lua_State *L) { > + lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); > + return 1; > +} > + > + > +static int d2s (lua_State *L) { > + double d = luaL_checknumber(L, 1); > + lua_pushlstring(L, cast(char *, &d), sizeof(d)); > + return 1; > +} > + > + > +static int num2int (lua_State *L) { > + lua_pushinteger(L, lua_tointeger(L, 1)); > + return 1; > +} > + > + > +static int newstate (lua_State *L) { > + void *ud; > + lua_Alloc f = lua_getallocf(L, &ud); > + lua_State *L1 = lua_newstate(f, ud); > + if (L1) > + lua_pushinteger(L, (unsigned long)L1); > + else > + lua_pushnil(L); > + return 1; > +} > + > + > +static int loadlib (lua_State *L) { > + static const luaL_Reg libs[] = { > + {"baselibopen", luaopen_base}, > + {"dblibopen", luaopen_debug}, > + {"iolibopen", luaopen_io}, > + {"mathlibopen", luaopen_math}, > + {"strlibopen", luaopen_string}, > + {"tablibopen", luaopen_table}, > + {"packageopen", luaopen_package}, > + {NULL, NULL} > + }; > + lua_State *L1 = cast(lua_State *, > + cast(unsigned long, luaL_checknumber(L, 1))); > + lua_pushvalue(L1, LUA_GLOBALSINDEX); > + luaL_register(L1, NULL, libs); > + return 0; > +} > + > +static int closestate (lua_State *L) { > + lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1))); > + lua_close(L1); > + return 0; > +} > + > +static int doremote (lua_State *L) { > + lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); > + size_t lcode; > + const char *code = luaL_checklstring(L, 2, &lcode); > + int status; > + lua_settop(L1, 0); > + status = luaL_loadbuffer(L1, code, lcode, code); > + if (status == 0) > + status = lua_pcall(L1, 0, LUA_MULTRET, 0); > + if (status != 0) { > + lua_pushnil(L); > + lua_pushinteger(L, status); > + lua_pushstring(L, lua_tostring(L1, -1)); > + return 3; > + } > + else { > + int i = 0; > + while (!lua_isnone(L1, ++i)) > + lua_pushstring(L, lua_tostring(L1, i)); > + lua_pop(L1, i-1); > + return i-1; > + } > +} > + > + > +static int log2_aux (lua_State *L) { > + lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1))); > + return 1; > +} > + > +static int int2fb_aux (lua_State *L) { > + int b = luaO_int2fb(luaL_checkint(L, 1)); > + lua_pushinteger(L, b); > + lua_pushinteger(L, luaO_fb2int(b)); > + return 2; > +} > + > + > + > +/* > +** {====================================================== > +** function to test the API with C. It interprets a kind of assembler > +** language with calls to the API, so the test can be driven by Lua code > +** ======================================================= > +*/ > + > +static const char *const delimits = " \t\n,;"; > + > +static void skip (const char **pc) { > + while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; > +} > + > +static int getnum_aux (lua_State *L, const char **pc) { > + int res = 0; > + int sig = 1; > + skip(pc); > + if (**pc == '.') { > + res = cast_int(lua_tonumber(L, -1)); > + lua_pop(L, 1); > + (*pc)++; > + return res; > + } > + else if (**pc == '-') { > + sig = -1; > + (*pc)++; > + } > + while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0'; > + return sig*res; > +} > + > +static const char *getname_aux (char *buff, const char **pc) { > + int i = 0; > + skip(pc); > + while (**pc != '\0' && !strchr(delimits, **pc)) > + buff[i++] = *(*pc)++; > + buff[i] = '\0'; > + return buff; > +} > + > + > +static int getindex_aux (lua_State *L, const char **pc) { > + skip(pc); > + switch (*(*pc)++) { > + case 'R': return LUA_REGISTRYINDEX; > + case 'G': return LUA_GLOBALSINDEX; > + case 'E': return LUA_ENVIRONINDEX; > + case 'U': return lua_upvalueindex(getnum_aux(L, pc)); > + default: (*pc)--; return getnum_aux(L, pc); > + } > +} > + > +#define EQ(s1) (strcmp(s1, inst) == 0) > + > +#define getnum (getnum_aux(L, &pc)) > +#define getname (getname_aux(buff, &pc)) > +#define getindex (getindex_aux(L, &pc)) > + > + > +static int testC (lua_State *L) { > + char buff[30]; > + lua_State *L1; > + const char *pc; > + if (lua_isnumber(L, 1)) { > + L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); > + pc = luaL_checkstring(L, 2); > + } > + else { > + L1 = L; > + pc = luaL_checkstring(L, 1); > + } > + for (;;) { > + const char *inst = getname; > + if EQ("") return 0; > + else if EQ("isnumber") { > + lua_pushinteger(L1, lua_isnumber(L1, getindex)); > + } > + else if EQ("isstring") { > + lua_pushinteger(L1, lua_isstring(L1, getindex)); > + } > + else if EQ("istable") { > + lua_pushinteger(L1, lua_istable(L1, getindex)); > + } > + else if EQ("iscfunction") { > + lua_pushinteger(L1, lua_iscfunction(L1, getindex)); > + } > + else if EQ("isfunction") { > + lua_pushinteger(L1, lua_isfunction(L1, getindex)); > + } > + else if EQ("isuserdata") { > + lua_pushinteger(L1, lua_isuserdata(L1, getindex)); > + } > + else if EQ("isudataval") { > + lua_pushinteger(L1, lua_islightuserdata(L1, getindex)); > + } > + else if EQ("isnil") { > + lua_pushinteger(L1, lua_isnil(L1, getindex)); > + } > + else if EQ("isnull") { > + lua_pushinteger(L1, lua_isnone(L1, getindex)); > + } > + else if EQ("tonumber") { > + lua_pushnumber(L1, lua_tonumber(L1, getindex)); > + } > + else if EQ("tostring") { > + const char *s = lua_tostring(L1, getindex); > + lua_pushstring(L1, s); > + } > + else if EQ("objsize") { > + lua_pushinteger(L1, lua_objlen(L1, getindex)); > + } > + else if EQ("tocfunction") { > + lua_pushcfunction(L1, lua_tocfunction(L1, getindex)); > + } > + else if EQ("return") { > + return getnum; > + } > + else if EQ("gettop") { > + lua_pushinteger(L1, lua_gettop(L1)); > + } > + else if EQ("settop") { > + lua_settop(L1, getnum); > + } > + else if EQ("pop") { > + lua_pop(L1, getnum); > + } > + else if EQ("pushnum") { > + lua_pushinteger(L1, getnum); > + } > + else if EQ("pushstring") { > + lua_pushstring(L1, getname); > + } > + else if EQ("pushnil") { > + lua_pushnil(L1); > + } > + else if EQ("pushbool") { > + lua_pushboolean(L1, getnum); > + } > + else if EQ("newuserdata") { > + lua_newuserdata(L1, getnum); > + } > + else if EQ("tobool") { > + lua_pushinteger(L1, lua_toboolean(L1, getindex)); > + } > + else if EQ("pushvalue") { > + lua_pushvalue(L1, getindex); > + } > + else if EQ("pushcclosure") { > + lua_pushcclosure(L1, testC, getnum); > + } > + else if EQ("remove") { > + lua_remove(L1, getnum); > + } > + else if EQ("insert") { > + lua_insert(L1, getnum); > + } > + else if EQ("replace") { > + lua_replace(L1, getindex); > + } > + else if EQ("gettable") { > + lua_gettable(L1, getindex); > + } > + else if EQ("settable") { > + lua_settable(L1, getindex); > + } > + else if EQ("next") { > + lua_next(L1, -2); > + } > + else if EQ("concat") { > + lua_concat(L1, getnum); > + } > + else if EQ("lessthan") { > + int a = getindex; > + lua_pushboolean(L1, lua_lessthan(L1, a, getindex)); > + } > + else if EQ("equal") { > + int a = getindex; > + lua_pushboolean(L1, lua_equal(L1, a, getindex)); > + } > + else if EQ("rawcall") { > + int narg = getnum; > + int nres = getnum; > + lua_call(L1, narg, nres); > + } > + else if EQ("call") { > + int narg = getnum; > + int nres = getnum; > + lua_pcall(L1, narg, nres, 0); > + } > + else if EQ("loadstring") { > + size_t sl; > + const char *s = luaL_checklstring(L1, getnum, &sl); > + luaL_loadbuffer(L1, s, sl, s); > + } > + else if EQ("loadfile") { > + luaL_loadfile(L1, luaL_checkstring(L1, getnum)); > + } > + else if EQ("setmetatable") { > + lua_setmetatable(L1, getindex); > + } > + else if EQ("getmetatable") { > + if (lua_getmetatable(L1, getindex) == 0) > + lua_pushnil(L1); > + } > + else if EQ("type") { > + lua_pushstring(L1, luaL_typename(L1, getnum)); > + } > + else if EQ("getn") { > + int i = getindex; > + lua_pushinteger(L1, luaL_getn(L1, i)); > + } > +#ifndef luaL_setn > + else if EQ("setn") { > + int i = getindex; > + int n = cast_int(lua_tonumber(L1, -1)); > + luaL_setn(L1, i, n); > + lua_pop(L1, 1); > + } > +#endif > + else if EQ("throw") { > +#if defined(__cplusplus) > +static struct X { int x; } x; > + throw x; > +#else > + luaL_error(L1, "C++"); > +#endif > + break; > + } > + else luaL_error(L, "unknown instruction %s", buff); > + } > + return 0; > +} > + > +/* }====================================================== */ > + > + > +/* > +** {====================================================== > +** tests for yield inside hooks > +** ======================================================= > +*/ > + > +static void yieldf (lua_State *L, lua_Debug *ar) { > + lua_yield(L, 0); > +} > + > +static int setyhook (lua_State *L) { > + if (lua_isnoneornil(L, 1)) > + lua_sethook(L, NULL, 0, 0); /* turn off hooks */ > + else { > + const char *smask = luaL_checkstring(L, 1); > + int count = luaL_optint(L, 2, 0); > + int mask = 0; > + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; > + if (count > 0) mask |= LUA_MASKCOUNT; > + lua_sethook(L, yieldf, mask, count); > + } > + return 0; > +} > + > + > +static int coresume (lua_State *L) { > + int status; > + lua_State *co = lua_tothread(L, 1); > + luaL_argcheck(L, co, 1, "coroutine expected"); > + status = lua_resume(co, 0); > + if (status != 0) { > + lua_pushboolean(L, 0); > + lua_insert(L, -2); > + return 2; /* return false + error message */ > + } > + else { > + lua_pushboolean(L, 1); > + return 1; > + } > +} > + > +/* }====================================================== */ > + > + > + > +/* > +** {====================================================== > +** tests auxlib functions > +** ======================================================= > +*/ > + > +static int auxgsub (lua_State *L) { > + const char *s1 = luaL_checkstring(L, 1); > + const char *s2 = luaL_checkstring(L, 2); > + const char *s3 = luaL_checkstring(L, 3); > + lua_settop(L, 3); > + luaL_gsub(L, s1, s2, s3); > + lua_assert(lua_gettop(L) == 4); > + return 1; > +} > + > + > +/* }====================================================== */ > + > + > + > +static const struct luaL_Reg tests_funcs[] = { > + {"checkmemory", lua_checkmemory}, > + {"closestate", closestate}, > + {"d2s", d2s}, > + {"doonnewstack", doonnewstack}, > + {"doremote", doremote}, > + {"gccolor", get_gccolor}, > + {"gcstate", gcstate}, > + {"getref", getref}, > + {"gsub", auxgsub}, > + {"hash", hash_query}, > + {"int2fb", int2fb_aux}, > + {"limits", get_limits}, > + {"listcode", listcode}, > + {"listk", listk}, > + {"listlocals", listlocals}, > + {"loadlib", loadlib}, > + {"log2", log2_aux}, > + {"newstate", newstate}, > + {"newuserdata", newuserdata}, > + {"num2int", num2int}, > + {"pushuserdata", pushuserdata}, > + {"querystr", string_query}, > + {"querytab", table_query}, > + {"ref", tref}, > + {"resume", coresume}, > + {"s2d", s2d}, > + {"setyhook", setyhook}, > + {"stacklevel", stacklevel}, > + {"testC", testC}, > + {"totalmem", mem_query}, > + {"trick", settrick}, > + {"udataval", udataval}, > + {"unref", unref}, > + {"upvalue", upvalue}, > + {NULL, NULL} > +}; > + > + > +int luaB_opentests (lua_State *L) { > + void *ud; > + lua_assert(lua_getallocf(L, &ud) == debug_realloc); > + lua_assert(ud == cast(void *, &memcontrol)); > + lua_setallocf(L, lua_getallocf(L, NULL), ud); > + lua_state = L; /* keep first state to be opened */ > + luaL_register(L, "T", tests_funcs); > + return 0; > +} > + > + > +#undef main > +int main (int argc, char *argv[]) { > + int ret; > + char *limit = getenv("MEMLIMIT"); > + if (limit) > + memcontrol.memlimit = strtoul(limit, NULL, 10); > + ret = l_main(argc, argv); > + lua_assert(memcontrol.numblocks == 0); > + lua_assert(memcontrol.total == 0); > + return ret; > +} > + > +#endif > diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.h b/test/PUC-Lua-5.1-tests/etc/ltests.h > new file mode 100644 > index 0000000..e570212 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/etc/ltests.h > @@ -0,0 +1,92 @@ > +/* > +** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp $ > +** Internal Header for Debugging of the Lua Implementation > +** See Copyright Notice in lua.h > +*/ > + > +#ifndef ltests_h > +#define ltests_h > + > + > +#include <stdlib.h> > + > + > +#define LUA_DEBUG > + > +#undef NDEBUG > +#include <assert.h> > +#define lua_assert(c) assert(c) > + > + > +/* to avoid warnings, and to make sure value is really unused */ > +#define UNUSED(x) (x=0, (void)(x)) > + > + > +/* memory allocator control variables */ > +typedef struct Memcontrol { > + unsigned long numblocks; > + unsigned long total; > + unsigned long maxmem; > + unsigned long memlimit; > +} Memcontrol; > + > +LUAI_DATA Memcontrol memcontrol; > + > + > +/* > +** generic variable for debug tricks > +*/ > +LUAI_DATA int Trick; > + > + > +void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize); > + > +#ifdef lua_c > +#define luaL_newstate() lua_newstate(debug_realloc, &memcontrol) > +#endif > + > + > +typedef struct CallInfo *pCallInfo; > + > +int lua_checkmemory (lua_State *L); > +int lua_checkpc (lua_State *L, pCallInfo ci); > + > + > +/* test for lock/unlock */ > +#undef luai_userstateopen > +#undef luai_userstatethread > +#undef lua_lock > +#undef lua_unlock > +#undef LUAI_EXTRASPACE > + > +struct L_EXTRA { int lock; int *plock; }; > +#define LUAI_EXTRASPACE sizeof(struct L_EXTRA) > +#define getlock(l) (cast(struct L_EXTRA *, l) - 1) > +#define luai_userstateopen(l) \ > + (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) > +#define luai_userstatethread(l,l1) (getlock(l1)->plock = getlock(l)->plock) > +#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) > +#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) > + > + > +int luaB_opentests (lua_State *L); > + > +#ifdef lua_c > +#define luaL_openlibs(L) { (luaL_openlibs)(L); luaB_opentests(L); } > +#endif > + > + > + > +/* real main will be defined at `ltests.c' */ > +int l_main (int argc, char *argv[]); > +#define main l_main > + > + > + > +/* change some sizes to give some bugs a chance */ > + > +#undef LUAL_BUFFERSIZE > +#define LUAL_BUFFERSIZE 27 > +#define MINSTRTABSIZE 2 > + > +#endif > diff --git a/test/PUC-Lua-5.1-tests/events.lua b/test/PUC-Lua-5.1-tests/events.lua > new file mode 100644 > index 0000000..5234b00 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/events.lua > @@ -0,0 +1,360 @@ > +print('testing metatables') > + > +X = 20; B = 30 > + > +setfenv(1, setmetatable({}, {__index=_G})) > + > +collectgarbage() > + > +X = X+10 > +assert(X == 30 and _G.X == 20) > +B = false > +assert(B == false) > +B = nil > +assert(B == 30) > + > +assert(getmetatable{} == nil) > +assert(getmetatable(4) == nil) > +assert(getmetatable(nil) == nil) > +a={}; setmetatable(a, {__metatable = "xuxu", > + __tostring=function(x) return x.name end}) > +assert(getmetatable(a) == "xuxu") > +assert(tostring(a) == nil) > +-- cannot change a protected metatable > +assert(pcall(setmetatable, a, {}) == false) > +a.name = "gororoba" > +assert(tostring(a) == "gororoba") > + > +local a, t = {10,20,30; x="10", y="20"}, {} > +assert(setmetatable(a,t) == a) > +assert(getmetatable(a) == t) > +assert(setmetatable(a,nil) == a) > +assert(getmetatable(a) == nil) > +assert(setmetatable(a,t) == a) > + > + > +function f (t, i, e) > + assert(not e) > + local p = rawget(t, "parent") > + return (p and p[i]+3), "dummy return" > +end > + > +t.__index = f > + > +a.parent = {z=25, x=12, [4] = 24} > +assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") > + > +collectgarbage() > + > +a = setmetatable({}, t) > +function f(t, i, v) rawset(t, i, v-3) end > +t.__newindex = f > +a[1] = 30; a.x = "101"; a[5] = 200 > +assert(a[1] == 27 and a.x == 98 and a[5] == 197) > + > + > +local c = {} > +a = setmetatable({}, t) > +t.__newindex = c > +a[1] = 10; a[2] = 20; a[3] = 90 > +assert(c[1] == 10 and c[2] == 20 and c[3] == 90) > + > + > +do > + local a; > + a = setmetatable({}, {__index = setmetatable({}, > + {__index = setmetatable({}, > + {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) > + a[0] = 20 > + for i=0,10 do > + assert(a[i*3] == 20 + i*4) > + end > +end > + > + > +do -- newindex > + local foi > + local a = {} > + for i=1,10 do a[i] = 0; a['a'..i] = 0; end > + setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) > + foi = false; a[1]=0; assert(not foi) > + foi = false; a['a1']=0; assert(not foi) > + foi = false; a['a11']=0; assert(foi) > + foi = false; a[11]=0; assert(foi) > + foi = false; a[1]=nil; assert(not foi) > + foi = false; a[1]=nil; assert(foi) > +end > + > + > +function f (t, ...) return t, {...} end > +t.__call = f > + > +do > + local x,y = a(unpack{'a', 1}) > + assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) > + x,y = a() > + assert(x==a and y[1]==nil) > +end > + > + > +local b = setmetatable({}, t) > +setmetatable(b,t) > + > +function f(op) > + return function (...) cap = {[0] = op, ...} ; return (...) end > +end > +t.__add = f("add") > +t.__sub = f("sub") > +t.__mul = f("mul") > +t.__div = f("div") > +t.__mod = f("mod") > +t.__unm = f("unm") > +t.__pow = f("pow") > + > +assert(b+5 == b) > +assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) > +assert(b+'5' == b) > +assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) > +assert(5+b == 5) > +assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) > +assert('5'+b == '5') > +assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) > +b=b-3; assert(getmetatable(b) == t) > +assert(5-a == 5) > +assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) > +assert('5'-a == '5') > +assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) > +assert(a*a == a) > +assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) > +assert(a/0 == a) > +assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) > +assert(a%2 == a) > +assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) > +assert(-a == a) > +assert(cap[0] == "unm" and cap[1] == a) > +assert(a^4 == a) > +assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) > +assert(a^'4' == a) > +assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) > +assert(4^a == 4) > +assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) > +assert('4'^a == '4') > +assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) > + > + > +t = {} > +t.__lt = function (a,b,c) > + collectgarbage() > + assert(c == nil) > + if type(a) == 'table' then a = a.x end > + if type(b) == 'table' then b = b.x end > + return a<b, "dummy" > +end > + > +function Op(x) return setmetatable({x=x}, t) end > + > +local function test () > + assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) > + assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) > + assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) > + assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) > + assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) > + assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) > + assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) > + assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) > +end > + > +test() > + > +t.__le = function (a,b,c) > + assert(c == nil) > + if type(a) == 'table' then a = a.x end > + if type(b) == 'table' then b = b.x end > + return a<=b, "dummy" > +end > + > +test() -- retest comparisons, now using both `lt' and `le' > + > + > +-- test `partial order' > + > +local function Set(x) > + local y = {} > + for _,k in pairs(x) do y[k] = 1 end > + return setmetatable(y, t) > +end > + > +t.__lt = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] = nil > + end > + return next(b) ~= nil > +end > + > +t.__le = nil > + > +assert(Set{1,2,3} < Set{1,2,3,4}) > +assert(not(Set{1,2,3,4} < Set{1,2,3,4})) > +assert((Set{1,2,3,4} <= Set{1,2,3,4})) > +assert((Set{1,2,3,4} >= Set{1,2,3,4})) > +assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) > + > +t.__le = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + end > + return true > +end > + > +assert(not (Set{1,3} <= Set{3,5})) -- now its OK! > +assert(not(Set{1,3} <= Set{3,5})) > +assert(not(Set{1,3} >= Set{3,5})) > + > +t.__eq = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] = nil > + end > + return next(b) == nil > +end > + > +local s = Set{1,3,5} > +assert(s == Set{3,5,1}) > +assert(not rawequal(s, Set{3,5,1})) > +assert(rawequal(s, s)) > +assert(Set{1,3,5,1} == Set{3,5,1}) > +assert(Set{1,3,5} ~= Set{3,5,1,6}) > +t[Set{1,3,5}] = 1 > +assert(t[Set{1,3,5}] == nil) -- `__eq' is not valid for table accesses > + > + > +t.__concat = function (a,b,c) > + assert(c == nil) > + if type(a) == 'table' then a = a.val end > + if type(b) == 'table' then b = b.val end > + if A then return a..b > + else > + return setmetatable({val=a..b}, t) > + end > +end > + > +c = {val="c"}; setmetatable(c, t) > +d = {val="d"}; setmetatable(d, t) > + > +A = true > +assert(c..d == 'cd') > +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") > + > +A = false > +x = c..d > +assert(getmetatable(x) == t and x.val == 'cd') > +x = 0 .."a".."b"..c..d.."e".."f".."g" > +assert(x.val == "0abcdefg") > + > + > +-- test comparison compatibilities > +local t1, t2, c, d > +t1 = {}; c = {}; setmetatable(c, t1) > +d = {} > +t1.__eq = function () return true end > +t1.__lt = function () return true end > +assert(c ~= d and not pcall(function () return c < d end)) > +setmetatable(d, t1) > +assert(c == d and c < d and not(d <= c)) > +t2 = {} > +t2.__eq = t1.__eq > +t2.__lt = t1.__lt > +setmetatable(d, t2) > +assert(c == d and c < d and not(d <= c)) > + > + > + > +-- test for several levels of calls > +local i > +local tt = { > + __call = function (t, ...) > + i = i+1 > + if t.f then return t.f(...) > + else return {...} > + end > + end > +} > + > +local a = setmetatable({}, tt) > +local b = setmetatable({f=a}, tt) > +local c = setmetatable({f=b}, tt) > + > +i = 0 > +x = c(3,4,5) > +assert(i == 3 and x[1] == 3 and x[3] == 5) > + > + > +assert(_G.X == 20) > +assert(_G == getfenv(0)) > + > +print'+' > + > +local _g = _G > +setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end})) > + > +-- testing proxies > +assert(getmetatable(newproxy()) == nil) > +assert(getmetatable(newproxy(false)) == nil) > + > +local u = newproxy(true) > + > +getmetatable(u).__newindex = function (u,k,v) > + getmetatable(u)[k] = v > +end > + > +getmetatable(u).__index = function (u,k) > + return getmetatable(u)[k] > +end > + > +for i=1,10 do u[i] = i end > +for i=1,10 do assert(u[i] == i) end > + > +local k = newproxy(u) > +assert(getmetatable(k) == getmetatable(u)) > + > + > +a = {} > +rawset(a, "x", 1, 2, 3) > +assert(a.x == 1 and rawget(a, "x", 3) == 1) > + > +print '+' > + > +-- testing metatables for basic types > +mt = {} > +debug.setmetatable(10, mt) > +assert(getmetatable(-2) == mt) > +mt.__index = function (a,b) return a+b end > +assert((10)[3] == 13) > +assert((10)["3"] == 13) > +debug.setmetatable(23, nil) > +assert(getmetatable(-2) == nil) > + > +debug.setmetatable(true, mt) > +assert(getmetatable(false) == mt) > +mt.__index = function (a,b) return a or b end > +assert((true)[false] == true) > +assert((false)[false] == false) > +debug.setmetatable(false, nil) > +assert(getmetatable(true) == nil) > + > +debug.setmetatable(nil, mt) > +assert(getmetatable(nil) == mt) > +mt.__add = function (a,b) return (a or 0) + (b or 0) end > +assert(10 + nil == 10) > +assert(nil + 23 == 23) > +assert(nil + nil == 0) > +debug.setmetatable(nil, nil) > +assert(getmetatable(nil) == nil) > + > +debug.setmetatable(nil, {}) > + > + > +print 'OK' > + > +return 12 > diff --git a/test/PUC-Lua-5.1-tests/files.lua b/test/PUC-Lua-5.1-tests/files.lua > new file mode 100644 > index 0000000..903488c > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/files.lua > @@ -0,0 +1,324 @@ > + > +print('testing i/o') > + > +assert(io.input(io.stdin) == io.stdin) > +assert(io.output(io.stdout) == io.stdout) > + > + > +assert(type(io.input()) == "userdata" and io.type(io.output()) == "file") > +assert(io.type(8) == nil) > +local a = {}; setmetatable(a, {}) > +assert(io.type(a) == nil) > + > +local a,b,c = io.open('xuxu_nao_existe') > +assert(not a and type(b) == "string" and type(c) == "number") > + > +a,b,c = io.open('/a/b/c/d', 'w') > +assert(not a and type(b) == "string" and type(c) == "number") > + > +local file = os.tmpname() > +local otherfile = os.tmpname() > + > +assert(os.setlocale('C', 'all')) > + > +io.input(io.stdin); io.output(io.stdout); > + > +os.remove(file) > +assert(loadfile(file) == nil) > +assert(io.open(file) == nil) > +io.output(file) > +assert(io.output() ~= io.stdout) > + > +assert(io.output():seek() == 0) > +assert(io.write("alo alo")) > +assert(io.output():seek() == string.len("alo alo")) > +assert(io.output():seek("cur", -3) == string.len("alo alo")-3) > +assert(io.write("joao")) > +assert(io.output():seek("end") == string.len("alo joao")) > + > +assert(io.output():seek("set") == 0) > + > +assert(io.write('"�lo"', "{a}\n", "second line\n", "third line \n")) > +assert(io.write('�fourth_line')) > +io.output(io.stdout) > +collectgarbage() -- file should be closed by GC > +assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) > +print('+') > + > +-- test GC for files > +collectgarbage() > +for i=1,120 do > + for i=1,5 do > + io.input(file) > + assert(io.open(file, 'r')) > + io.lines(file) > + end > + collectgarbage() > +end > + > +assert(os.rename(file, otherfile)) > +assert(os.rename(file, otherfile) == nil) > + > +io.output(io.open(otherfile, "a")) > +assert(io.write("\n\n\t\t 3450\n")); > +io.close() > + > +-- test line generators > +assert(os.rename(otherfile, file)) > +io.output(otherfile) > +local f = io.lines(file) > +while f() do end; > +assert(not pcall(f)) -- read lines after EOF > +assert(not pcall(f)) -- read lines after EOF > +-- copy from file to otherfile > +for l in io.lines(file) do io.write(l, "\n") end > +io.close() > +-- copy from otherfile back to file > +local f = assert(io.open(otherfile)) > +assert(io.type(f) == "file") > +io.output(file) > +assert(io.output():read() == nil) > +for l in f:lines() do io.write(l, "\n") end > +assert(f:close()); io.close() > +assert(not pcall(io.close, f)) -- error trying to close again > +assert(tostring(f) == "file (closed)") > +assert(io.type(f) == "closed file") > +io.input(file) > +f = io.open(otherfile):lines() > +for l in io.lines() do assert(l == f()) end > +assert(os.remove(otherfile)) > + > +io.input(file) > +do -- test error returns > + local a,b,c = io.input():write("xuxu") > + assert(not a and type(b) == "string" and type(c) == "number") > +end > +assert(io.read(0) == "") -- not eof > +assert(io.read(5, '*l') == '"�lo"') > +assert(io.read(0) == "") > +assert(io.read() == "second line") > +local x = io.input():seek() > +assert(io.read() == "third line ") > +assert(io.input():seek("set", x)) > +assert(io.read('*l') == "third line ") > +assert(io.read(1) == "�") > +assert(io.read(string.len"fourth_line") == "fourth_line") > +assert(io.input():seek("cur", -string.len"fourth_line")) > +assert(io.read() == "fourth_line") > +assert(io.read() == "") -- empty line > +assert(io.read('*n') == 3450) > +assert(io.read(1) == '\n') > +assert(io.read(0) == nil) -- end of file > +assert(io.read(1) == nil) -- end of file > +assert(({io.read(1)})[2] == nil) > +assert(io.read() == nil) -- end of file > +assert(({io.read()})[2] == nil) > +assert(io.read('*n') == nil) -- end of file > +assert(({io.read('*n')})[2] == nil) > +assert(io.read('*a') == '') -- end of file (OK for `*a') > +assert(io.read('*a') == '') -- end of file (OK for `*a') > +collectgarbage() > +print('+') > +io.close(io.input()) > +assert(not pcall(io.read)) > + > +assert(os.remove(file)) > + > +local t = '0123456789' > +for i=1,12 do t = t..t; end > +assert(string.len(t) == 10*2^12) > + > +io.output(file) > +io.write("alo\n") > +io.close() > +assert(not pcall(io.write)) > +local f = io.open(file, "a") > +io.output(f) > +collectgarbage() > + > +assert(io.write(' ' .. t .. ' ')) > +assert(io.write(';', 'end of file\n')) > +f:flush(); io.flush() > +f:close() > +print('+') > + > +io.input(file) > +assert(io.read() == "alo") > +assert(io.read(1) == ' ') > +assert(io.read(string.len(t)) == t) > +assert(io.read(1) == ' ') > +assert(io.read(0)) > +assert(io.read('*a') == ';end of file\n') > +assert(io.read(0) == nil) > +assert(io.close(io.input())) > + > +assert(os.remove(file)) > +print('+') > + > +local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'" > +io.output(file) > +assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1))) > +io.close() > +assert(loadfile(file))() > +assert(x1 == x2) > +print('+') > +assert(os.remove(file)) > +assert(os.remove(file) == nil) > +assert(os.remove(otherfile) == nil) > + > +io.output(file) > +assert(io.write("qualquer coisa\n")) > +assert(io.write("mais qualquer coisa")) > +io.close() > +io.output(assert(io.open(otherfile, 'wb'))) > +assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0")) > +io.close() > + > +local filehandle = assert(io.open(file, 'r')) > +local otherfilehandle = assert(io.open(otherfile, 'rb')) > +assert(filehandle ~= otherfilehandle) > +assert(type(filehandle) == "userdata") > +assert(filehandle:read('*l') == "qualquer coisa") > +io.input(otherfilehandle) > +assert(io.read(string.len"outra coisa") == "outra coisa") > +assert(filehandle:read('*l') == "mais qualquer coisa") > +filehandle:close(); > +assert(type(filehandle) == "userdata") > +io.input(otherfilehandle) > +assert(io.read(4) == "\0\1\3\0") > +assert(io.read(3) == "\0\0\0") > +assert(io.read(0) == "") -- 255 is not eof > +assert(io.read(1) == "\255") > +assert(io.read('*a') == "\0") > +assert(not io.read(0)) > +assert(otherfilehandle == io.input()) > +otherfilehandle:close() > +assert(os.remove(file)) > +assert(os.remove(otherfile)) > +collectgarbage() > + > +io.output(file) > +io.write[[ > + 123.4 -56e-2 not a number > +second line > +third line > + > +and the rest of the file > +]] > +io.close() > +io.input(file) > +local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10) > +assert(io.close(io.input())) > +assert(_ == ' ' and __ == nil) > +assert(type(a) == 'number' and a==123.4 and b==-56e-2) > +assert(d=='second line' and e=='third line') > +assert(h==[[ > + > +and the rest of the file > +]]) > +assert(os.remove(file)) > +collectgarbage() > + > +-- testing buffers > +do > + local f = assert(io.open(file, "w")) > + local fr = assert(io.open(file, "r")) > + assert(f:setvbuf("full", 2000)) > + f:write("x") > + assert(fr:read("*all") == "") -- full buffer; output not written yet > + f:close() > + fr:seek("set") > + assert(fr:read("*all") == "x") -- `close' flushes it > + f = assert(io.open(file), "w") > + assert(f:setvbuf("no")) > + f:write("x") > + fr:seek("set") > + assert(fr:read("*all") == "x") -- no buffer; output is ready > + f:close() > + f = assert(io.open(file, "a")) > + assert(f:setvbuf("line")) > + f:write("x") > + fr:seek("set", 1) > + assert(fr:read("*all") == "") -- line buffer; no output without `\n' > + f:write("a\n") > + fr:seek("set", 1) > + assert(fr:read("*all") == "xa\n") -- now we have a whole line > + f:close(); fr:close() > +end > + > + > +-- testing large files (> BUFSIZ) > +io.output(file) > +for i=1,5001 do io.write('0123456789123') end > +io.write('\n12346') > +io.close() > +io.input(file) > +local x = io.read('*a') > +io.input():seek('set', 0) > +local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003) > +assert(x == y and string.len(x) == 5001*13 + 6) > +io.input():seek('set', 0) > +y = io.read() -- huge line > +assert(x == y..'\n'..io.read()) > +assert(io.read() == nil) > +io.close(io.input()) > +assert(os.remove(file)) > +x = nil; y = nil > + > +x, y = pcall(io.popen, "ls") > +if x then > + assert(y:read("*a")) > + assert(y:close()) > +else > + (Message or print)('\a\n >>> popen not available<<<\n\a') > +end > + > +print'+' > + > +local t = os.time() > +T = os.date("*t", t) > +loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and > + T.hour==%H and T.min==%M and T.sec==%S and > + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() > + > +assert(os.time(T) == t) > + > +T = os.date("!*t", t) > +loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and > + T.hour==%H and T.min==%M and T.sec==%S and > + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() > + > +do > + local T = os.date("*t") > + local t = os.time(T) > + assert(type(T.isdst) == 'boolean') > + T.isdst = nil > + local t1 = os.time(T) > + assert(t == t1) -- if isdst is absent uses correct default > +end > + > +t = os.time(T) > +T.year = T.year-1; > +local t1 = os.time(T) > +-- allow for leap years > +assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2) > + > +t = os.time() > +t1 = os.time(os.date("*t")) > +assert(os.difftime(t1,t) <= 2) > + > +local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17} > +local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19} > +assert(os.difftime(t1,t2) == 60*2-2) > + > +io.output(io.stdout) > +local d = os.date('%d') > +local m = os.date('%m') > +local a = os.date('%Y') > +local ds = os.date('%w') + 1 > +local h = os.date('%H') > +local min = os.date('%M') > +local s = os.date('%S') > +io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a)) > +io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s)) > +io.write(string.format('%s\n', _VERSION)) > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua > new file mode 100644 > index 0000000..86a9f75 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/gc.lua > @@ -0,0 +1,312 @@ > +print('testing garbage collection') > + > +collectgarbage() > + > +_G["while"] = 234 > + > +limit = 5000 > + > + > + > +contCreate = 0 > + > +print('tables') > +while contCreate <= limit do > + local a = {}; a = nil > + contCreate = contCreate+1 > +end > + > +a = "a" > + > +contCreate = 0 > +print('strings') > +while contCreate <= limit do > + a = contCreate .. "b"; > + a = string.gsub(a, '(%d%d*)', string.upper) > + a = "a" > + contCreate = contCreate+1 > +end > + > + > +contCreate = 0 > + > +a = {} > + > +print('functions') > +function a:test () > + while contCreate <= limit do > + loadstring(string.format("function temp(a) return 'a%d' end", contCreate))() > + assert(temp() == string.format('a%d', contCreate)) > + contCreate = contCreate+1 > + end > +end > + > +a:test() > + > +-- collection of functions without locals, globals, etc. > +do local f = function () end end > + > + > +print("functions with errors") > +prog = [[ > +do > + a = 10; > + function foo(x,y) > + a = sin(a+0.456-0.23e-12); > + return function (z) return sin(%x+z) end > + end > + local x = function (w) a=a+w; end > +end > +]] > +do > + local step = 1 > + if rawget(_G, "_soft") then step = 13 end > + for i=1, string.len(prog), step do > + for j=i, string.len(prog), step do > + pcall(loadstring(string.sub(prog, i, j))) > + end > + end > +end > + > +print('long strings') > +x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789" > +assert(string.len(x)==80) > +s = '' > +n = 0 > +k = 300 > +while n < k do s = s..x; n=n+1; j=tostring(n) end > +assert(string.len(s) == k*80) > +s = string.sub(s, 1, 20000) > +s, i = string.gsub(s, '(%d%d%d%d)', math.sin) > +assert(i==20000/4) > +s = nil > +x = nil > + > +assert(_G["while"] == 234) > + > + > +local bytes = gcinfo() > +while 1 do > + local nbytes = gcinfo() > + if nbytes < bytes then break end -- run until gc > + bytes = nbytes > + a = {} > +end > + > + > +local function dosteps (siz) > + collectgarbage() > + collectgarbage"stop" > + local a = {} > + for i=1,100 do a[i] = {{}}; local b = {} end > + local x = gcinfo() > + local i = 0 > + repeat > + i = i+1 > + until collectgarbage("step", siz) > + assert(gcinfo() < x) > + return i > +end > + > +assert(dosteps(0) > 10) > +assert(dosteps(6) < dosteps(2)) > +assert(dosteps(10000) == 1) > +assert(collectgarbage("step", 1000000) == true) > +assert(collectgarbage("step", 1000000)) > + > + > +do > + local x = gcinfo() > + collectgarbage() > + collectgarbage"stop" > + repeat > + local a = {} > + until gcinfo() > 1000 > + collectgarbage"restart" > + repeat > + local a = {} > + until gcinfo() < 1000 > +end > + > +lim = 15 > +a = {} > +-- fill a with `collectable' indices > +for i=1,lim do a[{}] = i end > +b = {} > +for k,v in pairs(a) do b[k]=v end > +-- remove all indices and collect them > +for n in pairs(b) do > + a[n] = nil > + assert(type(n) == 'table' and next(n) == nil) > + collectgarbage() > +end > +b = nil > +collectgarbage() > +for n in pairs(a) do error'cannot be here' end > +for i=1,lim do a[i] = i end > +for i=1,lim do assert(a[i] == i) end > + > + > +print('weak tables') > +a = {}; setmetatable(a, {__mode = 'k'}); > +-- fill a with some `collectable' indices > +for i=1,lim do a[{}] = i end > +-- and some non-collectable ones > +for i=1,lim do local t={}; a[t]=t end > +for i=1,lim do a[i] = i end > +for i=1,lim do local s=string.rep('@', i); a[s] = s..'#' end > +collectgarbage() > +local i = 0 > +for k,v in pairs(a) do assert(k==v or k..'#'==v); i=i+1 end > +assert(i == 3*lim) > + > +a = {}; setmetatable(a, {__mode = 'v'}); > +a[1] = string.rep('b', 21) > +collectgarbage() > +assert(a[1]) -- strings are *values* > +a[1] = nil > +-- fill a with some `collectable' values (in both parts of the table) > +for i=1,lim do a[i] = {} end > +for i=1,lim do a[i..'x'] = {} end > +-- and some non-collectable ones > +for i=1,lim do local t={}; a[t]=t end > +for i=1,lim do a[i+lim]=i..'x' end > +collectgarbage() > +local i = 0 > +for k,v in pairs(a) do assert(k==v or k-lim..'x' == v); i=i+1 end > +assert(i == 2*lim) > + > +a = {}; setmetatable(a, {__mode = 'vk'}); > +local x, y, z = {}, {}, {} > +-- keep only some items > +a[1], a[2], a[3] = x, y, z > +a[string.rep('$', 11)] = string.rep('$', 11) > +-- fill a with some `collectable' values > +for i=4,lim do a[i] = {} end > +for i=1,lim do a[{}] = i end > +for i=1,lim do local t={}; a[t]=t end > +collectgarbage() > +assert(next(a) ~= nil) > +local i = 0 > +for k,v in pairs(a) do > + assert((k == 1 and v == x) or > + (k == 2 and v == y) or > + (k == 3 and v == z) or k==v); > + i = i+1 > +end > +assert(i == 4) > +x,y,z=nil > +collectgarbage() > +assert(next(a) == string.rep('$', 11)) > + > + > +-- testing userdata > +collectgarbage("stop") -- stop collection > +local u = newproxy(true) > +local s = 0 > +local a = {[u] = 0}; setmetatable(a, {__mode = 'vk'}) > +for i=1,10 do a[newproxy(u)] = i end > +for k in pairs(a) do assert(getmetatable(k) == getmetatable(u)) end > +local a1 = {}; for k,v in pairs(a) do a1[k] = v end > +for k,v in pairs(a1) do a[v] = k end > +for i =1,10 do assert(a[i]) end > +getmetatable(u).a = a1 > +getmetatable(u).u = u > +do > + local u = u > + getmetatable(u).__gc = function (o) > + assert(a[o] == 10-s) > + assert(a[10-s] == nil) -- udata already removed from weak table > + assert(getmetatable(o) == getmetatable(u)) > + assert(getmetatable(o).a[o] == 10-s) > + s=s+1 > + end > +end > +a1, u = nil > +assert(next(a) ~= nil) > +collectgarbage() > +assert(s==11) > +collectgarbage() > +assert(next(a) == nil) -- finalized keys are removed in two cycles > + > + > +-- __gc x weak tables > +local u = newproxy(true) > +setmetatable(getmetatable(u), {__mode = "v"}) > +getmetatable(u).__gc = function (o) os.exit(1) end -- cannot happen > +collectgarbage() > + > +local u = newproxy(true) > +local m = getmetatable(u) > +m.x = {[{0}] = 1; [0] = {1}}; setmetatable(m.x, {__mode = "kv"}); > +m.__gc = function (o) > + assert(next(getmetatable(o).x) == nil) > + m = 10 > +end > +u, m = nil > +collectgarbage() > +assert(m==10) > + > + > +-- errors during collection > +u = newproxy(true) > +getmetatable(u).__gc = function () error "!!!" end > +u = nil > +assert(not pcall(collectgarbage)) > + > + > +if not rawget(_G, "_soft") then > + print("deep structures") > + local a = {} > + for i = 1,200000 do > + a = {next = a} > + end > + collectgarbage() > +end > + > +-- create many threads with self-references and open upvalues > +local thread_id = 0 > +local threads = {} > + > +function fn(thread) > + local x = {} > + threads[thread_id] = function() > + thread = x > + end > + coroutine.yield() > +end > + > +while thread_id < 1000 do > + local thread = coroutine.create(fn) > + coroutine.resume(thread, thread) > + thread_id = thread_id + 1 > +end > + > + > + > +-- create a userdata to be collected when state is closed > +do > + local newproxy,assert,type,print,getmetatable = > + newproxy,assert,type,print,getmetatable > + local u = newproxy(true) > + local tt = getmetatable(u) > + ___Glob = {u} -- avoid udata being collected before program end > + tt.__gc = function (o) > + assert(getmetatable(o) == tt) > + -- create new objects during GC > + local a = 'xuxu'..(10+3)..'joao', {} > + ___Glob = o -- ressurect object! > + newproxy(o) -- creates a new one with same metatable > + print(">>> closing state " .. "<<<\n") > + end > +end > + > +-- create several udata to raise errors when collected while closing state > +do > + local u = newproxy(true) > + getmetatable(u).__gc = function (o) return o + 1 end > + table.insert(___Glob, u) -- preserve udata until the end > + for i = 1,10 do table.insert(___Glob, newproxy(u)) end > +end > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > new file mode 100644 > index 0000000..f24e7f3 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > @@ -0,0 +1,18 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +# The original tarball contains subdirectory "libs" with an empty > +# subdirectory "libs/P1", to be used by tests. > +# Instead of tracking empty directory with some anchor-file for > +# git, create this directory via CMake. > +add_custom_target(PUC-Lua-5.1-tests-prepare) > +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare > + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > + COMMAND ${CMAKE_COMMAND} -E make_directory P1 > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 > diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c > new file mode 100644 > index 0000000..812bb9a > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c > @@ -0,0 +1,40 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > +#include "lauxlib.h" > + > +static int id (lua_State *L) { > + return lua_gettop(L); > +} > + > + > +static const struct luaL_reg funcs[] = { > + {"id", id}, > + {NULL, NULL} > +}; > + > + > +int anotherfunc (lua_State *L) { > + lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2)); > + return 1; > +} > + > + > +int luaopen_lib1_sub (lua_State *L) { > + luaL_register(L, "lib1.sub", funcs + 1); > + return 1; > +} > + > + > +int luaopen_lib1 (lua_State *L) { > + luaL_register(L, "lib1", funcs); > + return 1; > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib11.c b/test/PUC-Lua-5.1-tests/libs/lib11.c > new file mode 100644 > index 0000000..3efa3d3 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib11.c > @@ -0,0 +1,18 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > + > + > +int luaopen_lib1 (lua_State *L); > + > +int luaopen_lib11 (lua_State *L) { > + return luaopen_lib1(L); > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c > new file mode 100644 > index 0000000..9972cbe > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c > @@ -0,0 +1,28 @@ > +/* > +** compile with > +** gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > +#include "lauxlib.h" > + > +static int id (lua_State *L) { > + return lua_gettop(L); > +} > + > + > +static const struct luaL_reg funcs[] = { > + {"id", id}, > + {NULL, NULL} > +}; > + > + > +int luaopen_lib2 (lua_State *L) { > + luaL_register(L, "lib2", funcs); > + lua_pushnumber(L, 0.5); > + lua_setglobal(L, "x"); > + return 1; > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib21.c b/test/PUC-Lua-5.1-tests/libs/lib21.c > new file mode 100644 > index 0000000..167507f > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib21.c > @@ -0,0 +1,18 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > + > + > +int luaopen_lib2 (lua_State *L); > + > +int luaopen_lib21 (lua_State *L) { > + return luaopen_lib2(L); > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua > new file mode 100644 > index 0000000..01d84d5 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/literals.lua > @@ -0,0 +1,176 @@ > +print('testing scanner') > + > +local function dostring (x) return assert(loadstring(x))() end > + > +dostring("x = 'a\0a'") > +assert(x == 'a\0a' and string.len(x) == 3) > + > +-- escape sequences > +assert('\n\"\'\\' == [[ > + > +"'\]]) > + > +assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$")) > + > +-- assume ASCII just for tests: > +assert("\09912" == 'c12') > +assert("\99ab" == 'cab') > +assert("\099" == '\99') > +assert("\099\n" == 'c\10') > +assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo') > + > +assert(010 .. 020 .. -030 == "1020-30") > + > +-- long variable names > + > +var = string.rep('a', 15000) > +prog = string.format("%s = 5", var) > +dostring(prog) > +assert(_G[var] == 5) > +var = nil > +print('+') > + > +-- escapes -- > +assert("\n\t" == [[ > + > + ]]) > +assert([[ > + > + $debug]] == "\n $debug") > +assert([[ [ ]] ~= [[ ] ]]) > +-- long strings -- > +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" > +assert(string.len(b) == 960) > +prog = [=[ > +print('+') > + > +a1 = [["isto e' um string com v�rias 'aspas'"]] > +a2 = "'aspas'" > + > +assert(string.find(a1, a2) == 31) > +print('+') > + > +a1 = [==[temp = [[um valor qualquer]]; ]==] > +assert(loadstring(a1))() > +assert(temp == 'um valor qualquer') > +-- long strings -- > +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" > +assert(string.len(b) == 960) > +print('+') > + > +a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +]] > +assert(string.len(a) == 1863) > +assert(string.sub(a, 1, 40) == string.sub(b, 1, 40)) > +x = 1 > +]=] > + > +print('+') > +x = nil > +dostring(prog) > +assert(x) > + > +prog = nil > +a = nil > +b = nil > + > + > +-- testing line ends > +prog = [[ > +a = 1 -- a comment > +b = 2 > + > + > +x = [=[ > +hi > +]=] > +y = "\ > +hello\r\n\ > +" > +return debug.getinfo(1).currentline > +]] > + > +for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do > + local prog, nn = string.gsub(prog, "\n", n) > + assert(dostring(prog) == nn) > + assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n") > +end > + > + > +-- testing comments and strings with long brackets > +a = [==[]=]==] > +assert(a == "]=") > + > +a = [==[[===[[=[]]=][====[]]===]===]==] > +assert(a == "[===[[=[]]=][====[]]===]===") > + > +a = [====[[===[[=[]]=][====[]]===]===]====] > +assert(a == "[===[[=[]]=][====[]]===]===") > + > +a = [=[]]]]]]]]]=] > +assert(a == "]]]]]]]]") > + > + > +--[===[ > +x y z [==[ blu foo > +]== > +] > +]=]==] > +error error]=]===] > + > +-- generate all strings of four of these chars > +local x = {"=", "[", "]", "\n"} > +local len = 4 > +local function gen (c, n) > + if n==0 then coroutine.yield(c) > + else > + for _, a in pairs(x) do > + gen(c..a, n-1) > + end > + end > +end > + > +for s in coroutine.wrap(function () gen("", len) end) do > + assert(s == loadstring("return [====[\n"..s.."]====]")()) > +end > + > + > +-- testing decimal point locale > +if os.setlocale("pt_BR") or os.setlocale("ptb") then > + assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) > + assert(assert(loadstring("return 3.4"))() == 3.4) > + assert(assert(loadstring("return .4,3"))() == .4) > + assert(assert(loadstring("return 4."))() == 4.) > + assert(assert(loadstring("return 4.+.5"))() == 4.5) > + local a,b = loadstring("return 4.5.") > + assert(string.find(b, "'4%.5%.'")) > + assert(os.setlocale("C")) > +else > + (Message or print)( > + '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a') > +end > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/locals.lua b/test/PUC-Lua-5.1-tests/locals.lua > new file mode 100644 > index 0000000..011645a > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/locals.lua > @@ -0,0 +1,127 @@ > +print('testing local variables plus some extra stuff') > + > +do > + local i = 10 > + do local i = 100; assert(i==100) end > + do local i = 1000; assert(i==1000) end > + assert(i == 10) > + if i ~= 10 then > + local i = 20 > + else > + local i = 30 > + assert(i == 30) > + end > +end > + > + > + > +f = nil > + > +local f > +x = 1 > + > +a = nil > +loadstring('local a = {}')() > +assert(type(a) ~= 'table') > + > +function f (a) > + local _1, _2, _3, _4, _5 > + local _6, _7, _8, _9, _10 > + local x = 3 > + local b = a > + local c,d = a,b > + if (d == b) then > + local x = 'q' > + x = b > + assert(x == 2) > + else > + assert(nil) > + end > + assert(x == 3) > + local f = 10 > +end > + > +local b=10 > +local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3 > + > + > +assert(x == 1) > + > +f(2) > +assert(type(f) == 'function') > + > + > +-- testing globals ;-) > +do > + local f = {} > + local _G = _G > + for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end > + A=10; assert(f[1]() == 11) > + for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end > + assert(f[3]() == 4 and A == 11) > + local a,b = f[8](1) > + assert(b.A == 9) > + a,b = f[8](0) > + assert(b.A == 11) -- `real' global > + local g > + local function f () assert(setfenv(2, {a='10'}) == g) end > + g = function () f(); _G.assert(_G.getfenv(1).a == '10') end > + g(); assert(getfenv(g).a == '10') > +end > + > +-- test for global table of loaded chunks > +local function foo (s) > + return loadstring(s) > +end > + > +assert(getfenv(foo("")) == _G) > +local a = {loadstring = loadstring} > +setfenv(foo, a) > +assert(getfenv(foo("")) == _G) > +setfenv(0, a) -- change global environment > +assert(getfenv(foo("")) == a) > +setfenv(0, _G) > + > + > +-- testing limits for special instructions > + > +local a > +local p = 4 > +for i=2,31 do > + for j=-3,3 do > + assert(loadstring(string.format([[local a=%s;a=a+ > + %s; > + assert(a > + ==2^%s)]], j, p-j, i))) () > + assert(loadstring(string.format([[local a=%s; > + a=a-%s; > + assert(a==-2^%s)]], -j, p-j, i))) () > + assert(loadstring(string.format([[local a,b=0,%s; > + a=b-%s; > + assert(a==-2^%s)]], -j, p-j, i))) () > + end > + p =2*p > +end > + > +print'+' > + > + > +if rawget(_G, "querytab") then > + -- testing clearing of dead elements from tables > + collectgarbage("stop") -- stop GC > + local a = {[{}] = 4, [3] = 0, alo = 1, > + a1234567890123456789012345678901234567890 = 10} > + > + local t = querytab(a) > + > + for k,_ in pairs(a) do a[k] = nil end > + collectgarbage() -- restore GC and collect dead fiels in `a' > + for i=0,t-1 do > + local k = querytab(a, i) > + assert(k == nil or type(k) == 'number' or k == 'alo') > + end > +end > + > +print('OK') > + > +return 5,f > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > new file mode 100644 > index 0000000..f520896 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -0,0 +1,159 @@ > +# testing special comment on first line > + > +print ("testing lua.c options") > + > +assert(os.execute() ~= 0) -- machine has a system command > + > +prog = os.tmpname() > +otherprog = os.tmpname() > +out = os.tmpname() > + > +do > + local i = 0 > + while arg[i] do i=i-1 end > + progname = '"'..arg[i+1]..'"' > +end > +print(progname) > + > +local prepfile = function (s, p) > + p = p or prog > + io.output(p) > + io.write(s) > + assert(io.close()) > +end > + > +function checkout (s) > + io.input(out) > + local t = io.read("*a") > + io.input():close() > + assert(os.remove(out)) > + if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end > + assert(s == t) > + return t > +end > + > +function auxrun (...) > + local s = string.format(...) > + s = string.gsub(s, "lua", progname, 1) > + return os.execute(s) > +end > + > +function RUN (...) > + assert(auxrun(...) == 0) > +end > + > +function NoRun (...) > + print("\n(the next error is expected by the test)") > + assert(auxrun(...) ~= 0) > +end > + > +-- test 2 files > +prepfile("print(1); a=2") > +prepfile("print(a)", otherprog) > +RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out) > +checkout("1\n2\n2\n") > + > +local a = [[ > + assert(table.getn(arg) == 3 and arg[1] == 'a' and > + arg[2] == 'b' and arg[3] == 'c') > + assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s) > + assert(arg[4] == nil and arg[-4] == nil) > + local a, b, c = ... > + assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') > +]] > +a = string.format(a, progname) > +prepfile(a) > +RUN('lua "-e " -- %s a b c', prog) > + > +prepfile"assert(arg==nil)" > +prepfile("assert(arg)", otherprog) > +RUN("lua -l%s - < %s", prog, otherprog) > + > +prepfile"" > +RUN("lua - < %s > %s", prog, out) > +checkout("") > + > +-- test many arguments > +prepfile[[print(({...})[30])]] > +RUN("lua %s %s > %s", prog, string.rep(" a", 30), out) > +checkout("a\n") > + > +RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) > +checkout("1\n3\n") > + > +prepfile[[ > + print( > +1, a > +) > +]] > +RUN("lua - < %s > %s", prog, out) > +checkout("1\tnil\n") > + > +prepfile[[ > += (6*2-6) -- === > +a > += 10 > +print(a) > += a]] > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("6\n10\n10\n\n") > + > +prepfile("a = [[b\nc\nd\ne]]\n=a") > +print(prog) > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("b\nc\nd\ne\n\n") > + > +prompt = "alo" > +prepfile[[ -- > +a = 2 > +]] > +RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > +checkout(string.rep(prompt, 3).."\n") > + > +s = [=[ -- > +function f ( x ) > + local a = [[ > +xuxu > +]] > + local b = "\ > +xuxu\n" > + if x == 11 then return 1 , 2 end --[[ test multiple returns ]] > + return x + 1 > + --\\ > +end > +=( f( 10 ) ) > +assert( a == b ) > +=f( 11 ) ]=] > +s = string.gsub(s, ' ', '\n\n') > +prepfile(s) > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("11\n1\t2\n\n") > + > +prepfile[[#comment in 1st line without \n at the end]] > +RUN("lua %s", prog) > + > +prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)"))) > +RUN("lua %s > %s", prog, out) > +checkout("1\n") > + > +prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)"))) > +RUN("lua %s > %s", prog, out) > +checkout("1\n") > + > +-- close Lua with an open file > +prepfile(string.format([[io.output(%q); io.write('alo')]], out)) > +RUN("lua %s", prog) > +checkout('alo') > + > +assert(os.remove(prog)) > +assert(os.remove(otherprog)) > +assert(not os.remove(out)) > + > +RUN("lua -v") > + > +NoRun("lua -h") > +NoRun("lua -e") > +NoRun("lua -e a") > +NoRun("lua -f") > + > +print("OK") > diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua > new file mode 100644 > index 0000000..5076f38 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/math.lua > @@ -0,0 +1,208 @@ > +print("testing numbers and math lib") > + > +do > + local a,b,c = "2", " 3e0 ", " 10 " > + assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0) > + assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string') > + assert(a == "2" and b == " 3e0 " and c == " 10 " and -c == -" 10 ") > + assert(c%a == 0 and a^b == 8) > +end > + > + > +do > + local a,b = math.modf(3.5) > + assert(a == 3 and b == 0.5) > + assert(math.huge > 10e30) > + assert(-math.huge < -10e30) > +end > + > +function f(...) > + if select('#', ...) == 1 then > + return (...) > + else > + return "***" > + end > +end > + > +assert(tonumber{} == nil) > +assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and > + tonumber'.01' == 0.01 and tonumber'-1.' == -1 and > + tonumber'+1.' == 1) > +assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and > + tonumber'1e' == nil and tonumber'1.0e+' == nil and > + tonumber'.' == nil) > +assert(tonumber('-12') == -10-2) > +assert(tonumber('-1.2e2') == - - -120) > +assert(f(tonumber('1 a')) == nil) > +assert(f(tonumber('e1')) == nil) > +assert(f(tonumber('e 1')) == nil) > +assert(f(tonumber(' 3.4.5 ')) == nil) > +assert(f(tonumber('')) == nil) > +assert(f(tonumber('', 8)) == nil) > +assert(f(tonumber(' ')) == nil) > +assert(f(tonumber(' ', 9)) == nil) > +assert(f(tonumber('99', 8)) == nil) > +assert(tonumber(' 1010 ', 2) == 10) > +assert(tonumber('10', 36) == 36) > +--assert(tonumber('\n -10 \n', 36) == -36) > +--assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) > +assert(tonumber('fFfa', 15) == nil) > +--assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42) > +assert(tonumber(string.rep('1', 32), 2) + 1 == 2^32) > +--assert(tonumber('-fffffFFFFF', 16)-1 == -2^40) > +assert(tonumber('ffffFFFF', 16)+1 == 2^32) > + > +assert(1.1 == 1.+.1) > +assert(100.0 == 1E2 and .01 == 1e-2) > +assert(1111111111111111-1111111111111110== 1000.00e-03) > +-- 1234567890123456 > +assert(1.1 == '1.'+'.1') > +assert('1111111111111111'-'1111111111111110' == tonumber" +0.001e+3 \n\t") > + > +function eq (a,b,limit) > + if not limit then limit = 10E-10 end > + return math.abs(a-b) <= limit > +end > + > +assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31) > + > +assert(0.123456 > 0.123455) > + > +assert(tonumber('+1.23E30') == 1.23*10^30) > + > +-- testing order operators > +assert(not(1<1) and (1<2) and not(2<1)) > +assert(not('a'<'a') and ('a'<'b') and not('b'<'a')) > +assert((1<=1) and (1<=2) and not(2<=1)) > +assert(('a'<='a') and ('a'<='b') and not('b'<='a')) > +assert(not(1>1) and not(1>2) and (2>1)) > +assert(not('a'>'a') and not('a'>'b') and ('b'>'a')) > +assert((1>=1) and not(1>=2) and (2>=1)) > +assert(('a'>='a') and not('a'>='b') and ('b'>='a')) > + > +-- testing mod operator > +assert(-4%3 == 2) > +assert(4%-3 == -2) > +assert(math.pi - math.pi % 1 == 3) > +assert(math.pi - math.pi % 0.001 == 3.141) > + > +local function testbit(a, n) > + return a/2^n % 2 >= 1 > +end > + > +assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1)) > +assert(eq(math.tan(math.pi/4), 1)) > +assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0)) > +assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and > + eq(math.asin(1), math.pi/2)) > +assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2)) > +assert(math.abs(-10) == 10) > +assert(eq(math.atan2(1,0), math.pi/2)) > +assert(math.ceil(4.5) == 5.0) > +assert(math.floor(4.5) == 4.0) > +assert(math.mod(10,3) == 1) > +assert(eq(math.sqrt(10)^2, 10)) > +assert(eq(math.log10(2), math.log(2)/math.log(10))) > +assert(eq(math.exp(0), 1)) > +assert(eq(math.sin(10), math.sin(10%(2*math.pi)))) > +local v,e = math.frexp(math.pi) > +assert(eq(math.ldexp(v,e), math.pi)) > + > +assert(eq(math.tanh(3.5), math.sinh(3.5)/math.cosh(3.5))) > + > +assert(tonumber(' 1.3e-2 ') == 1.3e-2) > +assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) > + > +-- testing constant limits > +-- 2^23 = 8388608 > +assert(8388609 + -8388609 == 0) > +assert(8388608 + -8388608 == 0) > +assert(8388607 + -8388607 == 0) > + > +if rawget(_G, "_soft") then return end > + > +f = io.tmpfile() > +assert(f) > +f:write("a = {") > +i = 1 > +repeat > + f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n") > + i=i+1 > +until i > 1000 > +f:write("}") > +f:seek("set", 0) > +assert(loadstring(f:read('*a')))() > +assert(f:close()) > + > +assert(eq(a[300][1], math.sin(300))) > +assert(eq(a[600][1], math.sin(600))) > +assert(eq(a[500][2], math.cos(500))) > +assert(eq(a[800][2], math.cos(800))) > +assert(eq(a[200][3], 200/3)) > +assert(eq(a[1000][3], 1000/3, 0.001)) > +print('+') > + > +do -- testing NaN > + local NaN = 10e500 - 10e400 > + assert(NaN ~= NaN) > + assert(not (NaN < NaN)) > + assert(not (NaN <= NaN)) > + assert(not (NaN > NaN)) > + assert(not (NaN >= NaN)) > + assert(not (0 < NaN)) > + assert(not (NaN < 0)) > + local a = {} > + assert(not pcall(function () a[NaN] = 1 end)) > + assert(a[NaN] == nil) > + a[1] = 1 > + assert(not pcall(function () a[NaN] = 1 end)) > + assert(a[NaN] == nil) > +end > + > +require "checktable" > +stat(a) > + > +a = nil > + > +-- testing implicit convertions > + > +local a,b = '10', '20' > +assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20) > +assert(a == '10' and b == '20') > + > + > +math.randomseed(0) > + > +local i = 0 > +local Max = 0 > +local Min = 2 > +repeat > + local t = math.random() > + Max = math.max(Max, t) > + Min = math.min(Min, t) > + i=i+1 > + flag = eq(Max, 1, 0.001) and eq(Min, 0, 0.001) > +until flag or i>10000 > +assert(0 <= Min and Max<1) > +assert(flag); > + > +for i=1,10 do > + local t = math.random(5) > + assert(1 <= t and t <= 5) > +end > + > +i = 0 > +Max = -200 > +Min = 200 > +repeat > + local t = math.random(-10,0) > + Max = math.max(Max, t) > + Min = math.min(Min, t) > + i=i+1 > + flag = (Max == 0 and Min == -10) > +until flag or i>10000 > +assert(-10 <= Min and Max<=0) > +assert(flag); > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua > new file mode 100644 > index 0000000..7ceaa75 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/nextvar.lua > @@ -0,0 +1,396 @@ > +print('testing tables, next, and for') > + > +local a = {} > + > +-- make sure table has lots of space in hash part > +for i=1,100 do a[i.."+"] = true end > +for i=1,100 do a[i.."+"] = nil end > +-- fill hash part with numeric indices testing size operator > +for i=1,100 do > + a[i] = true > + assert(#a == i) > +end > + > + > +if T then > +-- testing table sizes > + > +local l2 = math.log(2) > +local function log2 (x) return math.log(x)/l2 end > + > +local function mp2 (n) -- minimum power of 2 >= n > + local mp = 2^math.ceil(log2(n)) > + assert(n == 0 or (mp/2 < n and n <= mp)) > + return mp > +end > + > +local function fb (n) > + local r, nn = T.int2fb(n) > + assert(r < 256) > + return nn > +end > + > +-- test fb function > +local a = 1 > +local lim = 2^30 > +while a < lim do > + local n = fb(a) > + assert(a <= n and n <= a*1.125) > + a = math.ceil(a*1.3) > +end > + > + > +local function check (t, na, nh) > + local a, h = T.querytab(t) > + if a ~= na or h ~= nh then > + print(na, nh, a, h) > + assert(nil) > + end > +end > + > +-- testing constructor sizes > +local lim = 40 > +local s = 'return {' > +for i=1,lim do > + s = s..i..',' > + local s = s > + for k=0,lim do > + local t = loadstring(s..'}')() > + assert(#t == i) > + check(t, fb(i), mp2(k)) > + s = string.format('%sa%d=%d,', s, k, k) > + end > +end > + > + > +-- tests with unknown number of elements > +local a = {} > +for i=1,lim do a[i] = i end -- build auxiliary table > +for k=0,lim do > + local a = {unpack(a,1,k)} > + assert(#a == k) > + check(a, k, 0) > + a = {1,2,3,unpack(a,1,k)} > + check(a, k+3, 0) > + assert(#a == k + 3) > +end > + > + > +print'+' > + > +-- testing tables dynamically built > +local lim = 130 > +local a = {}; a[2] = 1; check(a, 0, 1) > +a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) > +a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) > +a = {} > +for i = 1,lim do > + a[i] = 1 > + assert(#a == i) > + check(a, mp2(i), 0) > +end > + > +a = {} > +for i = 1,lim do > + a['a'..i] = 1 > + assert(#a == 0) > + check(a, 0, mp2(i)) > +end > + > +a = {} > +for i=1,16 do a[i] = i end > +check(a, 16, 0) > +for i=1,11 do a[i] = nil end > +for i=30,40 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 8) > +a[10] = 1 > +for i=30,40 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 8) > +for i=1,14 do a[i] = nil end > +for i=30,50 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 4) > + > +-- reverse filling > +for i=1,lim do > + local a = {} > + for i=i,1,-1 do a[i] = i end -- fill in reverse > + check(a, mp2(i), 0) > +end > + > +-- size tests for vararg > +lim = 35 > +function foo (n, ...) > + local arg = {...} > + check(arg, n, 0) > + assert(select('#', ...) == n) > + arg[n+1] = true > + check(arg, mp2(n+1), 0) > + arg.x = true > + check(arg, mp2(n+1), 1) > +end > +local a = {} > +for i=1,lim do a[i] = true; foo(i, unpack(a)) end > + > +end > + > + > +-- test size operation on empty tables > +assert(#{} == 0) > +assert(#{nil} == 0) > +assert(#{nil, nil} == 0) > +assert(#{nil, nil, nil} == 0) > +assert(#{nil, nil, nil, nil} == 0) > +print'+' > + > + > +local nofind = {} > + > +a,b,c = 1,2,3 > +a,b,c = nil > + > +local function find (name) > + local n,v > + while 1 do > + n,v = next(_G, n) > + if not n then return nofind end > + assert(v ~= nil) > + if n == name then return v end > + end > +end > + > +local function find1 (name) > + for n,v in pairs(_G) do > + if n==name then return v end > + end > + return nil -- not found > +end > + > +do -- create 10000 new global variables > + for i=1,10000 do _G[i] = i end > +end > + > + > +a = {x=90, y=8, z=23} > +assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90) > +assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil) > +table.foreach({}, error) > + > +table.foreachi({x=10, y=20}, error) > +local a = {n = 1} > +table.foreachi({n=3}, function (i, v) > + assert(a.n == i and not v) > + a.n=a.n+1 > +end) > +a = {10,20,30,nil,50} > +table.foreachi(a, function (i,v) assert(a[i] == v) end) > +assert(table.foreachi({'a', 'b', 'c'}, function (i,v) > + if i==2 then return v end > + end) == 'b') > + > + > +assert(print==find("print") and print == find1("print")) > +assert(_G["print"]==find("print")) > +assert(assert==find1("assert")) > +assert(nofind==find("return")) > +assert(not find1("return")) > +_G["ret" .. "urn"] = nil > +assert(nofind==find("return")) > +_G["xxx"] = 1 > +assert(xxx==find("xxx")) > +print('+') > + > +a = {} > +for i=0,10000 do > + if math.mod(i,10) ~= 0 then > + a['x'..i] = i > + end > +end > + > +n = {n=0} > +for i,v in pairs(a) do > + n.n = n.n+1 > + assert(i and v and a[i] == v) > +end > +assert(n.n == 9000) > +a = nil > + > +-- remove those 10000 new global variables > +for i=1,10000 do _G[i] = nil end > + > +do -- clear global table > + local a = {} > + local preserve = {io = 1, string = 1, debug = 1, os = 1, > + coroutine = 1, table = 1, math = 1} > + for n,v in pairs(_G) do a[n]=v end > + for n,v in pairs(a) do > + if not preserve[n] and type(v) ~= "function" and > + not string.find(n, "^[%u_]") then > + _G[n] = nil > + end > + collectgarbage() > + end > +end > + > +local function foo () > + local getfenv, setfenv, assert, next = > + getfenv, setfenv, assert, next > + local n = {gl1=3} > + setfenv(foo, n) > + assert(getfenv(foo) == getfenv(1)) > + assert(getfenv(foo) == n) > + assert(print == nil and gl1 == 3) > + gl1 = nil > + gl = 1 > + assert(n.gl == 1 and next(n, 'gl') == nil) > +end > +foo() > + > +print'+' > + > +local function checknext (a) > + local b = {} > + table.foreach(a, function (k,v) b[k] = v end) > + for k,v in pairs(b) do assert(a[k] == v) end > + for k,v in pairs(a) do assert(b[k] == v) end > + b = {} > + do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end > + for k,v in pairs(b) do assert(a[k] == v) end > + for k,v in pairs(a) do assert(b[k] == v) end > +end > + > +checknext{1,x=1,y=2,z=3} > +checknext{1,2,x=1,y=2,z=3} > +checknext{1,2,3,x=1,y=2,z=3} > +checknext{1,2,3,4,x=1,y=2,z=3} > +checknext{1,2,3,4,5,x=1,y=2,z=3} > + > +assert(table.getn{} == 0) > +assert(table.getn{[-1] = 2} == 0) > +assert(table.getn{1,2,3,nil,nil} == 3) > +for i=0,40 do > + local a = {} > + for j=1,i do a[j]=j end > + assert(table.getn(a) == i) > +end > + > + > +assert(table.maxn{} == 0) > +assert(table.maxn{["1000"] = true} == 0) > +assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) > +assert(table.maxn{[1000] = true} == 1000) > +assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) > + > + > +-- int overflow > +a = {} > +for i=0,50 do a[math.pow(2,i)] = true end > +assert(a[table.getn(a)]) > + > +print("+") > + > + > +-- erasing values > +local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, > + [100.3] = 4, [4] = 5} > + > +local n = 0 > +for k, v in pairs( t ) do > + n = n+1 > + assert(t[k] == v) > + t[k] = nil > + collectgarbage() > + assert(t[k] == nil) > +end > +assert(n == 5) > + > + > +local function test (a) > + table.insert(a, 10); table.insert(a, 2, 20); > + table.insert(a, 1, -1); table.insert(a, 40); > + table.insert(a, table.getn(a)+1, 50) > + table.insert(a, 2, -2) > + assert(table.remove(a,1) == -1) > + assert(table.remove(a,1) == -2) > + assert(table.remove(a,1) == 10) > + assert(table.remove(a,1) == 20) > + assert(table.remove(a,1) == 40) > + assert(table.remove(a,1) == 50) > + assert(table.remove(a,1) == nil) > +end > + > +a = {n=0, [-7] = "ban"} > +test(a) > +assert(a.n == 0 and a[-7] == "ban") > + > +a = {[-7] = "ban"}; > +test(a) > +assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban") > + > + > +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) > +assert(table.remove(a) == 10) > +assert(table.remove(a) == 20) > +assert(table.remove(a) == -1) > + > +a = {'c', 'd'} > +table.insert(a, 3, 'a') > +table.insert(a, 'b') > +assert(table.remove(a, 1) == 'c') > +assert(table.remove(a, 1) == 'd') > +assert(table.remove(a, 1) == 'a') > +assert(table.remove(a, 1) == 'b') > +assert(table.getn(a) == 0 and a.n == nil) > +print("+") > + > +a = {} > +for i=1,1000 do > + a[i] = i; a[i-1] = nil > +end > +assert(next(a,nil) == 1000 and next(a,1000) == nil) > + > +assert(next({}) == nil) > +assert(next({}, nil) == nil) > + > +for a,b in pairs{} do error"not here" end > +for i=1,0 do error'not here' end > +for i=0,1,-1 do error'not here' end > +a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) > +a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) > + > +a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11) > +-- precision problems > +--a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101) > +a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) > +a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) > +a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1) > +a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) > +a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0) > +a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) > + > +-- conversion > +a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) > + > + > +collectgarbage() > + > + > +-- testing generic 'for' > + > +local function f (n, p) > + local t = {}; for i=1,p do t[i] = i*10 end > + return function (_,n) > + if n > 0 then > + n = n-1 > + return n, unpack(t) > + end > + end, nil, n > +end > + > +local x = 0 > +for n,a,b,c,d in f(5,3) do > + x = x+1 > + assert(a == 10 and b == 20 and c == 30 and d == nil) > +end > +assert(x == 5) > + > +print"OK" > diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua > new file mode 100644 > index 0000000..fa125dc > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/pm.lua > @@ -0,0 +1,273 @@ > +print('testing pattern matching') > + > +function f(s, p) > + local i,e = string.find(s, p) > + if i then return string.sub(s, i, e) end > +end > + > +function f1(s, p) > + p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end) > + p = string.gsub(p, "^(^?)", "%1()", 1) > + p = string.gsub(p, "($?)$", "()%1", 1) > + local t = {string.match(s, p)} > + return string.sub(s, t[1], t[#t] - 1) > +end > + > +a,b = string.find('', '') -- empty patterns are tricky > +assert(a == 1 and b == 0); > +a,b = string.find('alo', '') > +assert(a == 1 and b == 0) > +a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position > +assert(a == 1 and b == 1) > +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the midle > +assert(a == 5 and b == 7) > +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the midle > +assert(a == 9 and b == 11) > +a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end > +assert(a == 9 and b == 11); > +a,b = string.find('a\0a\0a\0a\0\0ab', 'b') -- last position > +assert(a == 11 and b == 11) > +assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil) -- check ending > +assert(string.find('', '\0') == nil) > +assert(string.find('alo123alo', '12') == 4) > +assert(string.find('alo123alo', '^12') == nil) > + > +assert(f('aloALO', '%l*') == 'alo') > +assert(f('aLo_ALO', '%a*') == 'aLo') > + > +assert(f('aaab', 'a*') == 'aaa'); > +assert(f('aaa', '^.*$') == 'aaa'); > +assert(f('aaa', 'b*') == ''); > +assert(f('aaa', 'ab*a') == 'aa') > +assert(f('aba', 'ab*a') == 'aba') > +assert(f('aaab', 'a+') == 'aaa') > +assert(f('aaa', '^.+$') == 'aaa') > +assert(f('aaa', 'b+') == nil) > +assert(f('aaa', 'ab+a') == nil) > +assert(f('aba', 'ab+a') == 'aba') > +assert(f('a$a', '.$') == 'a') > +assert(f('a$a', '.%$') == 'a$') > +assert(f('a$a', '.$.') == 'a$a') > +assert(f('a$a', '$$') == nil) > +assert(f('a$b', 'a$') == nil) > +assert(f('a$a', '$') == '') > +assert(f('', 'b*') == '') > +assert(f('aaa', 'bb*') == nil) > +assert(f('aaab', 'a-') == '') > +assert(f('aaa', '^.-$') == 'aaa') > +assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') > +assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') > +assert(f('alo xo', '.o$') == 'xo') > +assert(f(' \n isto � assim', '%S%S*') == 'isto') > +assert(f(' \n isto � assim', '%S*$') == 'assim') > +assert(f(' \n isto � assim', '[a-z]*$') == 'assim') > +assert(f('um caracter ? extra', '[^%sa-z]') == '?') > +assert(f('', 'a?') == '') > +assert(f('�', '�?') == '�') > +assert(f('�bl', '�?b?l?') == '�bl') > +assert(f(' �bl', '�?b?l?') == '') > +assert(f('aa', '^aa?a?a') == 'aa') > +assert(f(']]]�b', '[^]]') == '�') > +assert(f("0alo alo", "%x*") == "0a") > +assert(f("alo alo", "%C+") == "alo alo") > +print('+') > + > +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o") > +assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3') > +assert(f1('=======', '^(=*)=%1$') == '=======') > +assert(string.match('==========', '^([=]*)=%1$') == nil) > + > +local function range (i, j) > + if i <= j then > + return i, range(i+1, j) > + end > +end > + > +local abc = string.char(range(0, 255)); > + > +assert(string.len(abc) == 256) > + > +function strset (p) > + local res = {s=''} > + string.gsub(abc, p, function (c) res.s = res.s .. c end) > + return res.s > +end; > + > +assert(string.len(strset('[\200-\210]')) == 11) > + > +assert(strset('[a-z]') == "abcdefghijklmnopqrstuvwxyz") > +assert(strset('[a-z%d]') == strset('[%da-uu-z]')) > +assert(strset('[a-]') == "-a") > +assert(strset('[^%W]') == strset('[%w]')) > +assert(strset('[]%%]') == '%]') > +assert(strset('[a%-z]') == '-az') > +assert(strset('[%^%[%-a%]%-b]') == '-[]^ab') > +assert(strset('%Z') == strset('[\1-\255]')) > +assert(strset('.') == strset('[\1-\255%z]')) > +print('+'); > + > +assert(string.match("alo xyzK", "(%w+)K") == "xyz") > +assert(string.match("254 K", "(%d*)K") == "") > +assert(string.match("alo ", "(%w*)$") == "") > +assert(string.match("alo ", "(%w+)$") == nil) > +assert(string.find("(�lo)", "%(�") == 1) > +local a, b, c, d, e = string.match("�lo alo", "^(((.).).* (%w*))$") > +assert(a == '�lo alo' and b == '�l' and c == '�' and d == 'alo' and e == nil) > +a, b, c, d = string.match('0123456789', '(.+(.?)())') > +assert(a == '0123456789' and b == '' and c == 11 and d == nil) > +print('+') > + > +assert(string.gsub('�lo �lo', '�', 'x') == 'xlo xlo') > +assert(string.gsub('alo �lo ', ' +$', '') == 'alo �lo') -- trim > +assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim > +assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') > +t = "ab� d" > +a, b = string.gsub(t, '(.)', '%1@') > +assert('@'..a == string.gsub(t, '', '@') and b == 5) > +a, b = string.gsub('ab�d', '(.)', '%0@', 2) > +assert(a == 'a@b@�d' and b == 2) > +assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') > +assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == > + "xyz=abc-abc=xyz") > +assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") > +assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") > +assert(string.gsub('���', '$', '\0�') == '���\0�') > +assert(string.gsub('', '^', 'r') == 'r') > +assert(string.gsub('', '$', 'r') == 'r') > +print('+') > + > +assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", string.upper) == > + "um (DOIS) tres (QUATRO)") > + > +do > + local function setglobal (n,v) rawset(_G, n, v) end > + string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal) > + assert(_G.a=="roberto" and _G.roberto=="a") > +end > + > +function f(a,b) return string.gsub(a,'.',b) end > +assert(string.gsub("trocar tudo em |teste|b| � |beleza|al|", "|([^|]*)|([^|]*)|", f) == > + "trocar tudo em bbbbb � alalalalalal") > + > +local function dostring (s) return loadstring(s)() or "" end > +assert(string.gsub("alo $a=1$ novamente $return a$", "$([^$]*)%$", dostring) == > + "alo novamente 1") > + > +x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$", > + "$([^$]*)%$", dostring) > +assert(x == ' assim vai para ALO') > + > +t = {} > +s = 'a alo jose joao' > +r = string.gsub(s, '()(%w+)()', function (a,w,b) > + assert(string.len(w) == b-a); > + t[a] = b-a; > + end) > +assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4) > + > + > +function isbalanced (s) > + return string.find(string.gsub(s, "%b()", ""), "[()]") == nil > +end > + > +assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a")) > +assert(not isbalanced("(9 ((8) 7) a b (\0 c) a")) > +assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo') > + > + > +local t = {"apple", "orange", "lime"; n=0} > +assert(string.gsub("x and x and x", "x", function () t.n=t.n+1; return t[t.n] end) > + == "apple and orange and lime") > + > +t = {n=0} > +string.gsub("first second word", "%w%w*", function (w) t.n=t.n+1; t[t.n] = w end) > +assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3) > + > +t = {n=0} > +assert(string.gsub("first second word", "%w+", > + function (w) t.n=t.n+1; t[t.n] = w end, 2) == "first second word") > +assert(t[1] == "first" and t[2] == "second" and t[3] == nil) > + > +assert(not pcall(string.gsub, "alo", "(.", print)) > +assert(not pcall(string.gsub, "alo", ".)", print)) > +assert(not pcall(string.gsub, "alo", "(.", {})) > +assert(not pcall(string.gsub, "alo", "(.)", "%2")) > +assert(not pcall(string.gsub, "alo", "(%1)", "a")) > +assert(not pcall(string.gsub, "alo", "(%0)", "a")) > + > +-- big strings > +local a = string.rep('a', 300000) > +assert(string.find(a, '^a*.?$')) > +assert(not string.find(a, '^a*.?b$')) > +assert(string.find(a, '^a-.?$')) > + > +-- deep nest of gsubs > +function rev (s) > + return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end) > +end > + > +local x = string.rep('012345', 10) > +assert(rev(rev(x)) == x) > + > + > +-- gsub with tables > +assert(string.gsub("alo alo", ".", {}) == "alo alo") > +assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo") > +assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo") > +assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo") > + > +assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo") > + > +t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end}) > +assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") > + > + > +-- tests for gmatch > +assert(string.gfind == string.gmatch) > +local a = 0 > +for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end > +assert(a==6) > + > +t = {n=0} > +for w in string.gmatch("first second word", "%w+") do > + t.n=t.n+1; t[t.n] = w > +end > +assert(t[1] == "first" and t[2] == "second" and t[3] == "word") > + > +t = {3, 6, 9} > +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do > + assert(i == table.remove(t, 1)) > +end > +assert(table.getn(t) == 0) > + > +t = {} > +for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do > + t[i] = j > +end > +a = 0 > +for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end > +assert(a == 3) > + > + > +-- tests for `%f' (`frontiers') > + > +assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") > +assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[") > +assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3") > +assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.") > +assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction") > +assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.") > + > +local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]") > +assert(i == 2 and e == 5) > +local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])") > +assert(k == 'alo ') > + > +local a = {1, 5, 9, 14, 17,} > +for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do > + assert(table.remove(a, 1) == k) > +end > +assert(table.getn(a) == 0) > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/sort.lua b/test/PUC-Lua-5.1-tests/sort.lua > new file mode 100644 > index 0000000..6fccd49 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/sort.lua > @@ -0,0 +1,74 @@ > +print"testing sort" > + > + > +function check (a, f) > + f = f or function (x,y) return x<y end; > + for n=table.getn(a),2,-1 do > + assert(not f(a[n], a[n-1])) > + end > +end > + > +a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", > + "Oct", "Nov", "Dec"} > + > +table.sort(a) > +check(a) > + > +limit = 30000 > +if rawget(_G, "_soft") then limit = 5000 end > + > +a = {} > +for i=1,limit do > + a[i] = math.random() > +end > + > +local x = os.clock() > +table.sort(a) > +print(string.format("Sorting %d elements in %.2f sec.", limit, os.clock()-x)) > +check(a) > + > +x = os.clock() > +table.sort(a) > +print(string.format("Re-sorting %d elements in %.2f sec.", limit, os.clock()-x)) > +check(a) > + > +a = {} > +for i=1,limit do > + a[i] = math.random() > +end > + > +x = os.clock(); i=0 > +table.sort(a, function(x,y) i=i+1; return y<x end) > +print(string.format("Invert-sorting other %d elements in %.2f sec., with %i comparisons", > + limit, os.clock()-x, i)) > +check(a, function(x,y) return y<x end) > + > + > +table.sort{} -- empty array > + > +for i=1,limit do a[i] = false end > +x = os.clock(); > +table.sort(a, function(x,y) return nil end) > +print(string.format("Sorting %d equal elements in %.2f sec.", limit, os.clock()-x)) > +check(a, function(x,y) return nil end) > +for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end > + > +a = {"�lo", "\0first :-)", "alo", "then this one", "45", "and a new"} > +table.sort(a) > +check(a) > + > +table.sort(a, function (x, y) > + loadstring(string.format("a[%q] = ''", x))() > + collectgarbage() > + return x<y > + end) > + > + > +tt = {__lt = function (a,b) return a.val < b.val end} > +a = {} > +for i=1,10 do a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end > +table.sort(a) > +check(a, tt.__lt) > +check(a) > + > +print"OK" > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > new file mode 100644 > index 0000000..237dbad > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/strings.lua > @@ -0,0 +1,176 @@ > +print('testing strings and string library') > + > +assert('alo' < 'alo1') > +assert('' < 'a') > +assert('alo\0alo' < 'alo\0b') > +assert('alo\0alo\0\0' > 'alo\0alo\0') > +assert('alo' < 'alo\0') > +assert('alo\0' > 'alo') > +assert('\0' < '\1') > +assert('\0\0' < '\0\1') > +assert('\1\0a\0a' <= '\1\0a\0a') > +assert(not ('\1\0a\0b' <= '\1\0a\0a')) > +assert('\0\0\0' < '\0\0\0\0') > +assert(not('\0\0\0\0' < '\0\0\0')) > +assert('\0\0\0' <= '\0\0\0\0') > +assert(not('\0\0\0\0' <= '\0\0\0')) > +assert('\0\0\0' <= '\0\0\0') > +assert('\0\0\0' >= '\0\0\0') > +assert(not ('\0\0b' < '\0\0a\0')) > +print('+') > + > +assert(string.sub("123456789",2,4) == "234") > +assert(string.sub("123456789",7) == "789") > +assert(string.sub("123456789",7,6) == "") > +assert(string.sub("123456789",7,7) == "7") > +assert(string.sub("123456789",0,0) == "") > +assert(string.sub("123456789",-10,10) == "123456789") > +assert(string.sub("123456789",1,9) == "123456789") > +assert(string.sub("123456789",-10,-20) == "") > +assert(string.sub("123456789",-1) == "9") > +assert(string.sub("123456789",-4) == "6789") > +assert(string.sub("123456789",-6, -4) == "456") > +assert(string.sub("\000123456789",3,5) == "234") > +assert(("\000123456789"):sub(8) == "789") > +print('+') > + > +assert(string.find("123456789", "345") == 3) > +a,b = string.find("123456789", "345") > +assert(string.sub("123456789", a, b) == "345") > +assert(string.find("1234567890123456789", "345", 3) == 3) > +assert(string.find("1234567890123456789", "345", 4) == 13) > +assert(string.find("1234567890123456789", "346", 4) == nil) > +assert(string.find("1234567890123456789", ".45", -9) == 13) > +assert(string.find("abcdefg", "\0", 5, 1) == nil) > +assert(string.find("", "") == 1) > +assert(string.find('', 'aaa', 1) == nil) > +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) > +print('+') > + > +assert(string.len("") == 0) > +assert(string.len("\0\0\0") == 3) > +assert(string.len("1234567890") == 10) > + > +assert(#"" == 0) > +assert(#"\0\0\0" == 3) > +assert(#"1234567890" == 10) > + > +assert(string.byte("a") == 97) > +assert(string.byte("�") > 127) > +assert(string.byte(string.char(255)) == 255) > +assert(string.byte(string.char(0)) == 0) > +assert(string.byte("\0") == 0) > +assert(string.byte("\0\0alo\0x", -1) == string.byte('x')) > +assert(string.byte("ba", 2) == 97) > +assert(string.byte("\n\n", 2, -1) == 10) > +assert(string.byte("\n\n", 2, 2) == 10) > +assert(string.byte("") == nil) > +assert(string.byte("hi", -3) == nil) > +assert(string.byte("hi", 3) == nil) > +assert(string.byte("hi", 9, 10) == nil) > +assert(string.byte("hi", 2, 1) == nil) > +assert(string.char() == "") > +assert(string.char(0, 255, 0) == "\0\255\0") > +assert(string.char(0, string.byte("�"), 0) == "\0�\0") > +assert(string.char(string.byte("�l\0�u", 1, -1)) == "�l\0�u") > +assert(string.char(string.byte("�l\0�u", 1, 0)) == "") > +assert(string.char(string.byte("�l\0�u", -10, 100)) == "�l\0�u") > +print('+') > + > +assert(string.upper("ab\0c") == "AB\0C") > +assert(string.lower("\0ABCc%$") == "\0abcc%$") > +assert(string.rep('teste', 0) == '') > +assert(string.rep('t�s\00t�', 2) == 't�s\0t�t�s\000t�') > +assert(string.rep('', 10) == '') > + > +assert(string.reverse"" == "") > +assert(string.reverse"\0\1\2\3" == "\3\2\1\0") > +assert(string.reverse"\0001234" == "4321\0") > + > +for i=0,30 do assert(string.len(string.rep('a', i)) == i) end > + > +assert(type(tostring(nil)) == 'string') > +assert(type(tostring(12)) == 'string') > +assert(''..12 == '12' and type(12 .. '') == 'string') > +assert(string.find(tostring{}, 'table:')) > +assert(string.find(tostring(print), 'function:')) > +assert(tostring(1234567890123) == '1234567890123') > +assert(#tostring('\0') == 1) > +assert(tostring(true) == "true") > +assert(tostring(false) == "false") > +print('+') > + > +x = '"�lo"\n\\' > +assert(string.format('%q%s', x, x) == '"\\"�lo\\"\\\n\\\\""�lo"\n\\') > +assert(string.format('%q', "\0") == [["\000"]]) > +assert(string.format("\0%c\0%c%x\0", string.byte("�"), string.byte("b"), 140) == > + "\0�\0b8c\0") > +assert(string.format('') == "") > +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == > + string.format("%c%c%c%c", 34, 48, 90, 100)) > +assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') > +assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") > +assert(tonumber(string.format("%f", 10.3)) == 10.3) > +x = string.format('"%-50s"', 'a') > +assert(#x == 52) > +assert(string.sub(x, 1, 4) == '"a ') > + > +assert(string.format("-%.20s.20s", string.rep("%", 2000)) == "-"..string.rep("%", 20)..".20s") > +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) == > + string.format("%q", "-"..string.rep("%", 2000)..".20s")) > + > + > +-- longest number that can be formated > +assert(string.len(string.format('%99.99f', -1e308)) >= 100) > + > +assert(loadstring("return 1\n--coment�rio sem EOL no final")() == 1) > + > + > +assert(table.concat{} == "") > +assert(table.concat({}, 'x') == "") > +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2") > +local a = {}; for i=1,3000 do a[i] = "xuxu" end > +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 3000)) > +assert(table.concat(a, "b", 20, 20) == "xuxu") > +assert(table.concat(a, "", 20, 21) == "xuxuxuxu") > +assert(table.concat(a, "", 22, 21) == "") > +assert(table.concat(a, "3", 2999) == "xuxu3xuxu") > + > +a = {"a","b","c"} > +assert(table.concat(a, ",", 1, 0) == "") > +assert(table.concat(a, ",", 1, 1) == "a") > +assert(table.concat(a, ",", 1, 2) == "a,b") > +assert(table.concat(a, ",", 2) == "b,c") > +assert(table.concat(a, ",", 3) == "c") > +assert(table.concat(a, ",", 4) == "") > + > +local locales = { "ptb", "ISO-8859-1", "pt_BR" } > +local function trylocale (w) > + for _, l in ipairs(locales) do > + if os.setlocale(l, w) then return true end > + end > + return false > +end > + > +if not trylocale("collate") then > + print("locale not supported") > +else > + assert("alo" < "�lo" and "�lo" < "amo") > +end > + > +if not trylocale("ctype") then > + print("locale not supported") > +else > + assert(string.gsub("����", "%a", "x") == "xxxxx") > + assert(string.gsub("����", "%l", "x") == "x�x�") > + assert(string.gsub("����", "%u", "x") == "�x�x") > + assert(string.upper"���{xuxu}��o" == "���{XUXU}��O") > +end > + > +os.setlocale("C") > +assert(os.setlocale() == 'C') > +assert(os.setlocale(nil, "numeric") == 'C') > + > +print('OK') > + > + > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > new file mode 100644 > index 0000000..ae068fa > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > @@ -0,0 +1,126 @@ > +print('testing vararg') > + > +_G.arg = nil > + > +function f(a, ...) > + assert(type(arg) == 'table') > + assert(type(arg.n) == 'number') > + for i=1,arg.n do assert(a[i]==arg[i]) end > + return arg.n > +end > + > +function c12 (...) > + assert(arg == nil) > + local x = {...}; x.n = table.getn(x) > + local res = (x.n==2 and x[1] == 1 and x[2] == 2) > + if res then res = 55 end > + return res, 2 > +end > + > +function vararg (...) return arg end > + > +local call = function (f, args) return f(unpack(args, 1, args.n)) end > + > +assert(f() == 0) > +assert(f({1,2,3}, 1, 2, 3) == 3) > +assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) > + > +assert(c12(1,2)==55) > +a,b = assert(call(c12, {1,2})) > +assert(a == 55 and b == 2) > +a = call(c12, {1,2;n=2}) > +assert(a == 55 and b == 2) > +a = call(c12, {1,2;n=1}) > +assert(not a) > +assert(c12(1,2,3) == false) > +local a = vararg(call(next, {_G,nil;n=2})) > +local b,c = next(_G) > +assert(a[1] == b and a[2] == c and a.n == 2) > +a = vararg(call(call, {c12, {1,2}})) > +assert(a.n == 2 and a[1] == 55 and a[2] == 2) > +a = call(print, {'+'}) > +assert(a == nil) > + > +local t = {1, 10} > +function t:f (...) return self[arg[1]]+arg.n end > +assert(t:f(1,4) == 3 and t:f(2) == 11) > +print('+') > + > +lim = 20 > +local i, a = 1, {} > +while i <= lim do a[i] = i+0.3; i=i+1 end > + > +function f(a, b, c, d, ...) > + local more = {...} > + assert(a == 1.3 and more[1] == 5.3 and > + more[lim-4] == lim+0.3 and not more[lim-3]) > +end > + > +function g(a,b,c) > + assert(a == 1.3 and b == 2.3 and c == 3.3) > +end > + > +call(f, a) > +call(g, a) > + > +a = {} > +i = 1 > +while i <= lim do a[i] = i; i=i+1 end > +assert(call(math.max, a) == lim) > + > +print("+") > + > + > +-- new-style varargs > + > +function oneless (a, ...) return ... end > + > +function f (n, a, ...) > + local b > + assert(arg == nil) > + if n == 0 then > + local b, c, d = ... > + return a, b, c, d, oneless(oneless(oneless(...))) > + else > + n, b, a = n-1, ..., a > + assert(b == ...) > + return f(n, a, ...) > + end > +end > + > +a,b,c,d,e = assert(f(10,5,4,3,2,1)) > +assert(a==5 and b==4 and c==3 and d==2 and e==1) > + > +a,b,c,d,e = f(4) > +assert(a==nil and b==nil and c==nil and d==nil and e==nil) > + > + > +-- varargs for main chunks > +f = loadstring[[ return {...} ]] > +x = f(2,3) > +assert(x[1] == 2 and x[2] == 3 and x[3] == nil) > + > + > +f = loadstring[[ > + local x = {...} > + for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end > + assert(x[select('#', ...)+1] == nil) > + return true > +]] > + > +assert(f("a", "b", nil, {}, assert)) > +assert(f()) > + > +a = {select(3, unpack{10,20,30,40})} > +assert(table.getn(a) == 2 and a[1] == 30 and a[2] == 40) > +a = {select(1)} > +assert(next(a) == nil) > +a = {select(-1, 3, 5, 7)} > +assert(a[1] == 7 and a[2] == nil) > +a = {select(-2, 3, 5, 7)} > +assert(a[1] == 5 and a[2] == 7 and a[3] == nil) > +pcall(select, 10000) > +pcall(select, -10000) > + > +print('OK') > + > diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua > new file mode 100644 > index 0000000..59e0142 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/verybig.lua > @@ -0,0 +1,100 @@ > +if rawget(_G, "_soft") then return 10 end > + > +print "testing large programs (>64k)" > + > +-- template to create a very big test file > +prog = [[$ > + > +local a,b > + > +b = {$1$ > + b30009 = 65534, > + b30010 = 65535, > + b30011 = 65536, > + b30012 = 65537, > + b30013 = 16777214, > + b30014 = 16777215, > + b30015 = 16777216, > + b30016 = 16777217, > + b30017 = 4294967294, > + b30018 = 4294967295, > + b30019 = 4294967296, > + b30020 = 4294967297, > + b30021 = -65534, > + b30022 = -65535, > + b30023 = -65536, > + b30024 = -4294967297, > + b30025 = 15012.5, > + $2$ > +}; > + > +assert(b.a50008 == 25004 and b["a11"] == 5.5) > +assert(b.a33007 == 16503.5 and b.a50009 == 25004.5) > +assert(b["b"..30024] == -4294967297) > + > +function b:xxx (a,b) return a+b end > +assert(b:xxx(10, 12) == 22) -- pushself with non-constant index > +b.xxx = nil > + > +s = 0; n=0 > +for a,b in pairs(b) do s=s+b; n=n+1 end > +assert(s==13977183656.5 and n==70001) > + > +require "checktable" > +stat(b) > + > +a = nil; b = nil > +print'+' > + > +function f(x) b=x end > + > +a = f{$3$} or 10 > + > +assert(a==10) > +assert(b[1] == "a10" and b[2] == 5 and b[table.getn(b)-1] == "a50009") > + > + > +function xxxx (x) return b[x] end > + > +assert(xxxx(3) == "a11") > + > +a = nil; b=nil > +xxxx = nil > + > +return 10 > + > +]] > + > +-- functions to fill in the $n$ > +F = { > +function () -- $1$ > + for i=10,50009 do > + io.write('a', i, ' = ', 5+((i-10)/2), ',\n') > + end > +end, > + > +function () -- $2$ > + for i=30026,50009 do > + io.write('b', i, ' = ', 15013+((i-30026)/2), ',\n') > + end > +end, > + > +function () -- $3$ > + for i=10,50009 do > + io.write('"a', i, '", ', 5+((i-10)/2), ',\n') > + end > +end, > +} > + > +file = os.tmpname() > +io.output(file) > +for s in string.gmatch(prog, "$([^$]+)") do > + local n = tonumber(s) > + if not n then io.write(s) else F[n]() end > +end > +io.close() > +result = dofile(file) > +assert(os.remove(file)) > +print'OK' > +return result > + > -- > 2.31.0 >
next prev parent reply other threads:[~2021-03-26 10:14 UTC|newest] Thread overview: 153+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt " Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches 2021-03-26 10:14 ` Sergey Ostanevich via Tarantool-patches [this message] 2021-03-30 22:13 ` Igor Munkin via Tarantool-patches 2021-04-01 8:11 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches 2021-03-26 11:01 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 8:21 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches 2021-03-26 11:07 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:25 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:43 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:40 ` Sergey Kaplun via Tarantool-patches 2021-04-06 16:56 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches 2021-03-26 11:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:50 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 11:22 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 9:37 ` Sergey Kaplun via Tarantool-patches 2021-04-06 15:24 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches 2021-03-26 11:26 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:31 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 9:56 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches 2021-03-26 11:30 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches 2021-03-26 11:32 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 10:10 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches 2021-03-26 11:35 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:33 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 2021-04-01 10:06 ` Sergey Kaplun via Tarantool-patches 2021-04-06 19:45 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 11:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:45 ` Sergey Kaplun via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 10:16 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches 2021-03-26 11:47 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:52 ` Sergey Kaplun via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:37 ` Sergey Kaplun via Tarantool-patches 2021-04-06 20:09 ` Igor Munkin via Tarantool-patches 2021-04-06 20:40 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches 2021-03-26 11:49 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches 2021-03-26 14:43 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:52 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches 2021-03-26 14:50 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:58 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 12:03 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches 2021-03-26 14:56 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 12:33 ` Sergey Kaplun via Tarantool-patches 2021-04-06 21:37 ` Igor Munkin via Tarantool-patches 2021-04-07 15:50 ` Sergey Kaplun via Tarantool-patches 2021-04-07 16:31 ` Igor Munkin via Tarantool-patches 2021-04-08 8:51 ` Sergey Kaplun via Tarantool-patches 2021-04-12 10:26 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 14:58 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 19:12 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-03-26 15:16 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 19:36 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches 2021-03-26 15:14 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-04-02 7:05 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:22 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-04-02 7:21 ` Sergey Kaplun via Tarantool-patches 2021-04-06 20:45 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches 2021-03-26 15:41 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-04-02 7:40 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches 2021-03-26 15:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 16:01 ` Sergey Kaplun via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-04-02 7:48 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches 2021-03-26 15:45 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-04-02 8:14 ` Sergey Kaplun via Tarantool-patches 2021-04-06 21:37 ` Igor Munkin via Tarantool-patches 2021-04-07 16:06 ` Sergey Kaplun via Tarantool-patches 2021-04-07 16:11 ` Igor Munkin via Tarantool-patches 2021-04-07 19:57 ` Sergey Kaplun via Tarantool-patches 2021-04-12 9:36 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches 2021-03-26 15:46 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-04-02 8:20 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 25/30] test: disable PUC Lua error test for syntax level Sergey Kaplun via Tarantool-patches 2021-03-26 15:52 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-04-02 8:30 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 26/30] test: disable tests with multiple -l options Sergey Kaplun via Tarantool-patches 2021-03-26 15:56 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 27/30] test: disable PUC Lua test for checking arg layout Sergey Kaplun via Tarantool-patches 2021-03-26 15:58 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-04-02 8:35 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 28/30] test: disable PUC Lua test checking -h option Sergey Kaplun via Tarantool-patches 2021-03-26 15:58 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-04-02 8:39 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 29/30] test: disable PUC Lua hanging GC test Sergey Kaplun via Tarantool-patches 2021-03-26 16:03 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-04-02 8:45 ` Sergey Kaplun via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 30/30] test: disable too depth recursive PUC Lua test Sergey Kaplun via Tarantool-patches 2021-03-26 16:28 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 16:45 ` Sergey Kaplun via Tarantool-patches 2021-03-31 19:24 ` Igor Munkin via Tarantool-patches 2021-04-02 8:47 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:09 ` [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Ostanevich via Tarantool-patches 2021-03-26 14:12 ` Sergey Kaplun via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-03-31 9:41 ` Sergey Kaplun via Tarantool-patches 2021-03-31 10:49 ` Igor Munkin via Tarantool-patches
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=D71B8C6B-3AFC-4989-B866-27547A85C790@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=sergos@tarantool.org \ --cc=skaplun@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox