From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 076DA6EC56; Tue, 16 Mar 2021 16:35:31 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 076DA6EC56 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1615901731; bh=/LqRG2A8DuN7iEgymy6YVTO9fC4aVvZGXi0rQHuP6FU=; h=In-Reply-To:Date:References:To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Pt2emvGiW/0iGTAaMu3BK7ArBqMEsRIlkX7WBCg91t2/rrY8DUound4K7bPpupuHb 7iMV6h06yKJXQa/M6QRsG1ReAzOwoCXLVx1br89IUXQG1OgY1lOHDp6+aWlKOWWGMt gahmGMcmmYGyABhAOAzUwxh2hn1zsRVj9r2d6n0M= Received: from smtp31.i.mail.ru (smtp31.i.mail.ru [94.100.177.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 2C4D56EC56 for ; Tue, 16 Mar 2021 16:35:26 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 2C4D56EC56 Received: by smtp31.i.mail.ru with esmtpa (envelope-from ) id 1lM9r1-0005Rp-O5; Tue, 16 Mar 2021 16:35:24 +0300 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.60.0.2.21\)) In-Reply-To: <19e526eec5407d656bbb667870a7a2527ab509a7.1615472551.git.skaplun@tarantool.org> Date: Tue, 16 Mar 2021 16:35:23 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <91E86450-7252-44D8-B6DA-001FD393FB1A@tarantool.org> References: <19e526eec5407d656bbb667870a7a2527ab509a7.1615472551.git.skaplun@tarantool.org> To: Sergey Kaplun X-Mailer: Apple Mail (2.3654.60.0.2.21) X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9D3134714A9BDB69BBBF766E27323369B0CCE27335774643500894C459B0CD1B9C4E2B6D0598574837B7CC40BDCB69AE1A39024E2EF3FFD6E8BED4F303C0FECC6 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE70993CE289E4873FDEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637BE899A9B5C1209058638F802B75D45FF914D58D5BE9E6BC131B5C99E7648C95CF89CA98302ED496FA9CF2605FE4A67032A2A9F7AF6679851A471835C12D1D9774AD6D5ED66289B5259CC434672EE6371117882F4460429724CE54428C33FAD30A8DF7F3B2552694AC26CFBAC0749D213D2E47CDBA5A9658359CC434672EE6371117882F4460429728AD0CFFFB425014E868A13BD56FB6657A7F4EDE966BC389F9E8FC8737B5C224982BBBAF5DF00056E089D37D7C0E48F6CCF19DD082D7633A0E7DDDDC251EA7DABAAAE862A0553A39223F8577A6DFFEA7CE52E467C461EF0E943847C11F186F3C5E7DDDDC251EA7DABCC89B49CDF41148FDCD13837A2BCF0203C9F3DD0FB1AF5EB4E70A05D1297E1BBCB5012B2E24CD356 X-C1DE0DAB: 0D63561A33F958A51D03A37B951D65A992403E834149D38DED04ED91DBE416B9D59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA75F04B387B5D7535DE410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D3454CC76E5F54B410C974B9601178D1EDB49B61DB2F9647D24C06686C87B04BCC2DF5DF699D2F1E2E41D7E09C32AA3244C7578E328D3158A1E3327E36811F55F4705AB220A9D022EBCFACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojwV/GgY7Z4vU0HFjpVBo7oQ== X-Mailru-Sender: 3B9A0136629DC912F4AABCEFC589C81EA75E6271E027F6B49BC697037B62419E5CD0503119E437EEAD07DD1419AC565FA614486B47F28B67C5E079CCF3B0523AED31B7EB2E253A9E112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 1/3] test: add PUC-Rio Lua 5.1 test suite X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Ostanevich via Tarantool-patches Reply-To: Sergey Ostanevich Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi! Thanks for the patch! > On 12 Mar 2021, at 08:36, Sergey Kaplun wrote: >=20 > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT > test suite. Source code taken verbatim from > https://www.lua.org/tests/lua5.1-tests.tar.gz. >=20 > and is slightly modified to be consistent with the > current LuaJIT's LuaC API. >=20 This should be a different commit, isn=E2=80=99t it? > Some tests may fail after this commit. They will be disabled > or adapted in the next patches. The fact patch causes - even temporarily - some fails is no good. The only exception is initial commit, that brings original test suite. Can you please make a consistent change that will left the tests = disabled until they adapted and enabled back? regards, Sergos >=20 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > .luacheckrc | 5 +- > test/CMakeLists.txt | 4 +- > test/PUC-Lua-5.1-tests/CMakeLists.txt | 89 ++ > 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/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 +++ > 34 files changed, 7783 insertions(+), 3 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/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 >=20 > diff --git a/.luacheckrc b/.luacheckrc > index 1a76108..cbd2912 100644 > --- a/.luacheckrc > +++ b/.luacheckrc > @@ -3,10 +3,11 @@ std =3D 'luajit' > -- This fork also introduces a new global for misc API namespace. > read_globals =3D { 'misc' } >=20 > --- 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 =3D { > 'dynasm/', > 'src/', > 'test/LuaJIT-tests/', > + 'test/PUC-Lua-5.1-tests/', > } > diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt > index 99471db..93c43ea 100644 > --- a/test/CMakeLists.txt > +++ b/test/CMakeLists.txt > @@ -43,11 +43,13 @@ endif() > set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e = dofile[[${LUAJIT_TEST_INIT}]]") > separate_arguments(LUAJIT_TEST_COMMAND) >=20 > -add_subdirectory(tarantool-tests) > add_subdirectory(LuaJIT-tests) > +add_subdirectory(PUC-Lua-5.1-tests) > +add_subdirectory(tarantool-tests) >=20 > add_custom_target(${PROJECT_NAME}-test DEPENDS > LuaJIT-tests > + PUC-Lua-5.1-tests > tarantool-tests > ) >=20 > 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..08bee36 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -0,0 +1,89 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/4473. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +set(TEST_RUNNER ${CMAKE_CURRENT_SOURCE_DIR}/all.lua) > +set(LIB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/libs) > +set(TESTLIB_PATH ${CMAKE_CURRENT_BINARY_DIR}/libs) > + > +# XXX: -fPIC is required to linking with static library. > +if(NOT BUILDMODE STREQUAL "static") > + # Build additional C libraries for tests. > + macro(build_lib lib sources) > + add_library(${lib} SHARED EXCLUDE_FROM_ALL ${sources}) > + target_include_directories(${lib} PRIVATE > + ${LUAJIT_SOURCE_DIR} > + ) > + set_target_properties(${lib} PROPERTIES > + LIBRARY_OUTPUT_DIRECTORY "${TESTLIB_PATH}" > + PREFIX "" > + ) > + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") > + set_target_properties(${lib} PROPERTIES > + LINK_FLAGS "-undefined dynamic_lookup" > + ) > + endif() > + target_link_libraries(${lib} PRIVATE libluajit_shared) > + list(APPEND TESTLIBS ${lib}) > + endmacro() > + > + build_lib(lib1 ${LIB_SOURCES}/lib1.c) > + build_lib(lib11 ${LIB_SOURCES}/lib1.c ${LIB_SOURCES}/lib11.c) > + build_lib(lib2 ${LIB_SOURCES}/lib2.c) > + build_lib(lib21 ${LIB_SOURCES}/lib2.c ${LIB_SOURCES}/lib21.c) > + > + set(LIB2COPY "${TESTLIB_PATH}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > + set(LIB_COPY "${TESTLIB_PATH}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > + > + add_custom_command( > + COMMENT "Copping lib2 to -lib2 for PUC-Rio Lua 5.1 tests" > + OUTPUT ${LIB_COPY} > + DEPENDS ${TESTLIBS} > + COMMAND ${CMAKE_COMMAND} -E copy ${LIB2COPY} ${LIB_COPY} > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > + ) > + list(APPEND TESTLIBS ${LIB_COPY}) > +endif() > + > +set(CUSTOM_TEST_DIR ${TESTLIB_PATH}/P1) > +add_custom_command( > + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > + OUTPUT ${CUSTOM_TEST_DIR} > + COMMAND ${CMAKE_COMMAND} -E make_directory ${CUSTOM_TEST_DIR} > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > + > +# TODO: PUC-Rio Lua 5.1 test suite also has special header > +# and 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, depends on specific PUC-Rio Lua 5.1 > +# internal headers and should be adopted for LuaJIT. > + > +add_custom_target(PUC-Lua-5.1-tests > + DEPENDS ${LUAJIT_TEST_BINARY} ${TESTLIBS} ${CUSTOM_TEST_DIR} > +) > + > +add_custom_command(TARGET PUC-Lua-5.1-tests > + COMMENT "Running PUC-Rio Lua 5.1 tests" > + COMMAND > + env > + # Tarantool doesn't support LUA_INIT and most likely it > + # never will. > + # See https://github.com/tarantool/tarantool/issues/5744 > + # for more info. > + # LUA_PATH=3D"${CMAKE_CURRENT_BINARY_DIR}/?.lua\;\;" > + # LUA_INIT=3D"package.path=3D'?\;'..package.path" > + # So use less preferable way for tests. > + LUA_PATH=3D"${LUA_PATH}\;\;" > + ${LUAJIT_TEST_COMMAND} ${TEST_RUNNER} > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=3D2 shiftwidth=3D2 > 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 =3D '?;'..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=3D'"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) > + > + > +--[=3D[ > + example of a long [comment], > + [[spanning several [lines]]] > + > +]=3D] > + > +print("current path:\n " .. string.gsub(package.path, ";", "\n ")) > + > + > +local msgs =3D {} > +function Message (m) > + print(m) > + msgs[#msgs+1] =3D string.sub(m, 3, -3) > +end > + > + > +local c =3D os.clock() > + > +assert(os.setlocale"C") > + > +local T,print,gcinfo,format,write,assert,type =3D > + T,print,gcinfo,string.format,io.write,assert,type > + > +local function formatmem (m) > + if m < 1024 then return m > + else > + m =3D m/1024 - m/1024%1 > + if m < 1024 then return m.."K" > + else > + m =3D m/1024 - m/1024%1 > + return m.."M" > + end > + end > +end > + > +local showmem =3D function () > + if not T then > + print(format(" ---- total memory: %s ----\n", = formatmem(gcinfo()))) > + else > + T.checkmemory() > + local a,b,c =3D T.totalmem() > + local d,e =3D 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 =3D function (n) > + showmem() > + local f =3D assert(loadfile(n)) > + local b =3D string.dump(f) > + f =3D assert(loadstring(b)) > + return f() > +end > + > +dofile('main.lua') > + > +do > + local u =3D newproxy(true) > + local newproxy, stderr =3D newproxy, io.stderr > + getmetatable(u).__gc =3D function (o) > + stderr:write'.' > + newproxy(o) > + end > +end > + > +local f =3D assert(loadfile('gc.lua')) > +f() > +dofile('db.lua') > +assert(dofile('calls.lua') =3D=3D deep and deep) > +dofile('strings.lua') > +dofile('literals.lua') > +assert(dofile('attrib.lua') =3D=3D 27) > +assert(dofile('locals.lua') =3D=3D 5) > +dofile('constructs.lua') > +dofile('code.lua') > +do > + local f =3D coroutine.wrap(assert(loadfile('big.lua'))) > + assert(f() =3D=3D 'b') > + assert(f() =3D=3D 'a') > +end > +dofile('nextvar.lua') > +dofile('pm.lua') > +dofile('api.lua') > +assert(dofile('events.lua') =3D=3D 12) > +dofile('vararg.lua') > +dofile('closure.lua') > +dofile('errors.lua') > +dofile('math.lua') > +dofile('sort.lua') > +assert(dofile('verybig.lua') =3D=3D 10); collectgarbage() > +dofile('files.lua') > + > +if #msgs > 0 then > + print("\ntests not performed:") > + for i=3D1,#msgs do > + print(msgs[i]) > + end > + print() > +end > + > +print("final OK !!!") > +print('cleaning all!!!!') > + > +debug.sethook(function (a) assert(type(a) =3D=3D 'string') end, "cr") > + > +local _G, collectgarbage, showmem, print, format, clock =3D > + _G, collectgarbage, showmem, print, format, os.clock > + > +local a=3D{} > +for n in pairs(_G) do a[n] =3D 1 end > +a.tostring =3D nil > +a.___Glob =3D nil > +for n in pairs(a) do _G[n] =3D nil end > + > +a =3D 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=3D=3Dnil 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) =3D=3D table.getn(t2)) > + for i=3D1,table.getn(t1) do assert(t1[i] =3D=3D t2[i]) end > +end > + > +function pack(...) return arg end > + > + > +print('testing C API') > + > +-- testing allignment > +a =3D T.d2s(12458954321123) > +assert(string.len(a) =3D=3D 8) -- sizeof(double) > +assert(T.s2d(a) =3D=3D 12458954321123) > + > +a,b,c =3D T.testC("pushnum 1; pushnum 2; pushnum 3; return 2") > +assert(a =3D=3D 2 and b =3D=3D 3 and not c) > + > +-- test that all trues are equal > +a,b,c =3D T.testC("pushbool 1; pushbool 2; pushbool 0; return 3") > +assert(a =3D=3D b and a =3D=3D true and c =3D=3D false) > +a,b,c =3D T.testC"pushbool 0; pushbool 10; pushnil;\ > + tobool -3; tobool -3; tobool -3; return 3" > +assert(a=3D=3D0 and b=3D=3D1 and c=3D=3D0) > + > + > +a,b,c =3D T.testC("gettop; return 2", 10, 20, 30, 40) > +assert(a =3D=3D 40 and b =3D=3D 5 and not c) > + > +t =3D pack(T.testC("settop 5; gettop; return .", 2, 3)) > +tcheck(t, {n=3D4,2,3}) > + > +t =3D pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23)) > +assert(t.n =3D=3D 10 and t[1] =3D=3D nil and t[10] =3D=3D nil) > + > +t =3D pack(T.testC("remove -2; gettop; return .", 2, 3, 4)) > +tcheck(t, {n=3D2,2,4}) > + > +t =3D pack(T.testC("insert -1; gettop; return .", 2, 3)) > +tcheck(t, {n=3D2,2,3}) > + > +t =3D pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3D4,2,5,3,4}) > + > +t =3D pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3D3,5,3,4}) > + > +t =3D pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3D3,2,3,5}) > + > +t =3D pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3D3,2,4,5}) > + > +t =3D 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=3D7,2,3,4,5,10,40,90}) > + > +t =3D pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", = 12)) > +tcheck(t, {n=3D1,"alo23joao12"}) > + > +-- testing MULTRET > +t =3D pack(T.testC("rawcall 2,-1; gettop; return .", > + function (a,b) return 1,2,3,4,a,b end, "alo", "joao")) > +tcheck(t, {n=3D6,1,2,3,4,"alo", "joao"}) > + > +do -- test returning more results than fit in the caller stack > + local a =3D {} > + for i=3D1,1000 do a[i] =3D true end; a[999] =3D 10 > + local b =3D T.testC([[call 1 -1; pop 1; tostring -1; return 1]], = unpack, a) > + assert(b =3D=3D "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 =3D {__lt =3D function (a,b) return a[1] < b[1] end} > +local a1,a3,a4 =3D 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 =3D T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20) > +assert(a =3D=3D 20 and b =3D=3D false) > + > + > +-- testing lua_is > + > +function count (x, n) > + n =3D n or 2 > + local prog =3D [[ > + isnumber %d; > + isstring %d; > + isfunction %d; > + iscfunction %d; > + istable %d; > + isuserdata %d; > + isnil %d; > + isnull %d; > + return 8 > + ]] > + prog =3D string.format(prog, n, n, n, n, n, n, n, n) > + local a,b,c,d,e,f,g,h =3D T.testC(prog, x) > + return a+b+c+d+e+f+g+(100*h) > +end > + > +assert(count(3) =3D=3D 2) > +assert(count('alo') =3D=3D 1) > +assert(count('32') =3D=3D 2) > +assert(count({}) =3D=3D 1) > +assert(count(print) =3D=3D 2) > +assert(count(function () end) =3D=3D 1) > +assert(count(nil) =3D=3D 1) > +assert(count(io.stdin) =3D=3D 1) > +assert(count(nil, 15) =3D=3D 100) > + > +-- testing lua_to... > + > +function to (s, x, n) > + n =3D n or 2 > + return T.testC(string.format("%s %d; return 1", s, n), x) > +end > + > +assert(to("tostring", {}) =3D=3D nil) > +assert(to("tostring", "alo") =3D=3D "alo") > +assert(to("tostring", 12) =3D=3D "12") > +assert(to("tostring", 12, 3) =3D=3D nil) > +assert(to("objsize", {}) =3D=3D 0) > +assert(to("objsize", "alo\0\0a") =3D=3D 6) > +assert(to("objsize", T.newuserdata(0)) =3D=3D 0) > +assert(to("objsize", T.newuserdata(101)) =3D=3D 101) > +assert(to("objsize", 12) =3D=3D 2) > +assert(to("objsize", 12, 3) =3D=3D 0) > +assert(to("tonumber", {}) =3D=3D 0) > +assert(to("tonumber", "12") =3D=3D 12) > +assert(to("tonumber", "s2") =3D=3D 0) > +assert(to("tonumber", 1, 20) =3D=3D 0) > +a =3D to("tocfunction", math.deg) > +assert(a(3) =3D=3D math.deg(3) and a ~=3D math.deg) > + > + > +-- testing errors > + > +a =3D T.testC([[ > + loadstring 2; call 0,1; > + pushvalue 3; insert -2; call 1, 1; > + call 0, 0; > + return 1 > +]], "x=3D150", function (a) assert(a=3D=3Dnil); return 3 end) > + > +assert(type(a) =3D=3D 'string' and x =3D=3D 150) > + > +function check3(p, ...) > + assert(arg.n =3D=3D 3) > + assert(string.find(arg[3], p)) > +end > +check3(":1:", T.testC("loadstring 2; gettop; return .", "x=3D")) > +check3("cannot read", T.testC("loadfile 2; gettop; return .", ".")) > +check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", = "xxxx")) > + > +-- testing table access > + > +a =3D {x=3D0, y=3D12} > +x, y =3D T.testC("gettable 2; pushvalue 4; gettable 2; return 2", > + a, 3, "y", 4, "x") > +assert(x =3D=3D 0 and y =3D=3D 12) > +T.testC("settable -5", a, 3, 4, "x", 15) > +assert(a.x =3D=3D 15) > +a[a] =3D print > +x =3D T.testC("gettable 2; return 1", a) -- table and key are the = same object! > +assert(x =3D=3D print) > +T.testC("settable 2", a, "x") -- table and key are the same = object! > +assert(a[a] =3D=3D "x") > + > +b =3D setmetatable({p =3D a}, {}) > +getmetatable(b).__index =3D function (t, i) return t.p[i] end > +k, x =3D T.testC("gettable 3, return 2", 4, b, 20, 35, "x") > +assert(x =3D=3D 15 and k =3D=3D 35) > +getmetatable(b).__index =3D function (t, i) return a[i] end > +getmetatable(b).__newindex =3D function (t, i,v ) a[i] =3D v end > +y =3D T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b) > +assert(y =3D=3D 12) > +k =3D T.testC("settable -5, return 1", b, 3, 4, "x", 16) > +assert(a.x =3D=3D 16 and k =3D=3D 4) > +a[b] =3D 'xuxu' > +y =3D T.testC("gettable 2, return 1", b) > +assert(y =3D=3D 'xuxu') > +T.testC("settable 2", b, 19) > +assert(a[b] =3D=3D 19) > + > +-- testing next > +a =3D {} > +t =3D pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=3D1,a}) > +a =3D {a=3D3} > +t =3D pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=3D3,a,'a',3}) > +t =3D pack(T.testC("next; pop 1; next; gettop; return .", a, nil)) > +tcheck(t, {n=3D1,a}) > + > + > + > +-- testing upvalues > + > +do > + local A =3D T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; = return 1]] > + t, b, c =3D A([[pushvalue U0; pushvalue U1; pushvalue U2; return = 3]]) > + assert(b =3D=3D 10 and c =3D=3D 20 and type(t) =3D=3D 'table') > + a, b =3D A([[tostring U3; tonumber U4; return 2]]) > + assert(a =3D=3D nil and b =3D=3D 0) > + A([[pushnum 100; pushnum 200; replace U2; replace U1]]) > + b, c =3D A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b =3D=3D 100 and c =3D=3D 200) > + A([[replace U2; replace U1]], {x=3D1}, {x=3D2}) > + b, c =3D A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b.x =3D=3D 1 and c.x =3D=3D 2) > + T.checkmemory() > +end > + > +local f =3D T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return = 1]] > +assert(T.upvalue(f, 1) =3D=3D 10 and > + T.upvalue(f, 2) =3D=3D 20 and > + T.upvalue(f, 3) =3D=3D nil) > +T.upvalue(f, 2, "xuxu") > +assert(T.upvalue(f, 2) =3D=3D "xuxu") > + > + > +-- testing environments > + > +assert(T.testC"pushvalue G; return 1" =3D=3D _G) > +assert(T.testC"pushvalue E; return 1" =3D=3D _G) > +local a =3D {} > +T.testC("replace E; return 1", a) > +assert(T.testC"pushvalue G; return 1" =3D=3D _G) > +assert(T.testC"pushvalue E; return 1" =3D=3D a) > +assert(debug.getfenv(T.testC) =3D=3D a) > +assert(debug.getfenv(T.upvalue) =3D=3D _G) > +-- userdata inherit environment > +local u =3D T.testC"newuserdata 0; return 1" > +assert(debug.getfenv(u) =3D=3D a) > +-- functions inherit environment > +u =3D T.testC"pushcclosure 0; return 1" > +assert(debug.getfenv(u) =3D=3D a) > +debug.setfenv(T.testC, _G) > +assert(T.testC"pushvalue E; return 1" =3D=3D _G) > + > +local b =3D newproxy() > +assert(debug.getfenv(b) =3D=3D _G) > +assert(debug.setfenv(b, a)) > +assert(debug.getfenv(b) =3D=3D a) > + > + > + > +-- testing locks (refs) > + > +-- reuse of references > +local i =3D T.ref{} > +T.unref(i) > +assert(T.ref{} =3D=3D i) > + > +Arr =3D {} > +Lim =3D 100 > +for i=3D1,Lim do -- lock many objects > + Arr[i] =3D T.ref({}) > +end > + > +assert(T.ref(nil) =3D=3D -1 and T.getref(-1) =3D=3D nil) > +T.unref(-1); T.unref(-1) > + > +for i=3D1,Lim do -- unlock all them > + T.unref(Arr[i]) > +end > + > +function printlocks () > + local n =3D T.testC("gettable R; return 1", "n") > + print("n", n) > + for i=3D0,n do > + print(i, T.testC("gettable R; return 1", i)) > + end > +end > + > + > +for i=3D1,Lim do -- lock many objects > + Arr[i] =3D T.ref({}) > +end > + > +for i=3D1,Lim,2 do -- unlock half of them > + T.unref(Arr[i]) > +end > + > +assert(type(T.getref(Arr[2])) =3D=3D 'table') > + > + > +assert(T.getref(-1) =3D=3D nil) > + > + > +a =3D T.ref({}) > + > +collectgarbage() > + > +assert(type(T.getref(a)) =3D=3D 'table') > + > + > +-- colect in cl the `val' of all collected userdata > +tt =3D {} > +cl =3D {n=3D0} > +A =3D nil; B =3D nil > +local F > +F =3D function (x) > + local udval =3D T.udataval(x) > + table.insert(cl, udval) > + local d =3D T.newuserdata(100) -- cria lixo > + d =3D nil > + assert(debug.getmetatable(x).__gc =3D=3D F) > + loadstring("table.insert({}, {})")() -- cria mais lixo > + collectgarbage() -- forca coleta de lixo durante coleta! > + assert(debug.getmetatable(x).__gc =3D=3D F) -- coleta anterior = nao melou isso? > + local dummy =3D {} -- cria lixo durante coleta > + if A ~=3D nil then > + assert(type(A) =3D=3D "userdata") > + assert(T.udataval(A) =3D=3D B) > + debug.getmetatable(A) -- just acess it > + end > + A =3D x -- ressucita userdata > + B =3D udval > + return 1,2,3 > +end > +tt.__gc =3D F > + > +-- test whether udate collection frees memory in the right time > +do > + collectgarbage(); > + collectgarbage(); > + local x =3D collectgarbage("count"); > + local a =3D T.newuserdata(5001) > + assert(T.testC("objsize 2; return 1", a) =3D=3D 5001) > + assert(collectgarbage("count") >=3D x+4) > + a =3D nil > + collectgarbage(); > + assert(collectgarbage("count") <=3D x+1) > + -- udata without finalizer > + x =3D collectgarbage("count") > + collectgarbage("stop") > + for i=3D1,1000 do newproxy(false) end > + assert(collectgarbage("count") > x+10) > + collectgarbage() > + assert(collectgarbage("count") <=3D x+1) > + -- udata with finalizer > + x =3D collectgarbage("count") > + collectgarbage() > + collectgarbage("stop") > + a =3D newproxy(true) > + getmetatable(a).__gc =3D function () end > + for i=3D1,1000 do newproxy(a) end > + assert(collectgarbage("count") >=3D x+10) > + collectgarbage() -- this collection only calls TM, without freeing = memory > + assert(collectgarbage("count") >=3D x+10) > + collectgarbage() -- now frees memory > + assert(collectgarbage("count") <=3D x+1) > +end > + > + > +collectgarbage("stop") > + > +-- create 3 userdatas with tag `tt' > +a =3D T.newuserdata(0); debug.setmetatable(a, tt); na =3D = T.udataval(a) > +b =3D T.newuserdata(0); debug.setmetatable(b, tt); nb =3D = T.udataval(b) > +c =3D T.newuserdata(0); debug.setmetatable(c, tt); nc =3D = T.udataval(c) > + > +-- create userdata without meta table > +x =3D T.newuserdata(4) > +y =3D T.newuserdata(0) > + > +assert(debug.getmetatable(x) =3D=3D nil and debug.getmetatable(y) =3D=3D= nil) > + > +d=3DT.ref(a); > +e=3DT.ref(b); > +f=3DT.ref(c); > +t =3D {T.getref(d), T.getref(e), T.getref(f)} > +assert(t[1] =3D=3D a and t[2] =3D=3D b and t[3] =3D=3D c) > + > +t=3Dnil; a=3Dnil; c=3Dnil; > +T.unref(e); T.unref(f) > + > +collectgarbage() > + > +-- check that unref objects have been collected > +assert(table.getn(cl) =3D=3D 1 and cl[1] =3D=3D nc) > + > +x =3D T.getref(d) > +assert(type(x) =3D=3D 'userdata' and debug.getmetatable(x) =3D=3D tt) > +x =3Dnil > +tt.b =3D b -- create cycle > +tt=3Dnil -- frees tt for GC > +A =3D nil > +b =3D nil > +T.unref(d); > +n5 =3D T.newuserdata(0) > +debug.setmetatable(n5, {__gc=3DF}) > +n5 =3D T.udataval(n5) > +collectgarbage() > +assert(table.getn(cl) =3D=3D 4) > +-- check order of collection > +assert(cl[2] =3D=3D n5 and cl[3] =3D=3D nb and cl[4] =3D=3D na) > + > + > +a, na =3D {}, {} > +for i=3D30,1,-1 do > + a[i] =3D T.newuserdata(0) > + debug.setmetatable(a[i], {__gc=3DF}) > + na[i] =3D T.udataval(a[i]) > +end > +cl =3D {} > +a =3D nil; collectgarbage() > +assert(table.getn(cl) =3D=3D 30) > +for i=3D1,30 do assert(cl[i] =3D=3D na[i]) end > +na =3D nil > + > + > +for i=3D2,Lim,2 do -- unlock the other half > + T.unref(Arr[i]) > +end > + > +x =3D T.newuserdata(41); debug.setmetatable(x, {__gc=3DF}) > +assert(T.testC("objsize 2; return 1", x) =3D=3D 41) > +cl =3D {} > +a =3D {[x] =3D 1} > +x =3D T.udataval(x) > +collectgarbage() > +-- old `x' cannot be collected (`a' still uses it) > +assert(table.getn(cl) =3D=3D 0) > +for n in pairs(a) do a[n] =3D nil end > +collectgarbage() > +assert(table.getn(cl) =3D=3D 1 and cl[1] =3D=3D 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 =3D {} > + local t =3D {__eq =3D function (a,b) return map[a] =3D=3D map[b] = end} > + local function f(x) > + local u =3D T.newuserdata(0) > + debug.setmetatable(u, t) > + map[u] =3D x > + return u > + end > + assert(f(10) =3D=3D f(10)) > + assert(f(10) ~=3D 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 =3D nil > + assert(f(10) ~=3D f(10)) > +end > + > +print'+' > + > + > + > = +-------------------------------------------------------------------------= > +do -- testing errors during GC > + local a =3D {} > + for i=3D1,20 do > + a[i] =3D T.newuserdata(i) -- creates several udata > + end > + for i=3D1,20,2 do -- mark half of them to raise error during GC > + debug.setmetatable(a[i], {__gc =3D function (x) error("error = inside gc") end}) > + end > + for i=3D2,20,2 do -- mark the other half to count and to create = more garbage > + debug.setmetatable(a[i], {__gc =3D function (x) = loadstring("A=3DA+1")() end}) > + end > + _G.A =3D 0 > + a =3D 0 > + while 1 do > + if xpcall(collectgarbage, function (s) a=3Da+1 end) then > + break -- stop if no more errors > + end > + end > + assert(a =3D=3D 10) -- number of errors > + assert(A =3D=3D 10) -- number of normal collections > +end > = +-------------------------------------------------------------------------= > +-- test for userdata vals > +do > + local a =3D {}; local lim =3D 30 > + for i=3D0,lim do a[i] =3D T.pushuserdata(i) end > + for i=3D0,lim do assert(T.udataval(a[i]) =3D=3D i) end > + for i=3D0,lim do assert(T.pushuserdata(i) =3D=3D a[i]) end > + for i=3D0,lim do a[a[i]] =3D i end > + for i=3D0,lim do a[T.pushuserdata(i)] =3D i end > + assert(type(tostring(a[1])) =3D=3D "string") > +end > + > + > = +-------------------------------------------------------------------------= > +-- testing multiple states > +T.closestate(T.newstate()); > +L1 =3D T.newstate() > +assert(L1) > +assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; = f()")).n =3D=3D 0) > + > +a, b =3D T.doremote(L1, "return f()") > +assert(a =3D=3D 'alo' and b =3D=3D '3') > + > +T.doremote(L1, "_ERRORMESSAGE =3D nil") > +-- error: `sin' is not defined > +a, b =3D T.doremote(L1, "return sin(1)") > +assert(a =3D=3D nil and b =3D=3D 2) -- 2 =3D=3D run-time error > + > +-- error: syntax error > +a, b, c =3D T.doremote(L1, "return a+") > +assert(a =3D=3D nil and b =3D=3D 3 and type(c) =3D=3D "string") -- = 3 =3D=3D syntax error > + > +T.loadlib(L1) > +a, b =3D T.doremote(L1, [[ > + a =3D strlibopen() > + a =3D packageopen() > + a =3D baselibopen(); assert(a =3D=3D _G and require("_G") =3D=3D a) > + a =3D iolibopen(); assert(type(a.read) =3D=3D "function") > + assert(require("io") =3D=3D a) > + a =3D tablibopen(); assert(type(a.insert) =3D=3D "function") > + a =3D dblibopen(); assert(type(a.getlocal) =3D=3D "function") > + a =3D mathlibopen(); assert(type(a.sin) =3D=3D "function") > + return string.sub('okinama', 1, 2) > +]]) > +assert(a =3D=3D "ok") > + > +T.closestate(L1); > + > +L1 =3D T.newstate() > +T.loadlib(L1) > +T.doremote(L1, "a =3D {}") > +T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1; > + settable -3]]) > +assert(T.doremote(L1, "return a.x") =3D=3D "1") > + > +T.closestate(L1) > + > +L1 =3D nil > + > +print('+') > + > = +-------------------------------------------------------------------------= > +-- testing memory limits > = +-------------------------------------------------------------------------= > +collectgarbage() > +T.totalmem(T.totalmem()+5000) -- set low memory limit (+5k) > +assert(not pcall(loadstring"local a=3D{}; for i=3D1,100000 do a[i]=3Di = 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 =3D T.totalmem() > + local oldM =3D M > + local a,b =3D nil > + while 1 do > + M =3D M+3 -- increase memory limit in small steps > + T.totalmem(M) > + a, b =3D 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 =3D testamem("state creation", T.newstate) > +T.closestate(b); -- close new state > + > + > +-- testing threads > + > +function expand (n,s) > + if n=3D=3D0 then return "" end > + local e =3D string.rep("=3D", n) > + return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); = %s]%s])\n", > + e, s, expand(n-1,s), e) > +end > + > +G=3D0; collectgarbage(); a =3Dcollectgarbage("count") > +loadstring(expand(20,"G=3DG+1"))() > +assert(G=3D=3D20); collectgarbage(); -- assert(gcinfo() <=3D a+1) > + > +testamem("thread creation", function () > + return T.doonnewstack("x=3D1") =3D=3D 0 -- try to create thread > +end) > + > + > +-- testing memory x compiler > + > +testamem("loadstring", function () > + return loadstring("x=3D1") -- try to do a loadstring > +end) > + > + > +local testprog =3D [[ > +local function foo () return end > +local t =3D {"x"} > +a =3D "aaa" > +for _, v in ipairs(t) do a=3Da..v end > +return true > +]] > + > +-- testing memory x dofile > +_G.a =3D nil > +local t =3Dos.tmpname() > +local f =3D assert(io.open(t, "w")) > +f:write(testprog) > +f:close() > +testamem("dofile", function () > + local a =3D loadfile(t) > + return a and a() > +end) > +assert(os.remove(t)) > +assert(_G.a =3D=3D "aaax") > + > + > +-- other generic tests > + > +testamem("string creation", function () > + local a, b =3D string.gsub("alo alo", "(a)", function (x) return = x..'b' end) > + return (a =3D=3D 'ablo ablo') > +end) > + > +testamem("dump/undump", function () > + local a =3D loadstring(testprog) > + local b =3D a and string.dump(a) > + a =3D b and loadstring(b) > + return a and a() > +end) > + > +local t =3D os.tmpname() > +testamem("file creation", function () > + local f =3D 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 =3D {}, 10 > + for i=3D1,lim do a[i] =3D i; a[i..'a'] =3D {} end > + return (type(a[lim..'a']) =3D=3D 'table' and a[lim] =3D=3D lim) > +end) > + > +local a =3D 1 > +close =3D nil > +testamem("closure creation", function () > + function close (b,c) > + return function (x) return a+b+c+x end > + end > + return (close(2,3)(4) =3D=3D 10) > +end) > + > +testamem("coroutines", function () > + local a =3D coroutine.wrap(function () > + coroutine.yield(string.rep("a", 10)) > + return {} > + end) > + assert(string.len(a()) =3D=3D 10) > + return a() > +end) > + > +print'+' > + > +-- testing some auxlib functions > +assert(T.gsub("alo.alo.uhuh.", ".", "//") =3D=3D "alo//alo//uhuh//") > +assert(T.gsub("alo.alo.uhuh.", "alo", "//") =3D=3D "//.//.uhuh.") > +assert(T.gsub("", "alo", "//") =3D=3D "") > +assert(T.gsub("...", ".", "/.") =3D=3D "/././.") > +assert(T.gsub("...", "...", "") =3D=3D "") > + > + > +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" =3D=3D string) > +assert(require"math" =3D=3D math) > +assert(require"table" =3D=3D table) > +assert(require"io" =3D=3D io) > +assert(require"os" =3D=3D os) > +assert(require"debug" =3D=3D debug) > +assert(require"coroutine" =3D=3D coroutine) > + > +assert(type(package.path) =3D=3D "string") > +assert(type(package.cpath) =3D=3D "string") > +assert(type(package.loaded) =3D=3D "table") > +assert(type(package.preload) =3D=3D "table") > + > + > +local DIR =3D "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 =3D { > + ["A.lua"] =3D "", > + ["B.lua"] =3D "assert(...=3D=3D'B');require 'A'", > + ["A.lc"] =3D "", > + ["A"] =3D "", > + ["L"] =3D "", > + ["XXxX"] =3D "", > + ["C.lua"] =3D "package.loaded[...] =3D 25; require'C'" > +} > + > +AA =3D nil > +local extras =3D [[ > +NAME =3D '%s' > +REQUIRED =3D ... > +return AA]] > + > +createfiles(files, "", extras) > + > + > +local oldpath =3D package.path > + > +package.path =3D string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", = DIR) > + > +local try =3D function (p, n, r) > + NAME =3D nil > + local rr =3D require(p) > + assert(NAME =3D=3D n) > + assert(REQUIRED =3D=3D p) > + assert(rr =3D=3D r) > +end > + > +assert(require"C" =3D=3D 25) > +assert(require"C" =3D=3D 25) > +AA =3D nil > +try('B', 'B.lua', true) > +assert(package.loaded.B) > +assert(require"B" =3D=3D true) > +assert(package.loaded.A) > +package.loaded.A =3D nil > +try('B', nil, true) -- should not reload package > +try('A', 'A.lua', true) > +package.loaded.A =3D nil > +os.remove(DIR..'A.lua') > +AA =3D {} > +try('A', 'A.lc', AA) -- now must find second option > +assert(require("A") =3D=3D AA) > +AA =3D false > +try('K', 'L', false) -- default option > +try('K', 'L', false) -- default option (should reload it) > +assert(rawget(_G, "_REQUIREDNAME") =3D=3D nil) > + > +AA =3D "x" > +try("X", "XXxX", AA) > + > + > +removefiles(files) > + > + > +-- testing require of sub-packages > + > +package.path =3D string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) > + > +files =3D { > + ["P1/init.lua"] =3D "AA =3D 10", > + ["P1/xuxu.lua"] =3D "AA =3D 20", > +} > + > +createfiles(files, "module(..., package.seeall)\n", "") > +AA =3D 0 > + > +local m =3D assert(require"P1") > +assert(m =3D=3D P1 and m._NAME =3D=3D "P1" and AA =3D=3D 0 and m.AA = =3D=3D 10) > +assert(require"P1" =3D=3D P1 and P1 =3D=3D m) > +assert(require"P1" =3D=3D P1) > +assert(P1._PACKAGE =3D=3D "") > + > +local m =3D assert(require"P1.xuxu") > +assert(m =3D=3D P1.xuxu and m._NAME =3D=3D "P1.xuxu" and AA =3D=3D 0 = and m.AA =3D=3D 20) > +assert(require"P1.xuxu" =3D=3D P1.xuxu and P1.xuxu =3D=3D m) > +assert(require"P1.xuxu" =3D=3D P1.xuxu) > +assert(require"P1" =3D=3D P1) > +assert(P1.xuxu._PACKAGE =3D=3D "P1.") > +assert(P1.AA =3D=3D 10 and P1._PACKAGE =3D=3D "") > +assert(P1._G =3D=3D _G and P1.xuxu._G =3D=3D _G) > + > + > + > +removefiles(files) > + > + > +package.path =3D "" > +assert(not pcall(require, "file_does_not_exist")) > +package.path =3D "??\0?" > +assert(not pcall(require, "file_does_not_exist1")) > + > +package.path =3D oldpath > + > +-- check 'require' error message > +local fname =3D "file_does_not_exist2" > +local m, err =3D pcall(require, fname) > +for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do > + t =3D string.gsub(t, "?", fname) > + assert(string.find(err, t, 1, true)) > +end > + > + > +local function import(...) > + local f =3D {...} > + return function (m) > + for i=3D1, #f do m[f[i]] =3D _G[f[i]] end > + end > +end > + > +local assert, module, package =3D assert, module, package > +X =3D nil; x =3D 0; assert(_G.x =3D=3D 0) -- `x' must be a global = variable > +module"X"; x =3D 1; assert(_M.x =3D=3D 1) > +module"X.a.b.c"; x =3D 2; assert(_M.x =3D=3D 2) > +module("X.a.b", package.seeall); x =3D 3 > +assert(X._NAME =3D=3D "X" and X.a.b.c._NAME =3D=3D "X.a.b.c" and = X.a.b._NAME =3D=3D "X.a.b") > +assert(X._M =3D=3D X and X.a.b.c._M =3D=3D X.a.b.c and X.a.b._M =3D=3D = X.a.b) > +assert(X.x =3D=3D 1 and X.a.b.c.x =3D=3D 2 and X.a.b.x =3D=3D 3) > +assert(X._PACKAGE =3D=3D "" and X.a.b.c._PACKAGE =3D=3D "X.a.b." and > + X.a.b._PACKAGE =3D=3D "X.a.") > +assert(_PACKAGE.."c" =3D=3D "X.a.c") > +assert(X.a._NAME =3D=3D nil and X.a._M =3D=3D nil) > +module("X.a", import("X")) ; x =3D 4 > +assert(X.a._NAME =3D=3D "X.a" and X.a.x =3D=3D 4 and X.a._M =3D=3D = X.a) > +module("X.a.b", package.seeall); assert(x =3D=3D 3); x =3D 5 > +assert(_NAME =3D=3D "X.a.b" and X.a.b.x =3D=3D 5) > + > +assert(X._G =3D=3D nil and X.a._G =3D=3D nil and X.a.b._G =3D=3D _G = and X.a.b.c._G =3D=3D nil) > + > +setfenv(1, _G) > +assert(x =3D=3D 0) > + > +assert(not pcall(module, "x")) > +assert(not pcall(module, "math.sin")) > + > + > +-- testing C libraries > + > + > +local p =3D "" -- On Mac OS X, redefine this to "_" > + > +-- assert(loadlib =3D=3D package.loadlib) -- only for compatibility > +local f, err, when =3D 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") =3D=3D lib1) > + collectgarbage() > + assert(lib1.id("x") =3D=3D "x") > + f =3D assert(package.loadlib("libs/lib1.so", p.."anotherfunc")) > + assert(f(10, 20) =3D=3D "1020\n") > + f, err, when =3D package.loadlib("libs/lib1.so", p.."xuxu") > + assert(not f and type(err) =3D=3D "string" and when =3D=3D "init") > + package.cpath =3D "libs/?.so" > + require"lib2" > + assert(lib2.id("x") =3D=3D "x") > + local fs =3D require"lib1.sub" > + assert(fs =3D=3D lib1.sub and next(lib1.sub) =3D=3D nil) > + module("lib2", package.seeall) > + f =3D require"-lib2" > + assert(f.id("x") =3D=3D "x" and _M =3D=3D f and _NAME =3D=3D = "lib2") > + module("lib1.sub", package.seeall) > + assert(_M =3D=3D fs) > + setfenv(1, _G) > + > +end > +f, err, when =3D package.loadlib("donotexist", p.."xuxu") > +assert(not f and type(err) =3D=3D "string" and (when =3D=3D "open" or = when =3D=3D "absent")) > + > + > +-- testing preload > + > +do > + local p =3D package > + package =3D {} > + p.preload.pl =3D function (...) > + module(...) > + function xuxu (x) return x+20 end > + end > + > + require"pl" > + assert(require"pl" =3D=3D pl) > + assert(pl.xuxu(10) =3D=3D 30) > + > + package =3D p > + assert(type(package.path) =3D=3D "string") > +end > + > + > + > +end --] > + > +print('+') > + > +print("testing assignments, logical operators, and constructors") > + > +local res, res2 =3D 27 > + > +a, b =3D 1, 2+3 > +assert(a=3D=3D1 and b=3D=3D5) > +a=3D{} > +function f() return 10, 11, 12 end > +a.x, b, a[1] =3D 1, 2, f() > +assert(a.x=3D=3D1 and b=3D=3D2 and a[1]=3D=3D10) > +a[f()], b, a[f()+3] =3D f(), a, 'x' > +assert(a[10] =3D=3D 10 and b =3D=3D a and a[13] =3D=3D 'x') > + > +do > + local f =3D function (n) local x =3D {}; for i=3D1,n do x[i]=3Di = end; > + return unpack(x) end; > + local a,b,c > + a,b =3D 0, f(1) > + assert(a =3D=3D 0 and b =3D=3D 1) > + A,b =3D 0, f(1) > + assert(A =3D=3D 0 and b =3D=3D 1) > + a,b,c =3D 0,5,f(4) > + assert(a=3D=3D0 and b=3D=3D5 and c=3D=3D1) > + a,b,c =3D 0,5,f(0) > + assert(a=3D=3D0 and b=3D=3D5 and c=3D=3Dnil) > +end > + > + > +a, b, c, d =3D 1 and nil, 1 or nil, (1 and (nil or 1)), 6 > +assert(not a and b and c and d=3D=3D6) > + > +d =3D 20 > +a, b, c, d =3D f() > +assert(a=3D=3D10 and b=3D=3D11 and c=3D=3D12 and d=3D=3Dnil) > +a,b =3D f(), 1, 2, 3, f() > +assert(a=3D=3D10 and b=3D=3D1) > + > +assert(ab =3D=3D true) > +assert((10 and 2) =3D=3D 2) > +assert((10 or 2) =3D=3D 10) > +assert((10 or assert(nil)) =3D=3D 10) > +assert(not (nil and assert(nil))) > +assert((nil or "alo") =3D=3D "alo") > +assert((nil and 10) =3D=3D nil) > +assert((false and 10) =3D=3D false) > +assert((true or 10) =3D=3D true) > +assert((false or 10) =3D=3D 10) > +assert(false ~=3D nil) > +assert(nil ~=3D false) > +assert(not nil =3D=3D true) > +assert(not not nil =3D=3D false) > +assert(not not 1 =3D=3D true) > +assert(not not a =3D=3D true) > +assert(not not (6 or nil) =3D=3D true) > +assert(not not (nil and 56) =3D=3D false) > +assert(not not (nil and true) =3D=3D false) > +print('+') > + > +a =3D {} > +a[true] =3D 20 > +a[false] =3D 10 > +assert(a[1<2] =3D=3D 20 and a[1>2] =3D=3D 10) > + > +function f(a) return a end > + > +local a =3D {} > +for i=3D3000,-3000,-1 do a[i] =3D i; end > +a[10e30] =3D "alo"; a[true] =3D 10; a[false] =3D 20 > +assert(a[10e30] =3D=3D 'alo' and a[not 1] =3D=3D 20 and a[10<20] =3D=3D= 10) > +for i=3D3000,-3000,-1 do assert(a[i] =3D=3D i); end > +a[print] =3D assert > +a[f] =3D print > +a[a] =3D a > +assert(a[a][a][a][a][print] =3D=3D assert) > +a[print](a[a[f]] =3D=3D a[print]) > +a =3D nil > + > +a =3D {10,9,8,7,6,5,4,3,2; [-3]=3D'a', [f]=3Dprint, a=3D'a', b=3D'ab'} > +a, a.x, a.y =3D a, a[-3] > +assert(a[1]=3D=3D10 and a[-3]=3D=3Da.a and a[f]=3D=3Dprint and = a.x=3D=3D'a' and not a.y) > +a[1], f(a)[2], b, c =3D {['alo']=3Dassert}, 10, a[1], a[f], 6, 10, = 23, f(a), 2 > +a[1].alo(a[2]=3D=3D10 and b=3D=3D10 and c=3D=3Dprint) > + > +a[2^31] =3D 10; a[2^31+1] =3D 11; a[-2^31] =3D 12; > +a[2^32] =3D 13; a[-2^32] =3D 14; a[2^32+1] =3D 15; a[10^33] =3D 16; > + > +assert(a[2^31] =3D=3D 10 and a[2^31+1] =3D=3D 11 and a[-2^31] =3D=3D = 12 and > + a[2^32] =3D=3D 13 and a[-2^32] =3D=3D 14 and a[2^32+1] =3D=3D = 15 and > + a[10^33] =3D=3D 16) > + > +a =3D nil > + > + > +do > + local a,i,j,b > + a =3D {'a', 'b'}; i=3D1; j=3D2; b=3Da > + i, a[i], a, j, a[j], a[i+j] =3D j, i, i, b, j, i > + assert(i =3D=3D 2 and b[1] =3D=3D 1 and a =3D=3D 1 and j =3D=3D b = and b[2] =3D=3D 2 and > + b[3] =3D=3D 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 =3D 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 =3D catter(129) > +local a, b =3D pcall(rep129, longs) > +assert(not a and string.find(b, "overflow")) > +print('+') > + > + > +require "checktable" > + > +--[[ lots of empty lines (to force SETLINEW) > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > +--]] > + > + > +a,b =3D nil,nil > +while not b do > +if a then > +b =3D { -- 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=3D23} > +else a =3D 1 end > + > + > +end > + > +assert(b.x =3D=3D 23) > +print('+') > + > +stat(b) > + > +repeat > +a =3D { > +n1 =3D 1.5, n2 =3D 2.5, n3 =3D 3.5, n4 =3D 4.5, n5 =3D 5.5, n6 =3D = 6.5, n7 =3D 7.5, > +n8 =3D 8.5, n9 =3D 9.5, n10 =3D 10.5, n11 =3D 11.5, n12 =3D 12.5, > +j301 =3D 301.5, j302 =3D 302.5, j303 =3D 303.5, j304 =3D 304.5, j305 = =3D 305.5, > +j306 =3D 306.5, j307 =3D 307.5, j308 =3D 308.5, j309 =3D 309.5, a310 = =3D 310.5, > +n311 =3D 311.5, n312 =3D 312.5, n313 =3D 313.5, n314 =3D 314.5, n315 = =3D 315.5, > +n316 =3D 316.5, n317 =3D 317.5, n318 =3D 318.5, n319 =3D 319.5, n320 = =3D 320.5, > +n321 =3D 321.5, n322 =3D 322.5, n323 =3D 323.5, n324 =3D 324.5, n325 = =3D 325.5, > +n326 =3D 326.5, n327 =3D 327.5, n328 =3D 328.5, a329 =3D 329.5, n330 = =3D 330.5, > +n331 =3D 331.5, n332 =3D 332.5, n333 =3D 333.5, n334 =3D 334.5, n335 = =3D 335.5, > +n336 =3D 336.5, n337 =3D 337.5, n338 =3D 338.5, n339 =3D 339.5, n340 = =3D 340.5, > +n341 =3D 341.5, z342 =3D 342.5, n343 =3D 343.5, n344 =3D 344.5, n345 = =3D 345.5, > +n346 =3D 346.5, n347 =3D 347.5, n348 =3D 348.5, n349 =3D 349.5, n350 = =3D 350.5, > +n351 =3D 351.5, n352 =3D 352.5, r353 =3D 353.5, n354 =3D 354.5, n355 = =3D 355.5, > +n356 =3D 356.5, n357 =3D 357.5, n358 =3D 358.5, n359 =3D 359.5, n360 = =3D 360.5, > +n361 =3D 361.5, n362 =3D 362.5, n363 =3D 363.5, n364 =3D 364.5, n365 = =3D 365.5, > +n366 =3D 366.5, z367 =3D 367.5, n368 =3D 368.5, n369 =3D 369.5, n370 = =3D 370.5, > +n371 =3D 371.5, n372 =3D 372.5, n373 =3D 373.5, n374 =3D 374.5, n375 = =3D 375.5, > +a376 =3D 376.5, n377 =3D 377.5, n378 =3D 378.5, n379 =3D 379.5, n380 = =3D 380.5, > +n381 =3D 381.5, n382 =3D 382.5, n383 =3D 383.5, n384 =3D 384.5, n385 = =3D 385.5, > +n386 =3D 386.5, n387 =3D 387.5, n388 =3D 388.5, n389 =3D 389.5, n390 = =3D 390.5, > +n391 =3D 391.5, n392 =3D 392.5, n393 =3D 393.5, n394 =3D 394.5, n395 = =3D 395.5, > +n396 =3D 396.5, n397 =3D 397.5, n398 =3D 398.5, n399 =3D 399.5, n400 = =3D 400.5, > +n13 =3D 13.5, n14 =3D 14.5, n15 =3D 15.5, n16 =3D 16.5, n17 =3D 17.5, > +n18 =3D 18.5, n19 =3D 19.5, n20 =3D 20.5, n21 =3D 21.5, n22 =3D 22.5, > +n23 =3D 23.5, a24 =3D 24.5, n25 =3D 25.5, n26 =3D 26.5, n27 =3D 27.5, > +n28 =3D 28.5, n29 =3D 29.5, j30 =3D 30.5, n31 =3D 31.5, n32 =3D 32.5, > +n33 =3D 33.5, n34 =3D 34.5, n35 =3D 35.5, n36 =3D 36.5, n37 =3D 37.5, > +n38 =3D 38.5, n39 =3D 39.5, n40 =3D 40.5, n41 =3D 41.5, n42 =3D 42.5, > +n43 =3D 43.5, n44 =3D 44.5, n45 =3D 45.5, n46 =3D 46.5, n47 =3D 47.5, > +n48 =3D 48.5, n49 =3D 49.5, n50 =3D 50.5, n51 =3D 51.5, n52 =3D 52.5, > +n53 =3D 53.5, n54 =3D 54.5, n55 =3D 55.5, n56 =3D 56.5, n57 =3D 57.5, > +n58 =3D 58.5, n59 =3D 59.5, n60 =3D 60.5, n61 =3D 61.5, n62 =3D 62.5, > +n63 =3D 63.5, n64 =3D 64.5, n65 =3D 65.5, a66 =3D 66.5, z67 =3D 67.5, > +n68 =3D 68.5, n69 =3D 69.5, n70 =3D 70.5, n71 =3D 71.5, n72 =3D 72.5, > +n73 =3D 73.5, n74 =3D 74.5, n75 =3D 75.5, n76 =3D 76.5, n77 =3D 77.5, > +n78 =3D 78.5, n79 =3D 79.5, n80 =3D 80.5, n81 =3D 81.5, n82 =3D 82.5, > +n83 =3D 83.5, n84 =3D 84.5, n85 =3D 85.5, n86 =3D 86.5, n87 =3D 87.5, > +n88 =3D 88.5, n89 =3D 89.5, n90 =3D 90.5, n91 =3D 91.5, n92 =3D 92.5, > +n93 =3D 93.5, n94 =3D 94.5, n95 =3D 95.5, n96 =3D 96.5, n97 =3D 97.5, > +n98 =3D 98.5, n99 =3D 99.5, n100 =3D 100.5, n201 =3D 201.5, n202 =3D = 202.5, > +n203 =3D 203.5, n204 =3D 204.5, n205 =3D 205.5, n206 =3D 206.5, n207 = =3D 207.5, > +n208 =3D 208.5, n209 =3D 209.5, n210 =3D 210.5, n211 =3D 211.5, n212 = =3D 212.5, > +n213 =3D 213.5, n214 =3D 214.5, n215 =3D 215.5, n216 =3D 216.5, n217 = =3D 217.5, > +n218 =3D 218.5, n219 =3D 219.5, n220 =3D 220.5, n221 =3D 221.5, n222 = =3D 222.5, > +n223 =3D 223.5, n224 =3D 224.5, n225 =3D 225.5, n226 =3D 226.5, n227 = =3D 227.5, > +n228 =3D 228.5, n229 =3D 229.5, n230 =3D 230.5, n231 =3D 231.5, n232 = =3D 232.5, > +n233 =3D 233.5, n234 =3D 234.5, n235 =3D 235.5, n236 =3D 236.5, n237 = =3D 237.5, > +n238 =3D 238.5, n239 =3D 239.5, a240 =3D 240.5, a241 =3D 241.5, a242 = =3D 242.5, > +a243 =3D 243.5, a244 =3D 244.5, a245 =3D 245.5, a246 =3D 246.5, a247 = =3D 247.5, > +a248 =3D 248.5, a249 =3D 249.5, n250 =3D 250.5, n251 =3D 251.5, n252 = =3D 252.5, > +n253 =3D 253.5, n254 =3D 254.5, n255 =3D 255.5, n256 =3D 256.5, n257 = =3D 257.5, > +n258 =3D 258.5, n259 =3D 259.5, n260 =3D 260.5, n261 =3D 261.5, n262 = =3D 262.5, > +n263 =3D 263.5, n264 =3D 264.5, n265 =3D 265.5, n266 =3D 266.5, n267 = =3D 267.5, > +n268 =3D 268.5, n269 =3D 269.5, n270 =3D 270.5, n271 =3D 271.5, n272 = =3D 272.5, > +n273 =3D 273.5, n274 =3D 274.5, n275 =3D 275.5, n276 =3D 276.5, n277 = =3D 277.5, > +n278 =3D 278.5, n279 =3D 279.5, n280 =3D 280.5, n281 =3D 281.5, n282 = =3D 282.5, > +n283 =3D 283.5, n284 =3D 284.5, n285 =3D 285.5, n286 =3D 286.5, n287 = =3D 287.5, > +n288 =3D 288.5, n289 =3D 289.5, n290 =3D 290.5, n291 =3D 291.5, n292 = =3D 292.5, > +n293 =3D 293.5, n294 =3D 294.5, n295 =3D 295.5, n296 =3D 296.5, n297 = =3D 297.5, > +n298 =3D 298.5, n299 =3D 299.5, j300 =3D 300} or 1 > +until 1 > + > +assert(a.n299 =3D=3D 299.5) > +xxx =3D 1 > +assert(xxx =3D=3D 1) > + > +stat(a) > + > +function a:findfield (f) > + local i,v =3D next(self, nil) > + while i ~=3D f do > + if not i then return end > + i,v =3D next(self, i) > + end > + return v > +end > + > +local ii =3D 0 > +i =3D 1 > +while b[i] do > + local r =3D a:findfield(b[i]); > + assert(a[b[i]] =3D=3D r) > + ii =3D math.max(ii,i) > + i =3D i+1 > +end > + > +assert(ii =3D=3D 299) > + > +function xxxx (x) coroutine.yield('b'); return ii+x end > + > +assert(xxxx(10) =3D=3D 309) > + > +a =3D nil > +b =3D nil > +a1 =3D nil > + > +print("tables with table indices:") > +i =3D 1; a=3D{} > +while i <=3D 1023 do a[{}] =3D i; i=3Di+1 end > +stat(a) > +a =3D nil > + > +print("tables with function indices:") > +a=3D{} > +for i=3D1,511 do local x; a[function () return x end] =3D i end > +stat(a) > +a =3D 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) =3D=3D 'boolean') > +assert(type(true) =3D=3D 'boolean' and type(false) =3D=3D 'boolean') > +assert(type(nil) =3D=3D 'nil' and type(-3) =3D=3D 'number' and = type'x' =3D=3D 'string' and > + type{} =3D=3D 'table' and type(type) =3D=3D 'function') > + > +assert(type(assert) =3D=3D type(print)) > +f =3D nil > +function f (x) return a:x (x) end > +assert(type(f) =3D=3D 'function') > + > + > +-- testing local-function recursion > +fact =3D false > +do > + local res =3D 1 > + local function fact (n) > + if n=3D=3D0 then return res > + else return n*fact(n-1) > + end > + end > + assert(fact(5) =3D=3D 120) > +end > +assert(fact =3D=3D false) > + > +-- testing declarations > +a =3D {i =3D 10} > +self =3D 20 > +function a:x (x) return x+self.i end > +function a.y (x) return x+self end > + > +assert(a:x(1)+10 =3D=3D a.y(1)) > + > +a.t =3D {i=3D-100} > +a["t"].x =3D function (self, a,b) return self.i+a+b end > + > +assert(a.t:x(2,3) =3D=3D -95) > + > +do > + local a =3D {x=3D0} > + function a:add (x) self.x, a.y =3D self.x+x, 20; return self end > + assert(a:add(10):add(20):add(30).x =3D=3D 60 and a.y =3D=3D 20) > +end > + > +local a =3D {b=3D{c=3D{}}} > + > +function a.b.c.f1 (x) return x+1 end > +function a.b.c:f2 (x,y) self[x] =3D y end > +assert(a.b.c.f1(4) =3D=3D 5) > +a.b.c:f2('k', 12); assert(a.b.c.k =3D=3D 12) > + > +print('+') > + > +t =3D nil -- 'declare' t > +function f(a,b,c) local d =3D 'a'; t=3D{a,b,c,d} end > + > +f( -- this line change must be valid > + 1,2) > +assert(t[1] =3D=3D 1 and t[2] =3D=3D 2 and t[3] =3D=3D nil and t[4] = =3D=3D 'a') > +f(1,2, -- this one too > + 3,4) > +assert(t[1] =3D=3D 1 and t[2] =3D=3D 2 and t[3] =3D=3D 3 and t[4] =3D=3D= 'a') > + > +function fat(x) > + if x <=3D 1 then return 1 > + else return x*loadstring("return fat(" .. x-1 .. ")")() > + end > +end > + > +assert(loadstring "loadstring 'assert(fat(6)=3D=3D720)' () ")() > +a =3D loadstring('return fat(5), 3') > +a,b =3D a() > +assert(a =3D=3D 120 and b =3D=3D 3) > +print('+') > + > +function err_on_n (n) > + if n=3D=3D0 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) =3D=3D 101) > +a =3D {} > +function a:deep (n) if n>0 then return self:deep(n-1) else return 101 = end end > +assert(a:deep(30000) =3D=3D 101) > + > +print('+') > + > + > +a =3D nil > +(function (x) a=3Dx end)(23) > +assert(a =3D=3D 23 and (function (x) return x*2 end)(20) =3D=3D 40) > + > + > +local x,y,z,a > +a =3D {}; lim =3D 2000 > +for i=3D1, lim do a[i]=3Di end > +assert(select(lim, unpack(a)) =3D=3D lim and select('#', unpack(a)) = =3D=3D lim) > +x =3D unpack(a) > +assert(x =3D=3D 1) > +x =3D {unpack(a)} > +assert(table.getn(x) =3D=3D lim and x[1] =3D=3D 1 and x[lim] =3D=3D = lim) > +x =3D {unpack(a, lim-2)} > +assert(table.getn(x) =3D=3D 3 and x[1] =3D=3D lim-2 and x[3] =3D=3D = lim) > +x =3D {unpack(a, 10, 6)} > +assert(next(x) =3D=3D nil) -- no elements > +x =3D {unpack(a, 11, 10)} > +assert(next(x) =3D=3D nil) -- no elements > +x,y =3D unpack(a, 10, 10) > +assert(x =3D=3D 10 and y =3D=3D nil) > +x,y,z =3D unpack(a, 10, 11) > +assert(x =3D=3D 10 and y =3D=3D 11 and z =3D=3D nil) > +a,x =3D unpack{1} > +assert(a=3D=3D1 and x=3D=3Dnil) > +a,x =3D unpack({1,2}, 1, 1) > +assert(a=3D=3D1 and x=3D=3Dnil) > + > + > +-- testing closures > + > +-- fixed-point operator > +Y =3D function (le) > + local function a (f) > + return le(function (x) return f(f)(x) end) > + end > + return a(a) > + end > + > + > +-- non-recursive factorial > + > +F =3D function (f) > + return function (n) > + if n =3D=3D 0 then return 1 > + else return n*f(n-1) end > + end > + end > + > +fat =3D Y(F) > + > +assert(fat(0) =3D=3D 1 and fat(4) =3D=3D 24 and Y(F)(5)=3D=3D5*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 =3D g(10) > +assert(f(9, 16) =3D=3D 10+11+12+13+10+9+16+10) > + > +Y, F, f =3D nil > +print('+') > + > +-- testing multiple returns > + > +function unlpack (t, i) > + i =3D i or 1 > + if (i <=3D table.getn(t)) then > + return t[i], unlpack(t, i+1) > + end > +end > + > +function equaltab (t1, t2) > + assert(table.getn(t1) =3D=3D table.getn(t2)) > + for i,v1 in ipairs(t1) do > + assert(v1 =3D=3D t2[i]) > + end > +end > + > +local function pack (...) > + local x =3D {...} > + x.n =3D 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 =3D unlpack{1,2,3} > +assert(a=3D=3D1 and b=3D=3D2 and c=3D=3D3 and d=3D=3Dnil) > +a =3D {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 =3D ret2(f()), ret2(f()) > +assert(a=3D=3D1 and b=3D=3D1 and c=3D=3D2 and d=3D=3Dnil) > +a,b,c,d =3D unlpack(pack(ret2(f()), ret2(f()))) > +assert(a=3D=3D1 and b=3D=3D1 and c=3D=3D2 and d=3D=3Dnil) > +a,b,c,d =3D unlpack(pack(ret2(f()), (ret2(f())))) > +assert(a=3D=3D1 and b=3D=3D1 and c=3D=3Dnil and d=3D=3Dnil) > + > +a =3D ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} > +assert(a[1] =3D=3D 1 and a[2] =3D=3D 3 and a[3] =3D=3D "a" and a[4] = =3D=3D "b") > + > + > +-- testing calls with 'incorrect' arguments > +rawget({}, "x", 1) > +rawset({}, "x", 1, 2) > +assert(math.sin(1,2) =3D=3D math.sin(1)) > +table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a + > + > +-- test for generic load > +x =3D "-- a comment\0\0\0\n x =3D 10 + \n23; \ > + local a =3D function () x =3D 'hi' end; \ > + return '\0'" > +local i =3D 0 > +function read1 (x) > + return function () > + collectgarbage() > + i=3Di+1 > + return string.sub(x, i, i) > + end > +end > + > +a =3D assert(load(read1(x), "modname")) > +assert(a() =3D=3D "\0" and _G.x =3D=3D 33) > +assert(debug.getinfo(a).source =3D=3D "modname") > + > +x =3D string.dump(loadstring("x =3D 1; return x")) > +i =3D 0 > +a =3D assert(load(read1(x))) > +assert(a() =3D=3D 1 and _G.x =3D=3D 1) > + > +i =3D 0 > +local a, b =3D load(read1("*a =3D 123")) > +assert(not a and type(b) =3D=3D "string" and i =3D=3D 2) > + > +a, b =3D load(function () error("hhi") end) > +assert(not a and string.find(b, "hhi")) > + > +-- test generic load with nested functions > +x =3D [[ > + return function (x) > + return function (y) > + return function (z) > + return x+y+z > + end > + end > + end > +]] > + > +a =3D assert(load(read1(x))) > +assert(a()(2)(3)(10) =3D=3D 15) > + > + > +-- test for dump/undump with upvalues > +local a, b =3D 20, 30 > +x =3D loadstring(string.dump(function (x) > + if x =3D=3D "set" then a =3D 10+b; b =3D b+1 else > + return a > + end > +end)) > +assert(x() =3D=3D nil) > +assert(debug.setupvalue(x, 1, "hi") =3D=3D "a") > +assert(x() =3D=3D "hi") > +assert(debug.setupvalue(x, 2, 13) =3D=3D "b") > +assert(not debug.setupvalue(x, 3, 10)) -- only 2 upvalues > +x("set") > +assert(x() =3D=3D 23) > +x("set") > +assert(x() =3D=3D 24) > + > + > +-- test for bug in parameter adjustment > +assert((function () return nil end)(4) =3D=3D nil) > +assert((function () local a; return a end)(4) =3D=3D nil) > +assert((function (a) return a end)() =3D=3D 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") =3D=3D nil) -- module not loaded before > + > +if T =3D=3D nil then > + stat =3D function () print"`querytab' nao ativo" end > + return > +end > + > + > +function checktable (t) > + local asize, hsize, ff =3D T.querytab(t) > + local l =3D {} > + for i=3D0,hsize-1 do > + local key,val,next =3D T.querytab(t, i + asize) > + if key =3D=3D nil then > + assert(l[i] =3D=3D nil and val=3D=3Dnil and next=3D=3Dnil) > + elseif key =3D=3D "" then > + assert(val=3D=3Dnil) > + else > + assert(t[key] =3D=3D val) > + local mp =3D T.hash(key, t) > + if l[i] then > + assert(l[i] =3D=3D mp) > + elseif mp ~=3D i then > + l[i] =3D mp > + else -- list head > + l[mp] =3D {mp} -- first element > + while next do > + assert(ff <=3D next and next < hsize) > + if l[next] then assert(l[next] =3D=3D mp) else l[next] =3D = mp end > + table.insert(l[mp], next) > + key,val,next =3D T.querytab(t, next) > + assert(key) > + end > + end > + end > + end > + l.asize =3D asize; l.hsize =3D hsize; l.ff =3D ff > + return l > +end > + > +function mostra (t) > + local asize, hsize, ff =3D T.querytab(t) > + print(asize, hsize, ff) > + print'------' > + for i=3D0,asize-1 do > + local _, v =3D T.querytab(t, i) > + print(string.format("[%d] -", i), v) > + end > + print'------' > + for i=3D0,hsize-1 do > + print(i, T.querytab(t, i+asize)) > + end > + print'-------------' > +end > + > +function stat (t) > + t =3D checktable(t) > + local nelem, nlist =3D 0, 0 > + local maxlist =3D {} > + for i=3D0,t.hsize-1 do > + if type(t[i]) =3D=3D 'table' then > + local n =3D table.getn(t[i]) > + nlist =3D nlist+1 > + nelem =3D nelem + n > + if not maxlist[n] then maxlist[n] =3D 0 end > + maxlist[n] =3D maxlist[n]+1 > + end > + end > + print(string.format("hsize=3D%d elements=3D%d load=3D%.2f = med.len=3D%.2f (asize=3D%d)", > + t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize)) > + for i=3D1,table.getn(maxlist) do > + local n =3D 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 =3D 0,{g=3D10} > +function f(x) > + local a =3D {} > + for i=3D1,1000 do > + local y =3D 0 > + do > + a[i] =3D function () B.g =3D B.g+1; y =3D y+x; return y+A end > + end > + end > + local dummy =3D function () return a[A] end > + collectgarbage() > + A =3D 1; assert(dummy() =3D=3D a[1]); A =3D 0; > + assert(a[1]() =3D=3D x) > + assert(a[3]() =3D=3D x) > + collectgarbage() > + assert(B.g =3D=3D 12) > + return a > +end > + > +a =3D f(10) > +-- force a GC in this level > +local x =3D {[1] =3D {}} -- to detect a GC > +setmetatable(x, {__mode =3D 'kv'}) > +while x[1] do -- repeat until GC > + local a =3D A..A..A..A -- create garbage > + A =3D A+1 > +end > +assert(a[1]() =3D=3D 20+A) > +assert(a[1]() =3D=3D 30+A) > +assert(a[2]() =3D=3D 10+A) > +collectgarbage() > +assert(a[2]() =3D=3D 20+A) > +assert(a[2]() =3D=3D 30+A) > +assert(a[3]() =3D=3D 20+A) > +assert(a[8]() =3D=3D 10+A) > +assert(getmetatable(x).__mode =3D=3D 'kv') > +assert(B.g =3D=3D 19) > + > +-- testing closures with 'for' control variable > +a =3D {} > +for i=3D1,10 do > + a[i] =3D {set =3D function(x) i=3Dx end, get =3D function () return = i end} > + if i =3D=3D 3 then break end > +end > +assert(a[4] =3D=3D nil) > +a[1].set(10) > +assert(a[2].get() =3D=3D 2) > +a[2].set('a') > +assert(a[3].get() =3D=3D 3) > +assert(a[2].get() =3D=3D 'a') > + > +a =3D {} > +for i, k in pairs{'a', 'b'} do > + a[i] =3D {set =3D function(x, y) i=3Dx; k=3Dy end, > + get =3D function () return i, k end} > + if i =3D=3D 2 then break end > +end > +a[1].set(10, 20) > +local r,s =3D a[2].get() > +assert(r =3D=3D 2 and s =3D=3D 'b') > +r,s =3D a[1].get() > +assert(r =3D=3D 10 and s =3D=3D 20) > +a[2].set('a', 'b') > +r,s =3D a[2].get() > +assert(r =3D=3D "a" and s =3D=3D "b") > + > + > +-- testing closures with 'for' control variable x break > +for i=3D1,3 do > + f =3D function () return i end > + break > +end > +assert(f() =3D=3D 1) > + > +for k, v in pairs{"a", "b"} do > + f =3D function () return k, v end > + break > +end > +assert(({f()})[1] =3D=3D 1) > +assert(({f()})[2] =3D=3D "a") > + > + > +-- testing closure x break x return x errors > + > +local b > +function f(x) > + local first =3D 1 > + while 1 do > + if x =3D=3D 3 and not first then return end > + local a =3D 'xuxu' > + b =3D function (op, y) > + if op =3D=3D 'set' then > + a =3D x+y > + else > + return a > + end > + end > + if x =3D=3D 1 then do break end > + elseif x =3D=3D 2 then return > + else if x ~=3D 3 then error() end > + end > + first =3D nil > + end > +end > + > +for i=3D1,3 do > + f(i) > + assert(b('get') =3D=3D 'xuxu') > + b('set', 10); assert(b('get') =3D=3D 10+i) > + b =3D nil > +end > + > +pcall(f, 4); > +assert(b('get') =3D=3D 'xuxu') > +b('set', 10); assert(b('get') =3D=3D 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 =3D f(10) > +w =3D 1.345 > +assert(y(20)(30) =3D=3D 60+w) > + > +-- testing closures x repeat-until > + > +local a =3D {} > +local i =3D 1 > +repeat > + local x =3D i > + a[i] =3D function () i =3D x+1; return x end > +until i > 10 or a[i]() ~=3D x > +assert(i =3D=3D 11 and a[1]() =3D=3D 1 and a[3]() =3D=3D 3 and i =3D=3D= 4) > + > +print'+' > + > + > +-- test for correctly closing upvalues in tail calls of vararg = functions > +local function t () > + local function c(a,b) assert(a=3D=3D"test" and b=3D=3D"OK") end > + local function v(f, ...) c("test", f() ~=3D 1 and "FAILED" or "OK") = end > + local x =3D 1 > + return v(function() return x end) > +end > +t() > + > + > +-- coroutine tests > + > +local f > + > +assert(coroutine.running() =3D=3D nil) > + > + > +-- tests for global environment > + > +local function foo (a) > + setfenv(0, a) > + coroutine.yield(getfenv()) > + assert(getfenv(0) =3D=3D a) > + assert(getfenv(1) =3D=3D _G) > + assert(getfenv(loadstring"") =3D=3D a) > + return getfenv() > +end > + > +f =3D coroutine.wrap(foo) > +local a =3D {} > +assert(f(a) =3D=3D _G) > +local a,b =3D pcall(f) > +assert(a and b =3D=3D _G) > + > + > +-- tests for multiple yield/resume arguments > + > +local function eqtab (t1, t2) > + assert(table.getn(t1) =3D=3D table.getn(t2)) > + for i,v in ipairs(t1) do > + assert(t2[i] =3D=3D v) > + end > +end > + > +_G.x =3D nil -- declare x > +function foo (a, ...) > + assert(coroutine.running() =3D=3D f) > + assert(coroutine.status(f) =3D=3D "running") > + local arg =3D {...} > + for i=3D1,table.getn(arg) do > + _G.x =3D {coroutine.yield(unpack(arg[i]))} > + end > + return unpack(a) > +end > + > +f =3D coroutine.create(foo) > +assert(type(f) =3D=3D "thread" and coroutine.status(f) =3D=3D = "suspended") > +assert(string.find(tostring(f), "thread")) > +local s,a,b,c,d > +s,a,b,c,d =3D coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'}) > +assert(s and a =3D=3D nil and coroutine.status(f) =3D=3D "suspended") > +s,a,b,c,d =3D coroutine.resume(f) > +eqtab(_G.x, {}) > +assert(s and a =3D=3D 1 and b =3D=3D nil) > +s,a,b,c,d =3D coroutine.resume(f, 1, 2, 3) > +eqtab(_G.x, {1, 2, 3}) > +assert(s and a =3D=3D 'a' and b =3D=3D 'b' and c =3D=3D 'c' and d =3D=3D= nil) > +s,a,b,c,d =3D coroutine.resume(f, "xuxu") > +eqtab(_G.x, {"xuxu"}) > +assert(s and a =3D=3D 1 and b =3D=3D 2 and c =3D=3D 3 and d =3D=3D = nil) > +assert(coroutine.status(f) =3D=3D "dead") > +s, a =3D coroutine.resume(f, "xuxu") > +assert(not s and string.find(a, "dead") and coroutine.status(f) =3D=3D = "dead") > + > + > +-- yields in tail calls > +local function foo (i) return coroutine.yield(i) end > +f =3D coroutine.wrap(function () > + for i=3D1,10 do > + assert(foo(i) =3D=3D _G.x) > + end > + return 'a' > +end) > +for i=3D1,10 do _G.x =3D i; assert(f(i) =3D=3D i) end > +_G.x =3D 'xuxu'; assert(f('xuxu') =3D=3D 'a') > + > +-- recursive > +function pf (n, i) > + coroutine.yield(n) > + pf(n*i, i+1) > +end > + > +f =3D coroutine.wrap(pf) > +local s=3D1 > +for i=3D1,10 do > + assert(f(1, 1) =3D=3D s) > + s =3D s*i > +end > + > +-- sieve > +function gen (n) > + return coroutine.wrap(function () > + for i=3D2,n do coroutine.yield(i) end > + end) > +end > + > + > +function filter (p, g) > + return coroutine.wrap(function () > + while 1 do > + local n =3D g() > + if n =3D=3D nil then return end > + if math.mod(n, p) ~=3D 0 then coroutine.yield(n) end > + end > + end) > +end > + > +local x =3D gen(100) > +local a =3D {} > +while 1 do > + local n =3D x() > + if n =3D=3D nil then break end > + table.insert(a, n) > + x =3D filter(n, x) > +end > + > +assert(table.getn(a) =3D=3D 25 and a[table.getn(a)] =3D=3D 97) > + > + > +-- errors in coroutines > +function foo () > + assert(debug.getinfo(1).currentline =3D=3D = debug.getinfo(foo).linedefined + 1) > + assert(debug.getinfo(2).currentline =3D=3D = debug.getinfo(goo).linedefined) > + coroutine.yield(3) > + error(foo) > +end > + > +function goo() foo() end > +x =3D coroutine.wrap(goo) > +assert(x() =3D=3D 3) > +local a,b =3D pcall(x) > +assert(not a and b =3D=3D foo) > + > +x =3D coroutine.create(goo) > +a,b =3D coroutine.resume(x) > +assert(a and b =3D=3D 3) > +a,b =3D coroutine.resume(x) > +assert(not a and b =3D=3D foo and coroutine.status(x) =3D=3D "dead") > +a,b =3D coroutine.resume(x) > +assert(not a and string.find(b, "dead") and coroutine.status(x) =3D=3D = "dead") > + > + > +-- co-routines x for loop > +function all (a, n, k) > + if k =3D=3D 0 then coroutine.yield(a) > + else > + for i=3D1,n do > + a[k] =3D i > + all(a, n, k-1) > + end > + end > +end > + > +local a =3D 0 > +for t in coroutine.wrap(function () all({}, 5, 4) end) do > + a =3D a+1 > +end > +assert(a =3D=3D 5^4) > + > + > +-- access to locals of collected corroutines > +local C =3D {}; setmetatable(C, {__mode =3D "kv"}) > +local x =3D coroutine.wrap (function () > + local a =3D 10 > + local function f () a =3D a+10; return a end > + while true do > + a =3D a+1 > + coroutine.yield(f) > + end > + end) > + > +C[1] =3D x; > + > +local f =3D x() > +assert(f() =3D=3D 21 and x()() =3D=3D 32 and x() =3D=3D f) > +x =3D nil > +collectgarbage() > +assert(C[1] =3D=3D nil) > +assert(f() =3D=3D 43 and f() =3D=3D 53) > + > + > +-- old bug: attempt to resume itself > + > +function co_func (current_co) > + assert(coroutine.running() =3D=3D current_co) > + assert(coroutine.resume(current_co) =3D=3D false) > + assert(coroutine.resume(current_co) =3D=3D false) > + return 10 > +end > + > +local co =3D coroutine.create(co_func) > +local a,b =3D coroutine.resume(co, co) > +assert(a =3D=3D true and b =3D=3D 10) > +assert(coroutine.resume(co, co) =3D=3D false) > +assert(coroutine.resume(co, co) =3D=3D false) > + > +-- access to locals of erroneous coroutines > +local x =3D coroutine.create (function () > + local a =3D 10 > + _G.f =3D function () a=3Da+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() =3D=3D 11) > +assert(_G.f() =3D=3D 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 =3D=3D t) > + if x =3D=3D 0 then return 1 > + else return x*fact(t, x-1) > + end > + end > + > + local A,B,a,b =3D 0,0,0,0 > + > + local x =3D coroutine.create(function () > + T.setyhook("", 2) > + A =3D fact("A", 10) > + end) > + > + local y =3D coroutine.create(function () > + T.setyhook("", 3) > + B =3D fact("B", 11) > + end) > + > + while A=3D=3D0 or B=3D=3D0 do > + if A=3D=3D0 then turn =3D "A"; T.resume(x) end > + if B=3D=3D0 then turn =3D "B"; T.resume(y) end > + end > + > + assert(B/A =3D=3D 11) > +end > + > + > +-- leaving a pending coroutine open > +_X =3D coroutine.wrap(function () > + local a =3D 10 > + local x =3D function () a =3D a+1 end > + coroutine.yield() > + end) > + > +_X() > + > + > +-- coroutine environments > +co =3D coroutine.create(function () > + coroutine.yield(getfenv(0)) > + return loadstring("return a")() > + end) > + > +a =3D {a =3D 15} > +debug.setfenv(co, a) > +assert(debug.getfenv(co) =3D=3D a) > +assert(select(2, coroutine.resume(co)) =3D=3D a) > +assert(select(2, coroutine.resume(co)) =3D=3D 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=3D=3Dnil 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 =3D T.listcode(f) > + for i=3D1, arg.n do > + -- print(arg[i], c[i]) > + assert(string.find(c[i], '- '..arg[i]..' *%d')) > + end > + assert(c[arg.n+2] =3D=3D nil) > +end > + > + > +function checkequal (a, b) > + a =3D T.listcode(a) > + b =3D T.listcode(b) > + for i =3D 1, table.getn(a) do > + a[i] =3D string.gsub(a[i], '%b()', '') -- remove line number > + b[i] =3D string.gsub(b[i], '%b()', '') -- remove line number > + assert(a[i] =3D=3D 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 =3D nil; d=3Dnil > +end, 'RETURN') > + > + > +-- single return > +check (function (a,b,c) return a end, 'RETURN') > + > + > +-- infinite loops > +check(function () while true do local a =3D -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () while 1 do local a =3D -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x =3D 1 until false end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x until nil end, > +'LOADNIL', 'JMP', 'RETURN') > + > +check(function () repeat local x =3D 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 =3D b*2 > + c[4], a[b] =3D -((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 =3D 0 > + a.x =3D b > + a[b] =3D 'y' > + a =3D 1 - a > + b =3D 1/a > + b =3D 5+4 > + a[true] =3D 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() =3D=3D -5) > + > +check(function () > + local a,b,c > + b[c], a =3D c, b > + b[a], a =3D c, b > + a, b =3D c, a > + a =3D a > +end, > + 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', > + -- no code for a =3D a > + 'RETURN') > + > + > +-- x =3D=3D nil , x ~=3D nil > +checkequal(function () if (a=3D=3Dnil) then a=3D1 end; if a~=3Dnil = then a=3D1 end end, > + function () if (a=3D=3D9) then a=3D1 end; if a~=3D9 then = a=3D1 end end) > + > +check(function () if a=3D=3Dnil then a=3D1 end end, > +'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN') > + > +-- de morgan > +checkequal(function () local a; if not (a or b) then b=3Da end end, > + function () local a; if (not a and not b) then b=3Da end = end) > + > +checkequal(function (l) local a; return 0 <=3D a and a <=3D l end, > + function (l) local a; return not (not(a >=3D 0) or not(a = <=3D 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 =3D=3D 2^(3^2)); > +assert(2^3*4 =3D=3D (2^3)*4); > +assert(2^-2 =3D=3D 1/4 and -2^- -2 =3D=3D - - -4); > +assert(not nil and 2 and not(2>3 or 3<2)); > +assert(-3-1-5 =3D=3D 0+0-9); > +assert(-2^2 =3D=3D -4 and (-2)^2 =3D=3D 4 and 2*2-3-1 =3D=3D 0); > +assert(2*1+3/3 =3D=3D 3 and 1+2 .. 3*1 =3D=3D "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 =3D 1,nil; > +assert(-(1 or 2) =3D=3D -1 and (1 and 2)+(-1.25 or -4) =3D=3D 0.75); > +x =3D ((b or a)+1 =3D=3D 2 and (10 or a)+1 =3D=3D 11); assert(x); > +x =3D (((2<3) or 1) =3D=3D true and (2<3 and 4) =3D=3D 4); assert(x); > + > +x,y=3D1,2; > +assert((x>y) and x or y =3D=3D 2); > +x,y=3D2,1; > +assert((x>y) and x or y =3D=3D 2); > + > +assert(1234567890 =3D=3D tonumber('1234567890') and 1234567890+1 =3D=3D= 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=3D{a=3D1}; x=3D{x=3D1}; x=3D{G=3D1} end > +end > + > +function f (i) > + if type(i) ~=3D 'number' then return i,'jojo'; end; > + if i > 0 then return i, f(i-1); end; > +end > + > +x =3D {f(3), f(5), f(10);}; > +assert(x[1] =3D=3D 3 and x[2] =3D=3D 5 and x[3] =3D=3D 10 and x[4] =3D=3D= 9 and x[12] =3D=3D 1); > +assert(x[nil] =3D=3D nil) > +x =3D {f'alo', f'xixi', nil}; > +assert(x[1] =3D=3D 'alo' and x[2] =3D=3D 'xixi' and x[3] =3D=3D nil); > +x =3D {f'alo'..'xixi'}; > +assert(x[1] =3D=3D 'aloxixi') > +x =3D {f{}} > +assert(x[2] =3D=3D 'jojo' and type(x[1]) =3D=3D 'table') > + > + > +local f =3D 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) =3D=3D 'a' and f(12) =3D=3D 'b' and f(26) =3D=3D 'c' and = f(100) =3D=3D nil) > + > +for i=3D1,1000 do break; end; > +n=3D100; > +i=3D3; > +t =3D {}; > +a=3Dnil > +while not a do > + a=3D0; for i=3D1,n do for i=3Di,1,-1 do a=3Da+1; t[i]=3D1; end; = end; > +end > +assert(a =3D=3D n*(n+1)/2 and i=3D=3D3); > +assert(t[1] and t[n] and not t[0] and not t[n+1]) > + > +function f(b) > + local x =3D 1; > + repeat > + local a; > + if b=3D=3D1 then local b=3D1; x=3D10; break > + elseif b=3D=3D2 then x=3D20; break; > + elseif b=3D=3D3 then x=3D30; > + else local a,b,c,d=3Dmath.sin(1); x=3Dx+1; > + end > + until x>=3D12; > + return x; > +end; > + > +assert(f(1) =3D=3D 10 and f(2) =3D=3D 20 and f(3) =3D=3D 30 and = f(4)=3D=3D12) > + > + > +local f =3D 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) =3D=3D 'a' and f(12) =3D=3D 'b' and f(26) =3D=3D 'c' and = f(100) =3D=3D 8) > + > +local a, b =3D nil, 23 > +x =3D {f(100)*2+3 or a, a or b+2} > +assert(x[1] =3D=3D 19 and x[2] =3D=3D 25) > +x =3D {f=3D2+3 or a, a =3D b+2} > +assert(x.f =3D=3D 5 and x.a =3D=3D 25) > + > +a=3D{y=3D1} > +x =3D {a.y} > +assert(x[1] =3D=3D 1) > + > +function f(i) > + while 1 do > + if i>0 then i=3Di-1; > + else return; end; > + end; > +end; > + > +function g(i) > + while 1 do > + if i>0 then i=3Di-1 > + else return end > + end > +end > + > +f(10); g(10); > + > +do > + function f () return 1,2,3; end > + local a, b, c =3D f(); > + assert(a=3D=3D1 and b=3D=3D2 and c=3D=3D3) > + a, b, c =3D (f()); > + assert(a=3D=3D1 and b=3D=3Dnil and c=3D=3Dnil) > +end > + > +local a,b =3D 3 and f(); > +assert(a=3D=3D1 and b=3D=3Dnil) > + > +function g() f(); return; end; > +assert(g() =3D=3D nil) > +function g() return nil or f() end > +a,b =3D g() > +assert(a=3D=3D1 and b=3D=3Dnil) > + > +print'+'; > + > + > +f =3D [[ > +return function ( a , b , c , d , e ) > + local x =3D a >=3D b or c or ( d and e ) or nil > + return x > +end , { a =3D 1 , b =3D 2 >=3D 1 , } or { 1 }; > +]] > +f =3D string.gsub(f, "%s+", "\n"); -- force a SETLINE between = opcodes > +f,a =3D loadstring(f)(); > +assert(a.a =3D=3D 1 and a.b) > + > +function g (a,b,c,d,e) > + if not (a>=3Db 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>=3Db or c or (d and e) or nil) do return 1; end; > + return 0; > +end; > + > +assert(f(2,1) =3D=3D true and g(2,1) =3D=3D 1 and h(2,1) =3D=3D 1) > +assert(f(1,2,'a') =3D=3D 'a' and g(1,2,'a') =3D=3D 1 and h(1,2,'a') = =3D=3D 1) > +assert(f(1,2,'a') > +~=3D -- force SETLINE before nil > +nil, "") > +assert(f(1,2,'a') =3D=3D 'a' and g(1,2,'a') =3D=3D 1 and h(1,2,'a') = =3D=3D 1) > +assert(f(1,2,nil,1,'x') =3D=3D 'x' and g(1,2,nil,1,'x') =3D=3D 1 and > + h(1,2,nil,1,'x') =3D=3D 1) > +assert(f(1,2,nil,nil,'x') =3D=3D nil and g(1,2,nil,nil,'x') =3D=3D 0 = and > + h(1,2,nil,nil,'x') =3D=3D 0) > +assert(f(1,2,nil,1,nil) =3D=3D nil and g(1,2,nil,1,nil) =3D=3D 0 and > + h(1,2,nil,1,nil) =3D=3D 0) > + > +assert(1 and 2<3 =3D=3D true and 2<3 and 'a'<'b' =3D=3D true) > +x =3D 2<3 and not 3; assert(x=3D=3Dfalse) > +x =3D 2<1 or (2>1 and 'a'); assert(x=3D=3D'a') > + > + > +do > + local a; if nil then a=3D1; else a=3D2; end; -- this nil comes = as PUSHNIL 2 > + assert(a=3D=3D2) > +end > + > +function F(a) > + assert(debug.getinfo(1, "n").name =3D=3D 'F') > + return a,2,3 > +end > + > +a,b =3D F(1)~=3Dnil; assert(a =3D=3D true and b =3D=3D nil); > +a,b =3D F(nil)=3D=3Dnil; assert(a =3D=3D true and b =3D=3D 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 =3D t.n > + local res =3D math.mod(math.floor(i/c), b)+1 > + c =3D c*b > + return t[res] > +end > + > +local arg =3D {" ( 1 < 2 ) ", " ( 1 >=3D 2 ) ", " F ( ) ", " nil "; = n=3D4} > + > +local op =3D {" and ", " or ", " =3D=3D ", " ~=3D "; n=3D4} > + > +local neg =3D {" ", " not "; n=3D2} > + > +local i =3D 0 > +repeat > + c =3D 1 > + local s =3D 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 =3D string.gsub(s, 'ID', '') > + K,X,NX,WX1,WX2 =3D nil > + s =3D string.format([[ > + local a =3D %s > + local b =3D not %s > + K =3D b > + local xxx; > + if %s then X =3D a else X =3D b end > + if %s then NX =3D b else NX =3D a end > + while %s do WX1 =3D a; break end > + while %s do WX2 =3D 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 =3D=3D K and not WX2 =3D=3D K) > + if math.mod(i,4000) =3D=3D 0 then print('+') end > + i =3D i+1 > +until i=3D=3Dc > + > +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=3D1 > +end > + > +function test (s, l, p) > + collectgarbage() -- avoid gc during trace > + local function f (event, line) > + assert(event =3D=3D 'line') > + local l =3D table.remove(l, 1) > + if p then print(l, line) end > + assert(l =3D=3D line, "wrong trace!!") > + end > + debug.sethook(f,"l"); loadstring(s)(); debug.sethook() > + assert(table.getn(l) =3D=3D 0) > +end > + > + > +do > + local a =3D debug.getinfo(print) > + assert(a.what =3D=3D "C" and a.short_src =3D=3D "[C]") > + local b =3D debug.getinfo(test, "SfL") > + assert(b.name =3D=3D nil and b.what =3D=3D "Lua" and b.linedefined = =3D=3D 11 and > + b.lastlinedefined =3D=3D b.linedefined + 10 and > + b.func =3D=3D 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 =3D "function f () end" > +local function dostring (s, x) return loadstring(s, x)() end > +dostring(a) > +assert(debug.getinfo(f).short_src =3D=3D string.format('[string = "%s"]', a)) > +dostring(a..string.format("; %s\n=3D1", string.rep('p', 400))) > +assert(string.find(debug.getinfo(f).short_src, '^%[string = [^\n]*%.%.%."%]$')) > +dostring("\n"..a) > +assert(debug.getinfo(f).short_src =3D=3D '[string "..."]') > +dostring(a, "") > +assert(debug.getinfo(f).short_src =3D=3D '[string ""]') > +dostring(a, "@xuxu") > +assert(debug.getinfo(f).short_src =3D=3D "xuxu") > +dostring(a, "@"..string.rep('p', 1000)..'t') > +assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$")) > +dostring(a, "=3Dxuxu") > +assert(debug.getinfo(f).short_src =3D=3D "xuxu") > +dostring(a, string.format("=3D%s", string.rep('x', 500))) > +assert(string.find(debug.getinfo(f).short_src, "^x*")) > +dostring(a, "=3D") > +assert(debug.getinfo(f).short_src =3D=3D "") > +a =3D nil; f =3D nil; > + > + > +repeat > + local g =3D {x =3D function () > + local a =3D debug.getinfo(2) > + assert(a.name =3D=3D 'f' and a.namewhat =3D=3D 'local') > + a =3D debug.getinfo(1) > + assert(a.name =3D=3D 'x' and a.namewhat =3D=3D 'field') > + return 'xixi' > + end} > + local f =3D function () return 1+1 and (not 1 or g.x()) end > + assert(f() =3D=3D 'xixi') > + g =3D debug.getinfo(f) > + assert(g.what =3D=3D "Lua" and g.func =3D=3D f and g.namewhat =3D=3D = "" and not g.name) > + > + function f (x, name) -- local! > + name =3D name or 'f' > + local a =3D debug.getinfo(1) > + assert(a.name =3D=3D name and a.namewhat =3D=3D 'local') > + return x > + end > + > + -- breaks in different conditions > + if 3>4 then break end; f() > + if 3<4 then a=3D1 else break end; f() > + while 1 do local x=3D10; break end; f() > + local b =3D 1 > + if 3>4 then return math.sin(1) end; f() > + a =3D 3<4; f() > + a =3D 3<4 or 1; f() > + repeat local x=3D20; if 4>3 then f() else break end; f() until 1 > + g =3D {} > + f(g).x =3D f(2) and f(10)+f(9) > + assert(g.x =3D=3D f(19)) > + function g(x) if not x then return 3 end return (x('a', 'x')) end > + assert(g(f) =3D=3D 'a') > +until 1 > + > +test([[if > +math.sin(1) > +then > + a=3D1 > +else > + a=3D2 > +end > +]], {2,4,7}) > + > +test([[-- > +if nil then > + a=3D1 > +else > + a=3D2 > +end > +]], {2,5,6}) > + > +test([[a=3D1 > +repeat > + a=3Da+1 > +until a=3D=3D3 > +]], {1,3,4,3,4}) > + > +test([[ do > + return > +end > +]], {2}) > + > +test([[local a > +a=3D1 > +while a<=3D3 do > + a=3Da+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=3D1]], {1,2,4,7}) > + > +test([[for i=3D1,3 do > + a=3Di > +end > +]], {1,2,1,2,1,2,1,3}) > + > +test([[for i,v in pairs{'a','b'} do > + a=3Di..v > +end > +]], {1,2,1,2,1,3}) > + > +test([[for i=3D1,4 do a=3D1 end]], {1,1,1,1,1}) > + > + > + > +print'+' > + > +a =3D {}; L =3D nil > +local glob =3D 1 > +local oldglob =3D glob > +debug.sethook(function (e,l) > + collectgarbage() -- force GC during a hook > + local f, m, c =3D debug.gethook() > + assert(m =3D=3D 'crl' and c =3D=3D 0) > + if e =3D=3D "line" then > + if glob ~=3D oldglob then > + L =3D l-1 -- get the first line where "glob" has changed > + oldglob =3D glob > + end > + elseif e =3D=3D "call" then > + local f =3D debug.getinfo(2, "f").func > + a[f] =3D 1 > + else assert(e =3D=3D "return") > + end > +end, "crl") > + > +function f(a,b) > + collectgarbage() > + local _, x =3D debug.getlocal(1, 1) > + local _, y =3D debug.getlocal(1, 2) > + assert(x =3D=3D a and y =3D=3D b) > + assert(debug.setlocal(2, 3, "pera") =3D=3D "AA".."AA") > + assert(debug.setlocal(2, 4, "ma=EF=BF=BD=EF=BF=BD") =3D=3D "B") > + x =3D debug.getinfo(2) > + assert(x.func =3D=3D g and x.what =3D=3D "Lua" and x.name =3D=3D = 'g' and > + x.nups =3D=3D 0 and string.find(x.source, "^@.*db%.lua")) > + glob =3D glob+1 > + assert(debug.getinfo(1, "l").currentline =3D=3D L+1) > + assert(debug.getinfo(1, "l").currentline =3D=3D L+2) > +end > + > +function foo() > + glob =3D glob+1 > + assert(debug.getinfo(1, "l").currentline =3D=3D L+1) > +end; foo() -- set L > +-- check line counting inside strings and empty lines > + > +_ =3D 'alo\ > +alo' .. [[ > + > +]] > +--[[ > +]] > +assert(debug.getinfo(1, "l").currentline =3D=3D L+11) -- check count = of lines > + > + > +function g(...) > + do local a,b,c; a=3Dmath.sin(40); end > + local feijao > + local AAAA,B =3D "xuxu", "mam=EF=BF=BDo" > + f(AAAA,B) > + assert(AAAA =3D=3D "pera" and B =3D=3D "ma=EF=BF=BD=EF=BF=BD") > + do > + local B =3D 13 > + local x,y =3D debug.getlocal(1,5) > + assert(x =3D=3D 'B' and y =3D=3D 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 =3D debug.getlocal(0, 1) > +assert(v =3D=3D 0 and n =3D=3D "(*temporary)") > +local n, v =3D debug.getlocal(0, 2) > +assert(v =3D=3D 2 and n =3D=3D "(*temporary)") > +assert(not debug.getlocal(0, 3)) > +assert(not debug.getlocal(0, 0)) > + > +function f() > + assert(select(2, debug.getlocal(2,3)) =3D=3D 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) =3D=3D 30) > + > + > +debug.sethook(nil); > +assert(debug.gethook() =3D=3D nil) > + > + > +-- testing access to function arguments > + > +X =3D nil > +a =3D {} > +function a:f (a, b, ...) local c =3D 13 end > +debug.sethook(function (e) > + assert(e =3D=3D "call") > + dostring("XX =3D 12") -- test dostring inside hooks > + -- testing errors inside hooks > + assert(not pcall(loadstring("a=3D'joao'+1"))) > + debug.sethook(function (e, l) > + assert(debug.getinfo(2, "l").currentline =3D=3D l) > + local f,m,c =3D debug.gethook() > + assert(e =3D=3D "line") > + assert(m =3D=3D 'l' and c =3D=3D 0) > + debug.sethook(nil) -- hook is called only once > + assert(not X) -- check that > + X =3D {}; local i =3D 1 > + local x,y > + while 1 do > + x,y =3D debug.getlocal(2, i) > + if x=3D=3Dnil then break end > + X[x] =3D y > + i =3D i+1 > + end > + end, "l") > +end, "c") > + > +a:f(1,2,3,4,5) > +assert(X.self =3D=3D a and X.a =3D=3D 1 and X.b =3D=3D 2 and = X.arg.n =3D=3D 3 and X.c =3D=3D nil) > +assert(XX =3D=3D 12) > +assert(debug.gethook() =3D=3D nil) > + > + > +-- testing upvalue access > +local function getupvalues (f) > + local t =3D {} > + local i =3D 1 > + while true do > + local name, value =3D debug.getupvalue(f, i) > + if not name then break end > + assert(not t[name]) > + t[name] =3D value > + i =3D i + 1 > + end > + return t > +end > + > +local a,b,c =3D 1,2,3 > +local function foo1 (a) b =3D a; return c end > +local function foo2 (x) a =3D x; return c+b end > +assert(debug.getupvalue(foo1, 3) =3D=3D nil) > +assert(debug.getupvalue(foo1, 0) =3D=3D nil) > +assert(debug.setupvalue(foo1, 3, "xuxu") =3D=3D nil) > +local t =3D getupvalues(foo1) > +assert(t.a =3D=3D nil and t.b =3D=3D 2 and t.c =3D=3D 3) > +t =3D getupvalues(foo2) > +assert(t.a =3D=3D 1 and t.b =3D=3D 2 and t.c =3D=3D 3) > +assert(debug.setupvalue(foo1, 1, "xuxu") =3D=3D "b") > +assert(({debug.getupvalue(foo2, 3)})[2] =3D=3D "xuxu") > +-- cannot manipulate C upvalues from Lua > +assert(debug.getupvalue(io.read, 1) =3D=3D nil) > +assert(debug.setupvalue(io.read, 1, 10) =3D=3D nil) > + > + > +-- testing count hooks > +local a=3D0 > +debug.sethook(function (e) a=3Da+1 end, "", 1) > +a=3D0; for i=3D1,1000 do end; assert(1000 < a and a < 1012) > +debug.sethook(function (e) a=3Da+1 end, "", 4) > +a=3D0; for i=3D1,1000 do end; assert(250 < a and a < 255) > +local f,m,c =3D debug.gethook() > +assert(m =3D=3D "" and c =3D=3D 4) > +debug.sethook(function (e) a=3Da+1 end, "", 4000) > +a=3D0; for i=3D1,1000 do end; assert(a =3D=3D 0) > +debug.sethook(print, "", 2^24 - 1) -- count upperbound > +local f,m,c =3D debug.gethook() > +assert(({debug.gethook()})[3] =3D=3D 2^24 - 1) > +debug.sethook() > + > + > +-- tests for tail calls > +local function f (x) > + if x then > + assert(debug.getinfo(1, "S").what =3D=3D "Lua") > + local tail =3D debug.getinfo(2) > + assert(not pcall(getfenv, 3)) > + assert(tail.what =3D=3D "tail" and tail.short_src =3D=3D "(tail = call)" and > + tail.linedefined =3D=3D -1 and tail.func =3D=3D nil) > + assert(debug.getinfo(3, "f").func =3D=3D g1) > + assert(getfenv(3)) > + assert(debug.getinfo(4, "S").what =3D=3D "tail") > + assert(not pcall(getfenv, 5)) > + assert(debug.getinfo(5, "S").what =3D=3D "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=3Dg1; return f(x) end > + > +h(true) > + > +local b =3D {} > +debug.sethook(function (e) table.insert(b, e) end, "cr") > +h(false) > +debug.sethook() > +local res =3D {"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 =3D=3D table.remove(b, 1)) end > + > + > +lim =3D 30000 > +local function foo (x) > + if x=3D=3D0 then > + assert(debug.getinfo(lim+2).what =3D=3D "main") > + for i=3D2,lim do assert(debug.getinfo(i, "S").what =3D=3D "tail") = end > + else return foo(x-1) > + end > +end > + > +foo(lim) > + > + > +print"+" > + > + > +-- testing traceback > + > +assert(debug.traceback(print) =3D=3D print) > +assert(debug.traceback(print, 4) =3D=3D 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 =3D debug.traceback(co) > + local i =3D 0 > + for l in string.gmatch(tb, "[^\n]+\n?") do > + assert(i =3D=3D 0 or string.find(l, p[i])) > + i =3D i+1 > + end > + assert(p[i] =3D=3D nil) > +end > + > + > +local function f (n) > + if n > 0 then return f(n-1) > + else coroutine.yield() end > +end > + > +local co =3D coroutine.create(f) > +coroutine.resume(co, 3) > +checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) > + > + > +co =3D coroutine.create(function (x) > + local a =3D 1 > + coroutine.yield(debug.getinfo(1, "l")) > + coroutine.yield(debug.getinfo(1, "l").currentline) > + return a > + end) > + > +local tr =3D {} > +local foo =3D function (e, l) table.insert(tr, l) end > +debug.sethook(co, foo, "l") > + > +local _, l =3D coroutine.resume(co, 10) > +local x =3D debug.getinfo(co, 1, "lfLS") > +assert(x.currentline =3D=3D l.currentline and = x.activelines[x.currentline]) > +assert(type(x.func) =3D=3D "function") > +for i=3Dx.linedefined + 1, x.lastlinedefined do > + assert(x.activelines[i]) > + x.activelines[i] =3D nil > +end > +assert(next(x.activelines) =3D=3D nil) -- no 'extra' elements > +assert(debug.getinfo(co, 2) =3D=3D nil) > +local a,b =3D debug.getlocal(co, 1, 1) > +assert(a =3D=3D "x" and b =3D=3D 10) > +a,b =3D debug.getlocal(co, 1, 2) > +assert(a =3D=3D "a" and b =3D=3D 1) > +debug.setlocal(co, 1, 2, "hi") > +assert(debug.gethook(co) =3D=3D foo) > +assert(table.getn(tr) =3D=3D 2 and > + tr[1] =3D=3D l.currentline-1 and tr[2] =3D=3D l.currentline) > + > +a,b,c =3D pcall(coroutine.resume, co) > +assert(a and b and c =3D=3D l.currentline+1) > +checktraceback(co, {"yield", "in function <"}) > + > +a,b =3D coroutine.resume(co) > +assert(a and b =3D=3D "hi") > +assert(table.getn(tr) =3D=3D 4 and tr[4] =3D=3D l.currentline+2) > +assert(debug.gethook(co) =3D=3D foo) > +assert(debug.gethook() =3D=3D nil) > +checktraceback(co, {}) > + > + > +-- check traceback of suspended (or dead with error) coroutines > + > +function f(i) if i=3D=3D0 then error(i) else coroutine.yield(); = f(i-1) end end > + > +co =3D coroutine.create(function (x) f(x) end) > +a, b =3D coroutine.resume(co, 3) > +t =3D {"'yield'", "'f'", "in function <"} > +while coroutine.status(co) =3D=3D "suspended" do > + checktraceback(co, t) > + a, b =3D coroutine.resume(co) > + table.insert(t, 2, "'f'") -- one more recursive call to 'f' > +end > +t[1] =3D "'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=3D1,1000 do > + g(i+j) > + end > +end > + > +local co =3D coroutine.wrap(f) > +co(10) > +pcall(co) > +pcall(co) > + > + > +assert(type(debug.getregistry()) =3D=3D "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 =3D loadstring(s) > + if f =3D=3D nil then return msg end > + local cond, msg =3D 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 =3D doit(prog) > + token =3D string.gsub(token, "(%p)", "%%%1") > + local pt =3D 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)") =3D=3D 'hi') > + > +-- test error message with no info > +assert(doit("error()") =3D=3D nil) > + > + > +-- test common errors/errors that crashed in the past > +assert(doit("unpack({}, 1, n=3D2^30)")) > +assert(doit("a=3Dmath.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=3D1;;") > +assert(doit"return;;") > +assert(doit"assert(false)") > +assert(doit"assert(nil)") > +assert(doit"a=3Dmath.sin\n(3)") > +assert(doit("function a (... , ...) end")) > +assert(doit("function a (, ...) end")) > + > +checksyntax([[ > + local a =3D {4 > + > +]], "'}' expected (to close '{' at line 1)", "", 3) > + > + > +-- tests for better error messages > + > +checkmessage("a=3D1; bbbb=3D2; a=3Dmath.sin(3)+bbbb(3)", "global = 'bbbb'") > +checkmessage("a=3D1; local a,bbbb=3D2,3; a =3D math.sin(1) and = bbbb(3)", > + "local 'bbbb'") > +checkmessage("a=3D{}; do local a=3D1 end a:bbbb(3)", "method 'bbbb'") > +checkmessage("local a=3D{}; a.bbbb(3)", "field 'bbbb'") > +assert(not string.find(doit"a=3D{13}; local bbbb=3D1; a[bbbb](3)", = "'bbbb'")) > +checkmessage("a=3D{13}; local bbbb=3D1; a[bbbb](3)", "number") > + > +aaa =3D nil > +checkmessage("aaa.bbb:ddd(9)", "global 'aaa'") > +checkmessage("local aaa=3D{bbb=3D1}; aaa.bbb:ddd(9)", "field 'bbb'") > +checkmessage("local aaa=3D{bbb=3D{}}; aaa.bbb:ddd(9)", "method = 'ddd'") > +checkmessage("local a,b,c; (function () a =3D b+1 end)()", "upvalue = 'b'") > +assert(not doit"local aaa=3D{bbb=3D{ddd=3Dnext}}; aaa.bbb:ddd(nil)") > + > +checkmessage("b=3D1; local aaa=3D'a'; x=3Daaa+b", "local 'aaa'") > +checkmessage("aaa=3D{}; x=3D3/aaa", "global 'aaa'") > +checkmessage("aaa=3D'2'; b=3Dnil;x=3Daaa*b", "global 'b'") > +checkmessage("aaa=3D{}; x=3D-aaa", "global 'aaa'") > +assert(not string.find(doit"aaa=3D{}; x=3D(aaa or aaa)+(aaa and = aaa)", "'aaa'")) > +assert(not string.find(doit"aaa=3D{}; (aaa or aaa)()", "'aaa'")) > + > +checkmessage([[aaa=3D9 > +repeat until 3=3D=3D3 > +local x=3Dmath.sin(math.cos(3)) > +if math.sin(1) =3D=3D x then return math.sin(1) end -- tail call > +local a,b =3D 1, { > + {x=3D'a'..'b'..'c', y=3D'b', z=3Dx}, > + {1,2,3,4,5} or 3+3<=3D3+3, > + 3+1>3+1, > + {d =3D x and aaa[x or y]}} > +]], "global 'aaa'") > + > +checkmessage([[ > +local x,y =3D {},1 > +if math.sin(1) =3D=3D 0 then return 3 end -- return > +x.a()]], "field 'a'") > + > +checkmessage([[ > +prefix =3D nil > +insert =3D 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 =3D print .. "a"]], "concatenate") > + > +checkmessage("getmetatable(io.stdin).__gc()", "no value") > + > +print'+' > + > + > +-- testing line error > + > +function lineerror (s) > + local err,msg =3D pcall(loadstring(s)) > + local line =3D string.match(msg, ":(%d+):") > + return line and line+0 > +end > + > +assert(lineerror"local a\n for i=3D1,'a' do \n print(i) \n end" =3D=3D = 2) > +assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" = =3D=3D 3) > +assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" =3D=3D = 4) > +assert(lineerror"function a.x.y ()\na=3Da+1\nend" =3D=3D 1) > + > +local p =3D [[ > +function g() f() end > +function f(x) error('a', X) end > +g() > +]] > +X=3D3;assert(lineerror(p) =3D=3D 3) > +X=3D0;assert(lineerror(p) =3D=3D nil) > +X=3D1;assert(lineerror(p) =3D=3D 2) > +X=3D2;assert(lineerror(p) =3D=3D 1) > + > +lineerror =3D nil > + > +C =3D 0 > +local l =3D debug.getinfo(1, "l").currentline; function y () C=3DC+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 =3D 0 > +local l1 > +local function g() > + l1 =3D debug.getinfo(1, "l").currentline; y() > +end > +local _, stackmsg =3D xpcall(g, debug.traceback) > +local stack =3D {} > +for line in string.gmatch(stackmsg, "[^\n]*") do > + local curr =3D string.match(line, ":(%d+):") > + if curr then table.insert(stack, tonumber(curr)) end > +end > +local i=3D1 > +while stack[i] ~=3D l1 do > + assert(stack[i] =3D=3D l) > + i =3D i+1 > +end > +assert(i > 15) > + > + > +-- error in error handling > +local res, msg =3D xpcall(error, error) > +assert(not res and type(msg) =3D=3D 'string') > + > +local function f (x) > + if x=3D=3D0 then error('a\n') > + else > + local aux =3D function () return f(x-1) end > + local a,b =3D xpcall(aux, aux) > + return a,b > + end > +end > +f(3) > + > +-- non string messages > +function f() error{msg=3D'x'} end > +res, msg =3D xpcall(f, function (r) return {msg=3Dr.msg..'y'} end) > +assert(msg.msg =3D=3D '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 =3D 1", "", "\255", 1) > + > +doit('I =3D loadstring("a=3D9+"); a=3D3') > +assert(a=3D=3D3 and I =3D=3D nil) > +print('+') > + > +lim =3D 1000 > +if rawget(_G, "_soft") then lim =3D 100 end > +for i=3D1,lim do > + doit('a =3D ') > + doit('a =3D 4+nil') > +end > + > + > +-- testing syntax limits > +local function testrep (init, rep) > + local s =3D "local a; "..init .. string.rep(rep, 400) > + local a,b =3D loadstring(s) > + assert(not a and string.find(b, "syntax levels")) > +end > +testrep("a=3D", "{") > +testrep("a=3D", "(") > +testrep("", "a(") > +testrep("", "do ") > +testrep("", "while a do ") > +testrep("", "if a then else ") > +testrep("", "function foo () ") > +testrep("a=3D", "a..") > +testrep("a=3D", "a^") > + > + > +-- testing other limits > +-- upvalues > +local s =3D "function foo ()\n local " > +for j =3D 1,70 do > + s =3D s.."a"..j..", " > +end > +s =3D s.."b\n" > +for j =3D 1,70 do > + s =3D s.."function foo"..j.." ()\n a"..j.."=3D3\n" > +end > +local a,b =3D loadstring(s) > +assert(string.find(b, "line 3")) > + > +-- local variables > +s =3D "\nfunction foo ()\n local " > +for j =3D 1,300 do > + s =3D s.."a"..j..", " > +end > +s =3D s.."b\n" > +local a,b =3D 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 > +#include > +#include > +#include > +#include > + > +#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 =3D 0; > + > + > +static lua_State *lua_state =3D NULL; > + > +int islocked =3D 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); > +} > + > + > +/* > +** = {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +** Controlled version for realloc. > +** = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > +*/ > + > +#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) =3D = size) > +#define checkblocksize(b, size) (size =3D=3D (*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 =3D {0L, 0L, 0L, ULONG_MAX}; > + > + > +static void *checkblock (void *block, size_t size) { > + void *b =3D blockhead(block); > + int i; > + for (i=3D0;i + lua_assert(*(cast(char *, b)+HEADER+size+i) =3D=3D MARK+i); /* = corrupted block? */ > + return b; > +} > + > + > +static void freeblock (Memcontrol *mc, void *block, size_t size) { > + if (block) { > + lua_assert(checkblocksize(block, size)); > + block =3D checkblock(block, size); > + fillmem(block, size+HEADER+MARKSIZE); /* erase block */ > + free(block); /* free original block */ > + mc->numblocks--; > + mc->total -=3D size; > + } > +} > + > + > +void *debug_realloc (void *ud, void *block, size_t oldsize, size_t = size) { > + Memcontrol *mc =3D cast(Memcontrol *, ud); > + lua_assert(oldsize =3D=3D 0 || checkblocksize(block, oldsize)); > + if (size =3D=3D 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 =3D HEADER+size+MARKSIZE; > + size_t commonsize =3D (oldsize < size) ? oldsize : size; > + if (realsize < size) return NULL; /* overflow! */ > + newblock =3D malloc(realsize); /* alloc a new block */ > + if (newblock =3D=3D 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 +=3D size; > + if (mc->total > mc->maxmem) > + mc->maxmem =3D mc->total; > + mc->numblocks++; > + setsize(newblock, size); > + for (i=3D0;i + *(cast(char *, newblock)+HEADER+size+i) =3D cast(char, MARK+i); > + return cast(char *, newblock)+HEADER; > + } > +} > + > + > +/* = }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ > + > + > + > +/* > +** {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > +** Functions to check memory consistency > +** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D > +*/ > + > +static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { > + if (isdead(g,t)) return 0; > + if (g->gcstate =3D=3D GCSpropagate) > + return !isblack(f) || !iswhite(t); > + else if (g->gcstate =3D=3D GCSfinalize) > + return iswhite(f); > + else > + return 1; > +} > + > + > +static void printobj (global_State *g, GCObject *o) { > + int i =3D 0; > + GCObject *p; > + for (p =3D g->rootgc; p !=3D o && p !=3D NULL; p =3D p->gch.next) = i++; > + if (p =3D=3D NULL) i =3D -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 =3D 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) =3D=3D (t)->value.gc->gch.tt) && = testobjref(g,f,gcvalue(t)))) > + > + > + > +static void checktable (global_State *g, Table *h) { > + int i; > + int weakkey =3D 0; > + int weakvalue =3D 0; > + const TValue *mode; > + GCObject *hgc =3D obj2gco(h); > + if (h->metatable) > + checkobjref(g, hgc, h->metatable); > + mode =3D gfasttm(g, h->metatable, TM_MODE); > + if (mode && ttisstring(mode)) { /* is there a weak mode? */ > + weakkey =3D (strchr(svalue(mode), 'k') !=3D NULL); > + weakvalue =3D (strchr(svalue(mode), 'v') !=3D NULL); > + } > + i =3D h->sizearray; > + while (i--) > + checkvalref(g, hgc, &h->array[i]); > + i =3D sizenode(h); > + while (i--) { > + Node *n =3D 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 =3D obj2gco(f); > + if (f->source) checkobjref(g, fgc, f->source); > + for (i=3D0; isizek; i++) { > + if (ttisstring(f->k+i)) > + checkobjref(g, fgc, rawtsvalue(f->k+i)); > + } > + for (i=3D0; isizeupvalues; i++) { > + if (f->upvalues[i]) > + checkobjref(g, fgc, f->upvalues[i]); > + } > + for (i=3D0; isizep; i++) { > + if (f->p[i]) > + checkobjref(g, fgc, f->p[i]); > + } > + for (i=3D0; isizelocvars; i++) { > + if (f->locvars[i].varname) > + checkobjref(g, fgc, f->locvars[i].varname); > + } > +} > + > + > + > +static void checkclosure (global_State *g, Closure *cl) { > + GCObject *clgc =3D obj2gco(cl); > + checkobjref(g, clgc, cl->l.env); > + if (cl->c.isC) { > + int i; > + for (i=3D0; ic.nupvalues; i++) > + checkvalref(g, clgc, &cl->c.upvalue[i]); > + } > + else { > + int i; > + lua_assert(cl->l.nupvalues =3D=3D cl->l.p->nups); > + checkobjref(g, clgc, cl->l.p); > + for (i=3D0; il.nupvalues; i++) { > + if (cl->l.upvals[i]) { > + lua_assert(cl->l.upvals[i]->tt =3D=3D 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 =3D L1->openupval; uvo !=3D NULL; uvo =3D uvo->gch.next) { > + UpVal *uv =3D gco2uv(uvo); > + lua_assert(uv->v !=3D &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 =3D L1->base_ci; ci <=3D L1->ci; ci++) { > + lua_assert(ci->top <=3D L1->stack_last); > + lua_assert(lua_checkpc(L1, ci)); > + } > + } > + else lua_assert(L1->size_ci =3D=3D 0); > + if (L1->stack) { > + for (o =3D L1->stack; o < L1->top; o++) > + checkliveness(g, o); > + } > + else lua_assert(L1->stacksize =3D=3D 0); > +} > + > + > +static void checkobject (global_State *g, GCObject *o) { > + if (isdead(g, o)) > +/* lua_assert(g->gcstate =3D=3D GCSsweepstring || g->gcstate =3D=3D = GCSsweep);*/ > +{ if (!(g->gcstate =3D=3D GCSsweepstring || g->gcstate =3D=3D = GCSsweep)) > +printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], = o->gch.marked); > +} > + else { > + if (g->gcstate =3D=3D GCSfinalize) > + lua_assert(iswhite(o)); > + switch (o->gch.tt) { > + case LUA_TUPVAL: { > + UpVal *uv =3D gco2uv(o); > + lua_assert(uv->v =3D=3D &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 =3D 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 =3D=3D L->base_ci || !f_isLua(ci)) return 1; > + else { > + Proto *p =3D ci_func(ci)->l.p; > + if (ci < L->ci) > + return p->code <=3D ci->savedpc && ci->savedpc <=3D p->code + = p->sizecode; > + else > + return p->code <=3D L->savedpc && L->savedpc <=3D p->code + = p->sizecode; > + } > +} > + > + > +int lua_checkmemory (lua_State *L) { > + global_State *g =3D G(L); > + GCObject *o; > + UpVal *uv; > + checkstack(g, g->mainthread); > + for (o =3D g->rootgc; o !=3D obj2gco(g->mainthread); o =3D = o->gch.next) > + checkobject(g, o); > + for (o =3D o->gch.next; o !=3D NULL; o =3D o->gch.next) { > + lua_assert(o->gch.tt =3D=3D LUA_TUSERDATA); > + checkobject(g, o); > + } > + for (uv =3D g->uvhead.u.l.next; uv !=3D &g->uvhead; uv =3D = uv->u.l.next) { > + lua_assert(uv->u.l.next->u.l.prev =3D=3D uv && = uv->u.l.prev->u.l.next =3D=3D uv); > + lua_assert(uv->v !=3D &uv->u.value); /* must be open */ > + lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never = black */ > + checkvalref(g, obj2gco(uv), uv->v); > + } > + return 0; > +} > + > +/* }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D */ > + > + > + > +/* > +** {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > +** Disassembler > +** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D > +*/ > + > + > +static char *buildop (Proto *p, int pc, char *buff) { > + Instruction i =3D p->code[pc]; > + OpCode o =3D GET_OPCODE(i); > + const char *name =3D luaP_opnames[o]; > + int line =3D 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=3D0; 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 =3D clvalue(obj_at(L, 1))->l.p; > + lua_newtable(L); > + setnameval(L, "maxstack", p->maxstacksize); > + setnameval(L, "numparams", p->numparams); > + for (pc=3D0; pcsizecode; 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 =3D clvalue(obj_at(L, 1))->l.p; > + lua_createtable(L, p->sizek, 0); > + for (i=3D0; isizek; 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 =3D luaL_checkint(L, 2) - 1; > + int i =3D 0; > + const char *name; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p =3D clvalue(obj_at(L, 1))->l.p; > + while ((name =3D luaF_getlocalname(p, ++i, pc)) !=3D NULL) > + lua_pushstring(L, name); > + return i-1; > +} > + > +/* }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D */ > + > + > + > + > +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 =3D luaL_checkint(L, 1); > + return 0; > + } > +} > + > + > +static int settrick (lua_State *L) { > + Trick =3D lua_tointeger(L, 1); > + return 0; > +} > + > + > +/*static int set_gcstate (lua_State *L) { > + static const char *const state[] =3D {"propagate", "sweep", = "finalize"}; > + return 0; > +}*/ > + > + > +static int get_gccolor (lua_State *L) { > + TValue *o; > + luaL_checkany(L, 1); > + o =3D 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) =3D=3D LUA_TSTRING, 1, "string = expected"); > + lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash); > + } > + else { > + TValue *o =3D obj_at(L, 1); > + Table *t; > + luaL_checktype(L, 2, LUA_TTABLE); > + t =3D 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 =3D 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 =3D luaL_optint(L, 2, -1); > + luaL_checktype(L, 1, LUA_TTABLE); > + t =3D hvalue(obj_at(L, 1)); > + if (i =3D=3D -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 -=3D 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, ""); > + 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 =3D &G(L)->strt; > + int s =3D luaL_optint(L, 2, 0) - 1; > + if (s=3D=3D-1) { > + lua_pushinteger(L ,tb->nuse); > + lua_pushinteger(L ,tb->size); > + return 2; > + } > + else if (s < tb->size) { > + GCObject *ts; > + int n =3D 0; > + for (ts =3D tb->hash[s]; ts; ts =3D 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 =3D lua_gettop(L); > + int lock =3D 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) =3D=3D level+1); /* +1 for result */ > + return 1; > +} > + > +static int getref (lua_State *L) { > + int level =3D lua_gettop(L); > + lua_getref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) =3D=3D level+1); > + return 1; > +} > + > +static int unref (lua_State *L) { > + int level =3D lua_gettop(L); > + lua_unref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) =3D=3D level); > + return 0; > +} > + > + > +static int upvalue (lua_State *L) { > + int n =3D luaL_checkint(L, 2); > + luaL_checktype(L, 1, LUA_TFUNCTION); > + if (lua_isnone(L, 3)) { > + const char *name =3D lua_getupvalue(L, 1, n); > + if (name =3D=3D NULL) return 0; > + lua_pushstring(L, name); > + return 2; > + } > + else { > + const char *name =3D lua_setupvalue(L, 1, n); > + lua_pushstring(L, name); > + return 1; > + } > +} > + > + > +static int newuserdata (lua_State *L) { > + size_t size =3D luaL_checkint(L, 1); > + char *p =3D cast(char *, lua_newuserdata(L, size)); > + while (size--) *p++ =3D '\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 =3D lua_newthread(L); > + size_t l; > + const char *s =3D luaL_checklstring(L, 1, &l); > + int status =3D luaL_loadbuffer(L1, s, l, s); > + if (status =3D=3D 0) > + status =3D 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 =3D 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 =3D lua_getallocf(L, &ud); > + lua_State *L1 =3D 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[] =3D { > + {"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 =3D 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 =3D cast(lua_State *, cast(unsigned long, = luaL_checknumber(L, 1))); > + lua_close(L1); > + return 0; > +} > + > +static int doremote (lua_State *L) { > + lua_State *L1 =3D cast(lua_State *,cast(unsigned = long,luaL_checknumber(L, 1))); > + size_t lcode; > + const char *code =3D luaL_checklstring(L, 2, &lcode); > + int status; > + lua_settop(L1, 0); > + status =3D luaL_loadbuffer(L1, code, lcode, code); > + if (status =3D=3D 0) > + status =3D lua_pcall(L1, 0, LUA_MULTRET, 0); > + if (status !=3D 0) { > + lua_pushnil(L); > + lua_pushinteger(L, status); > + lua_pushstring(L, lua_tostring(L1, -1)); > + return 3; > + } > + else { > + int i =3D 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 =3D luaO_int2fb(luaL_checkint(L, 1)); > + lua_pushinteger(L, b); > + lua_pushinteger(L, luaO_fb2int(b)); > + return 2; > +} > + > + > + > +/* > +** {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > +** 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 > +** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D > +*/ > + > +static const char *const delimits =3D " \t\n,;"; > + > +static void skip (const char **pc) { > + while (**pc !=3D '\0' && strchr(delimits, **pc)) (*pc)++; > +} > + > +static int getnum_aux (lua_State *L, const char **pc) { > + int res =3D 0; > + int sig =3D 1; > + skip(pc); > + if (**pc =3D=3D '.') { > + res =3D cast_int(lua_tonumber(L, -1)); > + lua_pop(L, 1); > + (*pc)++; > + return res; > + } > + else if (**pc =3D=3D '-') { > + sig =3D -1; > + (*pc)++; > + } > + while (isdigit(cast_int(**pc))) res =3D res*10 + (*(*pc)++) - '0'; > + return sig*res; > +} > + > +static const char *getname_aux (char *buff, const char **pc) { > + int i =3D 0; > + skip(pc); > + while (**pc !=3D '\0' && !strchr(delimits, **pc)) > + buff[i++] =3D *(*pc)++; > + buff[i] =3D '\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) =3D=3D 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 =3D cast(lua_State *,cast(unsigned long,luaL_checknumber(L, = 1))); > + pc =3D luaL_checkstring(L, 2); > + } > + else { > + L1 =3D L; > + pc =3D luaL_checkstring(L, 1); > + } > + for (;;) { > + const char *inst =3D 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 =3D 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 =3D getindex; > + lua_pushboolean(L1, lua_lessthan(L1, a, getindex)); > + } > + else if EQ("equal") { > + int a =3D getindex; > + lua_pushboolean(L1, lua_equal(L1, a, getindex)); > + } > + else if EQ("rawcall") { > + int narg =3D getnum; > + int nres =3D getnum; > + lua_call(L1, narg, nres); > + } > + else if EQ("call") { > + int narg =3D getnum; > + int nres =3D getnum; > + lua_pcall(L1, narg, nres, 0); > + } > + else if EQ("loadstring") { > + size_t sl; > + const char *s =3D 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) =3D=3D 0) > + lua_pushnil(L1); > + } > + else if EQ("type") { > + lua_pushstring(L1, luaL_typename(L1, getnum)); > + } > + else if EQ("getn") { > + int i =3D getindex; > + lua_pushinteger(L1, luaL_getn(L1, i)); > + } > +#ifndef luaL_setn > + else if EQ("setn") { > + int i =3D getindex; > + int n =3D 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; > +} > + > +/* }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D */ > + > + > +/* > +** {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > +** tests for yield inside hooks > +** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D > +*/ > + > +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 =3D luaL_checkstring(L, 1); > + int count =3D luaL_optint(L, 2, 0); > + int mask =3D 0; > + if (strchr(smask, 'l')) mask |=3D LUA_MASKLINE; > + if (count > 0) mask |=3D LUA_MASKCOUNT; > + lua_sethook(L, yieldf, mask, count); > + } > + return 0; > +} > + > + > +static int coresume (lua_State *L) { > + int status; > + lua_State *co =3D lua_tothread(L, 1); > + luaL_argcheck(L, co, 1, "coroutine expected"); > + status =3D lua_resume(co, 0); > + if (status !=3D 0) { > + lua_pushboolean(L, 0); > + lua_insert(L, -2); > + return 2; /* return false + error message */ > + } > + else { > + lua_pushboolean(L, 1); > + return 1; > + } > +} > + > +/* }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D */ > + > + > + > +/* > +** {=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > +** tests auxlib functions > +** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D > +*/ > + > +static int auxgsub (lua_State *L) { > + const char *s1 =3D luaL_checkstring(L, 1); > + const char *s2 =3D luaL_checkstring(L, 2); > + const char *s3 =3D luaL_checkstring(L, 3); > + lua_settop(L, 3); > + luaL_gsub(L, s1, s2, s3); > + lua_assert(lua_gettop(L) =3D=3D 4); > + return 1; > +} > + > + > +/* }=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D */ > + > + > + > +static const struct luaL_Reg tests_funcs[] =3D { > + {"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) =3D=3D debug_realloc); > + lua_assert(ud =3D=3D cast(void *, &memcontrol)); > + lua_setallocf(L, lua_getallocf(L, NULL), ud); > + lua_state =3D 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 =3D getenv("MEMLIMIT"); > + if (limit) > + memcontrol.memlimit =3D strtoul(limit, NULL, 10); > + ret =3D l_main(argc, argv); > + lua_assert(memcontrol.numblocks =3D=3D 0); > + lua_assert(memcontrol.total =3D=3D 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 > + > + > +#define LUA_DEBUG > + > +#undef NDEBUG > +#include > +#define lua_assert(c) assert(c) > + > + > +/* to avoid warnings, and to make sure value is really unused */ > +#define UNUSED(x) (x=3D0, (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 =3D 0, getlock(l)->plock =3D = &(getlock(l)->lock)) > +#define luai_userstatethread(l,l1) (getlock(l1)->plock =3D = getlock(l)->plock) > +#define lua_lock(l) lua_assert((*getlock(l)->plock)++ =3D=3D 0) > +#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) =3D=3D 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 =3D 20; B =3D 30 > + > +setfenv(1, setmetatable({}, {__index=3D_G})) > + > +collectgarbage() > + > +X =3D X+10 > +assert(X =3D=3D 30 and _G.X =3D=3D 20) > +B =3D false > +assert(B =3D=3D false) > +B =3D nil > +assert(B =3D=3D 30) > + > +assert(getmetatable{} =3D=3D nil) > +assert(getmetatable(4) =3D=3D nil) > +assert(getmetatable(nil) =3D=3D nil) > +a=3D{}; setmetatable(a, {__metatable =3D "xuxu", > + __tostring=3Dfunction(x) return x.name end}) > +assert(getmetatable(a) =3D=3D "xuxu") > +assert(tostring(a) =3D=3D nil) > +-- cannot change a protected metatable > +assert(pcall(setmetatable, a, {}) =3D=3D false) > +a.name =3D "gororoba" > +assert(tostring(a) =3D=3D "gororoba") > + > +local a, t =3D {10,20,30; x=3D"10", y=3D"20"}, {} > +assert(setmetatable(a,t) =3D=3D a) > +assert(getmetatable(a) =3D=3D t) > +assert(setmetatable(a,nil) =3D=3D a) > +assert(getmetatable(a) =3D=3D nil) > +assert(setmetatable(a,t) =3D=3D a) > + > + > +function f (t, i, e) > + assert(not e) > + local p =3D rawget(t, "parent") > + return (p and p[i]+3), "dummy return" > +end > + > +t.__index =3D f > + > +a.parent =3D {z=3D25, x=3D12, [4] =3D 24} > +assert(a[1] =3D=3D 10 and a.z =3D=3D 28 and a[4] =3D=3D 27 and a.x =3D=3D= "10") > + > +collectgarbage() > + > +a =3D setmetatable({}, t) > +function f(t, i, v) rawset(t, i, v-3) end > +t.__newindex =3D f > +a[1] =3D 30; a.x =3D "101"; a[5] =3D 200 > +assert(a[1] =3D=3D 27 and a.x =3D=3D 98 and a[5] =3D=3D 197) > + > + > +local c =3D {} > +a =3D setmetatable({}, t) > +t.__newindex =3D c > +a[1] =3D 10; a[2] =3D 20; a[3] =3D 90 > +assert(c[1] =3D=3D 10 and c[2] =3D=3D 20 and c[3] =3D=3D 90) > + > + > +do > + local a; > + a =3D setmetatable({}, {__index =3D setmetatable({}, > + {__index =3D setmetatable({}, > + {__index =3D function (_,n) return a[n-3]+4, = "lixo" end})})}) > + a[0] =3D 20 > + for i=3D0,10 do > + assert(a[i*3] =3D=3D 20 + i*4) > + end > +end > + > + > +do -- newindex > + local foi > + local a =3D {} > + for i=3D1,10 do a[i] =3D 0; a['a'..i] =3D 0; end > + setmetatable(a, {__newindex =3D function (t,k,v) foi=3Dtrue; = rawset(t,k,v) end}) > + foi =3D false; a[1]=3D0; assert(not foi) > + foi =3D false; a['a1']=3D0; assert(not foi) > + foi =3D false; a['a11']=3D0; assert(foi) > + foi =3D false; a[11]=3D0; assert(foi) > + foi =3D false; a[1]=3Dnil; assert(not foi) > + foi =3D false; a[1]=3Dnil; assert(foi) > +end > + > + > +function f (t, ...) return t, {...} end > +t.__call =3D f > + > +do > + local x,y =3D a(unpack{'a', 1}) > + assert(x=3D=3Da and y[1]=3D=3D'a' and y[2]=3D=3D1 and y[3]=3D=3Dnil) > + x,y =3D a() > + assert(x=3D=3Da and y[1]=3D=3Dnil) > +end > + > + > +local b =3D setmetatable({}, t) > +setmetatable(b,t) > + > +function f(op) > + return function (...) cap =3D {[0] =3D op, ...} ; return (...) end > +end > +t.__add =3D f("add") > +t.__sub =3D f("sub") > +t.__mul =3D f("mul") > +t.__div =3D f("div") > +t.__mod =3D f("mod") > +t.__unm =3D f("unm") > +t.__pow =3D f("pow") > + > +assert(b+5 =3D=3D b) > +assert(cap[0] =3D=3D "add" and cap[1] =3D=3D b and cap[2] =3D=3D 5 = and cap[3]=3D=3Dnil) > +assert(b+'5' =3D=3D b) > +assert(cap[0] =3D=3D "add" and cap[1] =3D=3D b and cap[2] =3D=3D '5' = and cap[3]=3D=3Dnil) > +assert(5+b =3D=3D 5) > +assert(cap[0] =3D=3D "add" and cap[1] =3D=3D 5 and cap[2] =3D=3D b = and cap[3]=3D=3Dnil) > +assert('5'+b =3D=3D '5') > +assert(cap[0] =3D=3D "add" and cap[1] =3D=3D '5' and cap[2] =3D=3D b = and cap[3]=3D=3Dnil) > +b=3Db-3; assert(getmetatable(b) =3D=3D t) > +assert(5-a =3D=3D 5) > +assert(cap[0] =3D=3D "sub" and cap[1] =3D=3D 5 and cap[2] =3D=3D a = and cap[3]=3D=3Dnil) > +assert('5'-a =3D=3D '5') > +assert(cap[0] =3D=3D "sub" and cap[1] =3D=3D '5' and cap[2] =3D=3D a = and cap[3]=3D=3Dnil) > +assert(a*a =3D=3D a) > +assert(cap[0] =3D=3D "mul" and cap[1] =3D=3D a and cap[2] =3D=3D a = and cap[3]=3D=3Dnil) > +assert(a/0 =3D=3D a) > +assert(cap[0] =3D=3D "div" and cap[1] =3D=3D a and cap[2] =3D=3D 0 = and cap[3]=3D=3Dnil) > +assert(a%2 =3D=3D a) > +assert(cap[0] =3D=3D "mod" and cap[1] =3D=3D a and cap[2] =3D=3D 2 = and cap[3]=3D=3Dnil) > +assert(-a =3D=3D a) > +assert(cap[0] =3D=3D "unm" and cap[1] =3D=3D a) > +assert(a^4 =3D=3D a) > +assert(cap[0] =3D=3D "pow" and cap[1] =3D=3D a and cap[2] =3D=3D 4 = and cap[3]=3D=3Dnil) > +assert(a^'4' =3D=3D a) > +assert(cap[0] =3D=3D "pow" and cap[1] =3D=3D a and cap[2] =3D=3D '4' = and cap[3]=3D=3Dnil) > +assert(4^a =3D=3D 4) > +assert(cap[0] =3D=3D "pow" and cap[1] =3D=3D 4 and cap[2] =3D=3D a = and cap[3]=3D=3Dnil) > +assert('4'^a =3D=3D '4') > +assert(cap[0] =3D=3D "pow" and cap[1] =3D=3D '4' and cap[2] =3D=3D a = and cap[3]=3D=3Dnil) > + > + > +t =3D {} > +t.__lt =3D function (a,b,c) > + collectgarbage() > + assert(c =3D=3D nil) > + if type(a) =3D=3D 'table' then a =3D a.x end > + if type(b) =3D=3D 'table' then b =3D b.x end > + return a +end > + > +function Op(x) return setmetatable({x=3Dx}, t) end > + > +local function test () > + assert(not(Op(1) + assert(not(Op('a') + assert((Op(1)<=3DOp(1)) and (Op(1)<=3DOp(2)) and not(Op(2)<=3DOp(1)))= > + assert((Op('a')<=3DOp('a')) and (Op('a')<=3DOp('b')) and = not(Op('b')<=3DOp('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)>=3DOp(1)) and not(Op(1)>=3DOp(2)) and (Op(2)>=3DOp(1)))= > + assert((Op('a')>=3DOp('a')) and not(Op('a')>=3DOp('b')) and = (Op('b')>=3DOp('a'))) > +end > + > +test() > + > +t.__le =3D function (a,b,c) > + assert(c =3D=3D nil) > + if type(a) =3D=3D 'table' then a =3D a.x end > + if type(b) =3D=3D 'table' then b =3D b.x end > + return a<=3Db, "dummy" > +end > + > +test() -- retest comparisons, now using both `lt' and `le' > + > + > +-- test `partial order' > + > +local function Set(x) > + local y =3D {} > + for _,k in pairs(x) do y[k] =3D 1 end > + return setmetatable(y, t) > +end > + > +t.__lt =3D function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] =3D nil > + end > + return next(b) ~=3D nil > +end > + > +t.__le =3D 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} <=3D Set{1,2,3,4})) > +assert((Set{1,2,3,4} >=3D Set{1,2,3,4})) > +assert((Set{1,3} <=3D Set{3,5})) -- wrong!! model needs a `le' = method ;-) > + > +t.__le =3D 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} <=3D Set{3,5})) -- now its OK! > +assert(not(Set{1,3} <=3D Set{3,5})) > +assert(not(Set{1,3} >=3D Set{3,5})) > + > +t.__eq =3D function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] =3D nil > + end > + return next(b) =3D=3D nil > +end > + > +local s =3D Set{1,3,5} > +assert(s =3D=3D Set{3,5,1}) > +assert(not rawequal(s, Set{3,5,1})) > +assert(rawequal(s, s)) > +assert(Set{1,3,5,1} =3D=3D Set{3,5,1}) > +assert(Set{1,3,5} ~=3D Set{3,5,1,6}) > +t[Set{1,3,5}] =3D 1 > +assert(t[Set{1,3,5}] =3D=3D nil) -- `__eq' is not valid for table = accesses > + > + > +t.__concat =3D function (a,b,c) > + assert(c =3D=3D nil) > + if type(a) =3D=3D 'table' then a =3D a.val end > + if type(b) =3D=3D 'table' then b =3D b.val end > + if A then return a..b > + else > + return setmetatable({val=3Da..b}, t) > + end > +end > + > +c =3D {val=3D"c"}; setmetatable(c, t) > +d =3D {val=3D"d"}; setmetatable(d, t) > + > +A =3D true > +assert(c..d =3D=3D 'cd') > +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" =3D=3D "0abcdef8g") > + > +A =3D false > +x =3D c..d > +assert(getmetatable(x) =3D=3D t and x.val =3D=3D 'cd') > +x =3D 0 .."a".."b"..c..d.."e".."f".."g" > +assert(x.val =3D=3D "0abcdefg") > + > + > +-- test comparison compatibilities > +local t1, t2, c, d > +t1 =3D {}; c =3D {}; setmetatable(c, t1) > +d =3D {} > +t1.__eq =3D function () return true end > +t1.__lt =3D function () return true end > +assert(c ~=3D d and not pcall(function () return c < d end)) > +setmetatable(d, t1) > +assert(c =3D=3D d and c < d and not(d <=3D c)) > +t2 =3D {} > +t2.__eq =3D t1.__eq > +t2.__lt =3D t1.__lt > +setmetatable(d, t2) > +assert(c =3D=3D d and c < d and not(d <=3D c)) > + > + > + > +-- test for several levels of calls > +local i > +local tt =3D { > + __call =3D function (t, ...) > + i =3D i+1 > + if t.f then return t.f(...) > + else return {...} > + end > + end > +} > + > +local a =3D setmetatable({}, tt) > +local b =3D setmetatable({f=3Da}, tt) > +local c =3D setmetatable({f=3Db}, tt) > + > +i =3D 0 > +x =3D c(3,4,5) > +assert(i =3D=3D 3 and x[1] =3D=3D 3 and x[3] =3D=3D 5) > + > + > +assert(_G.X =3D=3D 20) > +assert(_G =3D=3D getfenv(0)) > + > +print'+' > + > +local _g =3D _G > +setfenv(1, setmetatable({}, {__index=3Dfunction (_,k) return _g[k] = end})) > + > +-- testing proxies > +assert(getmetatable(newproxy()) =3D=3D nil) > +assert(getmetatable(newproxy(false)) =3D=3D nil) > + > +local u =3D newproxy(true) > + > +getmetatable(u).__newindex =3D function (u,k,v) > + getmetatable(u)[k] =3D v > +end > + > +getmetatable(u).__index =3D function (u,k) > + return getmetatable(u)[k] > +end > + > +for i=3D1,10 do u[i] =3D i end > +for i=3D1,10 do assert(u[i] =3D=3D i) end > + > +local k =3D newproxy(u) > +assert(getmetatable(k) =3D=3D getmetatable(u)) > + > + > +a =3D {} > +rawset(a, "x", 1, 2, 3) > +assert(a.x =3D=3D 1 and rawget(a, "x", 3) =3D=3D 1) > + > +print '+' > + > +-- testing metatables for basic types > +mt =3D {} > +debug.setmetatable(10, mt) > +assert(getmetatable(-2) =3D=3D mt) > +mt.__index =3D function (a,b) return a+b end > +assert((10)[3] =3D=3D 13) > +assert((10)["3"] =3D=3D 13) > +debug.setmetatable(23, nil) > +assert(getmetatable(-2) =3D=3D nil) > + > +debug.setmetatable(true, mt) > +assert(getmetatable(false) =3D=3D mt) > +mt.__index =3D function (a,b) return a or b end > +assert((true)[false] =3D=3D true) > +assert((false)[false] =3D=3D false) > +debug.setmetatable(false, nil) > +assert(getmetatable(true) =3D=3D nil) > + > +debug.setmetatable(nil, mt) > +assert(getmetatable(nil) =3D=3D mt) > +mt.__add =3D function (a,b) return (a or 0) + (b or 0) end > +assert(10 + nil =3D=3D 10) > +assert(nil + 23 =3D=3D 23) > +assert(nil + nil =3D=3D 0) > +debug.setmetatable(nil, nil) > +assert(getmetatable(nil) =3D=3D 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) =3D=3D io.stdin) > +assert(io.output(io.stdout) =3D=3D io.stdout) > + > + > +assert(type(io.input()) =3D=3D "userdata" and io.type(io.output()) =3D=3D= "file") > +assert(io.type(8) =3D=3D nil) > +local a =3D {}; setmetatable(a, {}) > +assert(io.type(a) =3D=3D nil) > + > +local a,b,c =3D io.open('xuxu_nao_existe') > +assert(not a and type(b) =3D=3D "string" and type(c) =3D=3D "number") > + > +a,b,c =3D io.open('/a/b/c/d', 'w') > +assert(not a and type(b) =3D=3D "string" and type(c) =3D=3D "number") > + > +local file =3D os.tmpname() > +local otherfile =3D os.tmpname() > + > +assert(os.setlocale('C', 'all')) > + > +io.input(io.stdin); io.output(io.stdout); > + > +os.remove(file) > +assert(loadfile(file) =3D=3D nil) > +assert(io.open(file) =3D=3D nil) > +io.output(file) > +assert(io.output() ~=3D io.stdout) > + > +assert(io.output():seek() =3D=3D 0) > +assert(io.write("alo alo")) > +assert(io.output():seek() =3D=3D string.len("alo alo")) > +assert(io.output():seek("cur", -3) =3D=3D string.len("alo alo")-3) > +assert(io.write("joao")) > +assert(io.output():seek("end") =3D=3D string.len("alo joao")) > + > +assert(io.output():seek("set") =3D=3D 0) > + > +assert(io.write('"=EF=BF=BDlo"', "{a}\n", "second line\n", "third = line \n")) > +assert(io.write('=EF=BF=BDfourth_line')) > +io.output(io.stdout) > +collectgarbage() -- file should be closed by GC > +assert(io.input() =3D=3D io.stdin and rawequal(io.output(), = io.stdout)) > +print('+') > + > +-- test GC for files > +collectgarbage() > +for i=3D1,120 do > + for i=3D1,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) =3D=3D 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 =3D 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 =3D assert(io.open(otherfile)) > +assert(io.type(f) =3D=3D "file") > +io.output(file) > +assert(io.output():read() =3D=3D 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) =3D=3D "file (closed)") > +assert(io.type(f) =3D=3D "closed file") > +io.input(file) > +f =3D io.open(otherfile):lines() > +for l in io.lines() do assert(l =3D=3D f()) end > +assert(os.remove(otherfile)) > + > +io.input(file) > +do -- test error returns > + local a,b,c =3D io.input():write("xuxu") > + assert(not a and type(b) =3D=3D "string" and type(c) =3D=3D = "number") > +end > +assert(io.read(0) =3D=3D "") -- not eof > +assert(io.read(5, '*l') =3D=3D '"=EF=BF=BDlo"') > +assert(io.read(0) =3D=3D "") > +assert(io.read() =3D=3D "second line") > +local x =3D io.input():seek() > +assert(io.read() =3D=3D "third line ") > +assert(io.input():seek("set", x)) > +assert(io.read('*l') =3D=3D "third line ") > +assert(io.read(1) =3D=3D "=EF=BF=BD") > +assert(io.read(string.len"fourth_line") =3D=3D "fourth_line") > +assert(io.input():seek("cur", -string.len"fourth_line")) > +assert(io.read() =3D=3D "fourth_line") > +assert(io.read() =3D=3D "") -- empty line > +assert(io.read('*n') =3D=3D 3450) > +assert(io.read(1) =3D=3D '\n') > +assert(io.read(0) =3D=3D nil) -- end of file > +assert(io.read(1) =3D=3D nil) -- end of file > +assert(({io.read(1)})[2] =3D=3D nil) > +assert(io.read() =3D=3D nil) -- end of file > +assert(({io.read()})[2] =3D=3D nil) > +assert(io.read('*n') =3D=3D nil) -- end of file > +assert(({io.read('*n')})[2] =3D=3D nil) > +assert(io.read('*a') =3D=3D '') -- end of file (OK for `*a') > +assert(io.read('*a') =3D=3D '') -- end of file (OK for `*a') > +collectgarbage() > +print('+') > +io.close(io.input()) > +assert(not pcall(io.read)) > + > +assert(os.remove(file)) > + > +local t =3D '0123456789' > +for i=3D1,12 do t =3D t..t; end > +assert(string.len(t) =3D=3D 10*2^12) > + > +io.output(file) > +io.write("alo\n") > +io.close() > +assert(not pcall(io.write)) > +local f =3D 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() =3D=3D "alo") > +assert(io.read(1) =3D=3D ' ') > +assert(io.read(string.len(t)) =3D=3D t) > +assert(io.read(1) =3D=3D ' ') > +assert(io.read(0)) > +assert(io.read('*a') =3D=3D ';end of file\n') > +assert(io.read(0) =3D=3D nil) > +assert(io.close(io.input())) > + > +assert(os.remove(file)) > +print('+') > + > +local x1 =3D "string\n\n\\com \"\"''coisas [[estranhas]] ]]'" > +io.output(file) > +assert(io.write(string.format("x2 =3D %q\n-- comment without ending = EOS", x1))) > +io.close() > +assert(loadfile(file))() > +assert(x1 =3D=3D x2) > +print('+') > +assert(os.remove(file)) > +assert(os.remove(file) =3D=3D nil) > +assert(os.remove(otherfile) =3D=3D 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 =3D assert(io.open(file, 'r')) > +local otherfilehandle =3D assert(io.open(otherfile, 'rb')) > +assert(filehandle ~=3D otherfilehandle) > +assert(type(filehandle) =3D=3D "userdata") > +assert(filehandle:read('*l') =3D=3D "qualquer coisa") > +io.input(otherfilehandle) > +assert(io.read(string.len"outra coisa") =3D=3D "outra coisa") > +assert(filehandle:read('*l') =3D=3D "mais qualquer coisa") > +filehandle:close(); > +assert(type(filehandle) =3D=3D "userdata") > +io.input(otherfilehandle) > +assert(io.read(4) =3D=3D "\0\1\3\0") > +assert(io.read(3) =3D=3D "\0\0\0") > +assert(io.read(0) =3D=3D "") -- 255 is not eof > +assert(io.read(1) =3D=3D "\255") > +assert(io.read('*a') =3D=3D "\0") > +assert(not io.read(0)) > +assert(otherfilehandle =3D=3D 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,__ =3D io.read(1, '*n', '*n', '*l', '*l', '*l', = '*a', 10) > +assert(io.close(io.input())) > +assert(_ =3D=3D ' ' and __ =3D=3D nil) > +assert(type(a) =3D=3D 'number' and a=3D=3D123.4 and b=3D=3D-56e-2) > +assert(d=3D=3D'second line' and e=3D=3D'third line') > +assert(h=3D=3D[[ > + > +and the rest of the file > +]]) > +assert(os.remove(file)) > +collectgarbage() > + > +-- testing buffers > +do > + local f =3D assert(io.open(file, "w")) > + local fr =3D assert(io.open(file, "r")) > + assert(f:setvbuf("full", 2000)) > + f:write("x") > + assert(fr:read("*all") =3D=3D "") -- full buffer; output not = written yet > + f:close() > + fr:seek("set") > + assert(fr:read("*all") =3D=3D "x") -- `close' flushes it > + f =3D assert(io.open(file), "w") > + assert(f:setvbuf("no")) > + f:write("x") > + fr:seek("set") > + assert(fr:read("*all") =3D=3D "x") -- no buffer; output is ready > + f:close() > + f =3D assert(io.open(file, "a")) > + assert(f:setvbuf("line")) > + f:write("x") > + fr:seek("set", 1) > + assert(fr:read("*all") =3D=3D "") -- line buffer; no output = without `\n' > + f:write("a\n") > + fr:seek("set", 1) > + assert(fr:read("*all") =3D=3D "xa\n") -- now we have a whole line > + f:close(); fr:close() > +end > + > + > +-- testing large files (> BUFSIZ) > +io.output(file) > +for i=3D1,5001 do io.write('0123456789123') end > +io.write('\n12346') > +io.close() > +io.input(file) > +local x =3D io.read('*a') > +io.input():seek('set', 0) > +local y =3D = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003) > +assert(x =3D=3D y and string.len(x) =3D=3D 5001*13 + 6) > +io.input():seek('set', 0) > +y =3D io.read() -- huge line > +assert(x =3D=3D y..'\n'..io.read()) > +assert(io.read() =3D=3D nil) > +io.close(io.input()) > +assert(os.remove(file)) > +x =3D nil; y =3D nil > + > +x, y =3D 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 =3D os.time() > +T =3D os.date("*t", t) > +loadstring(os.date([[assert(T.year=3D=3D%Y and T.month=3D=3D%m and = T.day=3D=3D%d and > + T.hour=3D=3D%H and T.min=3D=3D%M and T.sec=3D=3D%S and > + T.wday=3D=3D%w+1 and T.yday=3D=3D%j and type(T.isdst) =3D=3D = 'boolean')]], t))() > + > +assert(os.time(T) =3D=3D t) > + > +T =3D os.date("!*t", t) > +loadstring(os.date([[!assert(T.year=3D=3D%Y and T.month=3D=3D%m and = T.day=3D=3D%d and > + T.hour=3D=3D%H and T.min=3D=3D%M and T.sec=3D=3D%S and > + T.wday=3D=3D%w+1 and T.yday=3D=3D%j and type(T.isdst) =3D=3D = 'boolean')]], t))() > + > +do > + local T =3D os.date("*t") > + local t =3D os.time(T) > + assert(type(T.isdst) =3D=3D 'boolean') > + T.isdst =3D nil > + local t1 =3D os.time(T) > + assert(t =3D=3D t1) -- if isdst is absent uses correct default > +end > + > +t =3D os.time(T) > +T.year =3D T.year-1; > +local t1 =3D os.time(T) > +-- allow for leap years > +assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2) > + > +t =3D os.time() > +t1 =3D os.time(os.date("*t")) > +assert(os.difftime(t1,t) <=3D 2) > + > +local t1 =3D os.time{year=3D2000, month=3D10, day=3D1, hour=3D23, = min=3D12, sec=3D17} > +local t2 =3D os.time{year=3D2000, month=3D10, day=3D1, hour=3D23, = min=3D10, sec=3D19} > +assert(os.difftime(t1,t2) =3D=3D 60*2-2) > + > +io.output(io.stdout) > +local d =3D os.date('%d') > +local m =3D os.date('%m') > +local a =3D os.date('%Y') > +local ds =3D os.date('%w') + 1 > +local h =3D os.date('%H') > +local min =3D os.date('%M') > +local s =3D 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"] =3D 234 > + > +limit =3D 5000 > + > + > + > +contCreate =3D 0 > + > +print('tables') > +while contCreate <=3D limit do > + local a =3D {}; a =3D nil > + contCreate =3D contCreate+1 > +end > + > +a =3D "a" > + > +contCreate =3D 0 > +print('strings') > +while contCreate <=3D limit do > + a =3D contCreate .. "b"; > + a =3D string.gsub(a, '(%d%d*)', string.upper) > + a =3D "a" > + contCreate =3D contCreate+1 > +end > + > + > +contCreate =3D 0 > + > +a =3D {} > + > +print('functions') > +function a:test () > + while contCreate <=3D limit do > + loadstring(string.format("function temp(a) return 'a%d' end", = contCreate))() > + assert(temp() =3D=3D string.format('a%d', contCreate)) > + contCreate =3D contCreate+1 > + end > +end > + > +a:test() > + > +-- collection of functions without locals, globals, etc. > +do local f =3D function () end end > + > + > +print("functions with errors") > +prog =3D [[ > +do > + a =3D 10; > + function foo(x,y) > + a =3D sin(a+0.456-0.23e-12); > + return function (z) return sin(%x+z) end > + end > + local x =3D function (w) a=3Da+w; end > +end > +]] > +do > + local step =3D 1 > + if rawget(_G, "_soft") then step =3D 13 end > + for i=3D1, string.len(prog), step do > + for j=3Di, string.len(prog), step do > + pcall(loadstring(string.sub(prog, i, j))) > + end > + end > +end > + > +print('long strings') > +x =3D = "0123456789012345678901234567890123456789012345678901234567890123456789012= 3456789" > +assert(string.len(x)=3D=3D80) > +s =3D '' > +n =3D 0 > +k =3D 300 > +while n < k do s =3D s..x; n=3Dn+1; j=3Dtostring(n) end > +assert(string.len(s) =3D=3D k*80) > +s =3D string.sub(s, 1, 20000) > +s, i =3D string.gsub(s, '(%d%d%d%d)', math.sin) > +assert(i=3D=3D20000/4) > +s =3D nil > +x =3D nil > + > +assert(_G["while"] =3D=3D 234) > + > + > +local bytes =3D gcinfo() > +while 1 do > + local nbytes =3D gcinfo() > + if nbytes < bytes then break end -- run until gc > + bytes =3D nbytes > + a =3D {} > +end > + > + > +local function dosteps (siz) > + collectgarbage() > + collectgarbage"stop" > + local a =3D {} > + for i=3D1,100 do a[i] =3D {{}}; local b =3D {} end > + local x =3D gcinfo() > + local i =3D 0 > + repeat > + i =3D i+1 > + until collectgarbage("step", siz) > + assert(gcinfo() < x) > + return i > +end > + > +assert(dosteps(0) > 10) > +assert(dosteps(6) < dosteps(2)) > +assert(dosteps(10000) =3D=3D 1) > +assert(collectgarbage("step", 1000000) =3D=3D true) > +assert(collectgarbage("step", 1000000)) > + > + > +do > + local x =3D gcinfo() > + collectgarbage() > + collectgarbage"stop" > + repeat > + local a =3D {} > + until gcinfo() > 1000 > + collectgarbage"restart" > + repeat > + local a =3D {} > + until gcinfo() < 1000 > +end > + > +lim =3D 15 > +a =3D {} > +-- fill a with `collectable' indices > +for i=3D1,lim do a[{}] =3D i end > +b =3D {} > +for k,v in pairs(a) do b[k]=3Dv end > +-- remove all indices and collect them > +for n in pairs(b) do > + a[n] =3D nil > + assert(type(n) =3D=3D 'table' and next(n) =3D=3D nil) > + collectgarbage() > +end > +b =3D nil > +collectgarbage() > +for n in pairs(a) do error'cannot be here' end > +for i=3D1,lim do a[i] =3D i end > +for i=3D1,lim do assert(a[i] =3D=3D i) end > + > + > +print('weak tables') > +a =3D {}; setmetatable(a, {__mode =3D 'k'}); > +-- fill a with some `collectable' indices > +for i=3D1,lim do a[{}] =3D i end > +-- and some non-collectable ones > +for i=3D1,lim do local t=3D{}; a[t]=3Dt end > +for i=3D1,lim do a[i] =3D i end > +for i=3D1,lim do local s=3Dstring.rep('@', i); a[s] =3D s..'#' end > +collectgarbage() > +local i =3D 0 > +for k,v in pairs(a) do assert(k=3D=3Dv or k..'#'=3D=3Dv); i=3Di+1 end > +assert(i =3D=3D 3*lim) > + > +a =3D {}; setmetatable(a, {__mode =3D 'v'}); > +a[1] =3D string.rep('b', 21) > +collectgarbage() > +assert(a[1]) -- strings are *values* > +a[1] =3D nil > +-- fill a with some `collectable' values (in both parts of the table) > +for i=3D1,lim do a[i] =3D {} end > +for i=3D1,lim do a[i..'x'] =3D {} end > +-- and some non-collectable ones > +for i=3D1,lim do local t=3D{}; a[t]=3Dt end > +for i=3D1,lim do a[i+lim]=3Di..'x' end > +collectgarbage() > +local i =3D 0 > +for k,v in pairs(a) do assert(k=3D=3Dv or k-lim..'x' =3D=3D v); i=3Di+1= end > +assert(i =3D=3D 2*lim) > + > +a =3D {}; setmetatable(a, {__mode =3D 'vk'}); > +local x, y, z =3D {}, {}, {} > +-- keep only some items > +a[1], a[2], a[3] =3D x, y, z > +a[string.rep('$', 11)] =3D string.rep('$', 11) > +-- fill a with some `collectable' values > +for i=3D4,lim do a[i] =3D {} end > +for i=3D1,lim do a[{}] =3D i end > +for i=3D1,lim do local t=3D{}; a[t]=3Dt end > +collectgarbage() > +assert(next(a) ~=3D nil) > +local i =3D 0 > +for k,v in pairs(a) do > + assert((k =3D=3D 1 and v =3D=3D x) or > + (k =3D=3D 2 and v =3D=3D y) or > + (k =3D=3D 3 and v =3D=3D z) or k=3D=3Dv); > + i =3D i+1 > +end > +assert(i =3D=3D 4) > +x,y,z=3Dnil > +collectgarbage() > +assert(next(a) =3D=3D string.rep('$', 11)) > + > + > +-- testing userdata > +collectgarbage("stop") -- stop collection > +local u =3D newproxy(true) > +local s =3D 0 > +local a =3D {[u] =3D 0}; setmetatable(a, {__mode =3D 'vk'}) > +for i=3D1,10 do a[newproxy(u)] =3D i end > +for k in pairs(a) do assert(getmetatable(k) =3D=3D getmetatable(u)) = end > +local a1 =3D {}; for k,v in pairs(a) do a1[k] =3D v end > +for k,v in pairs(a1) do a[v] =3D k end > +for i =3D1,10 do assert(a[i]) end > +getmetatable(u).a =3D a1 > +getmetatable(u).u =3D u > +do > + local u =3D u > + getmetatable(u).__gc =3D function (o) > + assert(a[o] =3D=3D 10-s) > + assert(a[10-s] =3D=3D nil) -- udata already removed from weak = table > + assert(getmetatable(o) =3D=3D getmetatable(u)) > + assert(getmetatable(o).a[o] =3D=3D 10-s) > + s=3Ds+1 > + end > +end > +a1, u =3D nil > +assert(next(a) ~=3D nil) > +collectgarbage() > +assert(s=3D=3D11) > +collectgarbage() > +assert(next(a) =3D=3D nil) -- finalized keys are removed in two = cycles > + > + > +-- __gc x weak tables > +local u =3D newproxy(true) > +setmetatable(getmetatable(u), {__mode =3D "v"}) > +getmetatable(u).__gc =3D function (o) os.exit(1) end -- cannot = happen > +collectgarbage() > + > +local u =3D newproxy(true) > +local m =3D getmetatable(u) > +m.x =3D {[{0}] =3D 1; [0] =3D {1}}; setmetatable(m.x, {__mode =3D = "kv"}); > +m.__gc =3D function (o) > + assert(next(getmetatable(o).x) =3D=3D nil) > + m =3D 10 > +end > +u, m =3D nil > +collectgarbage() > +assert(m=3D=3D10) > + > + > +-- errors during collection > +u =3D newproxy(true) > +getmetatable(u).__gc =3D function () error "!!!" end > +u =3D nil > +assert(not pcall(collectgarbage)) > + > + > +if not rawget(_G, "_soft") then > + print("deep structures") > + local a =3D {} > + for i =3D 1,200000 do > + a =3D {next =3D a} > + end > + collectgarbage() > +end > + > +-- create many threads with self-references and open upvalues > +local thread_id =3D 0 > +local threads =3D {} > + > +function fn(thread) > + local x =3D {} > + threads[thread_id] =3D function() > + thread =3D x > + end > + coroutine.yield() > +end > + > +while thread_id < 1000 do > + local thread =3D coroutine.create(fn) > + coroutine.resume(thread, thread) > + thread_id =3D thread_id + 1 > +end > + > + > + > +-- create a userdata to be collected when state is closed > +do > + local newproxy,assert,type,print,getmetatable =3D > + newproxy,assert,type,print,getmetatable > + local u =3D newproxy(true) > + local tt =3D getmetatable(u) > + ___Glob =3D {u} -- avoid udata being collected before program end > + tt.__gc =3D function (o) > + assert(getmetatable(o) =3D=3D tt) > + -- create new objects during GC > + local a =3D 'xuxu'..(10+3)..'joao', {} > + ___Glob =3D 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 =3D newproxy(true) > + getmetatable(u).__gc =3D function (o) return o + 1 end > + table.insert(___Glob, u) -- preserve udata until the end > + for i =3D 1,10 do table.insert(___Glob, newproxy(u)) end > +end > + > +print('OK') > 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..22fe6de > --- /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=3D10.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[] =3D { > + {"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=3D10.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..876a212 > --- /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[] =3D { > + {"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=3D10.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 =3D 'a\0a'") > +assert(x =3D=3D 'a\0a' and string.len(x) =3D=3D 3) > + > +-- escape sequences > +assert('\n\"\'\\' =3D=3D [[ > + > +"'\]]) > + > +assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$")) > + > +-- assume ASCII just for tests: > +assert("\09912" =3D=3D 'c12') > +assert("\99ab" =3D=3D 'cab') > +assert("\099" =3D=3D '\99') > +assert("\099\n" =3D=3D 'c\10') > +assert('\0\0\0alo' =3D=3D '\0' .. '\0\0' .. 'alo') > + > +assert(010 .. 020 .. -030 =3D=3D "1020-30") > + > +-- long variable names > + > +var =3D string.rep('a', 15000) > +prog =3D string.format("%s =3D 5", var) > +dostring(prog) > +assert(_G[var] =3D=3D 5) > +var =3D nil > +print('+') > + > +-- escapes -- > +assert("\n\t" =3D=3D [[ > + > + ]]) > +assert([[ > + > + $debug]] =3D=3D "\n $debug") > +assert([[ [ ]] ~=3D [[ ] ]]) > +-- long strings -- > +b =3D = "0012345678901234567890123456789012345678912345678901234567890123456789012= 34567890012345678901234567890123456789012345678912345678901234567890123456= 78901234567890012345678901234567890123456789012345678912345678901234567890= 12345678901234567890012345678901234567890123456789012345678912345678901234= 56789012345678901234567890012345678901234567890123456789012345678912345678= 90123456789012345678901234567890012345678901234567890123456789012345678912= 34567890123456789012345678901234567890012345678901234567890123456789012345= 67891234567890123456789012345678901234567890012345678901234567890123456789= 01234567891234567890123456789012345678901234567890012345678901234567890123= 45678901234567891234567890123456789012345678901234567890012345678901234567= 89012345678901234567891234567890123456789012345678901234567890012345678901= 23456789012345678901234567891234567890123456789012345678901234567890012345= 6789012345678901234567890123456789123456789012345678901234567890123456789"= > +assert(string.len(b) =3D=3D 960) > +prog =3D [=3D[ > +print('+') > + > +a1 =3D [["isto e' um string com v=EF=BF=BDrias 'aspas'"]] > +a2 =3D "'aspas'" > + > +assert(string.find(a1, a2) =3D=3D 31) > +print('+') > + > +a1 =3D [=3D=3D[temp =3D [[um valor qualquer]]; ]=3D=3D] > +assert(loadstring(a1))() > +assert(temp =3D=3D 'um valor qualquer') > +-- long strings -- > +b =3D = "0012345678901234567890123456789012345678912345678901234567890123456789012= 34567890012345678901234567890123456789012345678912345678901234567890123456= 78901234567890012345678901234567890123456789012345678912345678901234567890= 12345678901234567890012345678901234567890123456789012345678912345678901234= 56789012345678901234567890012345678901234567890123456789012345678912345678= 90123456789012345678901234567890012345678901234567890123456789012345678912= 34567890123456789012345678901234567890012345678901234567890123456789012345= 67891234567890123456789012345678901234567890012345678901234567890123456789= 01234567891234567890123456789012345678901234567890012345678901234567890123= 45678901234567891234567890123456789012345678901234567890012345678901234567= 89012345678901234567891234567890123456789012345678901234567890012345678901= 23456789012345678901234567891234567890123456789012345678901234567890012345= 6789012345678901234567890123456789123456789012345678901234567890123456789"= > +assert(string.len(b) =3D=3D 960) > +print('+') > + > +a =3D = [[001234567890123456789012345678901234567891234567890123456789012345678901= 23456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > = +0012345678901234567890123456789012345678912345678901234567890123456789012= 3456789 > +]] > +assert(string.len(a) =3D=3D 1863) > +assert(string.sub(a, 1, 40) =3D=3D string.sub(b, 1, 40)) > +x =3D 1 > +]=3D] > + > +print('+') > +x =3D nil > +dostring(prog) > +assert(x) > + > +prog =3D nil > +a =3D nil > +b =3D nil > + > + > +-- testing line ends > +prog =3D [[ > +a =3D 1 -- a comment > +b =3D 2 > + > + > +x =3D [=3D[ > +hi > +]=3D] > +y =3D "\ > +hello\r\n\ > +" > +return debug.getinfo(1).currentline > +]] > + > +for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do > + local prog, nn =3D string.gsub(prog, "\n", n) > + assert(dostring(prog) =3D=3D nn) > + assert(_G.x =3D=3D "hi\n" and _G.y =3D=3D "\nhello\r\n\n") > +end > + > + > +-- testing comments and strings with long brackets > +a =3D [=3D=3D[]=3D]=3D=3D] > +assert(a =3D=3D "]=3D") > + > +a =3D [=3D=3D[[=3D=3D=3D[[=3D[]]=3D][=3D=3D=3D=3D[]]=3D=3D=3D]=3D=3D=3D= ]=3D=3D] > +assert(a =3D=3D "[=3D=3D=3D[[=3D[]]=3D][=3D=3D=3D=3D[]]=3D=3D=3D]=3D=3D= =3D") > + > +a =3D [=3D=3D=3D=3D[[=3D=3D=3D[[=3D[]]=3D][=3D=3D=3D=3D[]]=3D=3D=3D]=3D= =3D=3D]=3D=3D=3D=3D] > +assert(a =3D=3D "[=3D=3D=3D[[=3D[]]=3D][=3D=3D=3D=3D[]]=3D=3D=3D]=3D=3D= =3D") > + > +a =3D [=3D[]]]]]]]]]=3D] > +assert(a =3D=3D "]]]]]]]]") > + > + > +--[=3D=3D=3D[ > +x y z [=3D=3D[ blu foo > +]=3D=3D > +] > +]=3D]=3D=3D] > +error error]=3D]=3D=3D=3D] > + > +-- generate all strings of four of these chars > +local x =3D {"=3D", "[", "]", "\n"} > +local len =3D 4 > +local function gen (c, n) > + if n=3D=3D0 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 =3D=3D loadstring("return [=3D=3D=3D=3D[\n"..s.."]=3D=3D=3D=3D= ]")()) > +end > + > + > +-- testing decimal point locale > +if os.setlocale("pt_BR") or os.setlocale("ptb") then > + assert(tonumber("3,4") =3D=3D 3.4 and tonumber"3.4" =3D=3D nil) > + assert(assert(loadstring("return 3.4"))() =3D=3D 3.4) > + assert(assert(loadstring("return .4,3"))() =3D=3D .4) > + assert(assert(loadstring("return 4."))() =3D=3D 4.) > + assert(assert(loadstring("return 4.+.5"))() =3D=3D 4.5) > + local a,b =3D 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 =3D 10 > + do local i =3D 100; assert(i=3D=3D100) end > + do local i =3D 1000; assert(i=3D=3D1000) end > + assert(i =3D=3D 10) > + if i ~=3D 10 then > + local i =3D 20 > + else > + local i =3D 30 > + assert(i =3D=3D 30) > + end > +end > + > + > + > +f =3D nil > + > +local f > +x =3D 1 > + > +a =3D nil > +loadstring('local a =3D {}')() > +assert(type(a) ~=3D 'table') > + > +function f (a) > + local _1, _2, _3, _4, _5 > + local _6, _7, _8, _9, _10 > + local x =3D 3 > + local b =3D a > + local c,d =3D a,b > + if (d =3D=3D b) then > + local x =3D 'q' > + x =3D b > + assert(x =3D=3D 2) > + else > + assert(nil) > + end > + assert(x =3D=3D 3) > + local f =3D 10 > +end > + > +local b=3D10 > +local a; repeat local b; a,b=3D1,2; assert(a+1=3D=3Db); until a+b=3D=3D= 3 > + > + > +assert(x =3D=3D 1) > + > +f(2) > +assert(type(f) =3D=3D 'function') > + > + > +-- testing globals ;-) > +do > + local f =3D {} > + local _G =3D _G > + for i=3D1,10 do f[i] =3D function (x) A=3DA+1; return A, = _G.getfenv(x) end end > + A=3D10; assert(f[1]() =3D=3D 11) > + for i=3D1,10 do assert(setfenv(f[i], {A=3Di}) =3D=3D f[i]) end > + assert(f[3]() =3D=3D 4 and A =3D=3D 11) > + local a,b =3D f[8](1) > + assert(b.A =3D=3D 9) > + a,b =3D f[8](0) > + assert(b.A =3D=3D 11) -- `real' global > + local g > + local function f () assert(setfenv(2, {a=3D'10'}) =3D=3D g) end > + g =3D function () f(); _G.assert(_G.getfenv(1).a =3D=3D '10') end > + g(); assert(getfenv(g).a =3D=3D '10') > +end > + > +-- test for global table of loaded chunks > +local function foo (s) > + return loadstring(s) > +end > + > +assert(getfenv(foo("")) =3D=3D _G) > +local a =3D {loadstring =3D loadstring} > +setfenv(foo, a) > +assert(getfenv(foo("")) =3D=3D _G) > +setfenv(0, a) -- change global environment > +assert(getfenv(foo("")) =3D=3D a) > +setfenv(0, _G) > + > + > +-- testing limits for special instructions > + > +local a > +local p =3D 4 > +for i=3D2,31 do > + for j=3D-3,3 do > + assert(loadstring(string.format([[local a=3D%s;a=3Da+ > + %s; > + assert(a > + =3D=3D2^%s)]], j, p-j, i))) () > + assert(loadstring(string.format([[local a=3D%s; > + a=3Da-%s; > + assert(a=3D=3D-2^%s)]], -j, = p-j, i))) () > + assert(loadstring(string.format([[local a,b=3D0,%s; > + a=3Db-%s; > + assert(a=3D=3D-2^%s)]], -j, = p-j, i))) () > + end > + p =3D2*p > +end > + > +print'+' > + > + > +if rawget(_G, "querytab") then > + -- testing clearing of dead elements from tables > + collectgarbage("stop") -- stop GC > + local a =3D {[{}] =3D 4, [3] =3D 0, alo =3D 1, > + a1234567890123456789012345678901234567890 =3D 10} > + > + local t =3D querytab(a) > + > + for k,_ in pairs(a) do a[k] =3D nil end > + collectgarbage() -- restore GC and collect dead fiels in `a' > + for i=3D0,t-1 do > + local k =3D querytab(a, i) > + assert(k =3D=3D nil or type(k) =3D=3D 'number' or k =3D=3D '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() ~=3D 0) -- machine has a system command > + > +prog =3D os.tmpname() > +otherprog =3D os.tmpname() > +out =3D os.tmpname() > + > +do > + local i =3D 0 > + while arg[i] do i=3Di-1 end > + progname =3D '"'..arg[i+1]..'"' > +end > +print(progname) > + > +local prepfile =3D function (s, p) > + p =3D p or prog > + io.output(p) > + io.write(s) > + assert(io.close()) > +end > + > +function checkout (s) > + io.input(out) > + local t =3D io.read("*a") > + io.input():close() > + assert(os.remove(out)) > + if s ~=3D t then print(string.format("'%s' - '%s'\n", s, t)) end > + assert(s =3D=3D t) > + return t > +end > + > +function auxrun (...) > + local s =3D string.format(...) > + s =3D string.gsub(s, "lua", progname, 1) > + return os.execute(s) > +end > + > +function RUN (...) > + assert(auxrun(...) =3D=3D 0) > +end > + > +function NoRun (...) > + print("\n(the next error is expected by the test)") > + assert(auxrun(...) ~=3D 0) > +end > + > +-- test 2 files > +prepfile("print(1); a=3D2") > +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 =3D [[ > + assert(table.getn(arg) =3D=3D 3 and arg[1] =3D=3D 'a' and > + arg[2] =3D=3D 'b' and arg[3] =3D=3D 'c') > + assert(arg[-1] =3D=3D '--' and arg[-2] =3D=3D "-e " and arg[-3] =3D=3D= %s) > + assert(arg[4] =3D=3D nil and arg[-4] =3D=3D nil) > + local a, b, c =3D ... > + assert(... =3D=3D 'a' and a =3D=3D 'a' and b =3D=3D 'b' and c =3D=3D = 'c') > +]] > +a =3D string.format(a, progname) > +prepfile(a) > +RUN('lua "-e " -- %s a b c', prog) > + > +prepfile"assert(arg=3D=3Dnil)" > +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=3D3 -e "print(a)" > %s]], out) > +checkout("1\n3\n") > + > +prepfile[[ > + print( > +1, a > +) > +]] > +RUN("lua - < %s > %s", prog, out) > +checkout("1\tnil\n") > + > +prepfile[[ > +=3D (6*2-6) -- =3D=3D=3D > +a > +=3D 10 > +print(a) > +=3D a]] > +RUN([[lua -e"_PROMPT=3D'' _PROMPT2=3D''" -i < %s > %s]], prog, out) > +checkout("6\n10\n10\n\n") > + > +prepfile("a =3D [[b\nc\nd\ne]]\n=3Da") > +print(prog) > +RUN([[lua -e"_PROMPT=3D'' _PROMPT2=3D''" -i < %s > %s]], prog, out) > +checkout("b\nc\nd\ne\n\n") > + > +prompt =3D "alo" > +prepfile[[ -- > +a =3D 2 > +]] > +RUN([[lua "-e_PROMPT=3D'%s'" -i < %s > %s]], prompt, prog, out) > +checkout(string.rep(prompt, 3).."\n") > + > +s =3D [=3D[ -- > +function f ( x ) > + local a =3D [[ > +xuxu > +]] > + local b =3D "\ > +xuxu\n" > + if x =3D=3D 11 then return 1 , 2 end --[[ test multiple returns ]] > + return x + 1 > + --\\ > +end > +=3D( f( 10 ) ) > +assert( a =3D=3D b ) > +=3Df( 11 ) ]=3D] > +s =3D string.gsub(s, ' ', '\n\n') > +prepfile(s) > +RUN([[lua -e"_PROMPT=3D'' _PROMPT2=3D''" -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 =3D "2", " 3e0 ", " 10 " > + assert(a+b =3D=3D 5 and -b =3D=3D -3 and b+"2" =3D=3D 5 and "10"-c = =3D=3D 0) > + assert(type(a) =3D=3D 'string' and type(b) =3D=3D 'string' and = type(c) =3D=3D 'string') > + assert(a =3D=3D "2" and b =3D=3D " 3e0 " and c =3D=3D " 10 " and = -c =3D=3D -" 10 ") > + assert(c%a =3D=3D 0 and a^b =3D=3D 8) > +end > + > + > +do > + local a,b =3D math.modf(3.5) > + assert(a =3D=3D 3 and b =3D=3D 0.5) > + assert(math.huge > 10e30) > + assert(-math.huge < -10e30) > +end > + > +function f(...) > + if select('#', ...) =3D=3D 1 then > + return (...) > + else > + return "***" > + end > +end > + > +assert(tonumber{} =3D=3D nil) > +assert(tonumber'+0.01' =3D=3D 1/100 and tonumber'+.01' =3D=3D 0.01 = and > + tonumber'.01' =3D=3D 0.01 and tonumber'-1.' =3D=3D -1 and > + tonumber'+1.' =3D=3D 1) > +assert(tonumber'+ 0.01' =3D=3D nil and tonumber'+.e1' =3D=3D nil and > + tonumber'1e' =3D=3D nil and tonumber'1.0e+' =3D=3D nil and > + tonumber'.' =3D=3D nil) > +assert(tonumber('-12') =3D=3D -10-2) > +assert(tonumber('-1.2e2') =3D=3D - - -120) > +assert(f(tonumber('1 a')) =3D=3D nil) > +assert(f(tonumber('e1')) =3D=3D nil) > +assert(f(tonumber('e 1')) =3D=3D nil) > +assert(f(tonumber(' 3.4.5 ')) =3D=3D nil) > +assert(f(tonumber('')) =3D=3D nil) > +assert(f(tonumber('', 8)) =3D=3D nil) > +assert(f(tonumber(' ')) =3D=3D nil) > +assert(f(tonumber(' ', 9)) =3D=3D nil) > +assert(f(tonumber('99', 8)) =3D=3D nil) > +assert(tonumber(' 1010 ', 2) =3D=3D 10) > +assert(tonumber('10', 36) =3D=3D 36) > +--assert(tonumber('\n -10 \n', 36) =3D=3D -36) > +--assert(tonumber('-fFfa', 16) =3D=3D = -(10+(16*(15+(16*(15+(16*15))))))) > +assert(tonumber('fFfa', 15) =3D=3D nil) > +--assert(tonumber(string.rep('1', 42), 2) + 1 =3D=3D 2^42) > +assert(tonumber(string.rep('1', 32), 2) + 1 =3D=3D 2^32) > +--assert(tonumber('-fffffFFFFF', 16)-1 =3D=3D -2^40) > +assert(tonumber('ffffFFFF', 16)+1 =3D=3D 2^32) > + > +assert(1.1 =3D=3D 1.+.1) > +assert(100.0 =3D=3D 1E2 and .01 =3D=3D 1e-2) > +assert(1111111111111111-1111111111111110=3D=3D 1000.00e-03) > +-- 1234567890123456 > +assert(1.1 =3D=3D '1.'+'.1') > +assert('1111111111111111'-'1111111111111110' =3D=3D tonumber" = +0.001e+3 \n\t") > + > +function eq (a,b,limit) > + if not limit then limit =3D 10E-10 end > + return math.abs(a-b) <=3D limit > +end > + > +assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31) > + > +assert(0.123456 > 0.123455) > + > +assert(tonumber('+1.23E30') =3D=3D 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<=3D1) and (1<=3D2) and not(2<=3D1)) > +assert(('a'<=3D'a') and ('a'<=3D'b') and not('b'<=3D'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>=3D1) and not(1>=3D2) and (2>=3D1)) > +assert(('a'>=3D'a') and not('a'>=3D'b') and ('b'>=3D'a')) > + > +-- testing mod operator > +assert(-4%3 =3D=3D 2) > +assert(4%-3 =3D=3D -2) > +assert(math.pi - math.pi % 1 =3D=3D 3) > +assert(math.pi - math.pi % 0.001 =3D=3D 3.141) > + > +local function testbit(a, n) > + return a/2^n % 2 >=3D 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) =3D=3D 10) > +assert(eq(math.atan2(1,0), math.pi/2)) > +assert(math.ceil(4.5) =3D=3D 5.0) > +assert(math.floor(4.5) =3D=3D 4.0) > +assert(math.mod(10,3) =3D=3D 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 =3D 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 ') =3D=3D 1.3e-2) > +assert(tonumber(' -1.00000000000001 ') =3D=3D -1.00000000000001) > + > +-- testing constant limits > +-- 2^23 =3D 8388608 > +assert(8388609 + -8388609 =3D=3D 0) > +assert(8388608 + -8388608 =3D=3D 0) > +assert(8388607 + -8388607 =3D=3D 0) > + > +if rawget(_G, "_soft") then return end > + > +f =3D io.tmpfile() > +assert(f) > +f:write("a =3D {") > +i =3D 1 > +repeat > + f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n") > + i=3Di+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 =3D 10e500 - 10e400 > + assert(NaN ~=3D NaN) > + assert(not (NaN < NaN)) > + assert(not (NaN <=3D NaN)) > + assert(not (NaN > NaN)) > + assert(not (NaN >=3D NaN)) > + assert(not (0 < NaN)) > + assert(not (NaN < 0)) > + local a =3D {} > + assert(not pcall(function () a[NaN] =3D 1 end)) > + assert(a[NaN] =3D=3D nil) > + a[1] =3D 1 > + assert(not pcall(function () a[NaN] =3D 1 end)) > + assert(a[NaN] =3D=3D nil) > +end > + > +require "checktable" > +stat(a) > + > +a =3D nil > + > +-- testing implicit convertions > + > +local a,b =3D '10', '20' > +assert(a*b =3D=3D 200 and a+b =3D=3D 30 and a-b =3D=3D -10 and a/b =3D=3D= 0.5 and -b =3D=3D -20) > +assert(a =3D=3D '10' and b =3D=3D '20') > + > + > +math.randomseed(0) > + > +local i =3D 0 > +local Max =3D 0 > +local Min =3D 2 > +repeat > + local t =3D math.random() > + Max =3D math.max(Max, t) > + Min =3D math.min(Min, t) > + i=3Di+1 > + flag =3D eq(Max, 1, 0.001) and eq(Min, 0, 0.001) > +until flag or i>10000 > +assert(0 <=3D Min and Max<1) > +assert(flag); > + > +for i=3D1,10 do > + local t =3D math.random(5) > + assert(1 <=3D t and t <=3D 5) > +end > + > +i =3D 0 > +Max =3D -200 > +Min =3D 200 > +repeat > + local t =3D math.random(-10,0) > + Max =3D math.max(Max, t) > + Min =3D math.min(Min, t) > + i=3Di+1 > + flag =3D (Max =3D=3D 0 and Min =3D=3D -10) > +until flag or i>10000 > +assert(-10 <=3D Min and Max<=3D0) > +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 =3D {} > + > +-- make sure table has lots of space in hash part > +for i=3D1,100 do a[i.."+"] =3D true end > +for i=3D1,100 do a[i.."+"] =3D nil end > +-- fill hash part with numeric indices testing size operator > +for i=3D1,100 do > + a[i] =3D true > + assert(#a =3D=3D i) > +end > + > + > +if T then > +-- testing table sizes > + > +local l2 =3D math.log(2) > +local function log2 (x) return math.log(x)/l2 end > + > +local function mp2 (n) -- minimum power of 2 >=3D n > + local mp =3D 2^math.ceil(log2(n)) > + assert(n =3D=3D 0 or (mp/2 < n and n <=3D mp)) > + return mp > +end > + > +local function fb (n) > + local r, nn =3D T.int2fb(n) > + assert(r < 256) > + return nn > +end > + > +-- test fb function > +local a =3D 1 > +local lim =3D 2^30 > +while a < lim do > + local n =3D fb(a) > + assert(a <=3D n and n <=3D a*1.125) > + a =3D math.ceil(a*1.3) > +end > + > + > +local function check (t, na, nh) > + local a, h =3D T.querytab(t) > + if a ~=3D na or h ~=3D nh then > + print(na, nh, a, h) > + assert(nil) > + end > +end > + > +-- testing constructor sizes > +local lim =3D 40 > +local s =3D 'return {' > +for i=3D1,lim do > + s =3D s..i..',' > + local s =3D s > + for k=3D0,lim do > + local t =3D loadstring(s..'}')() > + assert(#t =3D=3D i) > + check(t, fb(i), mp2(k)) > + s =3D string.format('%sa%d=3D%d,', s, k, k) > + end > +end > + > + > +-- tests with unknown number of elements > +local a =3D {} > +for i=3D1,lim do a[i] =3D i end -- build auxiliary table > +for k=3D0,lim do > + local a =3D {unpack(a,1,k)} > + assert(#a =3D=3D k) > + check(a, k, 0) > + a =3D {1,2,3,unpack(a,1,k)} > + check(a, k+3, 0) > + assert(#a =3D=3D k + 3) > +end > + > + > +print'+' > + > +-- testing tables dynamically built > +local lim =3D 130 > +local a =3D {}; a[2] =3D 1; check(a, 0, 1) > +a =3D {}; a[0] =3D 1; check(a, 0, 1); a[2] =3D 1; check(a, 0, 2) > +a =3D {}; a[0] =3D 1; a[1] =3D 1; check(a, 1, 1) > +a =3D {} > +for i =3D 1,lim do > + a[i] =3D 1 > + assert(#a =3D=3D i) > + check(a, mp2(i), 0) > +end > + > +a =3D {} > +for i =3D 1,lim do > + a['a'..i] =3D 1 > + assert(#a =3D=3D 0) > + check(a, 0, mp2(i)) > +end > + > +a =3D {} > +for i=3D1,16 do a[i] =3D i end > +check(a, 16, 0) > +for i=3D1,11 do a[i] =3D nil end > +for i=3D30,40 do a[i] =3D nil end -- force a rehash (?) > +check(a, 0, 8) > +a[10] =3D 1 > +for i=3D30,40 do a[i] =3D nil end -- force a rehash (?) > +check(a, 0, 8) > +for i=3D1,14 do a[i] =3D nil end > +for i=3D30,50 do a[i] =3D nil end -- force a rehash (?) > +check(a, 0, 4) > + > +-- reverse filling > +for i=3D1,lim do > + local a =3D {} > + for i=3Di,1,-1 do a[i] =3D i end -- fill in reverse > + check(a, mp2(i), 0) > +end > + > +-- size tests for vararg > +lim =3D 35 > +function foo (n, ...) > + local arg =3D {...} > + check(arg, n, 0) > + assert(select('#', ...) =3D=3D n) > + arg[n+1] =3D true > + check(arg, mp2(n+1), 0) > + arg.x =3D true > + check(arg, mp2(n+1), 1) > +end > +local a =3D {} > +for i=3D1,lim do a[i] =3D true; foo(i, unpack(a)) end > + > +end > + > + > +-- test size operation on empty tables > +assert(#{} =3D=3D 0) > +assert(#{nil} =3D=3D 0) > +assert(#{nil, nil} =3D=3D 0) > +assert(#{nil, nil, nil} =3D=3D 0) > +assert(#{nil, nil, nil, nil} =3D=3D 0) > +print'+' > + > + > +local nofind =3D {} > + > +a,b,c =3D 1,2,3 > +a,b,c =3D nil > + > +local function find (name) > + local n,v > + while 1 do > + n,v =3D next(_G, n) > + if not n then return nofind end > + assert(v ~=3D nil) > + if n =3D=3D name then return v end > + end > +end > + > +local function find1 (name) > + for n,v in pairs(_G) do > + if n=3D=3Dname then return v end > + end > + return nil -- not found > +end > + > +do -- create 10000 new global variables > + for i=3D1,10000 do _G[i] =3D i end > +end > + > + > +a =3D {x=3D90, y=3D8, z=3D23} > +assert(table.foreach(a, function(i,v) if i=3D=3D'x' then return v end = end) =3D=3D 90) > +assert(table.foreach(a, function(i,v) if i=3D=3D'a' then return v end = end) =3D=3D nil) > +table.foreach({}, error) > + > +table.foreachi({x=3D10, y=3D20}, error) > +local a =3D {n =3D 1} > +table.foreachi({n=3D3}, function (i, v) > + assert(a.n =3D=3D i and not v) > + a.n=3Da.n+1 > +end) > +a =3D {10,20,30,nil,50} > +table.foreachi(a, function (i,v) assert(a[i] =3D=3D v) end) > +assert(table.foreachi({'a', 'b', 'c'}, function (i,v) > + if i=3D=3D2 then return v end > + end) =3D=3D 'b') > + > + > +assert(print=3D=3Dfind("print") and print =3D=3D find1("print")) > +assert(_G["print"]=3D=3Dfind("print")) > +assert(assert=3D=3Dfind1("assert")) > +assert(nofind=3D=3Dfind("return")) > +assert(not find1("return")) > +_G["ret" .. "urn"] =3D nil > +assert(nofind=3D=3Dfind("return")) > +_G["xxx"] =3D 1 > +assert(xxx=3D=3Dfind("xxx")) > +print('+') > + > +a =3D {} > +for i=3D0,10000 do > + if math.mod(i,10) ~=3D 0 then > + a['x'..i] =3D i > + end > +end > + > +n =3D {n=3D0} > +for i,v in pairs(a) do > + n.n =3D n.n+1 > + assert(i and v and a[i] =3D=3D v) > +end > +assert(n.n =3D=3D 9000) > +a =3D nil > + > +-- remove those 10000 new global variables > +for i=3D1,10000 do _G[i] =3D nil end > + > +do -- clear global table > + local a =3D {} > + local preserve =3D {io =3D 1, string =3D 1, debug =3D 1, os =3D 1, > + coroutine =3D 1, table =3D 1, math =3D 1} > + for n,v in pairs(_G) do a[n]=3Dv end > + for n,v in pairs(a) do > + if not preserve[n] and type(v) ~=3D "function" and > + not string.find(n, "^[%u_]") then > + _G[n] =3D nil > + end > + collectgarbage() > + end > +end > + > +local function foo () > + local getfenv, setfenv, assert, next =3D > + getfenv, setfenv, assert, next > + local n =3D {gl1=3D3} > + setfenv(foo, n) > + assert(getfenv(foo) =3D=3D getfenv(1)) > + assert(getfenv(foo) =3D=3D n) > + assert(print =3D=3D nil and gl1 =3D=3D 3) > + gl1 =3D nil > + gl =3D 1 > + assert(n.gl =3D=3D 1 and next(n, 'gl') =3D=3D nil) > +end > +foo() > + > +print'+' > + > +local function checknext (a) > + local b =3D {} > + table.foreach(a, function (k,v) b[k] =3D v end) > + for k,v in pairs(b) do assert(a[k] =3D=3D v) end > + for k,v in pairs(a) do assert(b[k] =3D=3D v) end > + b =3D {} > + do local k,v =3D next(a); while k do b[k] =3D v; k,v =3D next(a,k) = end end > + for k,v in pairs(b) do assert(a[k] =3D=3D v) end > + for k,v in pairs(a) do assert(b[k] =3D=3D v) end > +end > + > +checknext{1,x=3D1,y=3D2,z=3D3} > +checknext{1,2,x=3D1,y=3D2,z=3D3} > +checknext{1,2,3,x=3D1,y=3D2,z=3D3} > +checknext{1,2,3,4,x=3D1,y=3D2,z=3D3} > +checknext{1,2,3,4,5,x=3D1,y=3D2,z=3D3} > + > +assert(table.getn{} =3D=3D 0) > +assert(table.getn{[-1] =3D 2} =3D=3D 0) > +assert(table.getn{1,2,3,nil,nil} =3D=3D 3) > +for i=3D0,40 do > + local a =3D {} > + for j=3D1,i do a[j]=3Dj end > + assert(table.getn(a) =3D=3D i) > +end > + > + > +assert(table.maxn{} =3D=3D 0) > +assert(table.maxn{["1000"] =3D true} =3D=3D 0) > +assert(table.maxn{["1000"] =3D true, [24.5] =3D 3} =3D=3D 24.5) > +assert(table.maxn{[1000] =3D true} =3D=3D 1000) > +assert(table.maxn{[10] =3D true, [100*math.pi] =3D print} =3D=3D = 100*math.pi) > + > + > +-- int overflow > +a =3D {} > +for i=3D0,50 do a[math.pow(2,i)] =3D true end > +assert(a[table.getn(a)]) > + > +print("+") > + > + > +-- erasing values > +local t =3D {[{1}] =3D 1, [{2}] =3D 2, [string.rep("x ", 4)] =3D 3, > + [100.3] =3D 4, [4] =3D 5} > + > +local n =3D 0 > +for k, v in pairs( t ) do > + n =3D n+1 > + assert(t[k] =3D=3D v) > + t[k] =3D nil > + collectgarbage() > + assert(t[k] =3D=3D nil) > +end > +assert(n =3D=3D 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) =3D=3D -1) > + assert(table.remove(a,1) =3D=3D -2) > + assert(table.remove(a,1) =3D=3D 10) > + assert(table.remove(a,1) =3D=3D 20) > + assert(table.remove(a,1) =3D=3D 40) > + assert(table.remove(a,1) =3D=3D 50) > + assert(table.remove(a,1) =3D=3D nil) > +end > + > +a =3D {n=3D0, [-7] =3D "ban"} > +test(a) > +assert(a.n =3D=3D 0 and a[-7] =3D=3D "ban") > + > +a =3D {[-7] =3D "ban"}; > +test(a) > +assert(a.n =3D=3D nil and table.getn(a) =3D=3D 0 and a[-7] =3D=3D = "ban") > + > + > +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, = -1) > +assert(table.remove(a) =3D=3D 10) > +assert(table.remove(a) =3D=3D 20) > +assert(table.remove(a) =3D=3D -1) > + > +a =3D {'c', 'd'} > +table.insert(a, 3, 'a') > +table.insert(a, 'b') > +assert(table.remove(a, 1) =3D=3D 'c') > +assert(table.remove(a, 1) =3D=3D 'd') > +assert(table.remove(a, 1) =3D=3D 'a') > +assert(table.remove(a, 1) =3D=3D 'b') > +assert(table.getn(a) =3D=3D 0 and a.n =3D=3D nil) > +print("+") > + > +a =3D {} > +for i=3D1,1000 do > + a[i] =3D i; a[i-1] =3D nil > +end > +assert(next(a,nil) =3D=3D 1000 and next(a,1000) =3D=3D nil) > + > +assert(next({}) =3D=3D nil) > +assert(next({}, nil) =3D=3D nil) > + > +for a,b in pairs{} do error"not here" end > +for i=3D1,0 do error'not here' end > +for i=3D0,1,-1 do error'not here' end > +a =3D nil; for i=3D1,1 do assert(not a); a=3D1 end; assert(a) > +a =3D nil; for i=3D1,1,-1 do assert(not a); a=3D1 end; assert(a) > + > +a =3D 0; for i=3D0, 1, 0.1 do a=3Da+1 end; assert(a=3D=3D11) > +-- precision problems > +--a =3D 0; for i=3D1, 0, -0.01 do a=3Da+1 end; assert(a=3D=3D101) > +a =3D 0; for i=3D0, 0.999999999, 0.1 do a=3Da+1 end; assert(a=3D=3D10) > +a =3D 0; for i=3D1, 1, 1 do a=3Da+1 end; assert(a=3D=3D1) > +a =3D 0; for i=3D1e10, 1e10, -1 do a=3Da+1 end; assert(a=3D=3D1) > +a =3D 0; for i=3D1, 0.99999, 1 do a=3Da+1 end; assert(a=3D=3D0) > +a =3D 0; for i=3D99999, 1e5, -1 do a=3Da+1 end; assert(a=3D=3D0) > +a =3D 0; for i=3D1, 0.99999, -1 do a=3Da+1 end; assert(a=3D=3D1) > + > +-- conversion > +a =3D 0; for i=3D"10","1","-2" do a=3Da+1 end; assert(a=3D=3D5) > + > + > +collectgarbage() > + > + > +-- testing generic 'for' > + > +local function f (n, p) > + local t =3D {}; for i=3D1,p do t[i] =3D i*10 end > + return function (_,n) > + if n > 0 then > + n =3D n-1 > + return n, unpack(t) > + end > + end, nil, n > +end > + > +local x =3D 0 > +for n,a,b,c,d in f(5,3) do > + x =3D x+1 > + assert(a =3D=3D 10 and b =3D=3D 20 and c =3D=3D 30 and d =3D=3D = nil) > +end > +assert(x =3D=3D 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 =3D string.find(s, p) > + if i then return string.sub(s, i, e) end > +end > + > +function f1(s, p) > + p =3D string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) = end) > + p =3D string.gsub(p, "^(^?)", "%1()", 1) > + p =3D string.gsub(p, "($?)$", "()%1", 1) > + local t =3D {string.match(s, p)} > + return string.sub(s, t[1], t[#t] - 1) > +end > + > +a,b =3D string.find('', '') -- empty patterns are tricky > +assert(a =3D=3D 1 and b =3D=3D 0); > +a,b =3D string.find('alo', '') > +assert(a =3D=3D 1 and b =3D=3D 0) > +a,b =3D string.find('a\0o a\0o a\0o', 'a', 1) -- first position > +assert(a =3D=3D 1 and b =3D=3D 1) > +a,b =3D string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the = midle > +assert(a =3D=3D 5 and b =3D=3D 7) > +a,b =3D string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the = midle > +assert(a =3D=3D 9 and b =3D=3D 11) > +a,b =3D string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the = end > +assert(a =3D=3D 9 and b =3D=3D 11); > +a,b =3D string.find('a\0a\0a\0a\0\0ab', 'b') -- last position > +assert(a =3D=3D 11 and b =3D=3D 11) > +assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') =3D=3D nil) -- check = ending > +assert(string.find('', '\0') =3D=3D nil) > +assert(string.find('alo123alo', '12') =3D=3D 4) > +assert(string.find('alo123alo', '^12') =3D=3D nil) > + > +assert(f('aloALO', '%l*') =3D=3D 'alo') > +assert(f('aLo_ALO', '%a*') =3D=3D 'aLo') > + > +assert(f('aaab', 'a*') =3D=3D 'aaa'); > +assert(f('aaa', '^.*$') =3D=3D 'aaa'); > +assert(f('aaa', 'b*') =3D=3D ''); > +assert(f('aaa', 'ab*a') =3D=3D 'aa') > +assert(f('aba', 'ab*a') =3D=3D 'aba') > +assert(f('aaab', 'a+') =3D=3D 'aaa') > +assert(f('aaa', '^.+$') =3D=3D 'aaa') > +assert(f('aaa', 'b+') =3D=3D nil) > +assert(f('aaa', 'ab+a') =3D=3D nil) > +assert(f('aba', 'ab+a') =3D=3D 'aba') > +assert(f('a$a', '.$') =3D=3D 'a') > +assert(f('a$a', '.%$') =3D=3D 'a$') > +assert(f('a$a', '.$.') =3D=3D 'a$a') > +assert(f('a$a', '$$') =3D=3D nil) > +assert(f('a$b', 'a$') =3D=3D nil) > +assert(f('a$a', '$') =3D=3D '') > +assert(f('', 'b*') =3D=3D '') > +assert(f('aaa', 'bb*') =3D=3D nil) > +assert(f('aaab', 'a-') =3D=3D '') > +assert(f('aaa', '^.-$') =3D=3D 'aaa') > +assert(f('aabaaabaaabaaaba', 'b.*b') =3D=3D 'baaabaaabaaab') > +assert(f('aabaaabaaabaaaba', 'b.-b') =3D=3D 'baaab') > +assert(f('alo xo', '.o$') =3D=3D 'xo') > +assert(f(' \n isto =EF=BF=BD assim', '%S%S*') =3D=3D 'isto') > +assert(f(' \n isto =EF=BF=BD assim', '%S*$') =3D=3D 'assim') > +assert(f(' \n isto =EF=BF=BD assim', '[a-z]*$') =3D=3D 'assim') > +assert(f('um caracter ? extra', '[^%sa-z]') =3D=3D '?') > +assert(f('', 'a?') =3D=3D '') > +assert(f('=EF=BF=BD', '=EF=BF=BD?') =3D=3D '=EF=BF=BD') > +assert(f('=EF=BF=BDbl', '=EF=BF=BD?b?l?') =3D=3D '=EF=BF=BDbl') > +assert(f(' =EF=BF=BDbl', '=EF=BF=BD?b?l?') =3D=3D '') > +assert(f('aa', '^aa?a?a') =3D=3D 'aa') > +assert(f(']]]=EF=BF=BDb', '[^]]') =3D=3D '=EF=BF=BD') > +assert(f("0alo alo", "%x*") =3D=3D "0a") > +assert(f("alo alo", "%C+") =3D=3D "alo alo") > +print('+') > + > +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') =3D=3D "b\0o b\0o") > +assert(f1('axz123=3D 4=3D 4 34', '(.+)=3D(.*)=3D%2 %1') =3D=3D '3=3D = 4=3D 4 3') > +assert(f1('=3D=3D=3D=3D=3D=3D=3D', '^(=3D*)=3D%1$') =3D=3D '=3D=3D=3D=3D= =3D=3D=3D') > +assert(string.match('=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D', '^([=3D]*)=3D%1$'= ) =3D=3D nil) > + > +local function range (i, j) > + if i <=3D j then > + return i, range(i+1, j) > + end > +end > + > +local abc =3D string.char(range(0, 255)); > + > +assert(string.len(abc) =3D=3D 256) > + > +function strset (p) > + local res =3D {s=3D''} > + string.gsub(abc, p, function (c) res.s =3D res.s .. c end) > + return res.s > +end; > + > +assert(string.len(strset('[\200-\210]')) =3D=3D 11) > + > +assert(strset('[a-z]') =3D=3D "abcdefghijklmnopqrstuvwxyz") > +assert(strset('[a-z%d]') =3D=3D strset('[%da-uu-z]')) > +assert(strset('[a-]') =3D=3D "-a") > +assert(strset('[^%W]') =3D=3D strset('[%w]')) > +assert(strset('[]%%]') =3D=3D '%]') > +assert(strset('[a%-z]') =3D=3D '-az') > +assert(strset('[%^%[%-a%]%-b]') =3D=3D '-[]^ab') > +assert(strset('%Z') =3D=3D strset('[\1-\255]')) > +assert(strset('.') =3D=3D strset('[\1-\255%z]')) > +print('+'); > + > +assert(string.match("alo xyzK", "(%w+)K") =3D=3D "xyz") > +assert(string.match("254 K", "(%d*)K") =3D=3D "") > +assert(string.match("alo ", "(%w*)$") =3D=3D "") > +assert(string.match("alo ", "(%w+)$") =3D=3D nil) > +assert(string.find("(=EF=BF=BDlo)", "%(=EF=BF=BD") =3D=3D 1) > +local a, b, c, d, e =3D string.match("=EF=BF=BDlo alo", "^(((.).).* = (%w*))$") > +assert(a =3D=3D '=EF=BF=BDlo alo' and b =3D=3D '=EF=BF=BDl' and c =3D=3D= '=EF=BF=BD' and d =3D=3D 'alo' and e =3D=3D nil) > +a, b, c, d =3D string.match('0123456789', '(.+(.?)())') > +assert(a =3D=3D '0123456789' and b =3D=3D '' and c =3D=3D 11 and d =3D=3D= nil) > +print('+') > + > +assert(string.gsub('=EF=BF=BDlo =EF=BF=BDlo', '=EF=BF=BD', 'x') =3D=3D = 'xlo xlo') > +assert(string.gsub('alo =EF=BF=BDlo ', ' +$', '') =3D=3D 'alo = =EF=BF=BDlo') -- trim > +assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') =3D=3D 'alo = alo') -- double trim > +assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') =3D=3D 'alo alo = 123 ') > +t =3D "ab=EF=BF=BD d" > +a, b =3D string.gsub(t, '(.)', '%1@') > +assert('@'..a =3D=3D string.gsub(t, '', '@') and b =3D=3D 5) > +a, b =3D string.gsub('ab=EF=BF=BDd', '(.)', '%0@', 2) > +assert(a =3D=3D 'a@b@=EF=BF=BDd' and b =3D=3D 2) > +assert(string.gsub('alo alo', '()[al]', '%1') =3D=3D '12o 56o') > +assert(string.gsub("abc=3Dxyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") =3D=3D > + "xyz=3Dabc-abc=3Dxyz") > +assert(string.gsub("abc", "%w", "%1%0") =3D=3D "aabbcc") > +assert(string.gsub("abc", "%w+", "%0%1") =3D=3D "abcabc") > +assert(string.gsub('=EF=BF=BD=EF=BF=BD=EF=BF=BD', '$', '\0=EF=BF=BD') = =3D=3D '=EF=BF=BD=EF=BF=BD=EF=BF=BD\0=EF=BF=BD') > +assert(string.gsub('', '^', 'r') =3D=3D 'r') > +assert(string.gsub('', '$', 'r') =3D=3D 'r') > +print('+') > + > +assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", = string.upper) =3D=3D > + "um (DOIS) tres (QUATRO)") > + > +do > + local function setglobal (n,v) rawset(_G, n, v) end > + string.gsub("a=3Droberto,roberto=3Da", "(%w+)=3D(%w%w*)", = setglobal) > + assert(_G.a=3D=3D"roberto" and _G.roberto=3D=3D"a") > +end > + > +function f(a,b) return string.gsub(a,'.',b) end > +assert(string.gsub("trocar tudo em |teste|b| =EF=BF=BD |beleza|al|", = "|([^|]*)|([^|]*)|", f) =3D=3D > + "trocar tudo em bbbbb =EF=BF=BD alalalalalal") > + > +local function dostring (s) return loadstring(s)() or "" end > +assert(string.gsub("alo $a=3D1$ novamente $return a$", "$([^$]*)%$", = dostring) =3D=3D > + "alo novamente 1") > + > +x =3D string.gsub("$x=3Dstring.gsub('alo', '.', string.upper)$ assim = vai para $return x$", > + "$([^$]*)%$", dostring) > +assert(x =3D=3D ' assim vai para ALO') > + > +t =3D {} > +s =3D 'a alo jose joao' > +r =3D string.gsub(s, '()(%w+)()', function (a,w,b) > + assert(string.len(w) =3D=3D b-a); > + t[a] =3D b-a; > + end) > +assert(s =3D=3D r and t[1] =3D=3D 1 and t[3] =3D=3D 3 and t[7] =3D=3D = 4 and t[13] =3D=3D 4) > + > + > +function isbalanced (s) > + return string.find(string.gsub(s, "%b()", ""), "[()]") =3D=3D 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''", '"') =3D=3D 'alo " alo') > + > + > +local t =3D {"apple", "orange", "lime"; n=3D0} > +assert(string.gsub("x and x and x", "x", function () t.n=3Dt.n+1; = return t[t.n] end) > + =3D=3D "apple and orange and lime") > + > +t =3D {n=3D0} > +string.gsub("first second word", "%w%w*", function (w) t.n=3Dt.n+1; = t[t.n] =3D w end) > +assert(t[1] =3D=3D "first" and t[2] =3D=3D "second" and t[3] =3D=3D = "word" and t.n =3D=3D 3) > + > +t =3D {n=3D0} > +assert(string.gsub("first second word", "%w+", > + function (w) t.n=3Dt.n+1; t[t.n] =3D w end, 2) =3D=3D "first = second word") > +assert(t[1] =3D=3D "first" and t[2] =3D=3D "second" and t[3] =3D=3D = 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 =3D 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 =3D string.rep('012345', 10) > +assert(rev(rev(x)) =3D=3D x) > + > + > +-- gsub with tables > +assert(string.gsub("alo alo", ".", {}) =3D=3D "alo alo") > +assert(string.gsub("alo alo", "(.)", {a=3D"AA", l=3D""}) =3D=3D "AAo = AAo") > +assert(string.gsub("alo alo", "(.).", {a=3D"AA", l=3D"K"}) =3D=3D = "AAo AAo") > +assert(string.gsub("alo alo", "((.)(.?))", {al=3D"AA", o=3Dfalse}) =3D=3D= "AAo AAo") > + > +assert(string.gsub("alo alo", "().", {2,5,6}) =3D=3D "256 alo") > + > +t =3D {}; setmetatable(t, {__index =3D function (t,s) return = string.upper(s) end}) > +assert(string.gsub("a alo b hi", "%w%w+", t) =3D=3D "a ALO b HI") > + > + > +-- tests for gmatch > +assert(string.gfind =3D=3D string.gmatch) > +local a =3D 0 > +for i in string.gmatch('abcde', '()') do assert(i =3D=3D a+1); a=3Di = end > +assert(a=3D=3D6) > + > +t =3D {n=3D0} > +for w in string.gmatch("first second word", "%w+") do > + t.n=3Dt.n+1; t[t.n] =3D w > +end > +assert(t[1] =3D=3D "first" and t[2] =3D=3D "second" and t[3] =3D=3D = "word") > + > +t =3D {3, 6, 9} > +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do > + assert(i =3D=3D table.remove(t, 1)) > +end > +assert(table.getn(t) =3D=3D 0) > + > +t =3D {} > +for i,j in string.gmatch("13 14 10 =3D 11, 15=3D 16, 22=3D23", = "(%d+)%s*=3D%s*(%d+)") do > + t[i] =3D j > +end > +a =3D 0 > +for k,v in pairs(t) do assert(k+1 =3D=3D v+0); a=3Da+1 end > +assert(a =3D=3D 3) > + > + > +-- tests for `%f' (`frontiers') > + > +assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") =3D=3D "xaa xa x = xaa x") > +assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") =3D=3D "x[]] x]x] = x[[[") > +assert(string.gsub("01abc45de3", "%f[%d]", ".") =3D=3D = ".01abc.45de.3") > +assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") =3D=3D "01.bc45 = de3.") > +assert(string.gsub("function", "%f[\1-\255]%w", ".") =3D=3D = ".unction") > +assert(string.gsub("function", "%f[^\1-\255]", ".") =3D=3D = "function.") > + > +local i, e =3D string.find(" alo aalo allo", = "%f[%S].-%f[%s].-%f[%S]") > +assert(i =3D=3D 2 and e =3D=3D 5) > +local k =3D string.match(" alo aalo allo", = "%f[%S](.-%f[%s].-%f[%S])") > +assert(k =3D=3D 'alo ') > + > +local a =3D {1, 5, 9, 14, 17,} > +for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do > + assert(table.remove(a, 1) =3D=3D k) > +end > +assert(table.getn(a) =3D=3D 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 =3D f or function (x,y) return x + for n=3Dtable.getn(a),2,-1 do > + assert(not f(a[n], a[n-1])) > + end > +end > + > +a =3D {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", > + "Oct", "Nov", "Dec"} > + > +table.sort(a) > +check(a) > + > +limit =3D 30000 > +if rawget(_G, "_soft") then limit =3D 5000 end > + > +a =3D {} > +for i=3D1,limit do > + a[i] =3D math.random() > +end > + > +local x =3D os.clock() > +table.sort(a) > +print(string.format("Sorting %d elements in %.2f sec.", limit, = os.clock()-x)) > +check(a) > + > +x =3D os.clock() > +table.sort(a) > +print(string.format("Re-sorting %d elements in %.2f sec.", limit, = os.clock()-x)) > +check(a) > + > +a =3D {} > +for i=3D1,limit do > + a[i] =3D math.random() > +end > + > +x =3D os.clock(); i=3D0 > +table.sort(a, function(x,y) i=3Di+1; return y +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 + > + > +table.sort{} -- empty array > + > +for i=3D1,limit do a[i] =3D false end > +x =3D 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=3D=3D'n' and v=3D=3Dlimit) = end > + > +a =3D {"=EF=BF=BDlo", "\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] =3D ''", x))() > + collectgarbage() > + return x + end) > + > + > +tt =3D {__lt =3D function (a,b) return a.val < b.val end} > +a =3D {} > +for i=3D1,10 do a[i] =3D {val=3Dmath.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' <=3D '\1\0a\0a') > +assert(not ('\1\0a\0b' <=3D '\1\0a\0a')) > +assert('\0\0\0' < '\0\0\0\0') > +assert(not('\0\0\0\0' < '\0\0\0')) > +assert('\0\0\0' <=3D '\0\0\0\0') > +assert(not('\0\0\0\0' <=3D '\0\0\0')) > +assert('\0\0\0' <=3D '\0\0\0') > +assert('\0\0\0' >=3D '\0\0\0') > +assert(not ('\0\0b' < '\0\0a\0')) > +print('+') > + > +assert(string.sub("123456789",2,4) =3D=3D "234") > +assert(string.sub("123456789",7) =3D=3D "789") > +assert(string.sub("123456789",7,6) =3D=3D "") > +assert(string.sub("123456789",7,7) =3D=3D "7") > +assert(string.sub("123456789",0,0) =3D=3D "") > +assert(string.sub("123456789",-10,10) =3D=3D "123456789") > +assert(string.sub("123456789",1,9) =3D=3D "123456789") > +assert(string.sub("123456789",-10,-20) =3D=3D "") > +assert(string.sub("123456789",-1) =3D=3D "9") > +assert(string.sub("123456789",-4) =3D=3D "6789") > +assert(string.sub("123456789",-6, -4) =3D=3D "456") > +assert(string.sub("\000123456789",3,5) =3D=3D "234") > +assert(("\000123456789"):sub(8) =3D=3D "789") > +print('+') > + > +assert(string.find("123456789", "345") =3D=3D 3) > +a,b =3D string.find("123456789", "345") > +assert(string.sub("123456789", a, b) =3D=3D "345") > +assert(string.find("1234567890123456789", "345", 3) =3D=3D 3) > +assert(string.find("1234567890123456789", "345", 4) =3D=3D 13) > +assert(string.find("1234567890123456789", "346", 4) =3D=3D nil) > +assert(string.find("1234567890123456789", ".45", -9) =3D=3D 13) > +assert(string.find("abcdefg", "\0", 5, 1) =3D=3D nil) > +assert(string.find("", "") =3D=3D 1) > +assert(string.find('', 'aaa', 1) =3D=3D nil) > +assert(('alo(.)alo'):find('(.)', 1, 1) =3D=3D 4) > +print('+') > + > +assert(string.len("") =3D=3D 0) > +assert(string.len("\0\0\0") =3D=3D 3) > +assert(string.len("1234567890") =3D=3D 10) > + > +assert(#"" =3D=3D 0) > +assert(#"\0\0\0" =3D=3D 3) > +assert(#"1234567890" =3D=3D 10) > + > +assert(string.byte("a") =3D=3D 97) > +assert(string.byte("=EF=BF=BD") > 127) > +assert(string.byte(string.char(255)) =3D=3D 255) > +assert(string.byte(string.char(0)) =3D=3D 0) > +assert(string.byte("\0") =3D=3D 0) > +assert(string.byte("\0\0alo\0x", -1) =3D=3D string.byte('x')) > +assert(string.byte("ba", 2) =3D=3D 97) > +assert(string.byte("\n\n", 2, -1) =3D=3D 10) > +assert(string.byte("\n\n", 2, 2) =3D=3D 10) > +assert(string.byte("") =3D=3D nil) > +assert(string.byte("hi", -3) =3D=3D nil) > +assert(string.byte("hi", 3) =3D=3D nil) > +assert(string.byte("hi", 9, 10) =3D=3D nil) > +assert(string.byte("hi", 2, 1) =3D=3D nil) > +assert(string.char() =3D=3D "") > +assert(string.char(0, 255, 0) =3D=3D "\0\255\0") > +assert(string.char(0, string.byte("=EF=BF=BD"), 0) =3D=3D "\0=EF=BF=BD\= 0") > +assert(string.char(string.byte("=EF=BF=BDl\0=EF=BF=BDu", 1, -1)) =3D=3D= "=EF=BF=BDl\0=EF=BF=BDu") > +assert(string.char(string.byte("=EF=BF=BDl\0=EF=BF=BDu", 1, 0)) =3D=3D = "") > +assert(string.char(string.byte("=EF=BF=BDl\0=EF=BF=BDu", -10, 100)) = =3D=3D "=EF=BF=BDl\0=EF=BF=BDu") > +print('+') > + > +assert(string.upper("ab\0c") =3D=3D "AB\0C") > +assert(string.lower("\0ABCc%$") =3D=3D "\0abcc%$") > +assert(string.rep('teste', 0) =3D=3D '') > +assert(string.rep('t=EF=BF=BDs\00t=EF=BF=BD', 2) =3D=3D = 't=EF=BF=BDs\0t=EF=BF=BDt=EF=BF=BDs\000t=EF=BF=BD') > +assert(string.rep('', 10) =3D=3D '') > + > +assert(string.reverse"" =3D=3D "") > +assert(string.reverse"\0\1\2\3" =3D=3D "\3\2\1\0") > +assert(string.reverse"\0001234" =3D=3D "4321\0") > + > +for i=3D0,30 do assert(string.len(string.rep('a', i)) =3D=3D i) end > + > +assert(type(tostring(nil)) =3D=3D 'string') > +assert(type(tostring(12)) =3D=3D 'string') > +assert(''..12 =3D=3D '12' and type(12 .. '') =3D=3D 'string') > +assert(string.find(tostring{}, 'table:')) > +assert(string.find(tostring(print), 'function:')) > +assert(tostring(1234567890123) =3D=3D '1234567890123') > +assert(#tostring('\0') =3D=3D 1) > +assert(tostring(true) =3D=3D "true") > +assert(tostring(false) =3D=3D "false") > +print('+') > + > +x =3D '"=EF=BF=BDlo"\n\\' > +assert(string.format('%q%s', x, x) =3D=3D = '"\\"=EF=BF=BDlo\\"\\\n\\\\""=EF=BF=BDlo"\n\\') > +assert(string.format('%q', "\0") =3D=3D [["\000"]]) > +assert(string.format("\0%c\0%c%x\0", string.byte("=EF=BF=BD"), = string.byte("b"), 140) =3D=3D > + "\0=EF=BF=BD\0b8c\0") > +assert(string.format('') =3D=3D "") > = +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c"= ,90)..string.format("%c",100) =3D=3D > + string.format("%c%c%c%c", 34, 48, 90, 100)) > +assert(string.format("%s\0 is not \0%s", 'not be', 'be') =3D=3D 'not = be\0 is not \0be') > +assert(string.format("%%%d %010d", 10, 23) =3D=3D "%10 0000000023") > +assert(tonumber(string.format("%f", 10.3)) =3D=3D 10.3) > +x =3D string.format('"%-50s"', 'a') > +assert(#x =3D=3D 52) > +assert(string.sub(x, 1, 4) =3D=3D '"a ') > + > +assert(string.format("-%.20s.20s", string.rep("%", 2000)) =3D=3D = "-"..string.rep("%", 20)..".20s") > +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) =3D=3D > + string.format("%q", "-"..string.rep("%", 2000)..".20s")) > + > + > +-- longest number that can be formated > +assert(string.len(string.format('%99.99f', -1e308)) >=3D 100) > + > +assert(loadstring("return 1\n--coment=EF=BF=BDrio sem EOL no = final")() =3D=3D 1) > + > + > +assert(table.concat{} =3D=3D "") > +assert(table.concat({}, 'x') =3D=3D "") > +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') =3D=3D = "\0.\0.\0\1.\0.\0\1\2") > +local a =3D {}; for i=3D1,3000 do a[i] =3D "xuxu" end > +assert(table.concat(a, "123").."123" =3D=3D string.rep("xuxu123", = 3000)) > +assert(table.concat(a, "b", 20, 20) =3D=3D "xuxu") > +assert(table.concat(a, "", 20, 21) =3D=3D "xuxuxuxu") > +assert(table.concat(a, "", 22, 21) =3D=3D "") > +assert(table.concat(a, "3", 2999) =3D=3D "xuxu3xuxu") > + > +a =3D {"a","b","c"} > +assert(table.concat(a, ",", 1, 0) =3D=3D "") > +assert(table.concat(a, ",", 1, 1) =3D=3D "a") > +assert(table.concat(a, ",", 1, 2) =3D=3D "a,b") > +assert(table.concat(a, ",", 2) =3D=3D "b,c") > +assert(table.concat(a, ",", 3) =3D=3D "c") > +assert(table.concat(a, ",", 4) =3D=3D "") > + > +local locales =3D { "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" < "=EF=BF=BDlo" and "=EF=BF=BDlo" < "amo") > +end > + > +if not trylocale("ctype") then > + print("locale not supported") > +else > + assert(string.gsub("=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD", "%a", = "x") =3D=3D "xxxxx") > + assert(string.gsub("=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD", "%l", = "x") =3D=3D "x=EF=BF=BDx=EF=BF=BD") > + assert(string.gsub("=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD", "%u", = "x") =3D=3D "=EF=BF=BDx=EF=BF=BDx") > + assert(string.upper"=EF=BF=BD=EF=BF=BD=EF=BF=BD{xuxu}=EF=BF=BD=EF=BF=BD= o" =3D=3D "=EF=BF=BD=EF=BF=BD=EF=BF=BD{XUXU}=EF=BF=BD=EF=BF=BDO") > +end > + > +os.setlocale("C") > +assert(os.setlocale() =3D=3D 'C') > +assert(os.setlocale(nil, "numeric") =3D=3D '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 =3D nil > + > +function f(a, ...) > + assert(type(arg) =3D=3D 'table') > + assert(type(arg.n) =3D=3D 'number') > + for i=3D1,arg.n do assert(a[i]=3D=3Darg[i]) end > + return arg.n > +end > + > +function c12 (...) > + assert(arg =3D=3D nil) > + local x =3D {...}; x.n =3D table.getn(x) > + local res =3D (x.n=3D=3D2 and x[1] =3D=3D 1 and x[2] =3D=3D 2) > + if res then res =3D 55 end > + return res, 2 > +end > + > +function vararg (...) return arg end > + > +local call =3D function (f, args) return f(unpack(args, 1, args.n)) = end > + > +assert(f() =3D=3D 0) > +assert(f({1,2,3}, 1, 2, 3) =3D=3D 3) > +assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) =3D=3D 5) > + > +assert(c12(1,2)=3D=3D55) > +a,b =3D assert(call(c12, {1,2})) > +assert(a =3D=3D 55 and b =3D=3D 2) > +a =3D call(c12, {1,2;n=3D2}) > +assert(a =3D=3D 55 and b =3D=3D 2) > +a =3D call(c12, {1,2;n=3D1}) > +assert(not a) > +assert(c12(1,2,3) =3D=3D false) > +local a =3D vararg(call(next, {_G,nil;n=3D2})) > +local b,c =3D next(_G) > +assert(a[1] =3D=3D b and a[2] =3D=3D c and a.n =3D=3D 2) > +a =3D vararg(call(call, {c12, {1,2}})) > +assert(a.n =3D=3D 2 and a[1] =3D=3D 55 and a[2] =3D=3D 2) > +a =3D call(print, {'+'}) > +assert(a =3D=3D nil) > + > +local t =3D {1, 10} > +function t:f (...) return self[arg[1]]+arg.n end > +assert(t:f(1,4) =3D=3D 3 and t:f(2) =3D=3D 11) > +print('+') > + > +lim =3D 20 > +local i, a =3D 1, {} > +while i <=3D lim do a[i] =3D i+0.3; i=3Di+1 end > + > +function f(a, b, c, d, ...) > + local more =3D {...} > + assert(a =3D=3D 1.3 and more[1] =3D=3D 5.3 and > + more[lim-4] =3D=3D lim+0.3 and not more[lim-3]) > +end > + > +function g(a,b,c) > + assert(a =3D=3D 1.3 and b =3D=3D 2.3 and c =3D=3D 3.3) > +end > + > +call(f, a) > +call(g, a) > + > +a =3D {} > +i =3D 1 > +while i <=3D lim do a[i] =3D i; i=3Di+1 end > +assert(call(math.max, a) =3D=3D lim) > + > +print("+") > + > + > +-- new-style varargs > + > +function oneless (a, ...) return ... end > + > +function f (n, a, ...) > + local b > + assert(arg =3D=3D nil) > + if n =3D=3D 0 then > + local b, c, d =3D ... > + return a, b, c, d, oneless(oneless(oneless(...))) > + else > + n, b, a =3D n-1, ..., a > + assert(b =3D=3D ...) > + return f(n, a, ...) > + end > +end > + > +a,b,c,d,e =3D assert(f(10,5,4,3,2,1)) > +assert(a=3D=3D5 and b=3D=3D4 and c=3D=3D3 and d=3D=3D2 and e=3D=3D1) > + > +a,b,c,d,e =3D f(4) > +assert(a=3D=3Dnil and b=3D=3Dnil and c=3D=3Dnil and d=3D=3Dnil and = e=3D=3Dnil) > + > + > +-- varargs for main chunks > +f =3D loadstring[[ return {...} ]] > +x =3D f(2,3) > +assert(x[1] =3D=3D 2 and x[2] =3D=3D 3 and x[3] =3D=3D nil) > + > + > +f =3D loadstring[[ > + local x =3D {...} > + for i=3D1,select('#', ...) do assert(x[i] =3D=3D select(i, ...)) = end > + assert(x[select('#', ...)+1] =3D=3D nil) > + return true > +]] > + > +assert(f("a", "b", nil, {}, assert)) > +assert(f()) > + > +a =3D {select(3, unpack{10,20,30,40})} > +assert(table.getn(a) =3D=3D 2 and a[1] =3D=3D 30 and a[2] =3D=3D 40) > +a =3D {select(1)} > +assert(next(a) =3D=3D nil) > +a =3D {select(-1, 3, 5, 7)} > +assert(a[1] =3D=3D 7 and a[2] =3D=3D nil) > +a =3D {select(-2, 3, 5, 7)} > +assert(a[1] =3D=3D 5 and a[2] =3D=3D 7 and a[3] =3D=3D 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 =3D [[$ > + > +local a,b > + > +b =3D {$1$ > + b30009 =3D 65534, > + b30010 =3D 65535, > + b30011 =3D 65536, > + b30012 =3D 65537, > + b30013 =3D 16777214, > + b30014 =3D 16777215, > + b30015 =3D 16777216, > + b30016 =3D 16777217, > + b30017 =3D 4294967294, > + b30018 =3D 4294967295, > + b30019 =3D 4294967296, > + b30020 =3D 4294967297, > + b30021 =3D -65534, > + b30022 =3D -65535, > + b30023 =3D -65536, > + b30024 =3D -4294967297, > + b30025 =3D 15012.5, > + $2$ > +}; > + > +assert(b.a50008 =3D=3D 25004 and b["a11"] =3D=3D 5.5) > +assert(b.a33007 =3D=3D 16503.5 and b.a50009 =3D=3D 25004.5) > +assert(b["b"..30024] =3D=3D -4294967297) > + > +function b:xxx (a,b) return a+b end > +assert(b:xxx(10, 12) =3D=3D 22) -- pushself with non-constant index > +b.xxx =3D nil > + > +s =3D 0; n=3D0 > +for a,b in pairs(b) do s=3Ds+b; n=3Dn+1 end > +assert(s=3D=3D13977183656.5 and n=3D=3D70001) > + > +require "checktable" > +stat(b) > + > +a =3D nil; b =3D nil > +print'+' > + > +function f(x) b=3Dx end > + > +a =3D f{$3$} or 10 > + > +assert(a=3D=3D10) > +assert(b[1] =3D=3D "a10" and b[2] =3D=3D 5 and b[table.getn(b)-1] =3D=3D= "a50009") > + > + > +function xxxx (x) return b[x] end > + > +assert(xxxx(3) =3D=3D "a11") > + > +a =3D nil; b=3Dnil > +xxxx =3D nil > + > +return 10 > + > +]] > + > +-- functions to fill in the $n$ > +F =3D { > +function () -- $1$ > + for i=3D10,50009 do > + io.write('a', i, ' =3D ', 5+((i-10)/2), ',\n') > + end > +end, > + > +function () -- $2$ > + for i=3D30026,50009 do > + io.write('b', i, ' =3D ', 15013+((i-30026)/2), ',\n') > + end > +end, > + > +function () -- $3$ > + for i=3D10,50009 do > + io.write('"a', i, '", ', 5+((i-10)/2), ',\n') > + end > +end, > +} > + > +file =3D os.tmpname() > +io.output(file) > +for s in string.gmatch(prog, "$([^$]+)") do > + local n =3D tonumber(s) > + if not n then io.write(s) else F[n]() end > +end > +io.close() > +result =3D dofile(file) > +assert(os.remove(file)) > +print'OK' > +return result > + > --=20 > 2.28.0 >=20