* [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite @ 2021-03-26 7:42 Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches ` (31 more replies) 0 siblings, 32 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2 Test branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-5845-adapt-puc-rio-test-suite-v2 Side note: I reword commit about variable names in error messages a little, so the commit is different but the conten is the same. Issues: * https://github.com/tarantool/tarantool/issues/5845 * https://github.com/tarantool/tarantool/issues/4473 Suite is taken intact exept trailing whitespaces. Command to check: | $ diff -ruZ --color ../test/PUC-Lua-5.1-tests/ ~/Downloads/lua5.1-tests/ | Only in ../test/PUC-Lua-5.1-tests/: CMakeLists.txt | Only in ../test/PUC-Lua-5.1-tests/libs: CMakeLists.txt | Only in ~/Downloads/lua5.1-tests/libs: makefile | Only in ~/Downloads/lua5.1-tests/libs: P1 Changes in the v2: * split commits to atomic changes * more verbose comments for some tests * some test fixed instead commenting Sergey Kaplun (30): test: add PUC-Rio Lua 5.1 test suite test: add compiling for C libs from PUC-Rio-Lua5.1 test: adapt Lua 5.1 suite for out-of-source build test: remove quotes in progname from <main.lua> test: adapt arg availability test from Lua suite test: disable PUC Lua tests confused by -v output test: disable Lua tests for bytecode with header test: disable JIT for GC step counting tests test: disable Lua suite tests for line hook test: adapt test for debug.setlocal in Lua suite test: adapt getlocal PUC test for vararg func test: adapt PUC Lua test with count hooks test: disable PUC Lua test for tail call info test: adapt activeline check in the PUC Lua test test: disable PUC-Lua test for per-coroutine hooks test: adapt PUC Lua test for %q in fmt for LuaJIT test: disable locale-depended tests for Lua suite test: replace math.mod to math.fmod for Lua tests test: remove assert for string.gfind check test: adapt PUC Lua test for args in vararg func test: disable test for getfenv in closure tailcall test: disable PUC Lua test for var names in error test: disable PUC Lua test for fast function name test: disable PUC Lua test for non-asci identifier test: disable PUC Lua error test for syntax level test: disable tests with multiple -l options test: disable PUC Lua test for checking arg layout test: disable PUC Lua test checking -h option test: disable PUC Lua hanging GC test test: disable too depth recursive PUC Lua test .luacheckrc | 5 +- test/CMakeLists.txt | 2 + test/PUC-Lua-5.1-tests/CMakeLists.txt | 46 + test/PUC-Lua-5.1-tests/README | 41 + test/PUC-Lua-5.1-tests/all.lua | 146 +++ 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 | 430 ++++++++ test/PUC-Lua-5.1-tests/code.lua | 143 +++ test/PUC-Lua-5.1-tests/constructs.lua | 242 +++++ test/PUC-Lua-5.1-tests/db.lua | 576 ++++++++++ test/PUC-Lua-5.1-tests/errors.lua | 269 +++++ 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 | 325 ++++++ test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 64 ++ 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 | 181 +++ test/PUC-Lua-5.1-tests/locals.lua | 127 +++ test/PUC-Lua-5.1-tests/main.lua | 212 ++++ test/PUC-Lua-5.1-tests/math.lua | 209 ++++ test/PUC-Lua-5.1-tests/nextvar.lua | 397 +++++++ test/PUC-Lua-5.1-tests/pm.lua | 276 +++++ test/PUC-Lua-5.1-tests/sort.lua | 74 ++ test/PUC-Lua-5.1-tests/strings.lua | 191 ++++ test/PUC-Lua-5.1-tests/vararg.lua | 134 +++ test/PUC-Lua-5.1-tests/verybig.lua | 102 ++ 35 files changed, 8019 insertions(+), 2 deletions(-) create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt create mode 100644 test/PUC-Lua-5.1-tests/README create mode 100755 test/PUC-Lua-5.1-tests/all.lua create mode 100644 test/PUC-Lua-5.1-tests/api.lua create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua create mode 100644 test/PUC-Lua-5.1-tests/big.lua create mode 100644 test/PUC-Lua-5.1-tests/calls.lua create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua create mode 100644 test/PUC-Lua-5.1-tests/closure.lua create mode 100644 test/PUC-Lua-5.1-tests/code.lua create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua create mode 100644 test/PUC-Lua-5.1-tests/db.lua create mode 100644 test/PUC-Lua-5.1-tests/errors.lua create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h create mode 100644 test/PUC-Lua-5.1-tests/events.lua create mode 100644 test/PUC-Lua-5.1-tests/files.lua create mode 100644 test/PUC-Lua-5.1-tests/gc.lua create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c create mode 100644 test/PUC-Lua-5.1-tests/literals.lua create mode 100644 test/PUC-Lua-5.1-tests/locals.lua create mode 100644 test/PUC-Lua-5.1-tests/main.lua create mode 100644 test/PUC-Lua-5.1-tests/math.lua create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua create mode 100644 test/PUC-Lua-5.1-tests/pm.lua create mode 100644 test/PUC-Lua-5.1-tests/sort.lua create mode 100644 test/PUC-Lua-5.1-tests/strings.lua create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 10:14 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:13 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches ` (30 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 210215 bytes --] This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test suite. Source code taken verbatim (except trailing whitespaces) from https://www.lua.org/tests/lua5.1-tests.tar.gz. Some tests may fail after this commit. They will be disabled or adapted in the next patches. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- .luacheckrc | 5 +- test/CMakeLists.txt | 2 + test/PUC-Lua-5.1-tests/CMakeLists.txt | 45 + test/PUC-Lua-5.1-tests/README | 41 + test/PUC-Lua-5.1-tests/all.lua | 137 +++ test/PUC-Lua-5.1-tests/api.lua | 711 ++++++++++++ test/PUC-Lua-5.1-tests/attrib.lua | 339 ++++++ test/PUC-Lua-5.1-tests/big.lua | 381 +++++++ test/PUC-Lua-5.1-tests/calls.lua | 294 +++++ test/PUC-Lua-5.1-tests/checktable.lua | 77 ++ test/PUC-Lua-5.1-tests/closure.lua | 422 +++++++ test/PUC-Lua-5.1-tests/code.lua | 143 +++ test/PUC-Lua-5.1-tests/constructs.lua | 240 ++++ test/PUC-Lua-5.1-tests/db.lua | 499 +++++++++ test/PUC-Lua-5.1-tests/errors.lua | 250 +++++ test/PUC-Lua-5.1-tests/etc/ltests.c | 1147 ++++++++++++++++++++ test/PUC-Lua-5.1-tests/etc/ltests.h | 92 ++ test/PUC-Lua-5.1-tests/events.lua | 360 ++++++ test/PUC-Lua-5.1-tests/files.lua | 324 ++++++ test/PUC-Lua-5.1-tests/gc.lua | 312 ++++++ test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 18 + test/PUC-Lua-5.1-tests/libs/lib1.c | 40 + test/PUC-Lua-5.1-tests/libs/lib11.c | 18 + test/PUC-Lua-5.1-tests/libs/lib2.c | 28 + test/PUC-Lua-5.1-tests/libs/lib21.c | 18 + test/PUC-Lua-5.1-tests/literals.lua | 176 +++ test/PUC-Lua-5.1-tests/locals.lua | 127 +++ test/PUC-Lua-5.1-tests/main.lua | 159 +++ test/PUC-Lua-5.1-tests/math.lua | 208 ++++ test/PUC-Lua-5.1-tests/nextvar.lua | 396 +++++++ test/PUC-Lua-5.1-tests/pm.lua | 273 +++++ test/PUC-Lua-5.1-tests/sort.lua | 74 ++ test/PUC-Lua-5.1-tests/strings.lua | 176 +++ test/PUC-Lua-5.1-tests/vararg.lua | 126 +++ test/PUC-Lua-5.1-tests/verybig.lua | 100 ++ 35 files changed, 7756 insertions(+), 2 deletions(-) create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt create mode 100644 test/PUC-Lua-5.1-tests/README create mode 100755 test/PUC-Lua-5.1-tests/all.lua create mode 100644 test/PUC-Lua-5.1-tests/api.lua create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua create mode 100644 test/PUC-Lua-5.1-tests/big.lua create mode 100644 test/PUC-Lua-5.1-tests/calls.lua create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua create mode 100644 test/PUC-Lua-5.1-tests/closure.lua create mode 100644 test/PUC-Lua-5.1-tests/code.lua create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua create mode 100644 test/PUC-Lua-5.1-tests/db.lua create mode 100644 test/PUC-Lua-5.1-tests/errors.lua create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h create mode 100644 test/PUC-Lua-5.1-tests/events.lua create mode 100644 test/PUC-Lua-5.1-tests/files.lua create mode 100644 test/PUC-Lua-5.1-tests/gc.lua create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c create mode 100644 test/PUC-Lua-5.1-tests/literals.lua create mode 100644 test/PUC-Lua-5.1-tests/locals.lua create mode 100644 test/PUC-Lua-5.1-tests/main.lua create mode 100644 test/PUC-Lua-5.1-tests/math.lua create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua create mode 100644 test/PUC-Lua-5.1-tests/pm.lua create mode 100644 test/PUC-Lua-5.1-tests/sort.lua create mode 100644 test/PUC-Lua-5.1-tests/strings.lua create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua diff --git a/.luacheckrc b/.luacheckrc index 4e5dbdf..fd5583b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -3,11 +3,12 @@ std = 'luajit' -- This fork also introduces a new global for misc API namespace. read_globals = { 'misc' } --- These files are inherited from the vanilla LuaJIT and need to --- be coherent with the upstream. +-- These files are inherited from the vanilla LuaJIT or different +-- test suites and need to be coherent with the upstream. exclude_files = { 'dynasm/', 'src/', 'test/LuaJIT-tests/', + 'test/PUC-Lua-5.1-tests/', 'test/lua-Harness-tests/', } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 02fb2ed..30cbf87 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -44,11 +44,13 @@ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]" separate_arguments(LUAJIT_TEST_COMMAND) add_subdirectory(LuaJIT-tests) +add_subdirectory(PUC-Lua-5.1-tests) add_subdirectory(lua-Harness-tests) add_subdirectory(tarantool-tests) add_custom_target(${PROJECT_NAME}-test DEPENDS LuaJIT-tests + PUC-Lua-5.1-tests lua-Harness-tests tarantool-tests ) diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt new file mode 100644 index 0000000..773db0d --- /dev/null +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt @@ -0,0 +1,45 @@ +# Test suite that has been added from PUC-Rio Lua 5.1 test archive +# in scope of https://github.com/tarantool/tarantool/issues/5845. + +# See the rationale in the root CMakeLists.txt. +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) + +# XXX: There are two ways to set up the proper environment +# described in the suite's README: +# * set LUA_PATH to "?;./?.lua" +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to +# "package.path = '?;'..package.path" +# Unfortunately, Tarantool doesn't support LUA_INIT and most +# likely it never will. For more info, see +# https://github.com/tarantool/tarantool/issues/5744 +# Hence, there is no way other than set LUA_PATH environment +# variable as proposed in the first case. +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") + +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> +# subdirectory. +add_subdirectory(libs) + +# TODO: PUC-Rio Lua 5.1 test suite also has special header +# <ltests.h> and <ltests.c> translation unit to check some +# internal behaviour of the Lua implementation (see etc/ +# directory). It modifies realloc function to check memory +# consistency and also contains tests for yield in hooks +# and for the Lua C API. +# But, unfortunately, <ltests.c> depends on specific PUC-Rio +# Lua 5.1 internal headers and should be adapted for LuaJIT. + +add_custom_target(PUC-Lua-5.1-tests + DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare +) + +add_custom_command(TARGET PUC-Lua-5.1-tests + COMMENT "Running PUC-Rio Lua 5.1 tests" + COMMAND + env + LUA_PATH="${LUA_PATH}\;\;" + ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) + +# vim: expandtab tabstop=2 shiftwidth=2 diff --git a/test/PUC-Lua-5.1-tests/README b/test/PUC-Lua-5.1-tests/README new file mode 100644 index 0000000..e2d4b28 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/README @@ -0,0 +1,41 @@ +This tarball contains the official test scripts for Lua 5.1. +Unlike Lua itself, these tests do not aim portability, small footprint, +or easy of use. (Their main goal is to try to crash Lua.) They are not +intended for general use. You are wellcome to use them, but expect to +have to "dirt your hands". + +The tarball should expand in the following contents: + - several .lua scripts with the tests + - a main "all.lua" Lua script that invokes all the other scripts + - a subdirectory "libs" with an empty subdirectory "libs/P1", + to be used by the scripts + - a subdirectory "etc" with some extra files + +To run the tests, do as follows: + +- go to the test directory + +- set LUA_PATH to "?;./?.lua" (or, better yet, set LUA_PATH to "./?.lua;;" + and LUA_INIT to "package.path = '?;'..package.path") + +- run "lua all.lua" + + +-------------------------------------------- +Internal tests +-------------------------------------------- + +Some tests need a special library, "testC", that gives access to +several internal structures in Lua. +This library is only available when Lua is compiled in debug mode. +The scripts automatically detect its absence and skip those tests. + +If you want to run these tests, move etc/ltests.c and etc/ltests.h to +the directory with the source Lua files, and recompile Lua with +the option -DLUA_USER_H='"ltests.h"' (or its equivalent to define +LUA_USER_H as the string "ltests.h", including the quotes). This +option not only adds the testC library, but it adds several other +internal tests as well. After the recompilation, run the tests +as before. + + diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua new file mode 100755 index 0000000..8c4afac --- /dev/null +++ b/test/PUC-Lua-5.1-tests/all.lua @@ -0,0 +1,137 @@ +#!../lua + +math.randomseed(0) + +collectgarbage("setstepmul", 180) +collectgarbage("setpause", 190) + + +--[=[ + example of a long [comment], + [[spanning several [lines]]] + +]=] + +print("current path:\n " .. string.gsub(package.path, ";", "\n ")) + + +local msgs = {} +function Message (m) + print(m) + msgs[#msgs+1] = string.sub(m, 3, -3) +end + + +local c = os.clock() + +assert(os.setlocale"C") + +local T,print,gcinfo,format,write,assert,type = + T,print,gcinfo,string.format,io.write,assert,type + +local function formatmem (m) + if m < 1024 then return m + else + m = m/1024 - m/1024%1 + if m < 1024 then return m.."K" + else + m = m/1024 - m/1024%1 + return m.."M" + end + end +end + +local showmem = function () + if not T then + print(format(" ---- total memory: %s ----\n", formatmem(gcinfo()))) + else + T.checkmemory() + local a,b,c = T.totalmem() + local d,e = gcinfo() + print(format( + "\n ---- total memory: %s (%dK), max use: %s, blocks: %d\n", + formatmem(a), d, formatmem(c), b)) + end +end + + +-- +-- redefine dofile to run files through dump/undump +-- +dofile = function (n) + showmem() + local f = assert(loadfile(n)) + local b = string.dump(f) + f = assert(loadstring(b)) + return f() +end + +dofile('main.lua') + +do + local u = newproxy(true) + local newproxy, stderr = newproxy, io.stderr + getmetatable(u).__gc = function (o) + stderr:write'.' + newproxy(o) + end +end + +local f = assert(loadfile('gc.lua')) +f() +dofile('db.lua') +assert(dofile('calls.lua') == deep and deep) +dofile('strings.lua') +dofile('literals.lua') +assert(dofile('attrib.lua') == 27) +assert(dofile('locals.lua') == 5) +dofile('constructs.lua') +dofile('code.lua') +do + local f = coroutine.wrap(assert(loadfile('big.lua'))) + assert(f() == 'b') + assert(f() == 'a') +end +dofile('nextvar.lua') +dofile('pm.lua') +dofile('api.lua') +assert(dofile('events.lua') == 12) +dofile('vararg.lua') +dofile('closure.lua') +dofile('errors.lua') +dofile('math.lua') +dofile('sort.lua') +assert(dofile('verybig.lua') == 10); collectgarbage() +dofile('files.lua') + +if #msgs > 0 then + print("\ntests not performed:") + for i=1,#msgs do + print(msgs[i]) + end + print() +end + +print("final OK !!!") +print('cleaning all!!!!') + +debug.sethook(function (a) assert(type(a) == 'string') end, "cr") + +local _G, collectgarbage, showmem, print, format, clock = + _G, collectgarbage, showmem, print, format, os.clock + +local a={} +for n in pairs(_G) do a[n] = 1 end +a.tostring = nil +a.___Glob = nil +for n in pairs(a) do _G[n] = nil end + +a = nil +collectgarbage() +collectgarbage() +collectgarbage() +collectgarbage() +collectgarbage() +collectgarbage();showmem() + +print(format("\n\ntotal time: %.2f\n", clock()-c)) diff --git a/test/PUC-Lua-5.1-tests/api.lua b/test/PUC-Lua-5.1-tests/api.lua new file mode 100644 index 0000000..c955ebf --- /dev/null +++ b/test/PUC-Lua-5.1-tests/api.lua @@ -0,0 +1,711 @@ + +if T==nil then + (Message or print)('\a\n >>> testC not active: skipping API tests <<<\n\a') + return +end + + + +function tcheck (t1, t2) + table.remove(t1, 1) -- remove code + assert(table.getn(t1) == table.getn(t2)) + for i=1,table.getn(t1) do assert(t1[i] == t2[i]) end +end + +function pack(...) return arg end + + +print('testing C API') + +-- testing allignment +a = T.d2s(12458954321123) +assert(string.len(a) == 8) -- sizeof(double) +assert(T.s2d(a) == 12458954321123) + +a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2") +assert(a == 2 and b == 3 and not c) + +-- test that all trues are equal +a,b,c = T.testC("pushbool 1; pushbool 2; pushbool 0; return 3") +assert(a == b and a == true and c == false) +a,b,c = T.testC"pushbool 0; pushbool 10; pushnil;\ + tobool -3; tobool -3; tobool -3; return 3" +assert(a==0 and b==1 and c==0) + + +a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40) +assert(a == 40 and b == 5 and not c) + +t = pack(T.testC("settop 5; gettop; return .", 2, 3)) +tcheck(t, {n=4,2,3}) + +t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23)) +assert(t.n == 10 and t[1] == nil and t[10] == nil) + +t = pack(T.testC("remove -2; gettop; return .", 2, 3, 4)) +tcheck(t, {n=2,2,4}) + +t = pack(T.testC("insert -1; gettop; return .", 2, 3)) +tcheck(t, {n=2,2,3}) + +t = pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5)) +tcheck(t, {n=4,2,5,3,4}) + +t = pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5)) +tcheck(t, {n=3,5,3,4}) + +t = pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5)) +tcheck(t, {n=3,2,3,5}) + +t = pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5)) +tcheck(t, {n=3,2,4,5}) + +t = pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2; \ + insert 2; pushvalue 1; remove 1; insert 1; \ + insert -2; pushvalue -2; remove -3; gettop; return .", + 2, 3, 4, 5, 10, 40, 90)) +tcheck(t, {n=7,2,3,4,5,10,40,90}) + +t = pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", 12)) +tcheck(t, {n=1,"alo23joao12"}) + +-- testing MULTRET +t = pack(T.testC("rawcall 2,-1; gettop; return .", + function (a,b) return 1,2,3,4,a,b end, "alo", "joao")) +tcheck(t, {n=6,1,2,3,4,"alo", "joao"}) + +do -- test returning more results than fit in the caller stack + local a = {} + for i=1,1000 do a[i] = true end; a[999] = 10 + local b = T.testC([[call 1 -1; pop 1; tostring -1; return 1]], unpack, a) + assert(b == "10") +end + + +-- testing lessthan +assert(T.testC("lessthan 2 5, return 1", 3, 2, 2, 4, 2, 2)) +assert(T.testC("lessthan 5 2, return 1", 4, 2, 2, 3, 2, 2)) +assert(not T.testC("lessthan 2 -3, return 1", "4", "2", "2", "3", "2", "2")) +assert(not T.testC("lessthan -3 2, return 1", "3", "2", "2", "4", "2", "2")) + +local b = {__lt = function (a,b) return a[1] < b[1] end} +local a1,a3,a4 = setmetatable({1}, b), + setmetatable({3}, b), + setmetatable({4}, b) +assert(T.testC("lessthan 2 5, return 1", a3, 2, 2, a4, 2, 2)) +assert(T.testC("lessthan 5 -6, return 1", a4, 2, 2, a3, 2, 2)) +a,b = T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20) +assert(a == 20 and b == false) + + +-- testing lua_is + +function count (x, n) + n = n or 2 + local prog = [[ + isnumber %d; + isstring %d; + isfunction %d; + iscfunction %d; + istable %d; + isuserdata %d; + isnil %d; + isnull %d; + return 8 + ]] + prog = string.format(prog, n, n, n, n, n, n, n, n) + local a,b,c,d,e,f,g,h = T.testC(prog, x) + return a+b+c+d+e+f+g+(100*h) +end + +assert(count(3) == 2) +assert(count('alo') == 1) +assert(count('32') == 2) +assert(count({}) == 1) +assert(count(print) == 2) +assert(count(function () end) == 1) +assert(count(nil) == 1) +assert(count(io.stdin) == 1) +assert(count(nil, 15) == 100) + +-- testing lua_to... + +function to (s, x, n) + n = n or 2 + return T.testC(string.format("%s %d; return 1", s, n), x) +end + +assert(to("tostring", {}) == nil) +assert(to("tostring", "alo") == "alo") +assert(to("tostring", 12) == "12") +assert(to("tostring", 12, 3) == nil) +assert(to("objsize", {}) == 0) +assert(to("objsize", "alo\0\0a") == 6) +assert(to("objsize", T.newuserdata(0)) == 0) +assert(to("objsize", T.newuserdata(101)) == 101) +assert(to("objsize", 12) == 2) +assert(to("objsize", 12, 3) == 0) +assert(to("tonumber", {}) == 0) +assert(to("tonumber", "12") == 12) +assert(to("tonumber", "s2") == 0) +assert(to("tonumber", 1, 20) == 0) +a = to("tocfunction", math.deg) +assert(a(3) == math.deg(3) and a ~= math.deg) + + +-- testing errors + +a = T.testC([[ + loadstring 2; call 0,1; + pushvalue 3; insert -2; call 1, 1; + call 0, 0; + return 1 +]], "x=150", function (a) assert(a==nil); return 3 end) + +assert(type(a) == 'string' and x == 150) + +function check3(p, ...) + assert(arg.n == 3) + assert(string.find(arg[3], p)) +end +check3(":1:", T.testC("loadstring 2; gettop; return .", "x=")) +check3("cannot read", T.testC("loadfile 2; gettop; return .", ".")) +check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", "xxxx")) + +-- testing table access + +a = {x=0, y=12} +x, y = T.testC("gettable 2; pushvalue 4; gettable 2; return 2", + a, 3, "y", 4, "x") +assert(x == 0 and y == 12) +T.testC("settable -5", a, 3, 4, "x", 15) +assert(a.x == 15) +a[a] = print +x = T.testC("gettable 2; return 1", a) -- table and key are the same object! +assert(x == print) +T.testC("settable 2", a, "x") -- table and key are the same object! +assert(a[a] == "x") + +b = setmetatable({p = a}, {}) +getmetatable(b).__index = function (t, i) return t.p[i] end +k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x") +assert(x == 15 and k == 35) +getmetatable(b).__index = function (t, i) return a[i] end +getmetatable(b).__newindex = function (t, i,v ) a[i] = v end +y = T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b) +assert(y == 12) +k = T.testC("settable -5, return 1", b, 3, 4, "x", 16) +assert(a.x == 16 and k == 4) +a[b] = 'xuxu' +y = T.testC("gettable 2, return 1", b) +assert(y == 'xuxu') +T.testC("settable 2", b, 19) +assert(a[b] == 19) + +-- testing next +a = {} +t = pack(T.testC("next; gettop; return .", a, nil)) +tcheck(t, {n=1,a}) +a = {a=3} +t = pack(T.testC("next; gettop; return .", a, nil)) +tcheck(t, {n=3,a,'a',3}) +t = pack(T.testC("next; pop 1; next; gettop; return .", a, nil)) +tcheck(t, {n=1,a}) + + + +-- testing upvalues + +do + local A = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] + t, b, c = A([[pushvalue U0; pushvalue U1; pushvalue U2; return 3]]) + assert(b == 10 and c == 20 and type(t) == 'table') + a, b = A([[tostring U3; tonumber U4; return 2]]) + assert(a == nil and b == 0) + A([[pushnum 100; pushnum 200; replace U2; replace U1]]) + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) + assert(b == 100 and c == 200) + A([[replace U2; replace U1]], {x=1}, {x=2}) + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) + assert(b.x == 1 and c.x == 2) + T.checkmemory() +end + +local f = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] +assert(T.upvalue(f, 1) == 10 and + T.upvalue(f, 2) == 20 and + T.upvalue(f, 3) == nil) +T.upvalue(f, 2, "xuxu") +assert(T.upvalue(f, 2) == "xuxu") + + +-- testing environments + +assert(T.testC"pushvalue G; return 1" == _G) +assert(T.testC"pushvalue E; return 1" == _G) +local a = {} +T.testC("replace E; return 1", a) +assert(T.testC"pushvalue G; return 1" == _G) +assert(T.testC"pushvalue E; return 1" == a) +assert(debug.getfenv(T.testC) == a) +assert(debug.getfenv(T.upvalue) == _G) +-- userdata inherit environment +local u = T.testC"newuserdata 0; return 1" +assert(debug.getfenv(u) == a) +-- functions inherit environment +u = T.testC"pushcclosure 0; return 1" +assert(debug.getfenv(u) == a) +debug.setfenv(T.testC, _G) +assert(T.testC"pushvalue E; return 1" == _G) + +local b = newproxy() +assert(debug.getfenv(b) == _G) +assert(debug.setfenv(b, a)) +assert(debug.getfenv(b) == a) + + + +-- testing locks (refs) + +-- reuse of references +local i = T.ref{} +T.unref(i) +assert(T.ref{} == i) + +Arr = {} +Lim = 100 +for i=1,Lim do -- lock many objects + Arr[i] = T.ref({}) +end + +assert(T.ref(nil) == -1 and T.getref(-1) == nil) +T.unref(-1); T.unref(-1) + +for i=1,Lim do -- unlock all them + T.unref(Arr[i]) +end + +function printlocks () + local n = T.testC("gettable R; return 1", "n") + print("n", n) + for i=0,n do + print(i, T.testC("gettable R; return 1", i)) + end +end + + +for i=1,Lim do -- lock many objects + Arr[i] = T.ref({}) +end + +for i=1,Lim,2 do -- unlock half of them + T.unref(Arr[i]) +end + +assert(type(T.getref(Arr[2])) == 'table') + + +assert(T.getref(-1) == nil) + + +a = T.ref({}) + +collectgarbage() + +assert(type(T.getref(a)) == 'table') + + +-- colect in cl the `val' of all collected userdata +tt = {} +cl = {n=0} +A = nil; B = nil +local F +F = function (x) + local udval = T.udataval(x) + table.insert(cl, udval) + local d = T.newuserdata(100) -- cria lixo + d = nil + assert(debug.getmetatable(x).__gc == F) + loadstring("table.insert({}, {})")() -- cria mais lixo + collectgarbage() -- forca coleta de lixo durante coleta! + assert(debug.getmetatable(x).__gc == F) -- coleta anterior nao melou isso? + local dummy = {} -- cria lixo durante coleta + if A ~= nil then + assert(type(A) == "userdata") + assert(T.udataval(A) == B) + debug.getmetatable(A) -- just acess it + end + A = x -- ressucita userdata + B = udval + return 1,2,3 +end +tt.__gc = F + +-- test whether udate collection frees memory in the right time +do + collectgarbage(); + collectgarbage(); + local x = collectgarbage("count"); + local a = T.newuserdata(5001) + assert(T.testC("objsize 2; return 1", a) == 5001) + assert(collectgarbage("count") >= x+4) + a = nil + collectgarbage(); + assert(collectgarbage("count") <= x+1) + -- udata without finalizer + x = collectgarbage("count") + collectgarbage("stop") + for i=1,1000 do newproxy(false) end + assert(collectgarbage("count") > x+10) + collectgarbage() + assert(collectgarbage("count") <= x+1) + -- udata with finalizer + x = collectgarbage("count") + collectgarbage() + collectgarbage("stop") + a = newproxy(true) + getmetatable(a).__gc = function () end + for i=1,1000 do newproxy(a) end + assert(collectgarbage("count") >= x+10) + collectgarbage() -- this collection only calls TM, without freeing memory + assert(collectgarbage("count") >= x+10) + collectgarbage() -- now frees memory + assert(collectgarbage("count") <= x+1) +end + + +collectgarbage("stop") + +-- create 3 userdatas with tag `tt' +a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a) +b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b) +c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c) + +-- create userdata without meta table +x = T.newuserdata(4) +y = T.newuserdata(0) + +assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil) + +d=T.ref(a); +e=T.ref(b); +f=T.ref(c); +t = {T.getref(d), T.getref(e), T.getref(f)} +assert(t[1] == a and t[2] == b and t[3] == c) + +t=nil; a=nil; c=nil; +T.unref(e); T.unref(f) + +collectgarbage() + +-- check that unref objects have been collected +assert(table.getn(cl) == 1 and cl[1] == nc) + +x = T.getref(d) +assert(type(x) == 'userdata' and debug.getmetatable(x) == tt) +x =nil +tt.b = b -- create cycle +tt=nil -- frees tt for GC +A = nil +b = nil +T.unref(d); +n5 = T.newuserdata(0) +debug.setmetatable(n5, {__gc=F}) +n5 = T.udataval(n5) +collectgarbage() +assert(table.getn(cl) == 4) +-- check order of collection +assert(cl[2] == n5 and cl[3] == nb and cl[4] == na) + + +a, na = {}, {} +for i=30,1,-1 do + a[i] = T.newuserdata(0) + debug.setmetatable(a[i], {__gc=F}) + na[i] = T.udataval(a[i]) +end +cl = {} +a = nil; collectgarbage() +assert(table.getn(cl) == 30) +for i=1,30 do assert(cl[i] == na[i]) end +na = nil + + +for i=2,Lim,2 do -- unlock the other half + T.unref(Arr[i]) +end + +x = T.newuserdata(41); debug.setmetatable(x, {__gc=F}) +assert(T.testC("objsize 2; return 1", x) == 41) +cl = {} +a = {[x] = 1} +x = T.udataval(x) +collectgarbage() +-- old `x' cannot be collected (`a' still uses it) +assert(table.getn(cl) == 0) +for n in pairs(a) do a[n] = nil end +collectgarbage() +assert(table.getn(cl) == 1 and cl[1] == x) -- old `x' must be collected + +-- testing lua_equal +assert(T.testC("equal 2 4; return 1", print, 1, print, 20)) +assert(T.testC("equal 3 2; return 1", 'alo', "alo")) +assert(T.testC("equal 2 3; return 1", nil, nil)) +assert(not T.testC("equal 2 3; return 1", {}, {})) +assert(not T.testC("equal 2 3; return 1")) +assert(not T.testC("equal 2 3; return 1", 3)) + +-- testing lua_equal with fallbacks +do + local map = {} + local t = {__eq = function (a,b) return map[a] == map[b] end} + local function f(x) + local u = T.newuserdata(0) + debug.setmetatable(u, t) + map[u] = x + return u + end + assert(f(10) == f(10)) + assert(f(10) ~= f(11)) + assert(T.testC("equal 2 3; return 1", f(10), f(10))) + assert(not T.testC("equal 2 3; return 1", f(10), f(20))) + t.__eq = nil + assert(f(10) ~= f(10)) +end + +print'+' + + + +------------------------------------------------------------------------- +do -- testing errors during GC + local a = {} + for i=1,20 do + a[i] = T.newuserdata(i) -- creates several udata + end + for i=1,20,2 do -- mark half of them to raise error during GC + debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end}) + end + for i=2,20,2 do -- mark the other half to count and to create more garbage + debug.setmetatable(a[i], {__gc = function (x) loadstring("A=A+1")() end}) + end + _G.A = 0 + a = 0 + while 1 do + if xpcall(collectgarbage, function (s) a=a+1 end) then + break -- stop if no more errors + end + end + assert(a == 10) -- number of errors + assert(A == 10) -- number of normal collections +end +------------------------------------------------------------------------- +-- test for userdata vals +do + local a = {}; local lim = 30 + for i=0,lim do a[i] = T.pushuserdata(i) end + for i=0,lim do assert(T.udataval(a[i]) == i) end + for i=0,lim do assert(T.pushuserdata(i) == a[i]) end + for i=0,lim do a[a[i]] = i end + for i=0,lim do a[T.pushuserdata(i)] = i end + assert(type(tostring(a[1])) == "string") +end + + +------------------------------------------------------------------------- +-- testing multiple states +T.closestate(T.newstate()); +L1 = T.newstate() +assert(L1) +assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; f()")).n == 0) + +a, b = T.doremote(L1, "return f()") +assert(a == 'alo' and b == '3') + +T.doremote(L1, "_ERRORMESSAGE = nil") +-- error: `sin' is not defined +a, b = T.doremote(L1, "return sin(1)") +assert(a == nil and b == 2) -- 2 == run-time error + +-- error: syntax error +a, b, c = T.doremote(L1, "return a+") +assert(a == nil and b == 3 and type(c) == "string") -- 3 == syntax error + +T.loadlib(L1) +a, b = T.doremote(L1, [[ + a = strlibopen() + a = packageopen() + a = baselibopen(); assert(a == _G and require("_G") == a) + a = iolibopen(); assert(type(a.read) == "function") + assert(require("io") == a) + a = tablibopen(); assert(type(a.insert) == "function") + a = dblibopen(); assert(type(a.getlocal) == "function") + a = mathlibopen(); assert(type(a.sin) == "function") + return string.sub('okinama', 1, 2) +]]) +assert(a == "ok") + +T.closestate(L1); + +L1 = T.newstate() +T.loadlib(L1) +T.doremote(L1, "a = {}") +T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1; + settable -3]]) +assert(T.doremote(L1, "return a.x") == "1") + +T.closestate(L1) + +L1 = nil + +print('+') + +------------------------------------------------------------------------- +-- testing memory limits +------------------------------------------------------------------------- +collectgarbage() +T.totalmem(T.totalmem()+5000) -- set low memory limit (+5k) +assert(not pcall(loadstring"local a={}; for i=1,100000 do a[i]=i end")) +T.totalmem(1000000000) -- restore high limit + + +local function stack(x) if x>0 then stack(x-1) end end + +-- test memory errors; increase memory limit in small steps, so that +-- we get memory errors in different parts of a given task, up to there +-- is enough memory to complete the task without errors +function testamem (s, f) + collectgarbage() + stack(10) -- ensure minimum stack size + local M = T.totalmem() + local oldM = M + local a,b = nil + while 1 do + M = M+3 -- increase memory limit in small steps + T.totalmem(M) + a, b = pcall(f) + if a and b then break end -- stop when no more errors + collectgarbage() + if not a and not string.find(b, "memory") then -- `real' error? + T.totalmem(1000000000) -- restore high limit + error(b, 0) + end + end + T.totalmem(1000000000) -- restore high limit + print("\nlimit for " .. s .. ": " .. M-oldM) + return b +end + + +-- testing memory errors when creating a new state + +b = testamem("state creation", T.newstate) +T.closestate(b); -- close new state + + +-- testing threads + +function expand (n,s) + if n==0 then return "" end + local e = string.rep("=", n) + return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n", + e, s, expand(n-1,s), e) +end + +G=0; collectgarbage(); a =collectgarbage("count") +loadstring(expand(20,"G=G+1"))() +assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1) + +testamem("thread creation", function () + return T.doonnewstack("x=1") == 0 -- try to create thread +end) + + +-- testing memory x compiler + +testamem("loadstring", function () + return loadstring("x=1") -- try to do a loadstring +end) + + +local testprog = [[ +local function foo () return end +local t = {"x"} +a = "aaa" +for _, v in ipairs(t) do a=a..v end +return true +]] + +-- testing memory x dofile +_G.a = nil +local t =os.tmpname() +local f = assert(io.open(t, "w")) +f:write(testprog) +f:close() +testamem("dofile", function () + local a = loadfile(t) + return a and a() +end) +assert(os.remove(t)) +assert(_G.a == "aaax") + + +-- other generic tests + +testamem("string creation", function () + local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end) + return (a == 'ablo ablo') +end) + +testamem("dump/undump", function () + local a = loadstring(testprog) + local b = a and string.dump(a) + a = b and loadstring(b) + return a and a() +end) + +local t = os.tmpname() +testamem("file creation", function () + local f = assert(io.open(t, 'w')) + assert (not io.open"nomenaoexistente") + io.close(f); + return not loadfile'nomenaoexistente' +end) +assert(os.remove(t)) + +testamem("table creation", function () + local a, lim = {}, 10 + for i=1,lim do a[i] = i; a[i..'a'] = {} end + return (type(a[lim..'a']) == 'table' and a[lim] == lim) +end) + +local a = 1 +close = nil +testamem("closure creation", function () + function close (b,c) + return function (x) return a+b+c+x end + end + return (close(2,3)(4) == 10) +end) + +testamem("coroutines", function () + local a = coroutine.wrap(function () + coroutine.yield(string.rep("a", 10)) + return {} + end) + assert(string.len(a()) == 10) + return a() +end) + +print'+' + +-- testing some auxlib functions +assert(T.gsub("alo.alo.uhuh.", ".", "//") == "alo//alo//uhuh//") +assert(T.gsub("alo.alo.uhuh.", "alo", "//") == "//.//.uhuh.") +assert(T.gsub("", "alo", "//") == "") +assert(T.gsub("...", ".", "/.") == "/././.") +assert(T.gsub("...", "...", "") == "") + + +print'OK' + diff --git a/test/PUC-Lua-5.1-tests/attrib.lua b/test/PUC-Lua-5.1-tests/attrib.lua new file mode 100644 index 0000000..655669b --- /dev/null +++ b/test/PUC-Lua-5.1-tests/attrib.lua @@ -0,0 +1,339 @@ +do --[ + +print "testing require" + +assert(require"string" == string) +assert(require"math" == math) +assert(require"table" == table) +assert(require"io" == io) +assert(require"os" == os) +assert(require"debug" == debug) +assert(require"coroutine" == coroutine) + +assert(type(package.path) == "string") +assert(type(package.cpath) == "string") +assert(type(package.loaded) == "table") +assert(type(package.preload) == "table") + + +local DIR = "libs/" + +local function createfiles (files, preextras, posextras) + for n,c in pairs(files) do + io.output(DIR..n) + io.write(string.format(preextras, n)) + io.write(c) + io.write(string.format(posextras, n)) + io.close(io.output()) + end +end + +function removefiles (files) + for n in pairs(files) do + os.remove(DIR..n) + end +end + +local files = { + ["A.lua"] = "", + ["B.lua"] = "assert(...=='B');require 'A'", + ["A.lc"] = "", + ["A"] = "", + ["L"] = "", + ["XXxX"] = "", + ["C.lua"] = "package.loaded[...] = 25; require'C'" +} + +AA = nil +local extras = [[ +NAME = '%s' +REQUIRED = ... +return AA]] + +createfiles(files, "", extras) + + +local oldpath = package.path + +package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR) + +local try = function (p, n, r) + NAME = nil + local rr = require(p) + assert(NAME == n) + assert(REQUIRED == p) + assert(rr == r) +end + +assert(require"C" == 25) +assert(require"C" == 25) +AA = nil +try('B', 'B.lua', true) +assert(package.loaded.B) +assert(require"B" == true) +assert(package.loaded.A) +package.loaded.A = nil +try('B', nil, true) -- should not reload package +try('A', 'A.lua', true) +package.loaded.A = nil +os.remove(DIR..'A.lua') +AA = {} +try('A', 'A.lc', AA) -- now must find second option +assert(require("A") == AA) +AA = false +try('K', 'L', false) -- default option +try('K', 'L', false) -- default option (should reload it) +assert(rawget(_G, "_REQUIREDNAME") == nil) + +AA = "x" +try("X", "XXxX", AA) + + +removefiles(files) + + +-- testing require of sub-packages + +package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) + +files = { + ["P1/init.lua"] = "AA = 10", + ["P1/xuxu.lua"] = "AA = 20", +} + +createfiles(files, "module(..., package.seeall)\n", "") +AA = 0 + +local m = assert(require"P1") +assert(m == P1 and m._NAME == "P1" and AA == 0 and m.AA == 10) +assert(require"P1" == P1 and P1 == m) +assert(require"P1" == P1) +assert(P1._PACKAGE == "") + +local m = assert(require"P1.xuxu") +assert(m == P1.xuxu and m._NAME == "P1.xuxu" and AA == 0 and m.AA == 20) +assert(require"P1.xuxu" == P1.xuxu and P1.xuxu == m) +assert(require"P1.xuxu" == P1.xuxu) +assert(require"P1" == P1) +assert(P1.xuxu._PACKAGE == "P1.") +assert(P1.AA == 10 and P1._PACKAGE == "") +assert(P1._G == _G and P1.xuxu._G == _G) + + + +removefiles(files) + + +package.path = "" +assert(not pcall(require, "file_does_not_exist")) +package.path = "??\0?" +assert(not pcall(require, "file_does_not_exist1")) + +package.path = oldpath + +-- check 'require' error message +local fname = "file_does_not_exist2" +local m, err = pcall(require, fname) +for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do + t = string.gsub(t, "?", fname) + assert(string.find(err, t, 1, true)) +end + + +local function import(...) + local f = {...} + return function (m) + for i=1, #f do m[f[i]] = _G[f[i]] end + end +end + +local assert, module, package = assert, module, package +X = nil; x = 0; assert(_G.x == 0) -- `x' must be a global variable +module"X"; x = 1; assert(_M.x == 1) +module"X.a.b.c"; x = 2; assert(_M.x == 2) +module("X.a.b", package.seeall); x = 3 +assert(X._NAME == "X" and X.a.b.c._NAME == "X.a.b.c" and X.a.b._NAME == "X.a.b") +assert(X._M == X and X.a.b.c._M == X.a.b.c and X.a.b._M == X.a.b) +assert(X.x == 1 and X.a.b.c.x == 2 and X.a.b.x == 3) +assert(X._PACKAGE == "" and X.a.b.c._PACKAGE == "X.a.b." and + X.a.b._PACKAGE == "X.a.") +assert(_PACKAGE.."c" == "X.a.c") +assert(X.a._NAME == nil and X.a._M == nil) +module("X.a", import("X")) ; x = 4 +assert(X.a._NAME == "X.a" and X.a.x == 4 and X.a._M == X.a) +module("X.a.b", package.seeall); assert(x == 3); x = 5 +assert(_NAME == "X.a.b" and X.a.b.x == 5) + +assert(X._G == nil and X.a._G == nil and X.a.b._G == _G and X.a.b.c._G == nil) + +setfenv(1, _G) +assert(x == 0) + +assert(not pcall(module, "x")) +assert(not pcall(module, "math.sin")) + + +-- testing C libraries + + +local p = "" -- On Mac OS X, redefine this to "_" + +-- assert(loadlib == package.loadlib) -- only for compatibility +local f, err, when = package.loadlib("libs/lib1.so", p.."luaopen_lib1") +if not f then + (Message or print)('\a\n >>> cannot load dynamic library <<<\n\a') + print(err, when) +else + f() -- open library + assert(require("lib1") == lib1) + collectgarbage() + assert(lib1.id("x") == "x") + f = assert(package.loadlib("libs/lib1.so", p.."anotherfunc")) + assert(f(10, 20) == "1020\n") + f, err, when = package.loadlib("libs/lib1.so", p.."xuxu") + assert(not f and type(err) == "string" and when == "init") + package.cpath = "libs/?.so" + require"lib2" + assert(lib2.id("x") == "x") + local fs = require"lib1.sub" + assert(fs == lib1.sub and next(lib1.sub) == nil) + module("lib2", package.seeall) + f = require"-lib2" + assert(f.id("x") == "x" and _M == f and _NAME == "lib2") + module("lib1.sub", package.seeall) + assert(_M == fs) + setfenv(1, _G) + +end +f, err, when = package.loadlib("donotexist", p.."xuxu") +assert(not f and type(err) == "string" and (when == "open" or when == "absent")) + + +-- testing preload + +do + local p = package + package = {} + p.preload.pl = function (...) + module(...) + function xuxu (x) return x+20 end + end + + require"pl" + assert(require"pl" == pl) + assert(pl.xuxu(10) == 30) + + package = p + assert(type(package.path) == "string") +end + + + +end --] + +print('+') + +print("testing assignments, logical operators, and constructors") + +local res, res2 = 27 + +a, b = 1, 2+3 +assert(a==1 and b==5) +a={} +function f() return 10, 11, 12 end +a.x, b, a[1] = 1, 2, f() +assert(a.x==1 and b==2 and a[1]==10) +a[f()], b, a[f()+3] = f(), a, 'x' +assert(a[10] == 10 and b == a and a[13] == 'x') + +do + local f = function (n) local x = {}; for i=1,n do x[i]=i end; + return unpack(x) end; + local a,b,c + a,b = 0, f(1) + assert(a == 0 and b == 1) + A,b = 0, f(1) + assert(A == 0 and b == 1) + a,b,c = 0,5,f(4) + assert(a==0 and b==5 and c==1) + a,b,c = 0,5,f(0) + assert(a==0 and b==5 and c==nil) +end + + +a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6 +assert(not a and b and c and d==6) + +d = 20 +a, b, c, d = f() +assert(a==10 and b==11 and c==12 and d==nil) +a,b = f(), 1, 2, 3, f() +assert(a==10 and b==1) + +assert(a<b == false and a>b == true) +assert((10 and 2) == 2) +assert((10 or 2) == 10) +assert((10 or assert(nil)) == 10) +assert(not (nil and assert(nil))) +assert((nil or "alo") == "alo") +assert((nil and 10) == nil) +assert((false and 10) == false) +assert((true or 10) == true) +assert((false or 10) == 10) +assert(false ~= nil) +assert(nil ~= false) +assert(not nil == true) +assert(not not nil == false) +assert(not not 1 == true) +assert(not not a == true) +assert(not not (6 or nil) == true) +assert(not not (nil and 56) == false) +assert(not not (nil and true) == false) +print('+') + +a = {} +a[true] = 20 +a[false] = 10 +assert(a[1<2] == 20 and a[1>2] == 10) + +function f(a) return a end + +local a = {} +for i=3000,-3000,-1 do a[i] = i; end +a[10e30] = "alo"; a[true] = 10; a[false] = 20 +assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10) +for i=3000,-3000,-1 do assert(a[i] == i); end +a[print] = assert +a[f] = print +a[a] = a +assert(a[a][a][a][a][print] == assert) +a[print](a[a[f]] == a[print]) +a = nil + +a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'} +a, a.x, a.y = a, a[-3] +assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y) +a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 +a[1].alo(a[2]==10 and b==10 and c==print) + +a[2^31] = 10; a[2^31+1] = 11; a[-2^31] = 12; +a[2^32] = 13; a[-2^32] = 14; a[2^32+1] = 15; a[10^33] = 16; + +assert(a[2^31] == 10 and a[2^31+1] == 11 and a[-2^31] == 12 and + a[2^32] == 13 and a[-2^32] == 14 and a[2^32+1] == 15 and + a[10^33] == 16) + +a = nil + + +do + local a,i,j,b + a = {'a', 'b'}; i=1; j=2; b=a + i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i + assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and + b[3] == 1) +end + +print('OK') + +return res diff --git a/test/PUC-Lua-5.1-tests/big.lua b/test/PUC-Lua-5.1-tests/big.lua new file mode 100644 index 0000000..9261288 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/big.lua @@ -0,0 +1,381 @@ +print "testing string length overflow" + +local longs = string.rep("\0", 2^25) +local function catter (i) + return assert(loadstring( + string.format("return function(a) return a%s end", + string.rep("..a", i-1))))() +end +rep129 = catter(129) +local a, b = pcall(rep129, longs) +assert(not a and string.find(b, "overflow")) +print('+') + + +require "checktable" + +--[[ lots of empty lines (to force SETLINEW) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +--]] + + +a,b = nil,nil +while not b do +if a then +b = { -- lots of strings (to force JMPW and PUSHCONSTANTW) +"n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10", +"n11", "n12", "j301", "j302", "j303", "j304", "j305", "j306", "j307", "j308", +"j309", "a310", "n311", "n312", "n313", "n314", "n315", "n316", "n317", "n318", +"n319", "n320", "n321", "n322", "n323", "n324", "n325", "n326", "n327", "n328", +"a329", "n330", "n331", "n332", "n333", "n334", "n335", "n336", "n337", "n338", +"n339", "n340", "n341", "z342", "n343", "n344", "n345", "n346", "n347", "n348", +"n349", "n350", "n351", "n352", "r353", "n354", "n355", "n356", "n357", "n358", +"n359", "n360", "n361", "n362", "n363", "n364", "n365", "n366", "z367", "n368", +"n369", "n370", "n371", "n372", "n373", "n374", "n375", "a376", "n377", "n378", +"n379", "n380", "n381", "n382", "n383", "n384", "n385", "n386", "n387", "n388", +"n389", "n390", "n391", "n392", "n393", "n394", "n395", "n396", "n397", "n398", +"n399", "n400", "n13", "n14", "n15", "n16", "n17", "n18", "n19", "n20", +"n21", "n22", "n23", "a24", "n25", "n26", "n27", "n28", "n29", "j30", +"n31", "n32", "n33", "n34", "n35", "n36", "n37", "n38", "n39", "n40", +"n41", "n42", "n43", "n44", "n45", "n46", "n47", "n48", "n49", "n50", +"n51", "n52", "n53", "n54", "n55", "n56", "n57", "n58", "n59", "n60", +"n61", "n62", "n63", "n64", "n65", "a66", "z67", "n68", "n69", "n70", +"n71", "n72", "n73", "n74", "n75", "n76", "n77", "n78", "n79", "n80", +"n81", "n82", "n83", "n84", "n85", "n86", "n87", "n88", "n89", "n90", +"n91", "n92", "n93", "n94", "n95", "n96", "n97", "n98", "n99", "n100", +"n201", "n202", "n203", "n204", "n205", "n206", "n207", "n208", "n209", "n210", +"n211", "n212", "n213", "n214", "n215", "n216", "n217", "n218", "n219", "n220", +"n221", "n222", "n223", "n224", "n225", "n226", "n227", "n228", "n229", "n230", +"n231", "n232", "n233", "n234", "n235", "n236", "n237", "n238", "n239", "a240", +"a241", "a242", "a243", "a244", "a245", "a246", "a247", "a248", "a249", "n250", +"n251", "n252", "n253", "n254", "n255", "n256", "n257", "n258", "n259", "n260", +"n261", "n262", "n263", "n264", "n265", "n266", "n267", "n268", "n269", "n270", +"n271", "n272", "n273", "n274", "n275", "n276", "n277", "n278", "n279", "n280", +"n281", "n282", "n283", "n284", "n285", "n286", "n287", "n288", "n289", "n290", +"n291", "n292", "n293", "n294", "n295", "n296", "n297", "n298", "n299" +; x=23} +else a = 1 end + + +end + +assert(b.x == 23) +print('+') + +stat(b) + +repeat +a = { +n1 = 1.5, n2 = 2.5, n3 = 3.5, n4 = 4.5, n5 = 5.5, n6 = 6.5, n7 = 7.5, +n8 = 8.5, n9 = 9.5, n10 = 10.5, n11 = 11.5, n12 = 12.5, +j301 = 301.5, j302 = 302.5, j303 = 303.5, j304 = 304.5, j305 = 305.5, +j306 = 306.5, j307 = 307.5, j308 = 308.5, j309 = 309.5, a310 = 310.5, +n311 = 311.5, n312 = 312.5, n313 = 313.5, n314 = 314.5, n315 = 315.5, +n316 = 316.5, n317 = 317.5, n318 = 318.5, n319 = 319.5, n320 = 320.5, +n321 = 321.5, n322 = 322.5, n323 = 323.5, n324 = 324.5, n325 = 325.5, +n326 = 326.5, n327 = 327.5, n328 = 328.5, a329 = 329.5, n330 = 330.5, +n331 = 331.5, n332 = 332.5, n333 = 333.5, n334 = 334.5, n335 = 335.5, +n336 = 336.5, n337 = 337.5, n338 = 338.5, n339 = 339.5, n340 = 340.5, +n341 = 341.5, z342 = 342.5, n343 = 343.5, n344 = 344.5, n345 = 345.5, +n346 = 346.5, n347 = 347.5, n348 = 348.5, n349 = 349.5, n350 = 350.5, +n351 = 351.5, n352 = 352.5, r353 = 353.5, n354 = 354.5, n355 = 355.5, +n356 = 356.5, n357 = 357.5, n358 = 358.5, n359 = 359.5, n360 = 360.5, +n361 = 361.5, n362 = 362.5, n363 = 363.5, n364 = 364.5, n365 = 365.5, +n366 = 366.5, z367 = 367.5, n368 = 368.5, n369 = 369.5, n370 = 370.5, +n371 = 371.5, n372 = 372.5, n373 = 373.5, n374 = 374.5, n375 = 375.5, +a376 = 376.5, n377 = 377.5, n378 = 378.5, n379 = 379.5, n380 = 380.5, +n381 = 381.5, n382 = 382.5, n383 = 383.5, n384 = 384.5, n385 = 385.5, +n386 = 386.5, n387 = 387.5, n388 = 388.5, n389 = 389.5, n390 = 390.5, +n391 = 391.5, n392 = 392.5, n393 = 393.5, n394 = 394.5, n395 = 395.5, +n396 = 396.5, n397 = 397.5, n398 = 398.5, n399 = 399.5, n400 = 400.5, +n13 = 13.5, n14 = 14.5, n15 = 15.5, n16 = 16.5, n17 = 17.5, +n18 = 18.5, n19 = 19.5, n20 = 20.5, n21 = 21.5, n22 = 22.5, +n23 = 23.5, a24 = 24.5, n25 = 25.5, n26 = 26.5, n27 = 27.5, +n28 = 28.5, n29 = 29.5, j30 = 30.5, n31 = 31.5, n32 = 32.5, +n33 = 33.5, n34 = 34.5, n35 = 35.5, n36 = 36.5, n37 = 37.5, +n38 = 38.5, n39 = 39.5, n40 = 40.5, n41 = 41.5, n42 = 42.5, +n43 = 43.5, n44 = 44.5, n45 = 45.5, n46 = 46.5, n47 = 47.5, +n48 = 48.5, n49 = 49.5, n50 = 50.5, n51 = 51.5, n52 = 52.5, +n53 = 53.5, n54 = 54.5, n55 = 55.5, n56 = 56.5, n57 = 57.5, +n58 = 58.5, n59 = 59.5, n60 = 60.5, n61 = 61.5, n62 = 62.5, +n63 = 63.5, n64 = 64.5, n65 = 65.5, a66 = 66.5, z67 = 67.5, +n68 = 68.5, n69 = 69.5, n70 = 70.5, n71 = 71.5, n72 = 72.5, +n73 = 73.5, n74 = 74.5, n75 = 75.5, n76 = 76.5, n77 = 77.5, +n78 = 78.5, n79 = 79.5, n80 = 80.5, n81 = 81.5, n82 = 82.5, +n83 = 83.5, n84 = 84.5, n85 = 85.5, n86 = 86.5, n87 = 87.5, +n88 = 88.5, n89 = 89.5, n90 = 90.5, n91 = 91.5, n92 = 92.5, +n93 = 93.5, n94 = 94.5, n95 = 95.5, n96 = 96.5, n97 = 97.5, +n98 = 98.5, n99 = 99.5, n100 = 100.5, n201 = 201.5, n202 = 202.5, +n203 = 203.5, n204 = 204.5, n205 = 205.5, n206 = 206.5, n207 = 207.5, +n208 = 208.5, n209 = 209.5, n210 = 210.5, n211 = 211.5, n212 = 212.5, +n213 = 213.5, n214 = 214.5, n215 = 215.5, n216 = 216.5, n217 = 217.5, +n218 = 218.5, n219 = 219.5, n220 = 220.5, n221 = 221.5, n222 = 222.5, +n223 = 223.5, n224 = 224.5, n225 = 225.5, n226 = 226.5, n227 = 227.5, +n228 = 228.5, n229 = 229.5, n230 = 230.5, n231 = 231.5, n232 = 232.5, +n233 = 233.5, n234 = 234.5, n235 = 235.5, n236 = 236.5, n237 = 237.5, +n238 = 238.5, n239 = 239.5, a240 = 240.5, a241 = 241.5, a242 = 242.5, +a243 = 243.5, a244 = 244.5, a245 = 245.5, a246 = 246.5, a247 = 247.5, +a248 = 248.5, a249 = 249.5, n250 = 250.5, n251 = 251.5, n252 = 252.5, +n253 = 253.5, n254 = 254.5, n255 = 255.5, n256 = 256.5, n257 = 257.5, +n258 = 258.5, n259 = 259.5, n260 = 260.5, n261 = 261.5, n262 = 262.5, +n263 = 263.5, n264 = 264.5, n265 = 265.5, n266 = 266.5, n267 = 267.5, +n268 = 268.5, n269 = 269.5, n270 = 270.5, n271 = 271.5, n272 = 272.5, +n273 = 273.5, n274 = 274.5, n275 = 275.5, n276 = 276.5, n277 = 277.5, +n278 = 278.5, n279 = 279.5, n280 = 280.5, n281 = 281.5, n282 = 282.5, +n283 = 283.5, n284 = 284.5, n285 = 285.5, n286 = 286.5, n287 = 287.5, +n288 = 288.5, n289 = 289.5, n290 = 290.5, n291 = 291.5, n292 = 292.5, +n293 = 293.5, n294 = 294.5, n295 = 295.5, n296 = 296.5, n297 = 297.5, +n298 = 298.5, n299 = 299.5, j300 = 300} or 1 +until 1 + +assert(a.n299 == 299.5) +xxx = 1 +assert(xxx == 1) + +stat(a) + +function a:findfield (f) + local i,v = next(self, nil) + while i ~= f do + if not i then return end + i,v = next(self, i) + end + return v +end + +local ii = 0 +i = 1 +while b[i] do + local r = a:findfield(b[i]); + assert(a[b[i]] == r) + ii = math.max(ii,i) + i = i+1 +end + +assert(ii == 299) + +function xxxx (x) coroutine.yield('b'); return ii+x end + +assert(xxxx(10) == 309) + +a = nil +b = nil +a1 = nil + +print("tables with table indices:") +i = 1; a={} +while i <= 1023 do a[{}] = i; i=i+1 end +stat(a) +a = nil + +print("tables with function indices:") +a={} +for i=1,511 do local x; a[function () return x end] = i end +stat(a) +a = nil + +print'OK' + +return 'a' diff --git a/test/PUC-Lua-5.1-tests/calls.lua b/test/PUC-Lua-5.1-tests/calls.lua new file mode 100644 index 0000000..788f9a1 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/calls.lua @@ -0,0 +1,294 @@ +print("testing functions and calls") + +-- get the opportunity to test 'type' too ;) + +assert(type(1<2) == 'boolean') +assert(type(true) == 'boolean' and type(false) == 'boolean') +assert(type(nil) == 'nil' and type(-3) == 'number' and type'x' == 'string' and + type{} == 'table' and type(type) == 'function') + +assert(type(assert) == type(print)) +f = nil +function f (x) return a:x (x) end +assert(type(f) == 'function') + + +-- testing local-function recursion +fact = false +do + local res = 1 + local function fact (n) + if n==0 then return res + else return n*fact(n-1) + end + end + assert(fact(5) == 120) +end +assert(fact == false) + +-- testing declarations +a = {i = 10} +self = 20 +function a:x (x) return x+self.i end +function a.y (x) return x+self end + +assert(a:x(1)+10 == a.y(1)) + +a.t = {i=-100} +a["t"].x = function (self, a,b) return self.i+a+b end + +assert(a.t:x(2,3) == -95) + +do + local a = {x=0} + function a:add (x) self.x, a.y = self.x+x, 20; return self end + assert(a:add(10):add(20):add(30).x == 60 and a.y == 20) +end + +local a = {b={c={}}} + +function a.b.c.f1 (x) return x+1 end +function a.b.c:f2 (x,y) self[x] = y end +assert(a.b.c.f1(4) == 5) +a.b.c:f2('k', 12); assert(a.b.c.k == 12) + +print('+') + +t = nil -- 'declare' t +function f(a,b,c) local d = 'a'; t={a,b,c,d} end + +f( -- this line change must be valid + 1,2) +assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a') +f(1,2, -- this one too + 3,4) +assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') + +function fat(x) + if x <= 1 then return 1 + else return x*loadstring("return fat(" .. x-1 .. ")")() + end +end + +assert(loadstring "loadstring 'assert(fat(6)==720)' () ")() +a = loadstring('return fat(5), 3') +a,b = a() +assert(a == 120 and b == 3) +print('+') + +function err_on_n (n) + if n==0 then error(); exit(1); + else err_on_n (n-1); exit(1); + end +end + +do + function dummy (n) + if n > 0 then + assert(not pcall(err_on_n, n)) + dummy(n-1) + end + end +end + +dummy(10) + +function deep (n) + if n>0 then deep(n-1) end +end +deep(10) +deep(200) + +-- testing tail call +function deep (n) if n>0 then return deep(n-1) else return 101 end end +assert(deep(30000) == 101) +a = {} +function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end +assert(a:deep(30000) == 101) + +print('+') + + +a = nil +(function (x) a=x end)(23) +assert(a == 23 and (function (x) return x*2 end)(20) == 40) + + +local x,y,z,a +a = {}; lim = 2000 +for i=1, lim do a[i]=i end +assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) +x = unpack(a) +assert(x == 1) +x = {unpack(a)} +assert(table.getn(x) == lim and x[1] == 1 and x[lim] == lim) +x = {unpack(a, lim-2)} +assert(table.getn(x) == 3 and x[1] == lim-2 and x[3] == lim) +x = {unpack(a, 10, 6)} +assert(next(x) == nil) -- no elements +x = {unpack(a, 11, 10)} +assert(next(x) == nil) -- no elements +x,y = unpack(a, 10, 10) +assert(x == 10 and y == nil) +x,y,z = unpack(a, 10, 11) +assert(x == 10 and y == 11 and z == nil) +a,x = unpack{1} +assert(a==1 and x==nil) +a,x = unpack({1,2}, 1, 1) +assert(a==1 and x==nil) + + +-- testing closures + +-- fixed-point operator +Y = function (le) + local function a (f) + return le(function (x) return f(f)(x) end) + end + return a(a) + end + + +-- non-recursive factorial + +F = function (f) + return function (n) + if n == 0 then return 1 + else return n*f(n-1) end + end + end + +fat = Y(F) + +assert(fat(0) == 1 and fat(4) == 24 and Y(F)(5)==5*Y(F)(4)) + +local function g (z) + local function f (a,b,c,d) + return function (x,y) return a+b+c+d+a+x+y+z end + end + return f(z,z+1,z+2,z+3) +end + +f = g(10) +assert(f(9, 16) == 10+11+12+13+10+9+16+10) + +Y, F, f = nil +print('+') + +-- testing multiple returns + +function unlpack (t, i) + i = i or 1 + if (i <= table.getn(t)) then + return t[i], unlpack(t, i+1) + end +end + +function equaltab (t1, t2) + assert(table.getn(t1) == table.getn(t2)) + for i,v1 in ipairs(t1) do + assert(v1 == t2[i]) + end +end + +local function pack (...) + local x = {...} + x.n = select('#', ...) + return x +end + +function f() return 1,2,30,4 end +function ret2 (a,b) return a,b end + +local a,b,c,d = unlpack{1,2,3} +assert(a==1 and b==2 and c==3 and d==nil) +a = {1,2,3,4,false,10,'alo',false,assert} +equaltab(pack(unlpack(a)), a) +equaltab(pack(unlpack(a), -1), {1,-1}) +a,b,c,d = ret2(f()), ret2(f()) +assert(a==1 and b==1 and c==2 and d==nil) +a,b,c,d = unlpack(pack(ret2(f()), ret2(f()))) +assert(a==1 and b==1 and c==2 and d==nil) +a,b,c,d = unlpack(pack(ret2(f()), (ret2(f())))) +assert(a==1 and b==1 and c==nil and d==nil) + +a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} +assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") + + +-- testing calls with 'incorrect' arguments +rawget({}, "x", 1) +rawset({}, "x", 1, 2) +assert(math.sin(1,2) == math.sin(1)) +table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg") + + +-- test for generic load +x = "-- a comment\0\0\0\n x = 10 + \n23; \ + local a = function () x = 'hi' end; \ + return '\0'" +local i = 0 +function read1 (x) + return function () + collectgarbage() + i=i+1 + return string.sub(x, i, i) + end +end + +a = assert(load(read1(x), "modname")) +assert(a() == "\0" and _G.x == 33) +assert(debug.getinfo(a).source == "modname") + +x = string.dump(loadstring("x = 1; return x")) +i = 0 +a = assert(load(read1(x))) +assert(a() == 1 and _G.x == 1) + +i = 0 +local a, b = load(read1("*a = 123")) +assert(not a and type(b) == "string" and i == 2) + +a, b = load(function () error("hhi") end) +assert(not a and string.find(b, "hhi")) + +-- test generic load with nested functions +x = [[ + return function (x) + return function (y) + return function (z) + return x+y+z + end + end + end +]] + +a = assert(load(read1(x))) +assert(a()(2)(3)(10) == 15) + + +-- test for dump/undump with upvalues +local a, b = 20, 30 +x = loadstring(string.dump(function (x) + if x == "set" then a = 10+b; b = b+1 else + return a + end +end)) +assert(x() == nil) +assert(debug.setupvalue(x, 1, "hi") == "a") +assert(x() == "hi") +assert(debug.setupvalue(x, 2, 13) == "b") +assert(not debug.setupvalue(x, 3, 10)) -- only 2 upvalues +x("set") +assert(x() == 23) +x("set") +assert(x() == 24) + + +-- test for bug in parameter adjustment +assert((function () return nil end)(4) == nil) +assert((function () local a; return a end)(4) == nil) +assert((function (a) return a end)() == nil) + +print('OK') +return deep diff --git a/test/PUC-Lua-5.1-tests/checktable.lua b/test/PUC-Lua-5.1-tests/checktable.lua new file mode 100644 index 0000000..f0938be --- /dev/null +++ b/test/PUC-Lua-5.1-tests/checktable.lua @@ -0,0 +1,77 @@ + +assert(rawget(_G, "stat") == nil) -- module not loaded before + +if T == nil then + stat = function () print"`querytab' nao ativo" end + return +end + + +function checktable (t) + local asize, hsize, ff = T.querytab(t) + local l = {} + for i=0,hsize-1 do + local key,val,next = T.querytab(t, i + asize) + if key == nil then + assert(l[i] == nil and val==nil and next==nil) + elseif key == "<undef>" then + assert(val==nil) + else + assert(t[key] == val) + local mp = T.hash(key, t) + if l[i] then + assert(l[i] == mp) + elseif mp ~= i then + l[i] = mp + else -- list head + l[mp] = {mp} -- first element + while next do + assert(ff <= next and next < hsize) + if l[next] then assert(l[next] == mp) else l[next] = mp end + table.insert(l[mp], next) + key,val,next = T.querytab(t, next) + assert(key) + end + end + end + end + l.asize = asize; l.hsize = hsize; l.ff = ff + return l +end + +function mostra (t) + local asize, hsize, ff = T.querytab(t) + print(asize, hsize, ff) + print'------' + for i=0,asize-1 do + local _, v = T.querytab(t, i) + print(string.format("[%d] -", i), v) + end + print'------' + for i=0,hsize-1 do + print(i, T.querytab(t, i+asize)) + end + print'-------------' +end + +function stat (t) + t = checktable(t) + local nelem, nlist = 0, 0 + local maxlist = {} + for i=0,t.hsize-1 do + if type(t[i]) == 'table' then + local n = table.getn(t[i]) + nlist = nlist+1 + nelem = nelem + n + if not maxlist[n] then maxlist[n] = 0 end + maxlist[n] = maxlist[n]+1 + end + end + print(string.format("hsize=%d elements=%d load=%.2f med.len=%.2f (asize=%d)", + t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize)) + for i=1,table.getn(maxlist) do + local n = maxlist[i] or 0 + print(string.format("%5d %10d %.2f%%", i, n, n*100/nlist)) + end +end + diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua new file mode 100644 index 0000000..27ca0ad --- /dev/null +++ b/test/PUC-Lua-5.1-tests/closure.lua @@ -0,0 +1,422 @@ +print "testing closures and coroutines" + +local A,B = 0,{g=10} +function f(x) + local a = {} + for i=1,1000 do + local y = 0 + do + a[i] = function () B.g = B.g+1; y = y+x; return y+A end + end + end + local dummy = function () return a[A] end + collectgarbage() + A = 1; assert(dummy() == a[1]); A = 0; + assert(a[1]() == x) + assert(a[3]() == x) + collectgarbage() + assert(B.g == 12) + return a +end + +a = f(10) +-- force a GC in this level +local x = {[1] = {}} -- to detect a GC +setmetatable(x, {__mode = 'kv'}) +while x[1] do -- repeat until GC + local a = A..A..A..A -- create garbage + A = A+1 +end +assert(a[1]() == 20+A) +assert(a[1]() == 30+A) +assert(a[2]() == 10+A) +collectgarbage() +assert(a[2]() == 20+A) +assert(a[2]() == 30+A) +assert(a[3]() == 20+A) +assert(a[8]() == 10+A) +assert(getmetatable(x).__mode == 'kv') +assert(B.g == 19) + +-- testing closures with 'for' control variable +a = {} +for i=1,10 do + a[i] = {set = function(x) i=x end, get = function () return i end} + if i == 3 then break end +end +assert(a[4] == nil) +a[1].set(10) +assert(a[2].get() == 2) +a[2].set('a') +assert(a[3].get() == 3) +assert(a[2].get() == 'a') + +a = {} +for i, k in pairs{'a', 'b'} do + a[i] = {set = function(x, y) i=x; k=y end, + get = function () return i, k end} + if i == 2 then break end +end +a[1].set(10, 20) +local r,s = a[2].get() +assert(r == 2 and s == 'b') +r,s = a[1].get() +assert(r == 10 and s == 20) +a[2].set('a', 'b') +r,s = a[2].get() +assert(r == "a" and s == "b") + + +-- testing closures with 'for' control variable x break +for i=1,3 do + f = function () return i end + break +end +assert(f() == 1) + +for k, v in pairs{"a", "b"} do + f = function () return k, v end + break +end +assert(({f()})[1] == 1) +assert(({f()})[2] == "a") + + +-- testing closure x break x return x errors + +local b +function f(x) + local first = 1 + while 1 do + if x == 3 and not first then return end + local a = 'xuxu' + b = function (op, y) + if op == 'set' then + a = x+y + else + return a + end + end + if x == 1 then do break end + elseif x == 2 then return + else if x ~= 3 then error() end + end + first = nil + end +end + +for i=1,3 do + f(i) + assert(b('get') == 'xuxu') + b('set', 10); assert(b('get') == 10+i) + b = nil +end + +pcall(f, 4); +assert(b('get') == 'xuxu') +b('set', 10); assert(b('get') == 14) + + +local w +-- testing multi-level closure +function f(x) + return function (y) + return function (z) return w+x+y+z end + end +end + +y = f(10) +w = 1.345 +assert(y(20)(30) == 60+w) + +-- testing closures x repeat-until + +local a = {} +local i = 1 +repeat + local x = i + a[i] = function () i = x+1; return x end +until i > 10 or a[i]() ~= x +assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) + +print'+' + + +-- test for correctly closing upvalues in tail calls of vararg functions +local function t () + local function c(a,b) assert(a=="test" and b=="OK") end + local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end + local x = 1 + return v(function() return x end) +end +t() + + +-- coroutine tests + +local f + +assert(coroutine.running() == nil) + + +-- tests for global environment + +local function foo (a) + setfenv(0, a) + coroutine.yield(getfenv()) + assert(getfenv(0) == a) + assert(getfenv(1) == _G) + assert(getfenv(loadstring"") == a) + return getfenv() +end + +f = coroutine.wrap(foo) +local a = {} +assert(f(a) == _G) +local a,b = pcall(f) +assert(a and b == _G) + + +-- tests for multiple yield/resume arguments + +local function eqtab (t1, t2) + assert(table.getn(t1) == table.getn(t2)) + for i,v in ipairs(t1) do + assert(t2[i] == v) + end +end + +_G.x = nil -- declare x +function foo (a, ...) + assert(coroutine.running() == f) + assert(coroutine.status(f) == "running") + local arg = {...} + for i=1,table.getn(arg) do + _G.x = {coroutine.yield(unpack(arg[i]))} + end + return unpack(a) +end + +f = coroutine.create(foo) +assert(type(f) == "thread" and coroutine.status(f) == "suspended") +assert(string.find(tostring(f), "thread")) +local s,a,b,c,d +s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'}) +assert(s and a == nil and coroutine.status(f) == "suspended") +s,a,b,c,d = coroutine.resume(f) +eqtab(_G.x, {}) +assert(s and a == 1 and b == nil) +s,a,b,c,d = coroutine.resume(f, 1, 2, 3) +eqtab(_G.x, {1, 2, 3}) +assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil) +s,a,b,c,d = coroutine.resume(f, "xuxu") +eqtab(_G.x, {"xuxu"}) +assert(s and a == 1 and b == 2 and c == 3 and d == nil) +assert(coroutine.status(f) == "dead") +s, a = coroutine.resume(f, "xuxu") +assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") + + +-- yields in tail calls +local function foo (i) return coroutine.yield(i) end +f = coroutine.wrap(function () + for i=1,10 do + assert(foo(i) == _G.x) + end + return 'a' +end) +for i=1,10 do _G.x = i; assert(f(i) == i) end +_G.x = 'xuxu'; assert(f('xuxu') == 'a') + +-- recursive +function pf (n, i) + coroutine.yield(n) + pf(n*i, i+1) +end + +f = coroutine.wrap(pf) +local s=1 +for i=1,10 do + assert(f(1, 1) == s) + s = s*i +end + +-- sieve +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + + +function filter (p, g) + return coroutine.wrap(function () + while 1 do + local n = g() + if n == nil then return end + if math.mod(n, p) ~= 0 then coroutine.yield(n) end + end + end) +end + +local x = gen(100) +local a = {} +while 1 do + local n = x() + if n == nil then break end + table.insert(a, n) + x = filter(n, x) +end + +assert(table.getn(a) == 25 and a[table.getn(a)] == 97) + + +-- errors in coroutines +function foo () + assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1) + assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined) + coroutine.yield(3) + error(foo) +end + +function goo() foo() end +x = coroutine.wrap(goo) +assert(x() == 3) +local a,b = pcall(x) +assert(not a and b == foo) + +x = coroutine.create(goo) +a,b = coroutine.resume(x) +assert(a and b == 3) +a,b = coroutine.resume(x) +assert(not a and b == foo and coroutine.status(x) == "dead") +a,b = coroutine.resume(x) +assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") + + +-- co-routines x for loop +function all (a, n, k) + if k == 0 then coroutine.yield(a) + else + for i=1,n do + a[k] = i + all(a, n, k-1) + end + end +end + +local a = 0 +for t in coroutine.wrap(function () all({}, 5, 4) end) do + a = a+1 +end +assert(a == 5^4) + + +-- access to locals of collected corroutines +local C = {}; setmetatable(C, {__mode = "kv"}) +local x = coroutine.wrap (function () + local a = 10 + local function f () a = a+10; return a end + while true do + a = a+1 + coroutine.yield(f) + end + end) + +C[1] = x; + +local f = x() +assert(f() == 21 and x()() == 32 and x() == f) +x = nil +collectgarbage() +assert(C[1] == nil) +assert(f() == 43 and f() == 53) + + +-- old bug: attempt to resume itself + +function co_func (current_co) + assert(coroutine.running() == current_co) + assert(coroutine.resume(current_co) == false) + assert(coroutine.resume(current_co) == false) + return 10 +end + +local co = coroutine.create(co_func) +local a,b = coroutine.resume(co, co) +assert(a == true and b == 10) +assert(coroutine.resume(co, co) == false) +assert(coroutine.resume(co, co) == false) + +-- access to locals of erroneous coroutines +local x = coroutine.create (function () + local a = 10 + _G.f = function () a=a+1; return a end + error('x') + end) + +assert(not coroutine.resume(x)) +-- overwrite previous position of local `a' +assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) +assert(_G.f() == 11) +assert(_G.f() == 12) + + +if not T then + (Message or print)('\a\n >>> testC not active: skipping yield/hook tests <<<\n\a') +else + + local turn + + function fact (t, x) + assert(turn == t) + if x == 0 then return 1 + else return x*fact(t, x-1) + end + end + + local A,B,a,b = 0,0,0,0 + + local x = coroutine.create(function () + T.setyhook("", 2) + A = fact("A", 10) + end) + + local y = coroutine.create(function () + T.setyhook("", 3) + B = fact("B", 11) + end) + + while A==0 or B==0 do + if A==0 then turn = "A"; T.resume(x) end + if B==0 then turn = "B"; T.resume(y) end + end + + assert(B/A == 11) +end + + +-- leaving a pending coroutine open +_X = coroutine.wrap(function () + local a = 10 + local x = function () a = a+1 end + coroutine.yield() + end) + +_X() + + +-- coroutine environments +co = coroutine.create(function () + coroutine.yield(getfenv(0)) + return loadstring("return a")() + end) + +a = {a = 15} +debug.setfenv(co, a) +assert(debug.getfenv(co) == a) +assert(select(2, coroutine.resume(co)) == a) +assert(select(2, coroutine.resume(co)) == a.a) + + +print'OK' diff --git a/test/PUC-Lua-5.1-tests/code.lua b/test/PUC-Lua-5.1-tests/code.lua new file mode 100644 index 0000000..875d488 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/code.lua @@ -0,0 +1,143 @@ + +if T==nil then + (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a') + return +end +print "testing code generation and optimizations" + + +-- this code gave an error for the code checker +do + local function f (a) + for k,v,w in a do end + end +end + + +function check (f, ...) + local c = T.listcode(f) + for i=1, arg.n do + -- print(arg[i], c[i]) + assert(string.find(c[i], '- '..arg[i]..' *%d')) + end + assert(c[arg.n+2] == nil) +end + + +function checkequal (a, b) + a = T.listcode(a) + b = T.listcode(b) + for i = 1, table.getn(a) do + a[i] = string.gsub(a[i], '%b()', '') -- remove line number + b[i] = string.gsub(b[i], '%b()', '') -- remove line number + assert(a[i] == b[i]) + end +end + + +-- some basic instructions +check(function () + (function () end){f()} +end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN') + + +-- sequence of LOADNILs +check(function () + local a,b,c + local d; local e; + a = nil; d=nil +end, 'RETURN') + + +-- single return +check (function (a,b,c) return a end, 'RETURN') + + +-- infinite loops +check(function () while true do local a = -1 end end, +'LOADK', 'JMP', 'RETURN') + +check(function () while 1 do local a = -1 end end, +'LOADK', 'JMP', 'RETURN') + +check(function () repeat local x = 1 until false end, +'LOADK', 'JMP', 'RETURN') + +check(function () repeat local x until nil end, +'LOADNIL', 'JMP', 'RETURN') + +check(function () repeat local x = 1 until true end, +'LOADK', 'RETURN') + + +-- concat optimization +check(function (a,b,c,d) return a..b..c..d end, + 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') + +-- not +check(function () return not not nil end, 'LOADBOOL', 'RETURN') +check(function () return not not false end, 'LOADBOOL', 'RETURN') +check(function () return not not true end, 'LOADBOOL', 'RETURN') +check(function () return not not 1 end, 'LOADBOOL', 'RETURN') + +-- direct access to locals +check(function () + local a,b,c,d + a = b*2 + c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b +end, + 'MUL', + 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', + 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') + + +-- direct access to constants +check(function () + local a,b + a.x = 0 + a.x = b + a[b] = 'y' + a = 1 - a + b = 1/a + b = 5+4 + a[true] = false +end, + 'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK', + 'SETTABLE', 'RETURN') + +local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end + +check(f, 'LOADK', 'RETURN') +assert(f() == -5) + +check(function () + local a,b,c + b[c], a = c, b + b[a], a = c, b + a, b = c, a + a = a +end, + 'MOVE', 'MOVE', 'SETTABLE', + 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', + 'MOVE', 'MOVE', 'MOVE', + -- no code for a = a + 'RETURN') + + +-- x == nil , x ~= nil +checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end, + function () if (a==9) then a=1 end; if a~=9 then a=1 end end) + +check(function () if a==nil then a=1 end end, +'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN') + +-- de morgan +checkequal(function () local a; if not (a or b) then b=a end end, + function () local a; if (not a and not b) then b=a end end) + +checkequal(function (l) local a; return 0 <= a and a <= l end, + function (l) local a; return not (not(a >= 0) or not(a <= l)) end) + + +print 'OK' + diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua new file mode 100644 index 0000000..5fb3798 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/constructs.lua @@ -0,0 +1,240 @@ +print "testing syntax" + +-- testing priorities + +assert(2^3^2 == 2^(3^2)); +assert(2^3*4 == (2^3)*4); +assert(2^-2 == 1/4 and -2^- -2 == - - -4); +assert(not nil and 2 and not(2>3 or 3<2)); +assert(-3-1-5 == 0+0-9); +assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0); +assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33"); +assert(not(2+1 > 3*1) and "a".."b" > "a"); + +assert(not ((true or false) and nil)) +assert( true or false and nil) + +local a,b = 1,nil; +assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75); +x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x); +x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x); + +x,y=1,2; +assert((x>y) and x or y == 2); +x,y=2,1; +assert((x>y) and x or y == 2); + +assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) + + +-- silly loops +repeat until 1; repeat until true; +while false do end; while nil do end; + +do -- test old bug (first name could not be an `upvalue') + local a; function f(x) x={a=1}; x={x=1}; x={G=1} end +end + +function f (i) + if type(i) ~= 'number' then return i,'jojo'; end; + if i > 0 then return i, f(i-1); end; +end + +x = {f(3), f(5), f(10);}; +assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1); +assert(x[nil] == nil) +x = {f'alo', f'xixi', nil}; +assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil); +x = {f'alo'..'xixi'}; +assert(x[1] == 'aloxixi') +x = {f{}} +assert(x[2] == 'jojo' and type(x[1]) == 'table') + + +local f = function (i) + if i < 10 then return 'a'; + elseif i < 20 then return 'b'; + elseif i < 30 then return 'c'; + end; +end + +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil) + +for i=1,1000 do break; end; +n=100; +i=3; +t = {}; +a=nil +while not a do + a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end; +end +assert(a == n*(n+1)/2 and i==3); +assert(t[1] and t[n] and not t[0] and not t[n+1]) + +function f(b) + local x = 1; + repeat + local a; + if b==1 then local b=1; x=10; break + elseif b==2 then x=20; break; + elseif b==3 then x=30; + else local a,b,c,d=math.sin(1); x=x+1; + end + until x>=12; + return x; +end; + +assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12) + + +local f = function (i) + if i < 10 then return 'a' + elseif i < 20 then return 'b' + elseif i < 30 then return 'c' + else return 8 + end +end + +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8) + +local a, b = nil, 23 +x = {f(100)*2+3 or a, a or b+2} +assert(x[1] == 19 and x[2] == 25) +x = {f=2+3 or a, a = b+2} +assert(x.f == 5 and x.a == 25) + +a={y=1} +x = {a.y} +assert(x[1] == 1) + +function f(i) + while 1 do + if i>0 then i=i-1; + else return; end; + end; +end; + +function g(i) + while 1 do + if i>0 then i=i-1 + else return end + end +end + +f(10); g(10); + +do + function f () return 1,2,3; end + local a, b, c = f(); + assert(a==1 and b==2 and c==3) + a, b, c = (f()); + assert(a==1 and b==nil and c==nil) +end + +local a,b = 3 and f(); +assert(a==1 and b==nil) + +function g() f(); return; end; +assert(g() == nil) +function g() return nil or f() end +a,b = g() +assert(a==1 and b==nil) + +print'+'; + + +f = [[ +return function ( a , b , c , d , e ) + local x = a >= b or c or ( d and e ) or nil + return x +end , { a = 1 , b = 2 >= 1 , } or { 1 }; +]] +f = string.gsub(f, "%s+", "\n"); -- force a SETLINE between opcodes +f,a = loadstring(f)(); +assert(a.a == 1 and a.b) + +function g (a,b,c,d,e) + if not (a>=b or c or d and e or nil) then return 0; else return 1; end; +end + +function h (a,b,c,d,e) + while (a>=b or c or (d and e) or nil) do return 1; end; + return 0; +end; + +assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1) +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) +assert(f(1,2,'a') +~= -- force SETLINE before nil +nil, "") +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) +assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and + h(1,2,nil,1,'x') == 1) +assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and + h(1,2,nil,nil,'x') == 0) +assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and + h(1,2,nil,1,nil) == 0) + +assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true) +x = 2<3 and not 3; assert(x==false) +x = 2<1 or (2>1 and 'a'); assert(x=='a') + + +do + local a; if nil then a=1; else a=2; end; -- this nil comes as PUSHNIL 2 + assert(a==2) +end + +function F(a) + assert(debug.getinfo(1, "n").name == 'F') + return a,2,3 +end + +a,b = F(1)~=nil; assert(a == true and b == nil); +a,b = F(nil)==nil; assert(a == true and b == nil) + +---------------------------------------------------------------- +-- creates all combinations of +-- [not] ([not] arg op [not] (arg op [not] arg )) +-- and tests each one + +function ID(x) return x end + +function f(t, i) + local b = t.n + local res = math.mod(math.floor(i/c), b)+1 + c = c*b + return t[res] +end + +local arg = {" ( 1 < 2 ) ", " ( 1 >= 2 ) ", " F ( ) ", " nil "; n=4} + +local op = {" and ", " or ", " == ", " ~= "; n=4} + +local neg = {" ", " not "; n=2} + +local i = 0 +repeat + c = 1 + local s = f(neg, i)..'ID('..f(neg, i)..f(arg, i)..f(op, i).. + f(neg, i)..'ID('..f(arg, i)..f(op, i)..f(neg, i)..f(arg, i)..'))' + local s1 = string.gsub(s, 'ID', '') + K,X,NX,WX1,WX2 = nil + s = string.format([[ + local a = %s + local b = not %s + K = b + local xxx; + if %s then X = a else X = b end + if %s then NX = b else NX = a end + while %s do WX1 = a; break end + while %s do WX2 = a; break end + repeat if (%s) then break end; assert(b) until not(%s) + ]], s1, s, s1, s, s1, s, s1, s, s) + assert(loadstring(s))() + assert(X and not NX and not WX1 == K and not WX2 == K) + if math.mod(i,4000) == 0 then print('+') end + i = i+1 +until i==c + +print'OK' diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua new file mode 100644 index 0000000..9d2c86f --- /dev/null +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -0,0 +1,499 @@ +-- testing debug library + +local function dostring(s) return assert(loadstring(s))() end + +print"testing debug library and debug information" + +do +local a=1 +end + +function test (s, l, p) + collectgarbage() -- avoid gc during trace + local function f (event, line) + assert(event == 'line') + local l = table.remove(l, 1) + if p then print(l, line) end + assert(l == line, "wrong trace!!") + end + debug.sethook(f,"l"); loadstring(s)(); debug.sethook() + assert(table.getn(l) == 0) +end + + +do + local a = debug.getinfo(print) + assert(a.what == "C" and a.short_src == "[C]") + local b = debug.getinfo(test, "SfL") + assert(b.name == nil and b.what == "Lua" and b.linedefined == 11 and + b.lastlinedefined == b.linedefined + 10 and + b.func == test and not string.find(b.short_src, "%[")) + assert(b.activelines[b.linedefined + 1] and + b.activelines[b.lastlinedefined]) + assert(not b.activelines[b.linedefined] and + not b.activelines[b.lastlinedefined + 1]) +end + + +-- test file and string names truncation +a = "function f () end" +local function dostring (s, x) return loadstring(s, x)() end +dostring(a) +assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a)) +dostring(a..string.format("; %s\n=1", string.rep('p', 400))) +assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$')) +dostring("\n"..a) +assert(debug.getinfo(f).short_src == '[string "..."]') +dostring(a, "") +assert(debug.getinfo(f).short_src == '[string ""]') +dostring(a, "@xuxu") +assert(debug.getinfo(f).short_src == "xuxu") +dostring(a, "@"..string.rep('p', 1000)..'t') +assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$")) +dostring(a, "=xuxu") +assert(debug.getinfo(f).short_src == "xuxu") +dostring(a, string.format("=%s", string.rep('x', 500))) +assert(string.find(debug.getinfo(f).short_src, "^x*")) +dostring(a, "=") +assert(debug.getinfo(f).short_src == "") +a = nil; f = nil; + + +repeat + local g = {x = function () + local a = debug.getinfo(2) + assert(a.name == 'f' and a.namewhat == 'local') + a = debug.getinfo(1) + assert(a.name == 'x' and a.namewhat == 'field') + return 'xixi' + end} + local f = function () return 1+1 and (not 1 or g.x()) end + assert(f() == 'xixi') + g = debug.getinfo(f) + assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name) + + function f (x, name) -- local! + name = name or 'f' + local a = debug.getinfo(1) + assert(a.name == name and a.namewhat == 'local') + return x + end + + -- breaks in different conditions + if 3>4 then break end; f() + if 3<4 then a=1 else break end; f() + while 1 do local x=10; break end; f() + local b = 1 + if 3>4 then return math.sin(1) end; f() + a = 3<4; f() + a = 3<4 or 1; f() + repeat local x=20; if 4>3 then f() else break end; f() until 1 + g = {} + f(g).x = f(2) and f(10)+f(9) + assert(g.x == f(19)) + function g(x) if not x then return 3 end return (x('a', 'x')) end + assert(g(f) == 'a') +until 1 + +test([[if +math.sin(1) +then + a=1 +else + a=2 +end +]], {2,4,7}) + +test([[-- +if nil then + a=1 +else + a=2 +end +]], {2,5,6}) + +test([[a=1 +repeat + a=a+1 +until a==3 +]], {1,3,4,3,4}) + +test([[ do + return +end +]], {2}) + +test([[local a +a=1 +while a<=3 do + a=a+1 +end +]], {2,3,4,3,4,3,4,3,5}) + +test([[while math.sin(1) do + if math.sin(1) + then + break + end +end +a=1]], {1,2,4,7}) + +test([[for i=1,3 do + a=i +end +]], {1,2,1,2,1,2,1,3}) + +test([[for i,v in pairs{'a','b'} do + a=i..v +end +]], {1,2,1,2,1,3}) + +test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) + + + +print'+' + +a = {}; L = nil +local glob = 1 +local oldglob = glob +debug.sethook(function (e,l) + collectgarbage() -- force GC during a hook + local f, m, c = debug.gethook() + assert(m == 'crl' and c == 0) + if e == "line" then + if glob ~= oldglob then + L = l-1 -- get the first line where "glob" has changed + oldglob = glob + end + elseif e == "call" then + local f = debug.getinfo(2, "f").func + a[f] = 1 + else assert(e == "return") + end +end, "crl") + +function f(a,b) + collectgarbage() + local _, x = debug.getlocal(1, 1) + local _, y = debug.getlocal(1, 2) + assert(x == a and y == b) + assert(debug.setlocal(2, 3, "pera") == "AA".."AA") + assert(debug.setlocal(2, 4, "maçã") == "B") + x = debug.getinfo(2) + assert(x.func == g and x.what == "Lua" and x.name == 'g' and + x.nups == 0 and string.find(x.source, "^@.*db%.lua")) + glob = glob+1 + assert(debug.getinfo(1, "l").currentline == L+1) + assert(debug.getinfo(1, "l").currentline == L+2) +end + +function foo() + glob = glob+1 + assert(debug.getinfo(1, "l").currentline == L+1) +end; foo() -- set L +-- check line counting inside strings and empty lines + +_ = 'alo\ +alo' .. [[ + +]] +--[[ +]] +assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines + + +function g(...) + do local a,b,c; a=math.sin(40); end + local feijao + local AAAA,B = "xuxu", "mamão" + f(AAAA,B) + assert(AAAA == "pera" and B == "maçã") + do + local B = 13 + local x,y = debug.getlocal(1,5) + assert(x == 'B' and y == 13) + end +end + +g() + + +assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print]) + + +-- tests for manipulating non-registered locals (C and Lua temporaries) + +local n, v = debug.getlocal(0, 1) +assert(v == 0 and n == "(*temporary)") +local n, v = debug.getlocal(0, 2) +assert(v == 2 and n == "(*temporary)") +assert(not debug.getlocal(0, 3)) +assert(not debug.getlocal(0, 0)) + +function f() + assert(select(2, debug.getlocal(2,3)) == 1) + assert(not debug.getlocal(2,4)) + debug.setlocal(2, 3, 10) + return 20 +end + +function g(a,b) return (a+1) + f() end + +assert(g(0,0) == 30) + + +debug.sethook(nil); +assert(debug.gethook() == nil) + + +-- testing access to function arguments + +X = nil +a = {} +function a:f (a, b, ...) local c = 13 end +debug.sethook(function (e) + assert(e == "call") + dostring("XX = 12") -- test dostring inside hooks + -- testing errors inside hooks + assert(not pcall(loadstring("a='joao'+1"))) + debug.sethook(function (e, l) + assert(debug.getinfo(2, "l").currentline == l) + local f,m,c = debug.gethook() + assert(e == "line") + assert(m == 'l' and c == 0) + debug.sethook(nil) -- hook is called only once + assert(not X) -- check that + X = {}; local i = 1 + local x,y + while 1 do + x,y = debug.getlocal(2, i) + if x==nil then break end + X[x] = y + i = i+1 + end + end, "l") +end, "c") + +a:f(1,2,3,4,5) +assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) +assert(XX == 12) +assert(debug.gethook() == nil) + + +-- testing upvalue access +local function getupvalues (f) + local t = {} + local i = 1 + while true do + local name, value = debug.getupvalue(f, i) + if not name then break end + assert(not t[name]) + t[name] = value + i = i + 1 + end + return t +end + +local a,b,c = 1,2,3 +local function foo1 (a) b = a; return c end +local function foo2 (x) a = x; return c+b end +assert(debug.getupvalue(foo1, 3) == nil) +assert(debug.getupvalue(foo1, 0) == nil) +assert(debug.setupvalue(foo1, 3, "xuxu") == nil) +local t = getupvalues(foo1) +assert(t.a == nil and t.b == 2 and t.c == 3) +t = getupvalues(foo2) +assert(t.a == 1 and t.b == 2 and t.c == 3) +assert(debug.setupvalue(foo1, 1, "xuxu") == "b") +assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu") +-- cannot manipulate C upvalues from Lua +assert(debug.getupvalue(io.read, 1) == nil) +assert(debug.setupvalue(io.read, 1, 10) == nil) + + +-- testing count hooks +local a=0 +debug.sethook(function (e) a=a+1 end, "", 1) +a=0; for i=1,1000 do end; assert(1000 < a and a < 1012) +debug.sethook(function (e) a=a+1 end, "", 4) +a=0; for i=1,1000 do end; assert(250 < a and a < 255) +local f,m,c = debug.gethook() +assert(m == "" and c == 4) +debug.sethook(function (e) a=a+1 end, "", 4000) +a=0; for i=1,1000 do end; assert(a == 0) +debug.sethook(print, "", 2^24 - 1) -- count upperbound +local f,m,c = debug.gethook() +assert(({debug.gethook()})[3] == 2^24 - 1) +debug.sethook() + + +-- tests for tail calls +local function f (x) + if x then + assert(debug.getinfo(1, "S").what == "Lua") + local tail = debug.getinfo(2) + assert(not pcall(getfenv, 3)) + assert(tail.what == "tail" and tail.short_src == "(tail call)" and + tail.linedefined == -1 and tail.func == nil) + assert(debug.getinfo(3, "f").func == g1) + assert(getfenv(3)) + assert(debug.getinfo(4, "S").what == "tail") + assert(not pcall(getfenv, 5)) + assert(debug.getinfo(5, "S").what == "main") + assert(getfenv(5)) + print"+" + end +end + +function g(x) return f(x) end + +function g1(x) g(x) end + +local function h (x) local f=g1; return f(x) end + +h(true) + +local b = {} +debug.sethook(function (e) table.insert(b, e) end, "cr") +h(false) +debug.sethook() +local res = {"return", -- first return (from sethook) + "call", "call", "call", "call", + "return", "tail return", "return", "tail return", + "call", -- last call (to sethook) +} +for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end + + +lim = 30000 +local function foo (x) + if x==0 then + assert(debug.getinfo(lim+2).what == "main") + for i=2,lim do assert(debug.getinfo(i, "S").what == "tail") end + else return foo(x-1) + end +end + +foo(lim) + + +print"+" + + +-- testing traceback + +assert(debug.traceback(print) == print) +assert(debug.traceback(print, 4) == print) +assert(string.find(debug.traceback("hi", 4), "^hi\n")) +assert(string.find(debug.traceback("hi"), "^hi\n")) +assert(not string.find(debug.traceback("hi"), "'traceback'")) +assert(string.find(debug.traceback("hi", 0), "'traceback'")) +assert(string.find(debug.traceback(), "^stack traceback:\n")) + +-- testing debugging of coroutines + +local function checktraceback (co, p) + local tb = debug.traceback(co) + local i = 0 + for l in string.gmatch(tb, "[^\n]+\n?") do + assert(i == 0 or string.find(l, p[i])) + i = i+1 + end + assert(p[i] == nil) +end + + +local function f (n) + if n > 0 then return f(n-1) + else coroutine.yield() end +end + +local co = coroutine.create(f) +coroutine.resume(co, 3) +checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) + + +co = coroutine.create(function (x) + local a = 1 + coroutine.yield(debug.getinfo(1, "l")) + coroutine.yield(debug.getinfo(1, "l").currentline) + return a + end) + +local tr = {} +local foo = function (e, l) table.insert(tr, l) end +debug.sethook(co, foo, "l") + +local _, l = coroutine.resume(co, 10) +local x = debug.getinfo(co, 1, "lfLS") +assert(x.currentline == l.currentline and x.activelines[x.currentline]) +assert(type(x.func) == "function") +for i=x.linedefined + 1, x.lastlinedefined do + assert(x.activelines[i]) + x.activelines[i] = nil +end +assert(next(x.activelines) == nil) -- no 'extra' elements +assert(debug.getinfo(co, 2) == nil) +local a,b = debug.getlocal(co, 1, 1) +assert(a == "x" and b == 10) +a,b = debug.getlocal(co, 1, 2) +assert(a == "a" and b == 1) +debug.setlocal(co, 1, 2, "hi") +assert(debug.gethook(co) == foo) +assert(table.getn(tr) == 2 and + tr[1] == l.currentline-1 and tr[2] == l.currentline) + +a,b,c = pcall(coroutine.resume, co) +assert(a and b and c == l.currentline+1) +checktraceback(co, {"yield", "in function <"}) + +a,b = coroutine.resume(co) +assert(a and b == "hi") +assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) +assert(debug.gethook(co) == foo) +assert(debug.gethook() == nil) +checktraceback(co, {}) + + +-- check traceback of suspended (or dead with error) coroutines + +function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end + +co = coroutine.create(function (x) f(x) end) +a, b = coroutine.resume(co, 3) +t = {"'yield'", "'f'", "in function <"} +while coroutine.status(co) == "suspended" do + checktraceback(co, t) + a, b = coroutine.resume(co) + table.insert(t, 2, "'f'") -- one more recursive call to 'f' +end +t[1] = "'error'" +checktraceback(co, t) + + +-- test acessing line numbers of a coroutine from a resume inside +-- a C function (this is a known bug in Lua 5.0) + +local function g(x) + coroutine.yield(x) +end + +local function f (i) + debug.sethook(function () end, "l") + for j=1,1000 do + g(i+j) + end +end + +local co = coroutine.wrap(f) +co(10) +pcall(co) +pcall(co) + + +assert(type(debug.getregistry()) == "table") + + +print"OK" + diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua new file mode 100644 index 0000000..e881211 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/errors.lua @@ -0,0 +1,250 @@ +print("testing errors") + +function doit (s) + local f, msg = loadstring(s) + if f == nil then return msg end + local cond, msg = pcall(f) + return (not cond) and msg +end + + +function checkmessage (prog, msg) + assert(string.find(doit(prog), msg, 1, true)) +end + +function checksyntax (prog, extra, token, line) + local msg = doit(prog) + token = string.gsub(token, "(%p)", "%%%1") + local pt = string.format([[^%%[string ".*"%%]:%d: .- near '%s'$]], + line, token) + assert(string.find(msg, pt)) + assert(string.find(msg, msg, 1, true)) +end + + +-- test error message with no extra info +assert(doit("error('hi', 0)") == 'hi') + +-- test error message with no info +assert(doit("error()") == nil) + + +-- test common errors/errors that crashed in the past +assert(doit("unpack({}, 1, n=2^30)")) +assert(doit("a=math.sin()")) +assert(not doit("tostring(1)") and doit("tostring()")) +assert(doit"tonumber()") +assert(doit"repeat until 1; a") +checksyntax("break label", "", "label", 1) +assert(doit";") +assert(doit"a=1;;") +assert(doit"return;;") +assert(doit"assert(false)") +assert(doit"assert(nil)") +assert(doit"a=math.sin\n(3)") +assert(doit("function a (... , ...) end")) +assert(doit("function a (, ...) end")) + +checksyntax([[ + local a = {4 + +]], "'}' expected (to close '{' at line 1)", "<eof>", 3) + + +-- tests for better error messages + +checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'") +checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)", + "local 'bbbb'") +checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'") +checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'") +assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'")) +checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number") + +aaa = nil +checkmessage("aaa.bbb:ddd(9)", "global 'aaa'") +checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'") +checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'") +checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'") +assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)") + +checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") +checkmessage("aaa={}; x=3/aaa", "global 'aaa'") +checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") +checkmessage("aaa={}; x=-aaa", "global 'aaa'") +assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) +assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) + +checkmessage([[aaa=9 +repeat until 3==3 +local x=math.sin(math.cos(3)) +if math.sin(1) == x then return math.sin(1) end -- tail call +local a,b = 1, { + {x='a'..'b'..'c', y='b', z=x}, + {1,2,3,4,5} or 3+3<=3+3, + 3+1>3+1, + {d = x and aaa[x or y]}} +]], "global 'aaa'") + +checkmessage([[ +local x,y = {},1 +if math.sin(1) == 0 then return 3 end -- return +x.a()]], "field 'a'") + +checkmessage([[ +prefix = nil +insert = nil +while 1 do + local a + if nil then break end + insert(prefix, a) +end]], "global 'insert'") + +checkmessage([[ -- tail call + return math.sin("a") +]], "'sin'") + +checkmessage([[collectgarbage("nooption")]], "invalid option") + +checkmessage([[x = print .. "a"]], "concatenate") + +checkmessage("getmetatable(io.stdin).__gc()", "no value") + +print'+' + + +-- testing line error + +function lineerror (s) + local err,msg = pcall(loadstring(s)) + local line = string.match(msg, ":(%d+):") + return line and line+0 +end + +assert(lineerror"local a\n for i=1,'a' do \n print(i) \n end" == 2) +assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" == 3) +assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" == 4) +assert(lineerror"function a.x.y ()\na=a+1\nend" == 1) + +local p = [[ +function g() f() end +function f(x) error('a', X) end +g() +]] +X=3;assert(lineerror(p) == 3) +X=0;assert(lineerror(p) == nil) +X=1;assert(lineerror(p) == 2) +X=2;assert(lineerror(p) == 1) + +lineerror = nil + +C = 0 +local l = debug.getinfo(1, "l").currentline; function y () C=C+1; y() end + +local function checkstackmessage (m) + return (string.find(m, "^.-:%d+: stack overflow")) +end +assert(checkstackmessage(doit('y()'))) +assert(checkstackmessage(doit('y()'))) +assert(checkstackmessage(doit('y()'))) +-- teste de linhas em erro +C = 0 +local l1 +local function g() + l1 = debug.getinfo(1, "l").currentline; y() +end +local _, stackmsg = xpcall(g, debug.traceback) +local stack = {} +for line in string.gmatch(stackmsg, "[^\n]*") do + local curr = string.match(line, ":(%d+):") + if curr then table.insert(stack, tonumber(curr)) end +end +local i=1 +while stack[i] ~= l1 do + assert(stack[i] == l) + i = i+1 +end +assert(i > 15) + + +-- error in error handling +local res, msg = xpcall(error, error) +assert(not res and type(msg) == 'string') + +local function f (x) + if x==0 then error('a\n') + else + local aux = function () return f(x-1) end + local a,b = xpcall(aux, aux) + return a,b + end +end +f(3) + +-- non string messages +function f() error{msg='x'} end +res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) +assert(msg.msg == 'xy') + +print('+') +checksyntax("syntax error", "", "error", 1) +checksyntax("1.000", "", "1.000", 1) +checksyntax("[[a]]", "", "[[a]]", 1) +checksyntax("'aa'", "", "'aa'", 1) + +-- test 255 as first char in a chunk +checksyntax("\255a = 1", "", "\255", 1) + +doit('I = loadstring("a=9+"); a=3') +assert(a==3 and I == nil) +print('+') + +lim = 1000 +if rawget(_G, "_soft") then lim = 100 end +for i=1,lim do + doit('a = ') + doit('a = 4+nil') +end + + +-- testing syntax limits +local function testrep (init, rep) + local s = "local a; "..init .. string.rep(rep, 400) + local a,b = loadstring(s) + assert(not a and string.find(b, "syntax levels")) +end +testrep("a=", "{") +testrep("a=", "(") +testrep("", "a(") +testrep("", "do ") +testrep("", "while a do ") +testrep("", "if a then else ") +testrep("", "function foo () ") +testrep("a=", "a..") +testrep("a=", "a^") + + +-- testing other limits +-- upvalues +local s = "function foo ()\n local " +for j = 1,70 do + s = s.."a"..j..", " +end +s = s.."b\n" +for j = 1,70 do + s = s.."function foo"..j.." ()\n a"..j.."=3\n" +end +local a,b = loadstring(s) +assert(string.find(b, "line 3")) + +-- local variables +s = "\nfunction foo ()\n local " +for j = 1,300 do + s = s.."a"..j..", " +end +s = s.."b\n" +local a,b = loadstring(s) +assert(string.find(b, "line 2")) + + +print('OK') diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.c b/test/PUC-Lua-5.1-tests/etc/ltests.c new file mode 100644 index 0000000..be949e5 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/etc/ltests.c @@ -0,0 +1,1147 @@ +/* +** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp $ +** Internal Module for Debugging of the Lua Implementation +** See Copyright Notice in lua.h +*/ + + +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define ltests_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lauxlib.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lualib.h" + + + +/* +** The whole module only makes sense with LUA_DEBUG on +*/ +#if defined(LUA_DEBUG) + + +int Trick = 0; + + +static lua_State *lua_state = NULL; + +int islocked = 0; + + +#define obj_at(L,k) (L->ci->base+(k) - 1) + + +static void setnameval (lua_State *L, const char *name, int val) { + lua_pushstring(L, name); + lua_pushinteger(L, val); + lua_settable(L, -3); +} + + +/* +** {====================================================================== +** Controlled version for realloc. +** ======================================================================= +*/ + +#define MARK 0x55 /* 01010101 (a nice pattern) */ + +#ifndef EXTERNMEMCHECK +/* full memory check */ +#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ +#define MARKSIZE 16 /* size of marks after each block */ +#define blockhead(b) (cast(char *, b) - HEADER) +#define setsize(newblock, size) (*cast(size_t *, newblock) = size) +#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) +#define fillmem(mem,size) memset(mem, -MARK, size) +#else +/* external memory check: don't do it twice */ +#define HEADER 0 +#define MARKSIZE 0 +#define blockhead(b) (b) +#define setsize(newblock, size) /* empty */ +#define checkblocksize(b,size) (1) +#define fillmem(mem,size) /* empty */ +#endif + + +Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX}; + + +static void *checkblock (void *block, size_t size) { + void *b = blockhead(block); + int i; + for (i=0;i<MARKSIZE;i++) + lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ + return b; +} + + +static void freeblock (Memcontrol *mc, void *block, size_t size) { + if (block) { + lua_assert(checkblocksize(block, size)); + block = checkblock(block, size); + fillmem(block, size+HEADER+MARKSIZE); /* erase block */ + free(block); /* free original block */ + mc->numblocks--; + mc->total -= size; + } +} + + +void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { + Memcontrol *mc = cast(Memcontrol *, ud); + lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); + if (size == 0) { + freeblock(mc, block, oldsize); + return NULL; + } + else if (size > oldsize && mc->total+size-oldsize > mc->memlimit) + return NULL; /* to test memory allocation errors */ + else { + void *newblock; + int i; + size_t realsize = HEADER+size+MARKSIZE; + size_t commonsize = (oldsize < size) ? oldsize : size; + if (realsize < size) return NULL; /* overflow! */ + newblock = malloc(realsize); /* alloc a new block */ + if (newblock == NULL) return NULL; + if (block) { + memcpy(cast(char *, newblock)+HEADER, block, commonsize); + freeblock(mc, block, oldsize); /* erase (and check) old copy */ + } + /* initialize new part of the block with something `weird' */ + fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); + mc->total += size; + if (mc->total > mc->maxmem) + mc->maxmem = mc->total; + mc->numblocks++; + setsize(newblock, size); + for (i=0;i<MARKSIZE;i++) + *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); + return cast(char *, newblock)+HEADER; + } +} + + +/* }====================================================================== */ + + + +/* +** {====================================================== +** Functions to check memory consistency +** ======================================================= +*/ + +static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { + if (isdead(g,t)) return 0; + if (g->gcstate == GCSpropagate) + return !isblack(f) || !iswhite(t); + else if (g->gcstate == GCSfinalize) + return iswhite(f); + else + return 1; +} + + +static void printobj (global_State *g, GCObject *o) { + int i = 0; + GCObject *p; + for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++; + if (p == NULL) i = -1; + printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o, + isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked); +} + + +static int testobjref (global_State *g, GCObject *f, GCObject *t) { + int r = testobjref1(g,f,t); + if (!r) { + printf("%d(%02X) - ", g->gcstate, g->currentwhite); + printobj(g, f); + printf("\t-> "); + printobj(g, t); + printf("\n"); + } + return r; +} + +#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) + +#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \ + ((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t)))) + + + +static void checktable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + GCObject *hgc = obj2gco(h); + if (h->metatable) + checkobjref(g, hgc, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + } + i = h->sizearray; + while (i--) + checkvalref(g, hgc, &h->array[i]); + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n))) { + lua_assert(!ttisnil(gkey(n))); + checkvalref(g, hgc, gkey(n)); + checkvalref(g, hgc, gval(n)); + } + } +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void checkproto (global_State *g, Proto *f) { + int i; + GCObject *fgc = obj2gco(f); + if (f->source) checkobjref(g, fgc, f->source); + for (i=0; i<f->sizek; i++) { + if (ttisstring(f->k+i)) + checkobjref(g, fgc, rawtsvalue(f->k+i)); + } + for (i=0; i<f->sizeupvalues; i++) { + if (f->upvalues[i]) + checkobjref(g, fgc, f->upvalues[i]); + } + for (i=0; i<f->sizep; i++) { + if (f->p[i]) + checkobjref(g, fgc, f->p[i]); + } + for (i=0; i<f->sizelocvars; i++) { + if (f->locvars[i].varname) + checkobjref(g, fgc, f->locvars[i].varname); + } +} + + + +static void checkclosure (global_State *g, Closure *cl) { + GCObject *clgc = obj2gco(cl); + checkobjref(g, clgc, cl->l.env); + if (cl->c.isC) { + int i; + for (i=0; i<cl->c.nupvalues; i++) + checkvalref(g, clgc, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + checkobjref(g, clgc, cl->l.p); + for (i=0; i<cl->l.nupvalues; i++) { + if (cl->l.upvals[i]) { + lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL); + checkobjref(g, clgc, cl->l.upvals[i]); + } + } + } +} + + +static void checkstack (global_State *g, lua_State *L1) { + StkId o; + CallInfo *ci; + GCObject *uvo; + lua_assert(!isdead(g, obj2gco(L1))); + for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) { + UpVal *uv = gco2uv(uvo); + lua_assert(uv->v != &uv->u.value); /* must be open */ + lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ + } + checkliveness(g, gt(L1)); + if (L1->base_ci) { + for (ci = L1->base_ci; ci <= L1->ci; ci++) { + lua_assert(ci->top <= L1->stack_last); + lua_assert(lua_checkpc(L1, ci)); + } + } + else lua_assert(L1->size_ci == 0); + if (L1->stack) { + for (o = L1->stack; o < L1->top; o++) + checkliveness(g, o); + } + else lua_assert(L1->stacksize == 0); +} + + +static void checkobject (global_State *g, GCObject *o) { + if (isdead(g, o)) +/* lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/ +{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep)) +printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked); +} + else { + if (g->gcstate == GCSfinalize) + lua_assert(iswhite(o)); + switch (o->gch.tt) { + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + lua_assert(uv->v == &uv->u.value); /* must be closed */ + lua_assert(!isgray(o)); /* closed upvalues are never gray */ + checkvalref(g, o, uv->v); + break; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + if (mt) checkobjref(g, o, mt); + break; + } + case LUA_TTABLE: { + checktable(g, gco2h(o)); + break; + } + case LUA_TTHREAD: { + checkstack(g, gco2th(o)); + break; + } + case LUA_TFUNCTION: { + checkclosure(g, gco2cl(o)); + break; + } + case LUA_TPROTO: { + checkproto(g, gco2p(o)); + break; + } + default: lua_assert(0); + } + } +} + + +int lua_checkpc (lua_State *L, pCallInfo ci) { + if (ci == L->base_ci || !f_isLua(ci)) return 1; + else { + Proto *p = ci_func(ci)->l.p; + if (ci < L->ci) + return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; + else + return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; + } +} + + +int lua_checkmemory (lua_State *L) { + global_State *g = G(L); + GCObject *o; + UpVal *uv; + checkstack(g, g->mainthread); + for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next) + checkobject(g, o); + for (o = o->gch.next; o != NULL; o = o->gch.next) { + lua_assert(o->gch.tt == LUA_TUSERDATA); + checkobject(g, o); + } + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + lua_assert(uv->v != &uv->u.value); /* must be open */ + lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */ + checkvalref(g, obj2gco(uv), uv->v); + } + return 0; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Disassembler +** ======================================================= +*/ + + +static char *buildop (Proto *p, int pc, char *buff) { + Instruction i = p->code[pc]; + OpCode o = GET_OPCODE(i); + const char *name = luaP_opnames[o]; + int line = getline(p, pc); + sprintf(buff, "(%4d) %4d - ", line, pc); + switch (getOpMode(o)) { + case iABC: + sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, + GETARG_A(i), GETARG_B(i), GETARG_C(i)); + break; + case iABx: + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); + break; + case iAsBx: + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); + break; + } + return buff; +} + + +#if 0 +void luaI_printcode (Proto *pt, int size) { + int pc; + for (pc=0; pc<size; pc++) { + char buff[100]; + printf("%s\n", buildop(pt, pc, buff)); + } + printf("-------\n"); +} +#endif + + +static int listcode (lua_State *L) { + int pc; + Proto *p; + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(obj_at(L, 1))->l.p; + lua_newtable(L); + setnameval(L, "maxstack", p->maxstacksize); + setnameval(L, "numparams", p->numparams); + for (pc=0; pc<p->sizecode; pc++) { + char buff[100]; + lua_pushinteger(L, pc+1); + lua_pushstring(L, buildop(p, pc, buff)); + lua_settable(L, -3); + } + return 1; +} + + +static int listk (lua_State *L) { + Proto *p; + int i; + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(obj_at(L, 1))->l.p; + lua_createtable(L, p->sizek, 0); + for (i=0; i<p->sizek; i++) { + luaA_pushobject(L, p->k+i); + lua_rawseti(L, -2, i+1); + } + return 1; +} + + +static int listlocals (lua_State *L) { + Proto *p; + int pc = luaL_checkint(L, 2) - 1; + int i = 0; + const char *name; + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(obj_at(L, 1))->l.p; + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) + lua_pushstring(L, name); + return i-1; +} + +/* }====================================================== */ + + + + +static int get_limits (lua_State *L) { + lua_createtable(L, 0, 5); + setnameval(L, "BITS_INT", LUAI_BITSINT); + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); + setnameval(L, "MAXVARS", LUAI_MAXVARS); + setnameval(L, "MAXSTACK", MAXSTACK); + setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES); + setnameval(L, "NUM_OPCODES", NUM_OPCODES); + return 1; +} + + +static int mem_query (lua_State *L) { + if (lua_isnone(L, 1)) { + lua_pushinteger(L, memcontrol.total); + lua_pushinteger(L, memcontrol.numblocks); + lua_pushinteger(L, memcontrol.maxmem); + return 3; + } + else { + memcontrol.memlimit = luaL_checkint(L, 1); + return 0; + } +} + + +static int settrick (lua_State *L) { + Trick = lua_tointeger(L, 1); + return 0; +} + + +/*static int set_gcstate (lua_State *L) { + static const char *const state[] = {"propagate", "sweep", "finalize"}; + return 0; +}*/ + + +static int get_gccolor (lua_State *L) { + TValue *o; + luaL_checkany(L, 1); + o = obj_at(L, 1); + if (!iscollectable(o)) + lua_pushstring(L, "no collectable"); + else + lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : + isblack(gcvalue(o)) ? "black" : "grey"); + return 1; +} + + +static int gcstate (lua_State *L) { + switch(G(L)->gcstate) { + case GCSpropagate: lua_pushstring(L, "propagate"); break; + case GCSsweepstring: lua_pushstring(L, "sweep strings"); break; + case GCSsweep: lua_pushstring(L, "sweep"); break; + case GCSfinalize: lua_pushstring(L, "finalize"); break; + } + return 1; +} + + +static int hash_query (lua_State *L) { + if (lua_isnone(L, 2)) { + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); + lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash); + } + else { + TValue *o = obj_at(L, 1); + Table *t; + luaL_checktype(L, 2, LUA_TTABLE); + t = hvalue(obj_at(L, 2)); + lua_pushinteger(L, luaH_mainposition(t, o) - t->node); + } + return 1; +} + + +static int stacklevel (lua_State *L) { + unsigned long a = 0; + lua_pushinteger(L, (L->top - L->stack)); + lua_pushinteger(L, (L->stack_last - L->stack)); + lua_pushinteger(L, (L->ci - L->base_ci)); + lua_pushinteger(L, (L->end_ci - L->base_ci)); + lua_pushinteger(L, (unsigned long)&a); + return 5; +} + + +static int table_query (lua_State *L) { + const Table *t; + int i = luaL_optint(L, 2, -1); + luaL_checktype(L, 1, LUA_TTABLE); + t = hvalue(obj_at(L, 1)); + if (i == -1) { + lua_pushinteger(L, t->sizearray); + lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t)); + lua_pushinteger(L, t->lastfree - t->node); + } + else if (i < t->sizearray) { + lua_pushinteger(L, i); + luaA_pushobject(L, &t->array[i]); + lua_pushnil(L); + } + else if ((i -= t->sizearray) < sizenode(t)) { + if (!ttisnil(gval(gnode(t, i))) || + ttisnil(gkey(gnode(t, i))) || + ttisnumber(gkey(gnode(t, i)))) { + luaA_pushobject(L, key2tval(gnode(t, i))); + } + else + lua_pushliteral(L, "<undef>"); + luaA_pushobject(L, gval(gnode(t, i))); + if (gnext(&t->node[i])) + lua_pushinteger(L, gnext(&t->node[i]) - t->node); + else + lua_pushnil(L); + } + return 3; +} + + +static int string_query (lua_State *L) { + stringtable *tb = &G(L)->strt; + int s = luaL_optint(L, 2, 0) - 1; + if (s==-1) { + lua_pushinteger(L ,tb->nuse); + lua_pushinteger(L ,tb->size); + return 2; + } + else if (s < tb->size) { + GCObject *ts; + int n = 0; + for (ts = tb->hash[s]; ts; ts = ts->gch.next) { + setsvalue2s(L, L->top, gco2ts(ts)); + incr_top(L); + n++; + } + return n; + } + return 0; +} + + +static int tref (lua_State *L) { + int level = lua_gettop(L); + int lock = luaL_optint(L, 2, 1); + luaL_checkany(L, 1); + lua_pushvalue(L, 1); + lua_pushinteger(L, lua_ref(L, lock)); + lua_assert(lua_gettop(L) == level+1); /* +1 for result */ + return 1; +} + +static int getref (lua_State *L) { + int level = lua_gettop(L); + lua_getref(L, luaL_checkint(L, 1)); + lua_assert(lua_gettop(L) == level+1); + return 1; +} + +static int unref (lua_State *L) { + int level = lua_gettop(L); + lua_unref(L, luaL_checkint(L, 1)); + lua_assert(lua_gettop(L) == level); + return 0; +} + + +static int upvalue (lua_State *L) { + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_isnone(L, 3)) { + const char *name = lua_getupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + return 2; + } + else { + const char *name = lua_setupvalue(L, 1, n); + lua_pushstring(L, name); + return 1; + } +} + + +static int newuserdata (lua_State *L) { + size_t size = luaL_checkint(L, 1); + char *p = cast(char *, lua_newuserdata(L, size)); + while (size--) *p++ = '\0'; + return 1; +} + + +static int pushuserdata (lua_State *L) { + lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); + return 1; +} + + +static int udataval (lua_State *L) { + lua_pushinteger(L, cast(long, lua_touserdata(L, 1))); + return 1; +} + + +static int doonnewstack (lua_State *L) { + lua_State *L1 = lua_newthread(L); + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + int status = luaL_loadbuffer(L1, s, l, s); + if (status == 0) + status = lua_pcall(L1, 0, 0, 0); + lua_pushinteger(L, status); + return 1; +} + + +static int s2d (lua_State *L) { + lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); + return 1; +} + + +static int d2s (lua_State *L) { + double d = luaL_checknumber(L, 1); + lua_pushlstring(L, cast(char *, &d), sizeof(d)); + return 1; +} + + +static int num2int (lua_State *L) { + lua_pushinteger(L, lua_tointeger(L, 1)); + return 1; +} + + +static int newstate (lua_State *L) { + void *ud; + lua_Alloc f = lua_getallocf(L, &ud); + lua_State *L1 = lua_newstate(f, ud); + if (L1) + lua_pushinteger(L, (unsigned long)L1); + else + lua_pushnil(L); + return 1; +} + + +static int loadlib (lua_State *L) { + static const luaL_Reg libs[] = { + {"baselibopen", luaopen_base}, + {"dblibopen", luaopen_debug}, + {"iolibopen", luaopen_io}, + {"mathlibopen", luaopen_math}, + {"strlibopen", luaopen_string}, + {"tablibopen", luaopen_table}, + {"packageopen", luaopen_package}, + {NULL, NULL} + }; + lua_State *L1 = cast(lua_State *, + cast(unsigned long, luaL_checknumber(L, 1))); + lua_pushvalue(L1, LUA_GLOBALSINDEX); + luaL_register(L1, NULL, libs); + return 0; +} + +static int closestate (lua_State *L) { + lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1))); + lua_close(L1); + return 0; +} + +static int doremote (lua_State *L) { + lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); + size_t lcode; + const char *code = luaL_checklstring(L, 2, &lcode); + int status; + lua_settop(L1, 0); + status = luaL_loadbuffer(L1, code, lcode, code); + if (status == 0) + status = lua_pcall(L1, 0, LUA_MULTRET, 0); + if (status != 0) { + lua_pushnil(L); + lua_pushinteger(L, status); + lua_pushstring(L, lua_tostring(L1, -1)); + return 3; + } + else { + int i = 0; + while (!lua_isnone(L1, ++i)) + lua_pushstring(L, lua_tostring(L1, i)); + lua_pop(L1, i-1); + return i-1; + } +} + + +static int log2_aux (lua_State *L) { + lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1))); + return 1; +} + +static int int2fb_aux (lua_State *L) { + int b = luaO_int2fb(luaL_checkint(L, 1)); + lua_pushinteger(L, b); + lua_pushinteger(L, luaO_fb2int(b)); + return 2; +} + + + +/* +** {====================================================== +** function to test the API with C. It interprets a kind of assembler +** language with calls to the API, so the test can be driven by Lua code +** ======================================================= +*/ + +static const char *const delimits = " \t\n,;"; + +static void skip (const char **pc) { + while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; +} + +static int getnum_aux (lua_State *L, const char **pc) { + int res = 0; + int sig = 1; + skip(pc); + if (**pc == '.') { + res = cast_int(lua_tonumber(L, -1)); + lua_pop(L, 1); + (*pc)++; + return res; + } + else if (**pc == '-') { + sig = -1; + (*pc)++; + } + while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0'; + return sig*res; +} + +static const char *getname_aux (char *buff, const char **pc) { + int i = 0; + skip(pc); + while (**pc != '\0' && !strchr(delimits, **pc)) + buff[i++] = *(*pc)++; + buff[i] = '\0'; + return buff; +} + + +static int getindex_aux (lua_State *L, const char **pc) { + skip(pc); + switch (*(*pc)++) { + case 'R': return LUA_REGISTRYINDEX; + case 'G': return LUA_GLOBALSINDEX; + case 'E': return LUA_ENVIRONINDEX; + case 'U': return lua_upvalueindex(getnum_aux(L, pc)); + default: (*pc)--; return getnum_aux(L, pc); + } +} + +#define EQ(s1) (strcmp(s1, inst) == 0) + +#define getnum (getnum_aux(L, &pc)) +#define getname (getname_aux(buff, &pc)) +#define getindex (getindex_aux(L, &pc)) + + +static int testC (lua_State *L) { + char buff[30]; + lua_State *L1; + const char *pc; + if (lua_isnumber(L, 1)) { + L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); + pc = luaL_checkstring(L, 2); + } + else { + L1 = L; + pc = luaL_checkstring(L, 1); + } + for (;;) { + const char *inst = getname; + if EQ("") return 0; + else if EQ("isnumber") { + lua_pushinteger(L1, lua_isnumber(L1, getindex)); + } + else if EQ("isstring") { + lua_pushinteger(L1, lua_isstring(L1, getindex)); + } + else if EQ("istable") { + lua_pushinteger(L1, lua_istable(L1, getindex)); + } + else if EQ("iscfunction") { + lua_pushinteger(L1, lua_iscfunction(L1, getindex)); + } + else if EQ("isfunction") { + lua_pushinteger(L1, lua_isfunction(L1, getindex)); + } + else if EQ("isuserdata") { + lua_pushinteger(L1, lua_isuserdata(L1, getindex)); + } + else if EQ("isudataval") { + lua_pushinteger(L1, lua_islightuserdata(L1, getindex)); + } + else if EQ("isnil") { + lua_pushinteger(L1, lua_isnil(L1, getindex)); + } + else if EQ("isnull") { + lua_pushinteger(L1, lua_isnone(L1, getindex)); + } + else if EQ("tonumber") { + lua_pushnumber(L1, lua_tonumber(L1, getindex)); + } + else if EQ("tostring") { + const char *s = lua_tostring(L1, getindex); + lua_pushstring(L1, s); + } + else if EQ("objsize") { + lua_pushinteger(L1, lua_objlen(L1, getindex)); + } + else if EQ("tocfunction") { + lua_pushcfunction(L1, lua_tocfunction(L1, getindex)); + } + else if EQ("return") { + return getnum; + } + else if EQ("gettop") { + lua_pushinteger(L1, lua_gettop(L1)); + } + else if EQ("settop") { + lua_settop(L1, getnum); + } + else if EQ("pop") { + lua_pop(L1, getnum); + } + else if EQ("pushnum") { + lua_pushinteger(L1, getnum); + } + else if EQ("pushstring") { + lua_pushstring(L1, getname); + } + else if EQ("pushnil") { + lua_pushnil(L1); + } + else if EQ("pushbool") { + lua_pushboolean(L1, getnum); + } + else if EQ("newuserdata") { + lua_newuserdata(L1, getnum); + } + else if EQ("tobool") { + lua_pushinteger(L1, lua_toboolean(L1, getindex)); + } + else if EQ("pushvalue") { + lua_pushvalue(L1, getindex); + } + else if EQ("pushcclosure") { + lua_pushcclosure(L1, testC, getnum); + } + else if EQ("remove") { + lua_remove(L1, getnum); + } + else if EQ("insert") { + lua_insert(L1, getnum); + } + else if EQ("replace") { + lua_replace(L1, getindex); + } + else if EQ("gettable") { + lua_gettable(L1, getindex); + } + else if EQ("settable") { + lua_settable(L1, getindex); + } + else if EQ("next") { + lua_next(L1, -2); + } + else if EQ("concat") { + lua_concat(L1, getnum); + } + else if EQ("lessthan") { + int a = getindex; + lua_pushboolean(L1, lua_lessthan(L1, a, getindex)); + } + else if EQ("equal") { + int a = getindex; + lua_pushboolean(L1, lua_equal(L1, a, getindex)); + } + else if EQ("rawcall") { + int narg = getnum; + int nres = getnum; + lua_call(L1, narg, nres); + } + else if EQ("call") { + int narg = getnum; + int nres = getnum; + lua_pcall(L1, narg, nres, 0); + } + else if EQ("loadstring") { + size_t sl; + const char *s = luaL_checklstring(L1, getnum, &sl); + luaL_loadbuffer(L1, s, sl, s); + } + else if EQ("loadfile") { + luaL_loadfile(L1, luaL_checkstring(L1, getnum)); + } + else if EQ("setmetatable") { + lua_setmetatable(L1, getindex); + } + else if EQ("getmetatable") { + if (lua_getmetatable(L1, getindex) == 0) + lua_pushnil(L1); + } + else if EQ("type") { + lua_pushstring(L1, luaL_typename(L1, getnum)); + } + else if EQ("getn") { + int i = getindex; + lua_pushinteger(L1, luaL_getn(L1, i)); + } +#ifndef luaL_setn + else if EQ("setn") { + int i = getindex; + int n = cast_int(lua_tonumber(L1, -1)); + luaL_setn(L1, i, n); + lua_pop(L1, 1); + } +#endif + else if EQ("throw") { +#if defined(__cplusplus) +static struct X { int x; } x; + throw x; +#else + luaL_error(L1, "C++"); +#endif + break; + } + else luaL_error(L, "unknown instruction %s", buff); + } + return 0; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** tests for yield inside hooks +** ======================================================= +*/ + +static void yieldf (lua_State *L, lua_Debug *ar) { + lua_yield(L, 0); +} + +static int setyhook (lua_State *L) { + if (lua_isnoneornil(L, 1)) + lua_sethook(L, NULL, 0, 0); /* turn off hooks */ + else { + const char *smask = luaL_checkstring(L, 1); + int count = luaL_optint(L, 2, 0); + int mask = 0; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + lua_sethook(L, yieldf, mask, count); + } + return 0; +} + + +static int coresume (lua_State *L) { + int status; + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + status = lua_resume(co, 0); + if (status != 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + return 1; + } +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** tests auxlib functions +** ======================================================= +*/ + +static int auxgsub (lua_State *L) { + const char *s1 = luaL_checkstring(L, 1); + const char *s2 = luaL_checkstring(L, 2); + const char *s3 = luaL_checkstring(L, 3); + lua_settop(L, 3); + luaL_gsub(L, s1, s2, s3); + lua_assert(lua_gettop(L) == 4); + return 1; +} + + +/* }====================================================== */ + + + +static const struct luaL_Reg tests_funcs[] = { + {"checkmemory", lua_checkmemory}, + {"closestate", closestate}, + {"d2s", d2s}, + {"doonnewstack", doonnewstack}, + {"doremote", doremote}, + {"gccolor", get_gccolor}, + {"gcstate", gcstate}, + {"getref", getref}, + {"gsub", auxgsub}, + {"hash", hash_query}, + {"int2fb", int2fb_aux}, + {"limits", get_limits}, + {"listcode", listcode}, + {"listk", listk}, + {"listlocals", listlocals}, + {"loadlib", loadlib}, + {"log2", log2_aux}, + {"newstate", newstate}, + {"newuserdata", newuserdata}, + {"num2int", num2int}, + {"pushuserdata", pushuserdata}, + {"querystr", string_query}, + {"querytab", table_query}, + {"ref", tref}, + {"resume", coresume}, + {"s2d", s2d}, + {"setyhook", setyhook}, + {"stacklevel", stacklevel}, + {"testC", testC}, + {"totalmem", mem_query}, + {"trick", settrick}, + {"udataval", udataval}, + {"unref", unref}, + {"upvalue", upvalue}, + {NULL, NULL} +}; + + +int luaB_opentests (lua_State *L) { + void *ud; + lua_assert(lua_getallocf(L, &ud) == debug_realloc); + lua_assert(ud == cast(void *, &memcontrol)); + lua_setallocf(L, lua_getallocf(L, NULL), ud); + lua_state = L; /* keep first state to be opened */ + luaL_register(L, "T", tests_funcs); + return 0; +} + + +#undef main +int main (int argc, char *argv[]) { + int ret; + char *limit = getenv("MEMLIMIT"); + if (limit) + memcontrol.memlimit = strtoul(limit, NULL, 10); + ret = l_main(argc, argv); + lua_assert(memcontrol.numblocks == 0); + lua_assert(memcontrol.total == 0); + return ret; +} + +#endif diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.h b/test/PUC-Lua-5.1-tests/etc/ltests.h new file mode 100644 index 0000000..e570212 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/etc/ltests.h @@ -0,0 +1,92 @@ +/* +** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp $ +** Internal Header for Debugging of the Lua Implementation +** See Copyright Notice in lua.h +*/ + +#ifndef ltests_h +#define ltests_h + + +#include <stdlib.h> + + +#define LUA_DEBUG + +#undef NDEBUG +#include <assert.h> +#define lua_assert(c) assert(c) + + +/* to avoid warnings, and to make sure value is really unused */ +#define UNUSED(x) (x=0, (void)(x)) + + +/* memory allocator control variables */ +typedef struct Memcontrol { + unsigned long numblocks; + unsigned long total; + unsigned long maxmem; + unsigned long memlimit; +} Memcontrol; + +LUAI_DATA Memcontrol memcontrol; + + +/* +** generic variable for debug tricks +*/ +LUAI_DATA int Trick; + + +void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize); + +#ifdef lua_c +#define luaL_newstate() lua_newstate(debug_realloc, &memcontrol) +#endif + + +typedef struct CallInfo *pCallInfo; + +int lua_checkmemory (lua_State *L); +int lua_checkpc (lua_State *L, pCallInfo ci); + + +/* test for lock/unlock */ +#undef luai_userstateopen +#undef luai_userstatethread +#undef lua_lock +#undef lua_unlock +#undef LUAI_EXTRASPACE + +struct L_EXTRA { int lock; int *plock; }; +#define LUAI_EXTRASPACE sizeof(struct L_EXTRA) +#define getlock(l) (cast(struct L_EXTRA *, l) - 1) +#define luai_userstateopen(l) \ + (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) +#define luai_userstatethread(l,l1) (getlock(l1)->plock = getlock(l)->plock) +#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) +#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) + + +int luaB_opentests (lua_State *L); + +#ifdef lua_c +#define luaL_openlibs(L) { (luaL_openlibs)(L); luaB_opentests(L); } +#endif + + + +/* real main will be defined at `ltests.c' */ +int l_main (int argc, char *argv[]); +#define main l_main + + + +/* change some sizes to give some bugs a chance */ + +#undef LUAL_BUFFERSIZE +#define LUAL_BUFFERSIZE 27 +#define MINSTRTABSIZE 2 + +#endif diff --git a/test/PUC-Lua-5.1-tests/events.lua b/test/PUC-Lua-5.1-tests/events.lua new file mode 100644 index 0000000..5234b00 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/events.lua @@ -0,0 +1,360 @@ +print('testing metatables') + +X = 20; B = 30 + +setfenv(1, setmetatable({}, {__index=_G})) + +collectgarbage() + +X = X+10 +assert(X == 30 and _G.X == 20) +B = false +assert(B == false) +B = nil +assert(B == 30) + +assert(getmetatable{} == nil) +assert(getmetatable(4) == nil) +assert(getmetatable(nil) == nil) +a={}; setmetatable(a, {__metatable = "xuxu", + __tostring=function(x) return x.name end}) +assert(getmetatable(a) == "xuxu") +assert(tostring(a) == nil) +-- cannot change a protected metatable +assert(pcall(setmetatable, a, {}) == false) +a.name = "gororoba" +assert(tostring(a) == "gororoba") + +local a, t = {10,20,30; x="10", y="20"}, {} +assert(setmetatable(a,t) == a) +assert(getmetatable(a) == t) +assert(setmetatable(a,nil) == a) +assert(getmetatable(a) == nil) +assert(setmetatable(a,t) == a) + + +function f (t, i, e) + assert(not e) + local p = rawget(t, "parent") + return (p and p[i]+3), "dummy return" +end + +t.__index = f + +a.parent = {z=25, x=12, [4] = 24} +assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") + +collectgarbage() + +a = setmetatable({}, t) +function f(t, i, v) rawset(t, i, v-3) end +t.__newindex = f +a[1] = 30; a.x = "101"; a[5] = 200 +assert(a[1] == 27 and a.x == 98 and a[5] == 197) + + +local c = {} +a = setmetatable({}, t) +t.__newindex = c +a[1] = 10; a[2] = 20; a[3] = 90 +assert(c[1] == 10 and c[2] == 20 and c[3] == 90) + + +do + local a; + a = setmetatable({}, {__index = setmetatable({}, + {__index = setmetatable({}, + {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) + a[0] = 20 + for i=0,10 do + assert(a[i*3] == 20 + i*4) + end +end + + +do -- newindex + local foi + local a = {} + for i=1,10 do a[i] = 0; a['a'..i] = 0; end + setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) + foi = false; a[1]=0; assert(not foi) + foi = false; a['a1']=0; assert(not foi) + foi = false; a['a11']=0; assert(foi) + foi = false; a[11]=0; assert(foi) + foi = false; a[1]=nil; assert(not foi) + foi = false; a[1]=nil; assert(foi) +end + + +function f (t, ...) return t, {...} end +t.__call = f + +do + local x,y = a(unpack{'a', 1}) + assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) + x,y = a() + assert(x==a and y[1]==nil) +end + + +local b = setmetatable({}, t) +setmetatable(b,t) + +function f(op) + return function (...) cap = {[0] = op, ...} ; return (...) end +end +t.__add = f("add") +t.__sub = f("sub") +t.__mul = f("mul") +t.__div = f("div") +t.__mod = f("mod") +t.__unm = f("unm") +t.__pow = f("pow") + +assert(b+5 == b) +assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) +assert(b+'5' == b) +assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) +assert(5+b == 5) +assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) +assert('5'+b == '5') +assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) +b=b-3; assert(getmetatable(b) == t) +assert(5-a == 5) +assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) +assert('5'-a == '5') +assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) +assert(a*a == a) +assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) +assert(a/0 == a) +assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) +assert(a%2 == a) +assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) +assert(-a == a) +assert(cap[0] == "unm" and cap[1] == a) +assert(a^4 == a) +assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) +assert(a^'4' == a) +assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) +assert(4^a == 4) +assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) +assert('4'^a == '4') +assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) + + +t = {} +t.__lt = function (a,b,c) + collectgarbage() + assert(c == nil) + if type(a) == 'table' then a = a.x end + if type(b) == 'table' then b = b.x end + return a<b, "dummy" +end + +function Op(x) return setmetatable({x=x}, t) end + +local function test () + assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) + assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) + assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) + assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) + assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) + assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) + assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) + assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) +end + +test() + +t.__le = function (a,b,c) + assert(c == nil) + if type(a) == 'table' then a = a.x end + if type(b) == 'table' then b = b.x end + return a<=b, "dummy" +end + +test() -- retest comparisons, now using both `lt' and `le' + + +-- test `partial order' + +local function Set(x) + local y = {} + for _,k in pairs(x) do y[k] = 1 end + return setmetatable(y, t) +end + +t.__lt = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + b[k] = nil + end + return next(b) ~= nil +end + +t.__le = nil + +assert(Set{1,2,3} < Set{1,2,3,4}) +assert(not(Set{1,2,3,4} < Set{1,2,3,4})) +assert((Set{1,2,3,4} <= Set{1,2,3,4})) +assert((Set{1,2,3,4} >= Set{1,2,3,4})) +assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) + +t.__le = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + end + return true +end + +assert(not (Set{1,3} <= Set{3,5})) -- now its OK! +assert(not(Set{1,3} <= Set{3,5})) +assert(not(Set{1,3} >= Set{3,5})) + +t.__eq = function (a,b) + for k in pairs(a) do + if not b[k] then return false end + b[k] = nil + end + return next(b) == nil +end + +local s = Set{1,3,5} +assert(s == Set{3,5,1}) +assert(not rawequal(s, Set{3,5,1})) +assert(rawequal(s, s)) +assert(Set{1,3,5,1} == Set{3,5,1}) +assert(Set{1,3,5} ~= Set{3,5,1,6}) +t[Set{1,3,5}] = 1 +assert(t[Set{1,3,5}] == nil) -- `__eq' is not valid for table accesses + + +t.__concat = function (a,b,c) + assert(c == nil) + if type(a) == 'table' then a = a.val end + if type(b) == 'table' then b = b.val end + if A then return a..b + else + return setmetatable({val=a..b}, t) + end +end + +c = {val="c"}; setmetatable(c, t) +d = {val="d"}; setmetatable(d, t) + +A = true +assert(c..d == 'cd') +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") + +A = false +x = c..d +assert(getmetatable(x) == t and x.val == 'cd') +x = 0 .."a".."b"..c..d.."e".."f".."g" +assert(x.val == "0abcdefg") + + +-- test comparison compatibilities +local t1, t2, c, d +t1 = {}; c = {}; setmetatable(c, t1) +d = {} +t1.__eq = function () return true end +t1.__lt = function () return true end +assert(c ~= d and not pcall(function () return c < d end)) +setmetatable(d, t1) +assert(c == d and c < d and not(d <= c)) +t2 = {} +t2.__eq = t1.__eq +t2.__lt = t1.__lt +setmetatable(d, t2) +assert(c == d and c < d and not(d <= c)) + + + +-- test for several levels of calls +local i +local tt = { + __call = function (t, ...) + i = i+1 + if t.f then return t.f(...) + else return {...} + end + end +} + +local a = setmetatable({}, tt) +local b = setmetatable({f=a}, tt) +local c = setmetatable({f=b}, tt) + +i = 0 +x = c(3,4,5) +assert(i == 3 and x[1] == 3 and x[3] == 5) + + +assert(_G.X == 20) +assert(_G == getfenv(0)) + +print'+' + +local _g = _G +setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end})) + +-- testing proxies +assert(getmetatable(newproxy()) == nil) +assert(getmetatable(newproxy(false)) == nil) + +local u = newproxy(true) + +getmetatable(u).__newindex = function (u,k,v) + getmetatable(u)[k] = v +end + +getmetatable(u).__index = function (u,k) + return getmetatable(u)[k] +end + +for i=1,10 do u[i] = i end +for i=1,10 do assert(u[i] == i) end + +local k = newproxy(u) +assert(getmetatable(k) == getmetatable(u)) + + +a = {} +rawset(a, "x", 1, 2, 3) +assert(a.x == 1 and rawget(a, "x", 3) == 1) + +print '+' + +-- testing metatables for basic types +mt = {} +debug.setmetatable(10, mt) +assert(getmetatable(-2) == mt) +mt.__index = function (a,b) return a+b end +assert((10)[3] == 13) +assert((10)["3"] == 13) +debug.setmetatable(23, nil) +assert(getmetatable(-2) == nil) + +debug.setmetatable(true, mt) +assert(getmetatable(false) == mt) +mt.__index = function (a,b) return a or b end +assert((true)[false] == true) +assert((false)[false] == false) +debug.setmetatable(false, nil) +assert(getmetatable(true) == nil) + +debug.setmetatable(nil, mt) +assert(getmetatable(nil) == mt) +mt.__add = function (a,b) return (a or 0) + (b or 0) end +assert(10 + nil == 10) +assert(nil + 23 == 23) +assert(nil + nil == 0) +debug.setmetatable(nil, nil) +assert(getmetatable(nil) == nil) + +debug.setmetatable(nil, {}) + + +print 'OK' + +return 12 diff --git a/test/PUC-Lua-5.1-tests/files.lua b/test/PUC-Lua-5.1-tests/files.lua new file mode 100644 index 0000000..903488c --- /dev/null +++ b/test/PUC-Lua-5.1-tests/files.lua @@ -0,0 +1,324 @@ + +print('testing i/o') + +assert(io.input(io.stdin) == io.stdin) +assert(io.output(io.stdout) == io.stdout) + + +assert(type(io.input()) == "userdata" and io.type(io.output()) == "file") +assert(io.type(8) == nil) +local a = {}; setmetatable(a, {}) +assert(io.type(a) == nil) + +local a,b,c = io.open('xuxu_nao_existe') +assert(not a and type(b) == "string" and type(c) == "number") + +a,b,c = io.open('/a/b/c/d', 'w') +assert(not a and type(b) == "string" and type(c) == "number") + +local file = os.tmpname() +local otherfile = os.tmpname() + +assert(os.setlocale('C', 'all')) + +io.input(io.stdin); io.output(io.stdout); + +os.remove(file) +assert(loadfile(file) == nil) +assert(io.open(file) == nil) +io.output(file) +assert(io.output() ~= io.stdout) + +assert(io.output():seek() == 0) +assert(io.write("alo alo")) +assert(io.output():seek() == string.len("alo alo")) +assert(io.output():seek("cur", -3) == string.len("alo alo")-3) +assert(io.write("joao")) +assert(io.output():seek("end") == string.len("alo joao")) + +assert(io.output():seek("set") == 0) + +assert(io.write('"álo"', "{a}\n", "second line\n", "third line \n")) +assert(io.write('çfourth_line')) +io.output(io.stdout) +collectgarbage() -- file should be closed by GC +assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) +print('+') + +-- test GC for files +collectgarbage() +for i=1,120 do + for i=1,5 do + io.input(file) + assert(io.open(file, 'r')) + io.lines(file) + end + collectgarbage() +end + +assert(os.rename(file, otherfile)) +assert(os.rename(file, otherfile) == nil) + +io.output(io.open(otherfile, "a")) +assert(io.write("\n\n\t\t 3450\n")); +io.close() + +-- test line generators +assert(os.rename(otherfile, file)) +io.output(otherfile) +local f = io.lines(file) +while f() do end; +assert(not pcall(f)) -- read lines after EOF +assert(not pcall(f)) -- read lines after EOF +-- copy from file to otherfile +for l in io.lines(file) do io.write(l, "\n") end +io.close() +-- copy from otherfile back to file +local f = assert(io.open(otherfile)) +assert(io.type(f) == "file") +io.output(file) +assert(io.output():read() == nil) +for l in f:lines() do io.write(l, "\n") end +assert(f:close()); io.close() +assert(not pcall(io.close, f)) -- error trying to close again +assert(tostring(f) == "file (closed)") +assert(io.type(f) == "closed file") +io.input(file) +f = io.open(otherfile):lines() +for l in io.lines() do assert(l == f()) end +assert(os.remove(otherfile)) + +io.input(file) +do -- test error returns + local a,b,c = io.input():write("xuxu") + assert(not a and type(b) == "string" and type(c) == "number") +end +assert(io.read(0) == "") -- not eof +assert(io.read(5, '*l') == '"álo"') +assert(io.read(0) == "") +assert(io.read() == "second line") +local x = io.input():seek() +assert(io.read() == "third line ") +assert(io.input():seek("set", x)) +assert(io.read('*l') == "third line ") +assert(io.read(1) == "ç") +assert(io.read(string.len"fourth_line") == "fourth_line") +assert(io.input():seek("cur", -string.len"fourth_line")) +assert(io.read() == "fourth_line") +assert(io.read() == "") -- empty line +assert(io.read('*n') == 3450) +assert(io.read(1) == '\n') +assert(io.read(0) == nil) -- end of file +assert(io.read(1) == nil) -- end of file +assert(({io.read(1)})[2] == nil) +assert(io.read() == nil) -- end of file +assert(({io.read()})[2] == nil) +assert(io.read('*n') == nil) -- end of file +assert(({io.read('*n')})[2] == nil) +assert(io.read('*a') == '') -- end of file (OK for `*a') +assert(io.read('*a') == '') -- end of file (OK for `*a') +collectgarbage() +print('+') +io.close(io.input()) +assert(not pcall(io.read)) + +assert(os.remove(file)) + +local t = '0123456789' +for i=1,12 do t = t..t; end +assert(string.len(t) == 10*2^12) + +io.output(file) +io.write("alo\n") +io.close() +assert(not pcall(io.write)) +local f = io.open(file, "a") +io.output(f) +collectgarbage() + +assert(io.write(' ' .. t .. ' ')) +assert(io.write(';', 'end of file\n')) +f:flush(); io.flush() +f:close() +print('+') + +io.input(file) +assert(io.read() == "alo") +assert(io.read(1) == ' ') +assert(io.read(string.len(t)) == t) +assert(io.read(1) == ' ') +assert(io.read(0)) +assert(io.read('*a') == ';end of file\n') +assert(io.read(0) == nil) +assert(io.close(io.input())) + +assert(os.remove(file)) +print('+') + +local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'" +io.output(file) +assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1))) +io.close() +assert(loadfile(file))() +assert(x1 == x2) +print('+') +assert(os.remove(file)) +assert(os.remove(file) == nil) +assert(os.remove(otherfile) == nil) + +io.output(file) +assert(io.write("qualquer coisa\n")) +assert(io.write("mais qualquer coisa")) +io.close() +io.output(assert(io.open(otherfile, 'wb'))) +assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0")) +io.close() + +local filehandle = assert(io.open(file, 'r')) +local otherfilehandle = assert(io.open(otherfile, 'rb')) +assert(filehandle ~= otherfilehandle) +assert(type(filehandle) == "userdata") +assert(filehandle:read('*l') == "qualquer coisa") +io.input(otherfilehandle) +assert(io.read(string.len"outra coisa") == "outra coisa") +assert(filehandle:read('*l') == "mais qualquer coisa") +filehandle:close(); +assert(type(filehandle) == "userdata") +io.input(otherfilehandle) +assert(io.read(4) == "\0\1\3\0") +assert(io.read(3) == "\0\0\0") +assert(io.read(0) == "") -- 255 is not eof +assert(io.read(1) == "\255") +assert(io.read('*a') == "\0") +assert(not io.read(0)) +assert(otherfilehandle == io.input()) +otherfilehandle:close() +assert(os.remove(file)) +assert(os.remove(otherfile)) +collectgarbage() + +io.output(file) +io.write[[ + 123.4 -56e-2 not a number +second line +third line + +and the rest of the file +]] +io.close() +io.input(file) +local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10) +assert(io.close(io.input())) +assert(_ == ' ' and __ == nil) +assert(type(a) == 'number' and a==123.4 and b==-56e-2) +assert(d=='second line' and e=='third line') +assert(h==[[ + +and the rest of the file +]]) +assert(os.remove(file)) +collectgarbage() + +-- testing buffers +do + local f = assert(io.open(file, "w")) + local fr = assert(io.open(file, "r")) + assert(f:setvbuf("full", 2000)) + f:write("x") + assert(fr:read("*all") == "") -- full buffer; output not written yet + f:close() + fr:seek("set") + assert(fr:read("*all") == "x") -- `close' flushes it + f = assert(io.open(file), "w") + assert(f:setvbuf("no")) + f:write("x") + fr:seek("set") + assert(fr:read("*all") == "x") -- no buffer; output is ready + f:close() + f = assert(io.open(file, "a")) + assert(f:setvbuf("line")) + f:write("x") + fr:seek("set", 1) + assert(fr:read("*all") == "") -- line buffer; no output without `\n' + f:write("a\n") + fr:seek("set", 1) + assert(fr:read("*all") == "xa\n") -- now we have a whole line + f:close(); fr:close() +end + + +-- testing large files (> BUFSIZ) +io.output(file) +for i=1,5001 do io.write('0123456789123') end +io.write('\n12346') +io.close() +io.input(file) +local x = io.read('*a') +io.input():seek('set', 0) +local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003) +assert(x == y and string.len(x) == 5001*13 + 6) +io.input():seek('set', 0) +y = io.read() -- huge line +assert(x == y..'\n'..io.read()) +assert(io.read() == nil) +io.close(io.input()) +assert(os.remove(file)) +x = nil; y = nil + +x, y = pcall(io.popen, "ls") +if x then + assert(y:read("*a")) + assert(y:close()) +else + (Message or print)('\a\n >>> popen not available<<<\n\a') +end + +print'+' + +local t = os.time() +T = os.date("*t", t) +loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and + T.hour==%H and T.min==%M and T.sec==%S and + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() + +assert(os.time(T) == t) + +T = os.date("!*t", t) +loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and + T.hour==%H and T.min==%M and T.sec==%S and + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() + +do + local T = os.date("*t") + local t = os.time(T) + assert(type(T.isdst) == 'boolean') + T.isdst = nil + local t1 = os.time(T) + assert(t == t1) -- if isdst is absent uses correct default +end + +t = os.time(T) +T.year = T.year-1; +local t1 = os.time(T) +-- allow for leap years +assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2) + +t = os.time() +t1 = os.time(os.date("*t")) +assert(os.difftime(t1,t) <= 2) + +local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17} +local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19} +assert(os.difftime(t1,t2) == 60*2-2) + +io.output(io.stdout) +local d = os.date('%d') +local m = os.date('%m') +local a = os.date('%Y') +local ds = os.date('%w') + 1 +local h = os.date('%H') +local min = os.date('%M') +local s = os.date('%S') +io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a)) +io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s)) +io.write(string.format('%s\n', _VERSION)) diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua new file mode 100644 index 0000000..86a9f75 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/gc.lua @@ -0,0 +1,312 @@ +print('testing garbage collection') + +collectgarbage() + +_G["while"] = 234 + +limit = 5000 + + + +contCreate = 0 + +print('tables') +while contCreate <= limit do + local a = {}; a = nil + contCreate = contCreate+1 +end + +a = "a" + +contCreate = 0 +print('strings') +while contCreate <= limit do + a = contCreate .. "b"; + a = string.gsub(a, '(%d%d*)', string.upper) + a = "a" + contCreate = contCreate+1 +end + + +contCreate = 0 + +a = {} + +print('functions') +function a:test () + while contCreate <= limit do + loadstring(string.format("function temp(a) return 'a%d' end", contCreate))() + assert(temp() == string.format('a%d', contCreate)) + contCreate = contCreate+1 + end +end + +a:test() + +-- collection of functions without locals, globals, etc. +do local f = function () end end + + +print("functions with errors") +prog = [[ +do + a = 10; + function foo(x,y) + a = sin(a+0.456-0.23e-12); + return function (z) return sin(%x+z) end + end + local x = function (w) a=a+w; end +end +]] +do + local step = 1 + if rawget(_G, "_soft") then step = 13 end + for i=1, string.len(prog), step do + for j=i, string.len(prog), step do + pcall(loadstring(string.sub(prog, i, j))) + end + end +end + +print('long strings') +x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789" +assert(string.len(x)==80) +s = '' +n = 0 +k = 300 +while n < k do s = s..x; n=n+1; j=tostring(n) end +assert(string.len(s) == k*80) +s = string.sub(s, 1, 20000) +s, i = string.gsub(s, '(%d%d%d%d)', math.sin) +assert(i==20000/4) +s = nil +x = nil + +assert(_G["while"] == 234) + + +local bytes = gcinfo() +while 1 do + local nbytes = gcinfo() + if nbytes < bytes then break end -- run until gc + bytes = nbytes + a = {} +end + + +local function dosteps (siz) + collectgarbage() + collectgarbage"stop" + local a = {} + for i=1,100 do a[i] = {{}}; local b = {} end + local x = gcinfo() + local i = 0 + repeat + i = i+1 + until collectgarbage("step", siz) + assert(gcinfo() < x) + return i +end + +assert(dosteps(0) > 10) +assert(dosteps(6) < dosteps(2)) +assert(dosteps(10000) == 1) +assert(collectgarbage("step", 1000000) == true) +assert(collectgarbage("step", 1000000)) + + +do + local x = gcinfo() + collectgarbage() + collectgarbage"stop" + repeat + local a = {} + until gcinfo() > 1000 + collectgarbage"restart" + repeat + local a = {} + until gcinfo() < 1000 +end + +lim = 15 +a = {} +-- fill a with `collectable' indices +for i=1,lim do a[{}] = i end +b = {} +for k,v in pairs(a) do b[k]=v end +-- remove all indices and collect them +for n in pairs(b) do + a[n] = nil + assert(type(n) == 'table' and next(n) == nil) + collectgarbage() +end +b = nil +collectgarbage() +for n in pairs(a) do error'cannot be here' end +for i=1,lim do a[i] = i end +for i=1,lim do assert(a[i] == i) end + + +print('weak tables') +a = {}; setmetatable(a, {__mode = 'k'}); +-- fill a with some `collectable' indices +for i=1,lim do a[{}] = i end +-- and some non-collectable ones +for i=1,lim do local t={}; a[t]=t end +for i=1,lim do a[i] = i end +for i=1,lim do local s=string.rep('@', i); a[s] = s..'#' end +collectgarbage() +local i = 0 +for k,v in pairs(a) do assert(k==v or k..'#'==v); i=i+1 end +assert(i == 3*lim) + +a = {}; setmetatable(a, {__mode = 'v'}); +a[1] = string.rep('b', 21) +collectgarbage() +assert(a[1]) -- strings are *values* +a[1] = nil +-- fill a with some `collectable' values (in both parts of the table) +for i=1,lim do a[i] = {} end +for i=1,lim do a[i..'x'] = {} end +-- and some non-collectable ones +for i=1,lim do local t={}; a[t]=t end +for i=1,lim do a[i+lim]=i..'x' end +collectgarbage() +local i = 0 +for k,v in pairs(a) do assert(k==v or k-lim..'x' == v); i=i+1 end +assert(i == 2*lim) + +a = {}; setmetatable(a, {__mode = 'vk'}); +local x, y, z = {}, {}, {} +-- keep only some items +a[1], a[2], a[3] = x, y, z +a[string.rep('$', 11)] = string.rep('$', 11) +-- fill a with some `collectable' values +for i=4,lim do a[i] = {} end +for i=1,lim do a[{}] = i end +for i=1,lim do local t={}; a[t]=t end +collectgarbage() +assert(next(a) ~= nil) +local i = 0 +for k,v in pairs(a) do + assert((k == 1 and v == x) or + (k == 2 and v == y) or + (k == 3 and v == z) or k==v); + i = i+1 +end +assert(i == 4) +x,y,z=nil +collectgarbage() +assert(next(a) == string.rep('$', 11)) + + +-- testing userdata +collectgarbage("stop") -- stop collection +local u = newproxy(true) +local s = 0 +local a = {[u] = 0}; setmetatable(a, {__mode = 'vk'}) +for i=1,10 do a[newproxy(u)] = i end +for k in pairs(a) do assert(getmetatable(k) == getmetatable(u)) end +local a1 = {}; for k,v in pairs(a) do a1[k] = v end +for k,v in pairs(a1) do a[v] = k end +for i =1,10 do assert(a[i]) end +getmetatable(u).a = a1 +getmetatable(u).u = u +do + local u = u + getmetatable(u).__gc = function (o) + assert(a[o] == 10-s) + assert(a[10-s] == nil) -- udata already removed from weak table + assert(getmetatable(o) == getmetatable(u)) + assert(getmetatable(o).a[o] == 10-s) + s=s+1 + end +end +a1, u = nil +assert(next(a) ~= nil) +collectgarbage() +assert(s==11) +collectgarbage() +assert(next(a) == nil) -- finalized keys are removed in two cycles + + +-- __gc x weak tables +local u = newproxy(true) +setmetatable(getmetatable(u), {__mode = "v"}) +getmetatable(u).__gc = function (o) os.exit(1) end -- cannot happen +collectgarbage() + +local u = newproxy(true) +local m = getmetatable(u) +m.x = {[{0}] = 1; [0] = {1}}; setmetatable(m.x, {__mode = "kv"}); +m.__gc = function (o) + assert(next(getmetatable(o).x) == nil) + m = 10 +end +u, m = nil +collectgarbage() +assert(m==10) + + +-- errors during collection +u = newproxy(true) +getmetatable(u).__gc = function () error "!!!" end +u = nil +assert(not pcall(collectgarbage)) + + +if not rawget(_G, "_soft") then + print("deep structures") + local a = {} + for i = 1,200000 do + a = {next = a} + end + collectgarbage() +end + +-- create many threads with self-references and open upvalues +local thread_id = 0 +local threads = {} + +function fn(thread) + local x = {} + threads[thread_id] = function() + thread = x + end + coroutine.yield() +end + +while thread_id < 1000 do + local thread = coroutine.create(fn) + coroutine.resume(thread, thread) + thread_id = thread_id + 1 +end + + + +-- create a userdata to be collected when state is closed +do + local newproxy,assert,type,print,getmetatable = + newproxy,assert,type,print,getmetatable + local u = newproxy(true) + local tt = getmetatable(u) + ___Glob = {u} -- avoid udata being collected before program end + tt.__gc = function (o) + assert(getmetatable(o) == tt) + -- create new objects during GC + local a = 'xuxu'..(10+3)..'joao', {} + ___Glob = o -- ressurect object! + newproxy(o) -- creates a new one with same metatable + print(">>> closing state " .. "<<<\n") + end +end + +-- create several udata to raise errors when collected while closing state +do + local u = newproxy(true) + getmetatable(u).__gc = function (o) return o + 1 end + table.insert(___Glob, u) -- preserve udata until the end + for i = 1,10 do table.insert(___Glob, newproxy(u)) end +end + +print('OK') diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt new file mode 100644 index 0000000..f24e7f3 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt @@ -0,0 +1,18 @@ +# Test suite that has been added from PUC-Rio Lua 5.1 test archive +# in scope of https://github.com/tarantool/tarantool/issues/5845. + +# See the rationale in the root CMakeLists.txt. +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) + +# The original tarball contains subdirectory "libs" with an empty +# subdirectory "libs/P1", to be used by tests. +# Instead of tracking empty directory with some anchor-file for +# git, create this directory via CMake. +add_custom_target(PUC-Lua-5.1-tests-prepare) +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" + COMMAND ${CMAKE_COMMAND} -E make_directory P1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) + +# vim: expandtab tabstop=2 shiftwidth=2 diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c new file mode 100644 index 0000000..812bb9a --- /dev/null +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c @@ -0,0 +1,40 @@ +/* +** compile with +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c +*/ + + +#include "lua.h" +#include "lauxlib.h" + +static int id (lua_State *L) { + return lua_gettop(L); +} + + +static const struct luaL_reg funcs[] = { + {"id", id}, + {NULL, NULL} +}; + + +int anotherfunc (lua_State *L) { + lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2)); + return 1; +} + + +int luaopen_lib1_sub (lua_State *L) { + luaL_register(L, "lib1.sub", funcs + 1); + return 1; +} + + +int luaopen_lib1 (lua_State *L) { + luaL_register(L, "lib1", funcs); + return 1; +} + + diff --git a/test/PUC-Lua-5.1-tests/libs/lib11.c b/test/PUC-Lua-5.1-tests/libs/lib11.c new file mode 100644 index 0000000..3efa3d3 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/libs/lib11.c @@ -0,0 +1,18 @@ +/* +** compile with +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c +*/ + + +#include "lua.h" + + +int luaopen_lib1 (lua_State *L); + +int luaopen_lib11 (lua_State *L) { + return luaopen_lib1(L); +} + + diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c new file mode 100644 index 0000000..9972cbe --- /dev/null +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c @@ -0,0 +1,28 @@ +/* +** compile with +** gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c +*/ + + +#include "lua.h" +#include "lauxlib.h" + +static int id (lua_State *L) { + return lua_gettop(L); +} + + +static const struct luaL_reg funcs[] = { + {"id", id}, + {NULL, NULL} +}; + + +int luaopen_lib2 (lua_State *L) { + luaL_register(L, "lib2", funcs); + lua_pushnumber(L, 0.5); + lua_setglobal(L, "x"); + return 1; +} + + diff --git a/test/PUC-Lua-5.1-tests/libs/lib21.c b/test/PUC-Lua-5.1-tests/libs/lib21.c new file mode 100644 index 0000000..167507f --- /dev/null +++ b/test/PUC-Lua-5.1-tests/libs/lib21.c @@ -0,0 +1,18 @@ +/* +** compile with +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c +*/ + + +#include "lua.h" + + +int luaopen_lib2 (lua_State *L); + +int luaopen_lib21 (lua_State *L) { + return luaopen_lib2(L); +} + + diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua new file mode 100644 index 0000000..01d84d5 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/literals.lua @@ -0,0 +1,176 @@ +print('testing scanner') + +local function dostring (x) return assert(loadstring(x))() end + +dostring("x = 'a\0a'") +assert(x == 'a\0a' and string.len(x) == 3) + +-- escape sequences +assert('\n\"\'\\' == [[ + +"'\]]) + +assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$")) + +-- assume ASCII just for tests: +assert("\09912" == 'c12') +assert("\99ab" == 'cab') +assert("\099" == '\99') +assert("\099\n" == 'c\10') +assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo') + +assert(010 .. 020 .. -030 == "1020-30") + +-- long variable names + +var = string.rep('a', 15000) +prog = string.format("%s = 5", var) +dostring(prog) +assert(_G[var] == 5) +var = nil +print('+') + +-- escapes -- +assert("\n\t" == [[ + + ]]) +assert([[ + + $debug]] == "\n $debug") +assert([[ [ ]] ~= [[ ] ]]) +-- long strings -- +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" +assert(string.len(b) == 960) +prog = [=[ +print('+') + +a1 = [["isto e' um string com várias 'aspas'"]] +a2 = "'aspas'" + +assert(string.find(a1, a2) == 31) +print('+') + +a1 = [==[temp = [[um valor qualquer]]; ]==] +assert(loadstring(a1))() +assert(temp == 'um valor qualquer') +-- long strings -- +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" +assert(string.len(b) == 960) +print('+') + +a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +00123456789012345678901234567890123456789123456789012345678901234567890123456789 +]] +assert(string.len(a) == 1863) +assert(string.sub(a, 1, 40) == string.sub(b, 1, 40)) +x = 1 +]=] + +print('+') +x = nil +dostring(prog) +assert(x) + +prog = nil +a = nil +b = nil + + +-- testing line ends +prog = [[ +a = 1 -- a comment +b = 2 + + +x = [=[ +hi +]=] +y = "\ +hello\r\n\ +" +return debug.getinfo(1).currentline +]] + +for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do + local prog, nn = string.gsub(prog, "\n", n) + assert(dostring(prog) == nn) + assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n") +end + + +-- testing comments and strings with long brackets +a = [==[]=]==] +assert(a == "]=") + +a = [==[[===[[=[]]=][====[]]===]===]==] +assert(a == "[===[[=[]]=][====[]]===]===") + +a = [====[[===[[=[]]=][====[]]===]===]====] +assert(a == "[===[[=[]]=][====[]]===]===") + +a = [=[]]]]]]]]]=] +assert(a == "]]]]]]]]") + + +--[===[ +x y z [==[ blu foo +]== +] +]=]==] +error error]=]===] + +-- generate all strings of four of these chars +local x = {"=", "[", "]", "\n"} +local len = 4 +local function gen (c, n) + if n==0 then coroutine.yield(c) + else + for _, a in pairs(x) do + gen(c..a, n-1) + end + end +end + +for s in coroutine.wrap(function () gen("", len) end) do + assert(s == loadstring("return [====[\n"..s.."]====]")()) +end + + +-- testing decimal point locale +if os.setlocale("pt_BR") or os.setlocale("ptb") then + assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) + assert(assert(loadstring("return 3.4"))() == 3.4) + assert(assert(loadstring("return .4,3"))() == .4) + assert(assert(loadstring("return 4."))() == 4.) + assert(assert(loadstring("return 4.+.5"))() == 4.5) + local a,b = loadstring("return 4.5.") + assert(string.find(b, "'4%.5%.'")) + assert(os.setlocale("C")) +else + (Message or print)( + '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a') +end + + +print('OK') diff --git a/test/PUC-Lua-5.1-tests/locals.lua b/test/PUC-Lua-5.1-tests/locals.lua new file mode 100644 index 0000000..011645a --- /dev/null +++ b/test/PUC-Lua-5.1-tests/locals.lua @@ -0,0 +1,127 @@ +print('testing local variables plus some extra stuff') + +do + local i = 10 + do local i = 100; assert(i==100) end + do local i = 1000; assert(i==1000) end + assert(i == 10) + if i ~= 10 then + local i = 20 + else + local i = 30 + assert(i == 30) + end +end + + + +f = nil + +local f +x = 1 + +a = nil +loadstring('local a = {}')() +assert(type(a) ~= 'table') + +function f (a) + local _1, _2, _3, _4, _5 + local _6, _7, _8, _9, _10 + local x = 3 + local b = a + local c,d = a,b + if (d == b) then + local x = 'q' + x = b + assert(x == 2) + else + assert(nil) + end + assert(x == 3) + local f = 10 +end + +local b=10 +local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3 + + +assert(x == 1) + +f(2) +assert(type(f) == 'function') + + +-- testing globals ;-) +do + local f = {} + local _G = _G + for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end + A=10; assert(f[1]() == 11) + for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end + assert(f[3]() == 4 and A == 11) + local a,b = f[8](1) + assert(b.A == 9) + a,b = f[8](0) + assert(b.A == 11) -- `real' global + local g + local function f () assert(setfenv(2, {a='10'}) == g) end + g = function () f(); _G.assert(_G.getfenv(1).a == '10') end + g(); assert(getfenv(g).a == '10') +end + +-- test for global table of loaded chunks +local function foo (s) + return loadstring(s) +end + +assert(getfenv(foo("")) == _G) +local a = {loadstring = loadstring} +setfenv(foo, a) +assert(getfenv(foo("")) == _G) +setfenv(0, a) -- change global environment +assert(getfenv(foo("")) == a) +setfenv(0, _G) + + +-- testing limits for special instructions + +local a +local p = 4 +for i=2,31 do + for j=-3,3 do + assert(loadstring(string.format([[local a=%s;a=a+ + %s; + assert(a + ==2^%s)]], j, p-j, i))) () + assert(loadstring(string.format([[local a=%s; + a=a-%s; + assert(a==-2^%s)]], -j, p-j, i))) () + assert(loadstring(string.format([[local a,b=0,%s; + a=b-%s; + assert(a==-2^%s)]], -j, p-j, i))) () + end + p =2*p +end + +print'+' + + +if rawget(_G, "querytab") then + -- testing clearing of dead elements from tables + collectgarbage("stop") -- stop GC + local a = {[{}] = 4, [3] = 0, alo = 1, + a1234567890123456789012345678901234567890 = 10} + + local t = querytab(a) + + for k,_ in pairs(a) do a[k] = nil end + collectgarbage() -- restore GC and collect dead fiels in `a' + for i=0,t-1 do + local k = querytab(a, i) + assert(k == nil or type(k) == 'number' or k == 'alo') + end +end + +print('OK') + +return 5,f diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua new file mode 100644 index 0000000..f520896 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/main.lua @@ -0,0 +1,159 @@ +# testing special comment on first line + +print ("testing lua.c options") + +assert(os.execute() ~= 0) -- machine has a system command + +prog = os.tmpname() +otherprog = os.tmpname() +out = os.tmpname() + +do + local i = 0 + while arg[i] do i=i-1 end + progname = '"'..arg[i+1]..'"' +end +print(progname) + +local prepfile = function (s, p) + p = p or prog + io.output(p) + io.write(s) + assert(io.close()) +end + +function checkout (s) + io.input(out) + local t = io.read("*a") + io.input():close() + assert(os.remove(out)) + if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end + assert(s == t) + return t +end + +function auxrun (...) + local s = string.format(...) + s = string.gsub(s, "lua", progname, 1) + return os.execute(s) +end + +function RUN (...) + assert(auxrun(...) == 0) +end + +function NoRun (...) + print("\n(the next error is expected by the test)") + assert(auxrun(...) ~= 0) +end + +-- test 2 files +prepfile("print(1); a=2") +prepfile("print(a)", otherprog) +RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out) +checkout("1\n2\n2\n") + +local a = [[ + assert(table.getn(arg) == 3 and arg[1] == 'a' and + arg[2] == 'b' and arg[3] == 'c') + assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s) + assert(arg[4] == nil and arg[-4] == nil) + local a, b, c = ... + assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') +]] +a = string.format(a, progname) +prepfile(a) +RUN('lua "-e " -- %s a b c', prog) + +prepfile"assert(arg==nil)" +prepfile("assert(arg)", otherprog) +RUN("lua -l%s - < %s", prog, otherprog) + +prepfile"" +RUN("lua - < %s > %s", prog, out) +checkout("") + +-- test many arguments +prepfile[[print(({...})[30])]] +RUN("lua %s %s > %s", prog, string.rep(" a", 30), out) +checkout("a\n") + +RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) +checkout("1\n3\n") + +prepfile[[ + print( +1, a +) +]] +RUN("lua - < %s > %s", prog, out) +checkout("1\tnil\n") + +prepfile[[ += (6*2-6) -- === +a += 10 +print(a) += a]] +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +checkout("6\n10\n10\n\n") + +prepfile("a = [[b\nc\nd\ne]]\n=a") +print(prog) +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +checkout("b\nc\nd\ne\n\n") + +prompt = "alo" +prepfile[[ -- +a = 2 +]] +RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) +checkout(string.rep(prompt, 3).."\n") + +s = [=[ -- +function f ( x ) + local a = [[ +xuxu +]] + local b = "\ +xuxu\n" + if x == 11 then return 1 , 2 end --[[ test multiple returns ]] + return x + 1 + --\\ +end +=( f( 10 ) ) +assert( a == b ) +=f( 11 ) ]=] +s = string.gsub(s, ' ', '\n\n') +prepfile(s) +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +checkout("11\n1\t2\n\n") + +prepfile[[#comment in 1st line without \n at the end]] +RUN("lua %s", prog) + +prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)"))) +RUN("lua %s > %s", prog, out) +checkout("1\n") + +prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)"))) +RUN("lua %s > %s", prog, out) +checkout("1\n") + +-- close Lua with an open file +prepfile(string.format([[io.output(%q); io.write('alo')]], out)) +RUN("lua %s", prog) +checkout('alo') + +assert(os.remove(prog)) +assert(os.remove(otherprog)) +assert(not os.remove(out)) + +RUN("lua -v") + +NoRun("lua -h") +NoRun("lua -e") +NoRun("lua -e a") +NoRun("lua -f") + +print("OK") diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua new file mode 100644 index 0000000..5076f38 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/math.lua @@ -0,0 +1,208 @@ +print("testing numbers and math lib") + +do + local a,b,c = "2", " 3e0 ", " 10 " + assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0) + assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string') + assert(a == "2" and b == " 3e0 " and c == " 10 " and -c == -" 10 ") + assert(c%a == 0 and a^b == 8) +end + + +do + local a,b = math.modf(3.5) + assert(a == 3 and b == 0.5) + assert(math.huge > 10e30) + assert(-math.huge < -10e30) +end + +function f(...) + if select('#', ...) == 1 then + return (...) + else + return "***" + end +end + +assert(tonumber{} == nil) +assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and + tonumber'.01' == 0.01 and tonumber'-1.' == -1 and + tonumber'+1.' == 1) +assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and + tonumber'1e' == nil and tonumber'1.0e+' == nil and + tonumber'.' == nil) +assert(tonumber('-12') == -10-2) +assert(tonumber('-1.2e2') == - - -120) +assert(f(tonumber('1 a')) == nil) +assert(f(tonumber('e1')) == nil) +assert(f(tonumber('e 1')) == nil) +assert(f(tonumber(' 3.4.5 ')) == nil) +assert(f(tonumber('')) == nil) +assert(f(tonumber('', 8)) == nil) +assert(f(tonumber(' ')) == nil) +assert(f(tonumber(' ', 9)) == nil) +assert(f(tonumber('99', 8)) == nil) +assert(tonumber(' 1010 ', 2) == 10) +assert(tonumber('10', 36) == 36) +--assert(tonumber('\n -10 \n', 36) == -36) +--assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) +assert(tonumber('fFfa', 15) == nil) +--assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42) +assert(tonumber(string.rep('1', 32), 2) + 1 == 2^32) +--assert(tonumber('-fffffFFFFF', 16)-1 == -2^40) +assert(tonumber('ffffFFFF', 16)+1 == 2^32) + +assert(1.1 == 1.+.1) +assert(100.0 == 1E2 and .01 == 1e-2) +assert(1111111111111111-1111111111111110== 1000.00e-03) +-- 1234567890123456 +assert(1.1 == '1.'+'.1') +assert('1111111111111111'-'1111111111111110' == tonumber" +0.001e+3 \n\t") + +function eq (a,b,limit) + if not limit then limit = 10E-10 end + return math.abs(a-b) <= limit +end + +assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31) + +assert(0.123456 > 0.123455) + +assert(tonumber('+1.23E30') == 1.23*10^30) + +-- testing order operators +assert(not(1<1) and (1<2) and not(2<1)) +assert(not('a'<'a') and ('a'<'b') and not('b'<'a')) +assert((1<=1) and (1<=2) and not(2<=1)) +assert(('a'<='a') and ('a'<='b') and not('b'<='a')) +assert(not(1>1) and not(1>2) and (2>1)) +assert(not('a'>'a') and not('a'>'b') and ('b'>'a')) +assert((1>=1) and not(1>=2) and (2>=1)) +assert(('a'>='a') and not('a'>='b') and ('b'>='a')) + +-- testing mod operator +assert(-4%3 == 2) +assert(4%-3 == -2) +assert(math.pi - math.pi % 1 == 3) +assert(math.pi - math.pi % 0.001 == 3.141) + +local function testbit(a, n) + return a/2^n % 2 >= 1 +end + +assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1)) +assert(eq(math.tan(math.pi/4), 1)) +assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0)) +assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and + eq(math.asin(1), math.pi/2)) +assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2)) +assert(math.abs(-10) == 10) +assert(eq(math.atan2(1,0), math.pi/2)) +assert(math.ceil(4.5) == 5.0) +assert(math.floor(4.5) == 4.0) +assert(math.mod(10,3) == 1) +assert(eq(math.sqrt(10)^2, 10)) +assert(eq(math.log10(2), math.log(2)/math.log(10))) +assert(eq(math.exp(0), 1)) +assert(eq(math.sin(10), math.sin(10%(2*math.pi)))) +local v,e = math.frexp(math.pi) +assert(eq(math.ldexp(v,e), math.pi)) + +assert(eq(math.tanh(3.5), math.sinh(3.5)/math.cosh(3.5))) + +assert(tonumber(' 1.3e-2 ') == 1.3e-2) +assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) + +-- testing constant limits +-- 2^23 = 8388608 +assert(8388609 + -8388609 == 0) +assert(8388608 + -8388608 == 0) +assert(8388607 + -8388607 == 0) + +if rawget(_G, "_soft") then return end + +f = io.tmpfile() +assert(f) +f:write("a = {") +i = 1 +repeat + f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n") + i=i+1 +until i > 1000 +f:write("}") +f:seek("set", 0) +assert(loadstring(f:read('*a')))() +assert(f:close()) + +assert(eq(a[300][1], math.sin(300))) +assert(eq(a[600][1], math.sin(600))) +assert(eq(a[500][2], math.cos(500))) +assert(eq(a[800][2], math.cos(800))) +assert(eq(a[200][3], 200/3)) +assert(eq(a[1000][3], 1000/3, 0.001)) +print('+') + +do -- testing NaN + local NaN = 10e500 - 10e400 + assert(NaN ~= NaN) + assert(not (NaN < NaN)) + assert(not (NaN <= NaN)) + assert(not (NaN > NaN)) + assert(not (NaN >= NaN)) + assert(not (0 < NaN)) + assert(not (NaN < 0)) + local a = {} + assert(not pcall(function () a[NaN] = 1 end)) + assert(a[NaN] == nil) + a[1] = 1 + assert(not pcall(function () a[NaN] = 1 end)) + assert(a[NaN] == nil) +end + +require "checktable" +stat(a) + +a = nil + +-- testing implicit convertions + +local a,b = '10', '20' +assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20) +assert(a == '10' and b == '20') + + +math.randomseed(0) + +local i = 0 +local Max = 0 +local Min = 2 +repeat + local t = math.random() + Max = math.max(Max, t) + Min = math.min(Min, t) + i=i+1 + flag = eq(Max, 1, 0.001) and eq(Min, 0, 0.001) +until flag or i>10000 +assert(0 <= Min and Max<1) +assert(flag); + +for i=1,10 do + local t = math.random(5) + assert(1 <= t and t <= 5) +end + +i = 0 +Max = -200 +Min = 200 +repeat + local t = math.random(-10,0) + Max = math.max(Max, t) + Min = math.min(Min, t) + i=i+1 + flag = (Max == 0 and Min == -10) +until flag or i>10000 +assert(-10 <= Min and Max<=0) +assert(flag); + + +print('OK') diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua new file mode 100644 index 0000000..7ceaa75 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/nextvar.lua @@ -0,0 +1,396 @@ +print('testing tables, next, and for') + +local a = {} + +-- make sure table has lots of space in hash part +for i=1,100 do a[i.."+"] = true end +for i=1,100 do a[i.."+"] = nil end +-- fill hash part with numeric indices testing size operator +for i=1,100 do + a[i] = true + assert(#a == i) +end + + +if T then +-- testing table sizes + +local l2 = math.log(2) +local function log2 (x) return math.log(x)/l2 end + +local function mp2 (n) -- minimum power of 2 >= n + local mp = 2^math.ceil(log2(n)) + assert(n == 0 or (mp/2 < n and n <= mp)) + return mp +end + +local function fb (n) + local r, nn = T.int2fb(n) + assert(r < 256) + return nn +end + +-- test fb function +local a = 1 +local lim = 2^30 +while a < lim do + local n = fb(a) + assert(a <= n and n <= a*1.125) + a = math.ceil(a*1.3) +end + + +local function check (t, na, nh) + local a, h = T.querytab(t) + if a ~= na or h ~= nh then + print(na, nh, a, h) + assert(nil) + end +end + +-- testing constructor sizes +local lim = 40 +local s = 'return {' +for i=1,lim do + s = s..i..',' + local s = s + for k=0,lim do + local t = loadstring(s..'}')() + assert(#t == i) + check(t, fb(i), mp2(k)) + s = string.format('%sa%d=%d,', s, k, k) + end +end + + +-- tests with unknown number of elements +local a = {} +for i=1,lim do a[i] = i end -- build auxiliary table +for k=0,lim do + local a = {unpack(a,1,k)} + assert(#a == k) + check(a, k, 0) + a = {1,2,3,unpack(a,1,k)} + check(a, k+3, 0) + assert(#a == k + 3) +end + + +print'+' + +-- testing tables dynamically built +local lim = 130 +local a = {}; a[2] = 1; check(a, 0, 1) +a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) +a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) +a = {} +for i = 1,lim do + a[i] = 1 + assert(#a == i) + check(a, mp2(i), 0) +end + +a = {} +for i = 1,lim do + a['a'..i] = 1 + assert(#a == 0) + check(a, 0, mp2(i)) +end + +a = {} +for i=1,16 do a[i] = i end +check(a, 16, 0) +for i=1,11 do a[i] = nil end +for i=30,40 do a[i] = nil end -- force a rehash (?) +check(a, 0, 8) +a[10] = 1 +for i=30,40 do a[i] = nil end -- force a rehash (?) +check(a, 0, 8) +for i=1,14 do a[i] = nil end +for i=30,50 do a[i] = nil end -- force a rehash (?) +check(a, 0, 4) + +-- reverse filling +for i=1,lim do + local a = {} + for i=i,1,-1 do a[i] = i end -- fill in reverse + check(a, mp2(i), 0) +end + +-- size tests for vararg +lim = 35 +function foo (n, ...) + local arg = {...} + check(arg, n, 0) + assert(select('#', ...) == n) + arg[n+1] = true + check(arg, mp2(n+1), 0) + arg.x = true + check(arg, mp2(n+1), 1) +end +local a = {} +for i=1,lim do a[i] = true; foo(i, unpack(a)) end + +end + + +-- test size operation on empty tables +assert(#{} == 0) +assert(#{nil} == 0) +assert(#{nil, nil} == 0) +assert(#{nil, nil, nil} == 0) +assert(#{nil, nil, nil, nil} == 0) +print'+' + + +local nofind = {} + +a,b,c = 1,2,3 +a,b,c = nil + +local function find (name) + local n,v + while 1 do + n,v = next(_G, n) + if not n then return nofind end + assert(v ~= nil) + if n == name then return v end + end +end + +local function find1 (name) + for n,v in pairs(_G) do + if n==name then return v end + end + return nil -- not found +end + +do -- create 10000 new global variables + for i=1,10000 do _G[i] = i end +end + + +a = {x=90, y=8, z=23} +assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90) +assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil) +table.foreach({}, error) + +table.foreachi({x=10, y=20}, error) +local a = {n = 1} +table.foreachi({n=3}, function (i, v) + assert(a.n == i and not v) + a.n=a.n+1 +end) +a = {10,20,30,nil,50} +table.foreachi(a, function (i,v) assert(a[i] == v) end) +assert(table.foreachi({'a', 'b', 'c'}, function (i,v) + if i==2 then return v end + end) == 'b') + + +assert(print==find("print") and print == find1("print")) +assert(_G["print"]==find("print")) +assert(assert==find1("assert")) +assert(nofind==find("return")) +assert(not find1("return")) +_G["ret" .. "urn"] = nil +assert(nofind==find("return")) +_G["xxx"] = 1 +assert(xxx==find("xxx")) +print('+') + +a = {} +for i=0,10000 do + if math.mod(i,10) ~= 0 then + a['x'..i] = i + end +end + +n = {n=0} +for i,v in pairs(a) do + n.n = n.n+1 + assert(i and v and a[i] == v) +end +assert(n.n == 9000) +a = nil + +-- remove those 10000 new global variables +for i=1,10000 do _G[i] = nil end + +do -- clear global table + local a = {} + local preserve = {io = 1, string = 1, debug = 1, os = 1, + coroutine = 1, table = 1, math = 1} + for n,v in pairs(_G) do a[n]=v end + for n,v in pairs(a) do + if not preserve[n] and type(v) ~= "function" and + not string.find(n, "^[%u_]") then + _G[n] = nil + end + collectgarbage() + end +end + +local function foo () + local getfenv, setfenv, assert, next = + getfenv, setfenv, assert, next + local n = {gl1=3} + setfenv(foo, n) + assert(getfenv(foo) == getfenv(1)) + assert(getfenv(foo) == n) + assert(print == nil and gl1 == 3) + gl1 = nil + gl = 1 + assert(n.gl == 1 and next(n, 'gl') == nil) +end +foo() + +print'+' + +local function checknext (a) + local b = {} + table.foreach(a, function (k,v) b[k] = v end) + for k,v in pairs(b) do assert(a[k] == v) end + for k,v in pairs(a) do assert(b[k] == v) end + b = {} + do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end + for k,v in pairs(b) do assert(a[k] == v) end + for k,v in pairs(a) do assert(b[k] == v) end +end + +checknext{1,x=1,y=2,z=3} +checknext{1,2,x=1,y=2,z=3} +checknext{1,2,3,x=1,y=2,z=3} +checknext{1,2,3,4,x=1,y=2,z=3} +checknext{1,2,3,4,5,x=1,y=2,z=3} + +assert(table.getn{} == 0) +assert(table.getn{[-1] = 2} == 0) +assert(table.getn{1,2,3,nil,nil} == 3) +for i=0,40 do + local a = {} + for j=1,i do a[j]=j end + assert(table.getn(a) == i) +end + + +assert(table.maxn{} == 0) +assert(table.maxn{["1000"] = true} == 0) +assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) +assert(table.maxn{[1000] = true} == 1000) +assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) + + +-- int overflow +a = {} +for i=0,50 do a[math.pow(2,i)] = true end +assert(a[table.getn(a)]) + +print("+") + + +-- erasing values +local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, + [100.3] = 4, [4] = 5} + +local n = 0 +for k, v in pairs( t ) do + n = n+1 + assert(t[k] == v) + t[k] = nil + collectgarbage() + assert(t[k] == nil) +end +assert(n == 5) + + +local function test (a) + table.insert(a, 10); table.insert(a, 2, 20); + table.insert(a, 1, -1); table.insert(a, 40); + table.insert(a, table.getn(a)+1, 50) + table.insert(a, 2, -2) + assert(table.remove(a,1) == -1) + assert(table.remove(a,1) == -2) + assert(table.remove(a,1) == 10) + assert(table.remove(a,1) == 20) + assert(table.remove(a,1) == 40) + assert(table.remove(a,1) == 50) + assert(table.remove(a,1) == nil) +end + +a = {n=0, [-7] = "ban"} +test(a) +assert(a.n == 0 and a[-7] == "ban") + +a = {[-7] = "ban"}; +test(a) +assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban") + + +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) +assert(table.remove(a) == 10) +assert(table.remove(a) == 20) +assert(table.remove(a) == -1) + +a = {'c', 'd'} +table.insert(a, 3, 'a') +table.insert(a, 'b') +assert(table.remove(a, 1) == 'c') +assert(table.remove(a, 1) == 'd') +assert(table.remove(a, 1) == 'a') +assert(table.remove(a, 1) == 'b') +assert(table.getn(a) == 0 and a.n == nil) +print("+") + +a = {} +for i=1,1000 do + a[i] = i; a[i-1] = nil +end +assert(next(a,nil) == 1000 and next(a,1000) == nil) + +assert(next({}) == nil) +assert(next({}, nil) == nil) + +for a,b in pairs{} do error"not here" end +for i=1,0 do error'not here' end +for i=0,1,-1 do error'not here' end +a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) +a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) + +a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11) +-- precision problems +--a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101) +a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) +a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) +a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1) +a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) +a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0) +a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) + +-- conversion +a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) + + +collectgarbage() + + +-- testing generic 'for' + +local function f (n, p) + local t = {}; for i=1,p do t[i] = i*10 end + return function (_,n) + if n > 0 then + n = n-1 + return n, unpack(t) + end + end, nil, n +end + +local x = 0 +for n,a,b,c,d in f(5,3) do + x = x+1 + assert(a == 10 and b == 20 and c == 30 and d == nil) +end +assert(x == 5) + +print"OK" diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua new file mode 100644 index 0000000..fa125dc --- /dev/null +++ b/test/PUC-Lua-5.1-tests/pm.lua @@ -0,0 +1,273 @@ +print('testing pattern matching') + +function f(s, p) + local i,e = string.find(s, p) + if i then return string.sub(s, i, e) end +end + +function f1(s, p) + p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end) + p = string.gsub(p, "^(^?)", "%1()", 1) + p = string.gsub(p, "($?)$", "()%1", 1) + local t = {string.match(s, p)} + return string.sub(s, t[1], t[#t] - 1) +end + +a,b = string.find('', '') -- empty patterns are tricky +assert(a == 1 and b == 0); +a,b = string.find('alo', '') +assert(a == 1 and b == 0) +a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position +assert(a == 1 and b == 1) +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the midle +assert(a == 5 and b == 7) +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the midle +assert(a == 9 and b == 11) +a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end +assert(a == 9 and b == 11); +a,b = string.find('a\0a\0a\0a\0\0ab', 'b') -- last position +assert(a == 11 and b == 11) +assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil) -- check ending +assert(string.find('', '\0') == nil) +assert(string.find('alo123alo', '12') == 4) +assert(string.find('alo123alo', '^12') == nil) + +assert(f('aloALO', '%l*') == 'alo') +assert(f('aLo_ALO', '%a*') == 'aLo') + +assert(f('aaab', 'a*') == 'aaa'); +assert(f('aaa', '^.*$') == 'aaa'); +assert(f('aaa', 'b*') == ''); +assert(f('aaa', 'ab*a') == 'aa') +assert(f('aba', 'ab*a') == 'aba') +assert(f('aaab', 'a+') == 'aaa') +assert(f('aaa', '^.+$') == 'aaa') +assert(f('aaa', 'b+') == nil) +assert(f('aaa', 'ab+a') == nil) +assert(f('aba', 'ab+a') == 'aba') +assert(f('a$a', '.$') == 'a') +assert(f('a$a', '.%$') == 'a$') +assert(f('a$a', '.$.') == 'a$a') +assert(f('a$a', '$$') == nil) +assert(f('a$b', 'a$') == nil) +assert(f('a$a', '$') == '') +assert(f('', 'b*') == '') +assert(f('aaa', 'bb*') == nil) +assert(f('aaab', 'a-') == '') +assert(f('aaa', '^.-$') == 'aaa') +assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') +assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') +assert(f('alo xo', '.o$') == 'xo') +assert(f(' \n isto é assim', '%S%S*') == 'isto') +assert(f(' \n isto é assim', '%S*$') == 'assim') +assert(f(' \n isto é assim', '[a-z]*$') == 'assim') +assert(f('um caracter ? extra', '[^%sa-z]') == '?') +assert(f('', 'a?') == '') +assert(f('á', 'á?') == 'á') +assert(f('ábl', 'á?b?l?') == 'ábl') +assert(f(' ábl', 'á?b?l?') == '') +assert(f('aa', '^aa?a?a') == 'aa') +assert(f(']]]áb', '[^]]') == 'á') +assert(f("0alo alo", "%x*") == "0a") +assert(f("alo alo", "%C+") == "alo alo") +print('+') + +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o") +assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3') +assert(f1('=======', '^(=*)=%1$') == '=======') +assert(string.match('==========', '^([=]*)=%1$') == nil) + +local function range (i, j) + if i <= j then + return i, range(i+1, j) + end +end + +local abc = string.char(range(0, 255)); + +assert(string.len(abc) == 256) + +function strset (p) + local res = {s=''} + string.gsub(abc, p, function (c) res.s = res.s .. c end) + return res.s +end; + +assert(string.len(strset('[\200-\210]')) == 11) + +assert(strset('[a-z]') == "abcdefghijklmnopqrstuvwxyz") +assert(strset('[a-z%d]') == strset('[%da-uu-z]')) +assert(strset('[a-]') == "-a") +assert(strset('[^%W]') == strset('[%w]')) +assert(strset('[]%%]') == '%]') +assert(strset('[a%-z]') == '-az') +assert(strset('[%^%[%-a%]%-b]') == '-[]^ab') +assert(strset('%Z') == strset('[\1-\255]')) +assert(strset('.') == strset('[\1-\255%z]')) +print('+'); + +assert(string.match("alo xyzK", "(%w+)K") == "xyz") +assert(string.match("254 K", "(%d*)K") == "") +assert(string.match("alo ", "(%w*)$") == "") +assert(string.match("alo ", "(%w+)$") == nil) +assert(string.find("(álo)", "%(á") == 1) +local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$") +assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) +a, b, c, d = string.match('0123456789', '(.+(.?)())') +assert(a == '0123456789' and b == '' and c == 11 and d == nil) +print('+') + +assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') +assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim +assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim +assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') +t = "abç d" +a, b = string.gsub(t, '(.)', '%1@') +assert('@'..a == string.gsub(t, '', '@') and b == 5) +a, b = string.gsub('abçd', '(.)', '%0@', 2) +assert(a == 'a@b@çd' and b == 2) +assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') +assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == + "xyz=abc-abc=xyz") +assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") +assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") +assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú') +assert(string.gsub('', '^', 'r') == 'r') +assert(string.gsub('', '$', 'r') == 'r') +print('+') + +assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", string.upper) == + "um (DOIS) tres (QUATRO)") + +do + local function setglobal (n,v) rawset(_G, n, v) end + string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal) + assert(_G.a=="roberto" and _G.roberto=="a") +end + +function f(a,b) return string.gsub(a,'.',b) end +assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == + "trocar tudo em bbbbb é alalalalalal") + +local function dostring (s) return loadstring(s)() or "" end +assert(string.gsub("alo $a=1$ novamente $return a$", "$([^$]*)%$", dostring) == + "alo novamente 1") + +x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$", + "$([^$]*)%$", dostring) +assert(x == ' assim vai para ALO') + +t = {} +s = 'a alo jose joao' +r = string.gsub(s, '()(%w+)()', function (a,w,b) + assert(string.len(w) == b-a); + t[a] = b-a; + end) +assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4) + + +function isbalanced (s) + return string.find(string.gsub(s, "%b()", ""), "[()]") == nil +end + +assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a")) +assert(not isbalanced("(9 ((8) 7) a b (\0 c) a")) +assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo') + + +local t = {"apple", "orange", "lime"; n=0} +assert(string.gsub("x and x and x", "x", function () t.n=t.n+1; return t[t.n] end) + == "apple and orange and lime") + +t = {n=0} +string.gsub("first second word", "%w%w*", function (w) t.n=t.n+1; t[t.n] = w end) +assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3) + +t = {n=0} +assert(string.gsub("first second word", "%w+", + function (w) t.n=t.n+1; t[t.n] = w end, 2) == "first second word") +assert(t[1] == "first" and t[2] == "second" and t[3] == nil) + +assert(not pcall(string.gsub, "alo", "(.", print)) +assert(not pcall(string.gsub, "alo", ".)", print)) +assert(not pcall(string.gsub, "alo", "(.", {})) +assert(not pcall(string.gsub, "alo", "(.)", "%2")) +assert(not pcall(string.gsub, "alo", "(%1)", "a")) +assert(not pcall(string.gsub, "alo", "(%0)", "a")) + +-- big strings +local a = string.rep('a', 300000) +assert(string.find(a, '^a*.?$')) +assert(not string.find(a, '^a*.?b$')) +assert(string.find(a, '^a-.?$')) + +-- deep nest of gsubs +function rev (s) + return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end) +end + +local x = string.rep('012345', 10) +assert(rev(rev(x)) == x) + + +-- gsub with tables +assert(string.gsub("alo alo", ".", {}) == "alo alo") +assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo") +assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo") +assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo") + +assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo") + +t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end}) +assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") + + +-- tests for gmatch +assert(string.gfind == string.gmatch) +local a = 0 +for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end +assert(a==6) + +t = {n=0} +for w in string.gmatch("first second word", "%w+") do + t.n=t.n+1; t[t.n] = w +end +assert(t[1] == "first" and t[2] == "second" and t[3] == "word") + +t = {3, 6, 9} +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do + assert(i == table.remove(t, 1)) +end +assert(table.getn(t) == 0) + +t = {} +for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do + t[i] = j +end +a = 0 +for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end +assert(a == 3) + + +-- tests for `%f' (`frontiers') + +assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") +assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[") +assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3") +assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.") +assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction") +assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.") + +local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]") +assert(i == 2 and e == 5) +local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])") +assert(k == 'alo ') + +local a = {1, 5, 9, 14, 17,} +for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do + assert(table.remove(a, 1) == k) +end +assert(table.getn(a) == 0) + + +print('OK') diff --git a/test/PUC-Lua-5.1-tests/sort.lua b/test/PUC-Lua-5.1-tests/sort.lua new file mode 100644 index 0000000..6fccd49 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/sort.lua @@ -0,0 +1,74 @@ +print"testing sort" + + +function check (a, f) + f = f or function (x,y) return x<y end; + for n=table.getn(a),2,-1 do + assert(not f(a[n], a[n-1])) + end +end + +a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"} + +table.sort(a) +check(a) + +limit = 30000 +if rawget(_G, "_soft") then limit = 5000 end + +a = {} +for i=1,limit do + a[i] = math.random() +end + +local x = os.clock() +table.sort(a) +print(string.format("Sorting %d elements in %.2f sec.", limit, os.clock()-x)) +check(a) + +x = os.clock() +table.sort(a) +print(string.format("Re-sorting %d elements in %.2f sec.", limit, os.clock()-x)) +check(a) + +a = {} +for i=1,limit do + a[i] = math.random() +end + +x = os.clock(); i=0 +table.sort(a, function(x,y) i=i+1; return y<x end) +print(string.format("Invert-sorting other %d elements in %.2f sec., with %i comparisons", + limit, os.clock()-x, i)) +check(a, function(x,y) return y<x end) + + +table.sort{} -- empty array + +for i=1,limit do a[i] = false end +x = os.clock(); +table.sort(a, function(x,y) return nil end) +print(string.format("Sorting %d equal elements in %.2f sec.", limit, os.clock()-x)) +check(a, function(x,y) return nil end) +for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end + +a = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"} +table.sort(a) +check(a) + +table.sort(a, function (x, y) + loadstring(string.format("a[%q] = ''", x))() + collectgarbage() + return x<y + end) + + +tt = {__lt = function (a,b) return a.val < b.val end} +a = {} +for i=1,10 do a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end +table.sort(a) +check(a, tt.__lt) +check(a) + +print"OK" diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua new file mode 100644 index 0000000..237dbad --- /dev/null +++ b/test/PUC-Lua-5.1-tests/strings.lua @@ -0,0 +1,176 @@ +print('testing strings and string library') + +assert('alo' < 'alo1') +assert('' < 'a') +assert('alo\0alo' < 'alo\0b') +assert('alo\0alo\0\0' > 'alo\0alo\0') +assert('alo' < 'alo\0') +assert('alo\0' > 'alo') +assert('\0' < '\1') +assert('\0\0' < '\0\1') +assert('\1\0a\0a' <= '\1\0a\0a') +assert(not ('\1\0a\0b' <= '\1\0a\0a')) +assert('\0\0\0' < '\0\0\0\0') +assert(not('\0\0\0\0' < '\0\0\0')) +assert('\0\0\0' <= '\0\0\0\0') +assert(not('\0\0\0\0' <= '\0\0\0')) +assert('\0\0\0' <= '\0\0\0') +assert('\0\0\0' >= '\0\0\0') +assert(not ('\0\0b' < '\0\0a\0')) +print('+') + +assert(string.sub("123456789",2,4) == "234") +assert(string.sub("123456789",7) == "789") +assert(string.sub("123456789",7,6) == "") +assert(string.sub("123456789",7,7) == "7") +assert(string.sub("123456789",0,0) == "") +assert(string.sub("123456789",-10,10) == "123456789") +assert(string.sub("123456789",1,9) == "123456789") +assert(string.sub("123456789",-10,-20) == "") +assert(string.sub("123456789",-1) == "9") +assert(string.sub("123456789",-4) == "6789") +assert(string.sub("123456789",-6, -4) == "456") +assert(string.sub("\000123456789",3,5) == "234") +assert(("\000123456789"):sub(8) == "789") +print('+') + +assert(string.find("123456789", "345") == 3) +a,b = string.find("123456789", "345") +assert(string.sub("123456789", a, b) == "345") +assert(string.find("1234567890123456789", "345", 3) == 3) +assert(string.find("1234567890123456789", "345", 4) == 13) +assert(string.find("1234567890123456789", "346", 4) == nil) +assert(string.find("1234567890123456789", ".45", -9) == 13) +assert(string.find("abcdefg", "\0", 5, 1) == nil) +assert(string.find("", "") == 1) +assert(string.find('', 'aaa', 1) == nil) +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) +print('+') + +assert(string.len("") == 0) +assert(string.len("\0\0\0") == 3) +assert(string.len("1234567890") == 10) + +assert(#"" == 0) +assert(#"\0\0\0" == 3) +assert(#"1234567890" == 10) + +assert(string.byte("a") == 97) +assert(string.byte("á") > 127) +assert(string.byte(string.char(255)) == 255) +assert(string.byte(string.char(0)) == 0) +assert(string.byte("\0") == 0) +assert(string.byte("\0\0alo\0x", -1) == string.byte('x')) +assert(string.byte("ba", 2) == 97) +assert(string.byte("\n\n", 2, -1) == 10) +assert(string.byte("\n\n", 2, 2) == 10) +assert(string.byte("") == nil) +assert(string.byte("hi", -3) == nil) +assert(string.byte("hi", 3) == nil) +assert(string.byte("hi", 9, 10) == nil) +assert(string.byte("hi", 2, 1) == nil) +assert(string.char() == "") +assert(string.char(0, 255, 0) == "\0\255\0") +assert(string.char(0, string.byte("á"), 0) == "\0á\0") +assert(string.char(string.byte("ál\0óu", 1, -1)) == "ál\0óu") +assert(string.char(string.byte("ál\0óu", 1, 0)) == "") +assert(string.char(string.byte("ál\0óu", -10, 100)) == "ál\0óu") +print('+') + +assert(string.upper("ab\0c") == "AB\0C") +assert(string.lower("\0ABCc%$") == "\0abcc%$") +assert(string.rep('teste', 0) == '') +assert(string.rep('tés\00tê', 2) == 'tés\0têtés\000tê') +assert(string.rep('', 10) == '') + +assert(string.reverse"" == "") +assert(string.reverse"\0\1\2\3" == "\3\2\1\0") +assert(string.reverse"\0001234" == "4321\0") + +for i=0,30 do assert(string.len(string.rep('a', i)) == i) end + +assert(type(tostring(nil)) == 'string') +assert(type(tostring(12)) == 'string') +assert(''..12 == '12' and type(12 .. '') == 'string') +assert(string.find(tostring{}, 'table:')) +assert(string.find(tostring(print), 'function:')) +assert(tostring(1234567890123) == '1234567890123') +assert(#tostring('\0') == 1) +assert(tostring(true) == "true") +assert(tostring(false) == "false") +print('+') + +x = '"ílo"\n\\' +assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\') +assert(string.format('%q', "\0") == [["\000"]]) +assert(string.format("\0%c\0%c%x\0", string.byte("á"), string.byte("b"), 140) == + "\0á\0b8c\0") +assert(string.format('') == "") +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == + string.format("%c%c%c%c", 34, 48, 90, 100)) +assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') +assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") +assert(tonumber(string.format("%f", 10.3)) == 10.3) +x = string.format('"%-50s"', 'a') +assert(#x == 52) +assert(string.sub(x, 1, 4) == '"a ') + +assert(string.format("-%.20s.20s", string.rep("%", 2000)) == "-"..string.rep("%", 20)..".20s") +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) == + string.format("%q", "-"..string.rep("%", 2000)..".20s")) + + +-- longest number that can be formated +assert(string.len(string.format('%99.99f', -1e308)) >= 100) + +assert(loadstring("return 1\n--comentário sem EOL no final")() == 1) + + +assert(table.concat{} == "") +assert(table.concat({}, 'x') == "") +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2") +local a = {}; for i=1,3000 do a[i] = "xuxu" end +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 3000)) +assert(table.concat(a, "b", 20, 20) == "xuxu") +assert(table.concat(a, "", 20, 21) == "xuxuxuxu") +assert(table.concat(a, "", 22, 21) == "") +assert(table.concat(a, "3", 2999) == "xuxu3xuxu") + +a = {"a","b","c"} +assert(table.concat(a, ",", 1, 0) == "") +assert(table.concat(a, ",", 1, 1) == "a") +assert(table.concat(a, ",", 1, 2) == "a,b") +assert(table.concat(a, ",", 2) == "b,c") +assert(table.concat(a, ",", 3) == "c") +assert(table.concat(a, ",", 4) == "") + +local locales = { "ptb", "ISO-8859-1", "pt_BR" } +local function trylocale (w) + for _, l in ipairs(locales) do + if os.setlocale(l, w) then return true end + end + return false +end + +if not trylocale("collate") then + print("locale not supported") +else + assert("alo" < "álo" and "álo" < "amo") +end + +if not trylocale("ctype") then + print("locale not supported") +else + assert(string.gsub("áéíóú", "%a", "x") == "xxxxx") + assert(string.gsub("áÁéÉ", "%l", "x") == "xÁxÉ") + assert(string.gsub("áÁéÉ", "%u", "x") == "áxéx") + assert(string.upper"áÁé{xuxu}ção" == "ÁÁÉ{XUXU}ÇÃO") +end + +os.setlocale("C") +assert(os.setlocale() == 'C') +assert(os.setlocale(nil, "numeric") == 'C') + +print('OK') + + diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua new file mode 100644 index 0000000..ae068fa --- /dev/null +++ b/test/PUC-Lua-5.1-tests/vararg.lua @@ -0,0 +1,126 @@ +print('testing vararg') + +_G.arg = nil + +function f(a, ...) + assert(type(arg) == 'table') + assert(type(arg.n) == 'number') + for i=1,arg.n do assert(a[i]==arg[i]) end + return arg.n +end + +function c12 (...) + assert(arg == nil) + local x = {...}; x.n = table.getn(x) + local res = (x.n==2 and x[1] == 1 and x[2] == 2) + if res then res = 55 end + return res, 2 +end + +function vararg (...) return arg end + +local call = function (f, args) return f(unpack(args, 1, args.n)) end + +assert(f() == 0) +assert(f({1,2,3}, 1, 2, 3) == 3) +assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) + +assert(c12(1,2)==55) +a,b = assert(call(c12, {1,2})) +assert(a == 55 and b == 2) +a = call(c12, {1,2;n=2}) +assert(a == 55 and b == 2) +a = call(c12, {1,2;n=1}) +assert(not a) +assert(c12(1,2,3) == false) +local a = vararg(call(next, {_G,nil;n=2})) +local b,c = next(_G) +assert(a[1] == b and a[2] == c and a.n == 2) +a = vararg(call(call, {c12, {1,2}})) +assert(a.n == 2 and a[1] == 55 and a[2] == 2) +a = call(print, {'+'}) +assert(a == nil) + +local t = {1, 10} +function t:f (...) return self[arg[1]]+arg.n end +assert(t:f(1,4) == 3 and t:f(2) == 11) +print('+') + +lim = 20 +local i, a = 1, {} +while i <= lim do a[i] = i+0.3; i=i+1 end + +function f(a, b, c, d, ...) + local more = {...} + assert(a == 1.3 and more[1] == 5.3 and + more[lim-4] == lim+0.3 and not more[lim-3]) +end + +function g(a,b,c) + assert(a == 1.3 and b == 2.3 and c == 3.3) +end + +call(f, a) +call(g, a) + +a = {} +i = 1 +while i <= lim do a[i] = i; i=i+1 end +assert(call(math.max, a) == lim) + +print("+") + + +-- new-style varargs + +function oneless (a, ...) return ... end + +function f (n, a, ...) + local b + assert(arg == nil) + if n == 0 then + local b, c, d = ... + return a, b, c, d, oneless(oneless(oneless(...))) + else + n, b, a = n-1, ..., a + assert(b == ...) + return f(n, a, ...) + end +end + +a,b,c,d,e = assert(f(10,5,4,3,2,1)) +assert(a==5 and b==4 and c==3 and d==2 and e==1) + +a,b,c,d,e = f(4) +assert(a==nil and b==nil and c==nil and d==nil and e==nil) + + +-- varargs for main chunks +f = loadstring[[ return {...} ]] +x = f(2,3) +assert(x[1] == 2 and x[2] == 3 and x[3] == nil) + + +f = loadstring[[ + local x = {...} + for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end + assert(x[select('#', ...)+1] == nil) + return true +]] + +assert(f("a", "b", nil, {}, assert)) +assert(f()) + +a = {select(3, unpack{10,20,30,40})} +assert(table.getn(a) == 2 and a[1] == 30 and a[2] == 40) +a = {select(1)} +assert(next(a) == nil) +a = {select(-1, 3, 5, 7)} +assert(a[1] == 7 and a[2] == nil) +a = {select(-2, 3, 5, 7)} +assert(a[1] == 5 and a[2] == 7 and a[3] == nil) +pcall(select, 10000) +pcall(select, -10000) + +print('OK') + diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua new file mode 100644 index 0000000..59e0142 --- /dev/null +++ b/test/PUC-Lua-5.1-tests/verybig.lua @@ -0,0 +1,100 @@ +if rawget(_G, "_soft") then return 10 end + +print "testing large programs (>64k)" + +-- template to create a very big test file +prog = [[$ + +local a,b + +b = {$1$ + b30009 = 65534, + b30010 = 65535, + b30011 = 65536, + b30012 = 65537, + b30013 = 16777214, + b30014 = 16777215, + b30015 = 16777216, + b30016 = 16777217, + b30017 = 4294967294, + b30018 = 4294967295, + b30019 = 4294967296, + b30020 = 4294967297, + b30021 = -65534, + b30022 = -65535, + b30023 = -65536, + b30024 = -4294967297, + b30025 = 15012.5, + $2$ +}; + +assert(b.a50008 == 25004 and b["a11"] == 5.5) +assert(b.a33007 == 16503.5 and b.a50009 == 25004.5) +assert(b["b"..30024] == -4294967297) + +function b:xxx (a,b) return a+b end +assert(b:xxx(10, 12) == 22) -- pushself with non-constant index +b.xxx = nil + +s = 0; n=0 +for a,b in pairs(b) do s=s+b; n=n+1 end +assert(s==13977183656.5 and n==70001) + +require "checktable" +stat(b) + +a = nil; b = nil +print'+' + +function f(x) b=x end + +a = f{$3$} or 10 + +assert(a==10) +assert(b[1] == "a10" and b[2] == 5 and b[table.getn(b)-1] == "a50009") + + +function xxxx (x) return b[x] end + +assert(xxxx(3) == "a11") + +a = nil; b=nil +xxxx = nil + +return 10 + +]] + +-- functions to fill in the $n$ +F = { +function () -- $1$ + for i=10,50009 do + io.write('a', i, ' = ', 5+((i-10)/2), ',\n') + end +end, + +function () -- $2$ + for i=30026,50009 do + io.write('b', i, ' = ', 15013+((i-30026)/2), ',\n') + end +end, + +function () -- $3$ + for i=10,50009 do + io.write('"a', i, '", ', 5+((i-10)/2), ',\n') + end +end, +} + +file = os.tmpname() +io.output(file) +for s in string.gmatch(prog, "$([^$]+)") do + local n = tonumber(s) + if not n then io.write(s) else F[n]() end +end +io.close() +result = dofile(file) +assert(os.remove(file)) +print'OK' +return result + -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches @ 2021-03-26 10:14 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:13 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 10:14 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Hi! Thanks for the patch, verified with $ for i in `find . -type f` ; do ii=`basename $i`; \ > diff -iwhite $i `find ../../test/PUC-Lua-5.1-tests/ -name $ii` ; done diff: missing operand after `./libs/makefile' diff: Try `diff --help' for more information. $ LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test > suite. Source code taken verbatim (except trailing whitespaces) from > https://www.lua.org/tests/lua5.1-tests.tar.gz. > > Some tests may fail after this commit. They will be disabled > or adapted in the next patches. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > .luacheckrc | 5 +- > test/CMakeLists.txt | 2 + > test/PUC-Lua-5.1-tests/CMakeLists.txt | 45 + > test/PUC-Lua-5.1-tests/README | 41 + > test/PUC-Lua-5.1-tests/all.lua | 137 +++ > test/PUC-Lua-5.1-tests/api.lua | 711 ++++++++++++ > test/PUC-Lua-5.1-tests/attrib.lua | 339 ++++++ > test/PUC-Lua-5.1-tests/big.lua | 381 +++++++ > test/PUC-Lua-5.1-tests/calls.lua | 294 +++++ > test/PUC-Lua-5.1-tests/checktable.lua | 77 ++ > test/PUC-Lua-5.1-tests/closure.lua | 422 +++++++ > test/PUC-Lua-5.1-tests/code.lua | 143 +++ > test/PUC-Lua-5.1-tests/constructs.lua | 240 ++++ > test/PUC-Lua-5.1-tests/db.lua | 499 +++++++++ > test/PUC-Lua-5.1-tests/errors.lua | 250 +++++ > test/PUC-Lua-5.1-tests/etc/ltests.c | 1147 ++++++++++++++++++++ > test/PUC-Lua-5.1-tests/etc/ltests.h | 92 ++ > test/PUC-Lua-5.1-tests/events.lua | 360 ++++++ > test/PUC-Lua-5.1-tests/files.lua | 324 ++++++ > test/PUC-Lua-5.1-tests/gc.lua | 312 ++++++ > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 18 + > test/PUC-Lua-5.1-tests/libs/lib1.c | 40 + > test/PUC-Lua-5.1-tests/libs/lib11.c | 18 + > test/PUC-Lua-5.1-tests/libs/lib2.c | 28 + > test/PUC-Lua-5.1-tests/libs/lib21.c | 18 + > test/PUC-Lua-5.1-tests/literals.lua | 176 +++ > test/PUC-Lua-5.1-tests/locals.lua | 127 +++ > test/PUC-Lua-5.1-tests/main.lua | 159 +++ > test/PUC-Lua-5.1-tests/math.lua | 208 ++++ > test/PUC-Lua-5.1-tests/nextvar.lua | 396 +++++++ > test/PUC-Lua-5.1-tests/pm.lua | 273 +++++ > test/PUC-Lua-5.1-tests/sort.lua | 74 ++ > test/PUC-Lua-5.1-tests/strings.lua | 176 +++ > test/PUC-Lua-5.1-tests/vararg.lua | 126 +++ > test/PUC-Lua-5.1-tests/verybig.lua | 100 ++ > 35 files changed, 7756 insertions(+), 2 deletions(-) > create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/README > create mode 100755 test/PUC-Lua-5.1-tests/all.lua > create mode 100644 test/PUC-Lua-5.1-tests/api.lua > create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua > create mode 100644 test/PUC-Lua-5.1-tests/big.lua > create mode 100644 test/PUC-Lua-5.1-tests/calls.lua > create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua > create mode 100644 test/PUC-Lua-5.1-tests/closure.lua > create mode 100644 test/PUC-Lua-5.1-tests/code.lua > create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua > create mode 100644 test/PUC-Lua-5.1-tests/db.lua > create mode 100644 test/PUC-Lua-5.1-tests/errors.lua > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h > create mode 100644 test/PUC-Lua-5.1-tests/events.lua > create mode 100644 test/PUC-Lua-5.1-tests/files.lua > create mode 100644 test/PUC-Lua-5.1-tests/gc.lua > create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c > create mode 100644 test/PUC-Lua-5.1-tests/literals.lua > create mode 100644 test/PUC-Lua-5.1-tests/locals.lua > create mode 100644 test/PUC-Lua-5.1-tests/main.lua > create mode 100644 test/PUC-Lua-5.1-tests/math.lua > create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua > create mode 100644 test/PUC-Lua-5.1-tests/pm.lua > create mode 100644 test/PUC-Lua-5.1-tests/sort.lua > create mode 100644 test/PUC-Lua-5.1-tests/strings.lua > create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua > create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua > > diff --git a/.luacheckrc b/.luacheckrc > index 4e5dbdf..fd5583b 100644 > --- a/.luacheckrc > +++ b/.luacheckrc > @@ -3,11 +3,12 @@ std = 'luajit' > -- This fork also introduces a new global for misc API namespace. > read_globals = { 'misc' } > > --- These files are inherited from the vanilla LuaJIT and need to > --- be coherent with the upstream. > +-- These files are inherited from the vanilla LuaJIT or different > +-- test suites and need to be coherent with the upstream. > exclude_files = { > 'dynasm/', > 'src/', > 'test/LuaJIT-tests/', > + 'test/PUC-Lua-5.1-tests/', > 'test/lua-Harness-tests/', > } > diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt > index 02fb2ed..30cbf87 100644 > --- a/test/CMakeLists.txt > +++ b/test/CMakeLists.txt > @@ -44,11 +44,13 @@ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]" > separate_arguments(LUAJIT_TEST_COMMAND) > > add_subdirectory(LuaJIT-tests) > +add_subdirectory(PUC-Lua-5.1-tests) > add_subdirectory(lua-Harness-tests) > add_subdirectory(tarantool-tests) > > add_custom_target(${PROJECT_NAME}-test DEPENDS > LuaJIT-tests > + PUC-Lua-5.1-tests > lua-Harness-tests > tarantool-tests > ) > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > new file mode 100644 > index 0000000..773db0d > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -0,0 +1,45 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +# XXX: There are two ways to set up the proper environment > +# described in the suite's README: > +# * set LUA_PATH to "?;./?.lua" > +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to > +# "package.path = '?;'..package.path" > +# Unfortunately, Tarantool doesn't support LUA_INIT and most > +# likely it never will. For more info, see > +# https://github.com/tarantool/tarantool/issues/5744 > +# Hence, there is no way other than set LUA_PATH environment > +# variable as proposed in the first case. > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > + > +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> > +# subdirectory. > +add_subdirectory(libs) > + > +# TODO: PUC-Rio Lua 5.1 test suite also has special header > +# <ltests.h> and <ltests.c> translation unit to check some > +# internal behaviour of the Lua implementation (see etc/ > +# directory). It modifies realloc function to check memory > +# consistency and also contains tests for yield in hooks > +# and for the Lua C API. > +# But, unfortunately, <ltests.c> depends on specific PUC-Rio > +# Lua 5.1 internal headers and should be adapted for LuaJIT. > + > +add_custom_target(PUC-Lua-5.1-tests > + DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare > +) > + > +add_custom_command(TARGET PUC-Lua-5.1-tests > + COMMENT "Running PUC-Rio Lua 5.1 tests" > + COMMAND > + env > + LUA_PATH="${LUA_PATH}\;\;" > + ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 > diff --git a/test/PUC-Lua-5.1-tests/README b/test/PUC-Lua-5.1-tests/README > new file mode 100644 > index 0000000..e2d4b28 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/README > @@ -0,0 +1,41 @@ > +This tarball contains the official test scripts for Lua 5.1. > +Unlike Lua itself, these tests do not aim portability, small footprint, > +or easy of use. (Their main goal is to try to crash Lua.) They are not > +intended for general use. You are wellcome to use them, but expect to > +have to "dirt your hands". > + > +The tarball should expand in the following contents: > + - several .lua scripts with the tests > + - a main "all.lua" Lua script that invokes all the other scripts > + - a subdirectory "libs" with an empty subdirectory "libs/P1", > + to be used by the scripts > + - a subdirectory "etc" with some extra files > + > +To run the tests, do as follows: > + > +- go to the test directory > + > +- set LUA_PATH to "?;./?.lua" (or, better yet, set LUA_PATH to "./?.lua;;" > + and LUA_INIT to "package.path = '?;'..package.path") > + > +- run "lua all.lua" > + > + > +-------------------------------------------- > +Internal tests > +-------------------------------------------- > + > +Some tests need a special library, "testC", that gives access to > +several internal structures in Lua. > +This library is only available when Lua is compiled in debug mode. > +The scripts automatically detect its absence and skip those tests. > + > +If you want to run these tests, move etc/ltests.c and etc/ltests.h to > +the directory with the source Lua files, and recompile Lua with > +the option -DLUA_USER_H='"ltests.h"' (or its equivalent to define > +LUA_USER_H as the string "ltests.h", including the quotes). This > +option not only adds the testC library, but it adds several other > +internal tests as well. After the recompilation, run the tests > +as before. > + > + > diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua > new file mode 100755 > index 0000000..8c4afac > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/all.lua > @@ -0,0 +1,137 @@ > +#!../lua > + > +math.randomseed(0) > + > +collectgarbage("setstepmul", 180) > +collectgarbage("setpause", 190) > + > + > +--[=[ > + example of a long [comment], > + [[spanning several [lines]]] > + > +]=] > + > +print("current path:\n " .. string.gsub(package.path, ";", "\n ")) > + > + > +local msgs = {} > +function Message (m) > + print(m) > + msgs[#msgs+1] = string.sub(m, 3, -3) > +end > + > + > +local c = os.clock() > + > +assert(os.setlocale"C") > + > +local T,print,gcinfo,format,write,assert,type = > + T,print,gcinfo,string.format,io.write,assert,type > + > +local function formatmem (m) > + if m < 1024 then return m > + else > + m = m/1024 - m/1024%1 > + if m < 1024 then return m.."K" > + else > + m = m/1024 - m/1024%1 > + return m.."M" > + end > + end > +end > + > +local showmem = function () > + if not T then > + print(format(" ---- total memory: %s ----\n", formatmem(gcinfo()))) > + else > + T.checkmemory() > + local a,b,c = T.totalmem() > + local d,e = gcinfo() > + print(format( > + "\n ---- total memory: %s (%dK), max use: %s, blocks: %d\n", > + formatmem(a), d, formatmem(c), b)) > + end > +end > + > + > +-- > +-- redefine dofile to run files through dump/undump > +-- > +dofile = function (n) > + showmem() > + local f = assert(loadfile(n)) > + local b = string.dump(f) > + f = assert(loadstring(b)) > + return f() > +end > + > +dofile('main.lua') > + > +do > + local u = newproxy(true) > + local newproxy, stderr = newproxy, io.stderr > + getmetatable(u).__gc = function (o) > + stderr:write'.' > + newproxy(o) > + end > +end > + > +local f = assert(loadfile('gc.lua')) > +f() > +dofile('db.lua') > +assert(dofile('calls.lua') == deep and deep) > +dofile('strings.lua') > +dofile('literals.lua') > +assert(dofile('attrib.lua') == 27) > +assert(dofile('locals.lua') == 5) > +dofile('constructs.lua') > +dofile('code.lua') > +do > + local f = coroutine.wrap(assert(loadfile('big.lua'))) > + assert(f() == 'b') > + assert(f() == 'a') > +end > +dofile('nextvar.lua') > +dofile('pm.lua') > +dofile('api.lua') > +assert(dofile('events.lua') == 12) > +dofile('vararg.lua') > +dofile('closure.lua') > +dofile('errors.lua') > +dofile('math.lua') > +dofile('sort.lua') > +assert(dofile('verybig.lua') == 10); collectgarbage() > +dofile('files.lua') > + > +if #msgs > 0 then > + print("\ntests not performed:") > + for i=1,#msgs do > + print(msgs[i]) > + end > + print() > +end > + > +print("final OK !!!") > +print('cleaning all!!!!') > + > +debug.sethook(function (a) assert(type(a) == 'string') end, "cr") > + > +local _G, collectgarbage, showmem, print, format, clock = > + _G, collectgarbage, showmem, print, format, os.clock > + > +local a={} > +for n in pairs(_G) do a[n] = 1 end > +a.tostring = nil > +a.___Glob = nil > +for n in pairs(a) do _G[n] = nil end > + > +a = nil > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage() > +collectgarbage();showmem() > + > +print(format("\n\ntotal time: %.2f\n", clock()-c)) > diff --git a/test/PUC-Lua-5.1-tests/api.lua b/test/PUC-Lua-5.1-tests/api.lua > new file mode 100644 > index 0000000..c955ebf > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/api.lua > @@ -0,0 +1,711 @@ > + > +if T==nil then > + (Message or print)('\a\n >>> testC not active: skipping API tests <<<\n\a') > + return > +end > + > + > + > +function tcheck (t1, t2) > + table.remove(t1, 1) -- remove code > + assert(table.getn(t1) == table.getn(t2)) > + for i=1,table.getn(t1) do assert(t1[i] == t2[i]) end > +end > + > +function pack(...) return arg end > + > + > +print('testing C API') > + > +-- testing allignment > +a = T.d2s(12458954321123) > +assert(string.len(a) == 8) -- sizeof(double) > +assert(T.s2d(a) == 12458954321123) > + > +a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2") > +assert(a == 2 and b == 3 and not c) > + > +-- test that all trues are equal > +a,b,c = T.testC("pushbool 1; pushbool 2; pushbool 0; return 3") > +assert(a == b and a == true and c == false) > +a,b,c = T.testC"pushbool 0; pushbool 10; pushnil;\ > + tobool -3; tobool -3; tobool -3; return 3" > +assert(a==0 and b==1 and c==0) > + > + > +a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40) > +assert(a == 40 and b == 5 and not c) > + > +t = pack(T.testC("settop 5; gettop; return .", 2, 3)) > +tcheck(t, {n=4,2,3}) > + > +t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23)) > +assert(t.n == 10 and t[1] == nil and t[10] == nil) > + > +t = pack(T.testC("remove -2; gettop; return .", 2, 3, 4)) > +tcheck(t, {n=2,2,4}) > + > +t = pack(T.testC("insert -1; gettop; return .", 2, 3)) > +tcheck(t, {n=2,2,3}) > + > +t = pack(T.testC("insert 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=4,2,5,3,4}) > + > +t = pack(T.testC("replace 2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,5,3,4}) > + > +t = pack(T.testC("replace -2; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,2,3,5}) > + > +t = pack(T.testC("remove 3; gettop; return .", 2, 3, 4, 5)) > +tcheck(t, {n=3,2,4,5}) > + > +t = pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2; \ > + insert 2; pushvalue 1; remove 1; insert 1; \ > + insert -2; pushvalue -2; remove -3; gettop; return .", > + 2, 3, 4, 5, 10, 40, 90)) > +tcheck(t, {n=7,2,3,4,5,10,40,90}) > + > +t = pack(T.testC("concat 5; gettop; return .", "alo", 2, 3, "joao", 12)) > +tcheck(t, {n=1,"alo23joao12"}) > + > +-- testing MULTRET > +t = pack(T.testC("rawcall 2,-1; gettop; return .", > + function (a,b) return 1,2,3,4,a,b end, "alo", "joao")) > +tcheck(t, {n=6,1,2,3,4,"alo", "joao"}) > + > +do -- test returning more results than fit in the caller stack > + local a = {} > + for i=1,1000 do a[i] = true end; a[999] = 10 > + local b = T.testC([[call 1 -1; pop 1; tostring -1; return 1]], unpack, a) > + assert(b == "10") > +end > + > + > +-- testing lessthan > +assert(T.testC("lessthan 2 5, return 1", 3, 2, 2, 4, 2, 2)) > +assert(T.testC("lessthan 5 2, return 1", 4, 2, 2, 3, 2, 2)) > +assert(not T.testC("lessthan 2 -3, return 1", "4", "2", "2", "3", "2", "2")) > +assert(not T.testC("lessthan -3 2, return 1", "3", "2", "2", "4", "2", "2")) > + > +local b = {__lt = function (a,b) return a[1] < b[1] end} > +local a1,a3,a4 = setmetatable({1}, b), > + setmetatable({3}, b), > + setmetatable({4}, b) > +assert(T.testC("lessthan 2 5, return 1", a3, 2, 2, a4, 2, 2)) > +assert(T.testC("lessthan 5 -6, return 1", a4, 2, 2, a3, 2, 2)) > +a,b = T.testC("lessthan 5 -6, return 2", a1, 2, 2, a3, 2, 20) > +assert(a == 20 and b == false) > + > + > +-- testing lua_is > + > +function count (x, n) > + n = n or 2 > + local prog = [[ > + isnumber %d; > + isstring %d; > + isfunction %d; > + iscfunction %d; > + istable %d; > + isuserdata %d; > + isnil %d; > + isnull %d; > + return 8 > + ]] > + prog = string.format(prog, n, n, n, n, n, n, n, n) > + local a,b,c,d,e,f,g,h = T.testC(prog, x) > + return a+b+c+d+e+f+g+(100*h) > +end > + > +assert(count(3) == 2) > +assert(count('alo') == 1) > +assert(count('32') == 2) > +assert(count({}) == 1) > +assert(count(print) == 2) > +assert(count(function () end) == 1) > +assert(count(nil) == 1) > +assert(count(io.stdin) == 1) > +assert(count(nil, 15) == 100) > + > +-- testing lua_to... > + > +function to (s, x, n) > + n = n or 2 > + return T.testC(string.format("%s %d; return 1", s, n), x) > +end > + > +assert(to("tostring", {}) == nil) > +assert(to("tostring", "alo") == "alo") > +assert(to("tostring", 12) == "12") > +assert(to("tostring", 12, 3) == nil) > +assert(to("objsize", {}) == 0) > +assert(to("objsize", "alo\0\0a") == 6) > +assert(to("objsize", T.newuserdata(0)) == 0) > +assert(to("objsize", T.newuserdata(101)) == 101) > +assert(to("objsize", 12) == 2) > +assert(to("objsize", 12, 3) == 0) > +assert(to("tonumber", {}) == 0) > +assert(to("tonumber", "12") == 12) > +assert(to("tonumber", "s2") == 0) > +assert(to("tonumber", 1, 20) == 0) > +a = to("tocfunction", math.deg) > +assert(a(3) == math.deg(3) and a ~= math.deg) > + > + > +-- testing errors > + > +a = T.testC([[ > + loadstring 2; call 0,1; > + pushvalue 3; insert -2; call 1, 1; > + call 0, 0; > + return 1 > +]], "x=150", function (a) assert(a==nil); return 3 end) > + > +assert(type(a) == 'string' and x == 150) > + > +function check3(p, ...) > + assert(arg.n == 3) > + assert(string.find(arg[3], p)) > +end > +check3(":1:", T.testC("loadstring 2; gettop; return .", "x=")) > +check3("cannot read", T.testC("loadfile 2; gettop; return .", ".")) > +check3("cannot open xxxx", T.testC("loadfile 2; gettop; return .", "xxxx")) > + > +-- testing table access > + > +a = {x=0, y=12} > +x, y = T.testC("gettable 2; pushvalue 4; gettable 2; return 2", > + a, 3, "y", 4, "x") > +assert(x == 0 and y == 12) > +T.testC("settable -5", a, 3, 4, "x", 15) > +assert(a.x == 15) > +a[a] = print > +x = T.testC("gettable 2; return 1", a) -- table and key are the same object! > +assert(x == print) > +T.testC("settable 2", a, "x") -- table and key are the same object! > +assert(a[a] == "x") > + > +b = setmetatable({p = a}, {}) > +getmetatable(b).__index = function (t, i) return t.p[i] end > +k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x") > +assert(x == 15 and k == 35) > +getmetatable(b).__index = function (t, i) return a[i] end > +getmetatable(b).__newindex = function (t, i,v ) a[i] = v end > +y = T.testC("insert 2; gettable -5; return 1", 2, 3, 4, "y", b) > +assert(y == 12) > +k = T.testC("settable -5, return 1", b, 3, 4, "x", 16) > +assert(a.x == 16 and k == 4) > +a[b] = 'xuxu' > +y = T.testC("gettable 2, return 1", b) > +assert(y == 'xuxu') > +T.testC("settable 2", b, 19) > +assert(a[b] == 19) > + > +-- testing next > +a = {} > +t = pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=1,a}) > +a = {a=3} > +t = pack(T.testC("next; gettop; return .", a, nil)) > +tcheck(t, {n=3,a,'a',3}) > +t = pack(T.testC("next; pop 1; next; gettop; return .", a, nil)) > +tcheck(t, {n=1,a}) > + > + > + > +-- testing upvalues > + > +do > + local A = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] > + t, b, c = A([[pushvalue U0; pushvalue U1; pushvalue U2; return 3]]) > + assert(b == 10 and c == 20 and type(t) == 'table') > + a, b = A([[tostring U3; tonumber U4; return 2]]) > + assert(a == nil and b == 0) > + A([[pushnum 100; pushnum 200; replace U2; replace U1]]) > + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b == 100 and c == 200) > + A([[replace U2; replace U1]], {x=1}, {x=2}) > + b, c = A([[pushvalue U1; pushvalue U2; return 2]]) > + assert(b.x == 1 and c.x == 2) > + T.checkmemory() > +end > + > +local f = T.testC[[ pushnum 10; pushnum 20; pushcclosure 2; return 1]] > +assert(T.upvalue(f, 1) == 10 and > + T.upvalue(f, 2) == 20 and > + T.upvalue(f, 3) == nil) > +T.upvalue(f, 2, "xuxu") > +assert(T.upvalue(f, 2) == "xuxu") > + > + > +-- testing environments > + > +assert(T.testC"pushvalue G; return 1" == _G) > +assert(T.testC"pushvalue E; return 1" == _G) > +local a = {} > +T.testC("replace E; return 1", a) > +assert(T.testC"pushvalue G; return 1" == _G) > +assert(T.testC"pushvalue E; return 1" == a) > +assert(debug.getfenv(T.testC) == a) > +assert(debug.getfenv(T.upvalue) == _G) > +-- userdata inherit environment > +local u = T.testC"newuserdata 0; return 1" > +assert(debug.getfenv(u) == a) > +-- functions inherit environment > +u = T.testC"pushcclosure 0; return 1" > +assert(debug.getfenv(u) == a) > +debug.setfenv(T.testC, _G) > +assert(T.testC"pushvalue E; return 1" == _G) > + > +local b = newproxy() > +assert(debug.getfenv(b) == _G) > +assert(debug.setfenv(b, a)) > +assert(debug.getfenv(b) == a) > + > + > + > +-- testing locks (refs) > + > +-- reuse of references > +local i = T.ref{} > +T.unref(i) > +assert(T.ref{} == i) > + > +Arr = {} > +Lim = 100 > +for i=1,Lim do -- lock many objects > + Arr[i] = T.ref({}) > +end > + > +assert(T.ref(nil) == -1 and T.getref(-1) == nil) > +T.unref(-1); T.unref(-1) > + > +for i=1,Lim do -- unlock all them > + T.unref(Arr[i]) > +end > + > +function printlocks () > + local n = T.testC("gettable R; return 1", "n") > + print("n", n) > + for i=0,n do > + print(i, T.testC("gettable R; return 1", i)) > + end > +end > + > + > +for i=1,Lim do -- lock many objects > + Arr[i] = T.ref({}) > +end > + > +for i=1,Lim,2 do -- unlock half of them > + T.unref(Arr[i]) > +end > + > +assert(type(T.getref(Arr[2])) == 'table') > + > + > +assert(T.getref(-1) == nil) > + > + > +a = T.ref({}) > + > +collectgarbage() > + > +assert(type(T.getref(a)) == 'table') > + > + > +-- colect in cl the `val' of all collected userdata > +tt = {} > +cl = {n=0} > +A = nil; B = nil > +local F > +F = function (x) > + local udval = T.udataval(x) > + table.insert(cl, udval) > + local d = T.newuserdata(100) -- cria lixo > + d = nil > + assert(debug.getmetatable(x).__gc == F) > + loadstring("table.insert({}, {})")() -- cria mais lixo > + collectgarbage() -- forca coleta de lixo durante coleta! > + assert(debug.getmetatable(x).__gc == F) -- coleta anterior nao melou isso? > + local dummy = {} -- cria lixo durante coleta > + if A ~= nil then > + assert(type(A) == "userdata") > + assert(T.udataval(A) == B) > + debug.getmetatable(A) -- just acess it > + end > + A = x -- ressucita userdata > + B = udval > + return 1,2,3 > +end > +tt.__gc = F > + > +-- test whether udate collection frees memory in the right time > +do > + collectgarbage(); > + collectgarbage(); > + local x = collectgarbage("count"); > + local a = T.newuserdata(5001) > + assert(T.testC("objsize 2; return 1", a) == 5001) > + assert(collectgarbage("count") >= x+4) > + a = nil > + collectgarbage(); > + assert(collectgarbage("count") <= x+1) > + -- udata without finalizer > + x = collectgarbage("count") > + collectgarbage("stop") > + for i=1,1000 do newproxy(false) end > + assert(collectgarbage("count") > x+10) > + collectgarbage() > + assert(collectgarbage("count") <= x+1) > + -- udata with finalizer > + x = collectgarbage("count") > + collectgarbage() > + collectgarbage("stop") > + a = newproxy(true) > + getmetatable(a).__gc = function () end > + for i=1,1000 do newproxy(a) end > + assert(collectgarbage("count") >= x+10) > + collectgarbage() -- this collection only calls TM, without freeing memory > + assert(collectgarbage("count") >= x+10) > + collectgarbage() -- now frees memory > + assert(collectgarbage("count") <= x+1) > +end > + > + > +collectgarbage("stop") > + > +-- create 3 userdatas with tag `tt' > +a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a) > +b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b) > +c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c) > + > +-- create userdata without meta table > +x = T.newuserdata(4) > +y = T.newuserdata(0) > + > +assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil) > + > +d=T.ref(a); > +e=T.ref(b); > +f=T.ref(c); > +t = {T.getref(d), T.getref(e), T.getref(f)} > +assert(t[1] == a and t[2] == b and t[3] == c) > + > +t=nil; a=nil; c=nil; > +T.unref(e); T.unref(f) > + > +collectgarbage() > + > +-- check that unref objects have been collected > +assert(table.getn(cl) == 1 and cl[1] == nc) > + > +x = T.getref(d) > +assert(type(x) == 'userdata' and debug.getmetatable(x) == tt) > +x =nil > +tt.b = b -- create cycle > +tt=nil -- frees tt for GC > +A = nil > +b = nil > +T.unref(d); > +n5 = T.newuserdata(0) > +debug.setmetatable(n5, {__gc=F}) > +n5 = T.udataval(n5) > +collectgarbage() > +assert(table.getn(cl) == 4) > +-- check order of collection > +assert(cl[2] == n5 and cl[3] == nb and cl[4] == na) > + > + > +a, na = {}, {} > +for i=30,1,-1 do > + a[i] = T.newuserdata(0) > + debug.setmetatable(a[i], {__gc=F}) > + na[i] = T.udataval(a[i]) > +end > +cl = {} > +a = nil; collectgarbage() > +assert(table.getn(cl) == 30) > +for i=1,30 do assert(cl[i] == na[i]) end > +na = nil > + > + > +for i=2,Lim,2 do -- unlock the other half > + T.unref(Arr[i]) > +end > + > +x = T.newuserdata(41); debug.setmetatable(x, {__gc=F}) > +assert(T.testC("objsize 2; return 1", x) == 41) > +cl = {} > +a = {[x] = 1} > +x = T.udataval(x) > +collectgarbage() > +-- old `x' cannot be collected (`a' still uses it) > +assert(table.getn(cl) == 0) > +for n in pairs(a) do a[n] = nil end > +collectgarbage() > +assert(table.getn(cl) == 1 and cl[1] == x) -- old `x' must be collected > + > +-- testing lua_equal > +assert(T.testC("equal 2 4; return 1", print, 1, print, 20)) > +assert(T.testC("equal 3 2; return 1", 'alo', "alo")) > +assert(T.testC("equal 2 3; return 1", nil, nil)) > +assert(not T.testC("equal 2 3; return 1", {}, {})) > +assert(not T.testC("equal 2 3; return 1")) > +assert(not T.testC("equal 2 3; return 1", 3)) > + > +-- testing lua_equal with fallbacks > +do > + local map = {} > + local t = {__eq = function (a,b) return map[a] == map[b] end} > + local function f(x) > + local u = T.newuserdata(0) > + debug.setmetatable(u, t) > + map[u] = x > + return u > + end > + assert(f(10) == f(10)) > + assert(f(10) ~= f(11)) > + assert(T.testC("equal 2 3; return 1", f(10), f(10))) > + assert(not T.testC("equal 2 3; return 1", f(10), f(20))) > + t.__eq = nil > + assert(f(10) ~= f(10)) > +end > + > +print'+' > + > + > + > +------------------------------------------------------------------------- > +do -- testing errors during GC > + local a = {} > + for i=1,20 do > + a[i] = T.newuserdata(i) -- creates several udata > + end > + for i=1,20,2 do -- mark half of them to raise error during GC > + debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end}) > + end > + for i=2,20,2 do -- mark the other half to count and to create more garbage > + debug.setmetatable(a[i], {__gc = function (x) loadstring("A=A+1")() end}) > + end > + _G.A = 0 > + a = 0 > + while 1 do > + if xpcall(collectgarbage, function (s) a=a+1 end) then > + break -- stop if no more errors > + end > + end > + assert(a == 10) -- number of errors > + assert(A == 10) -- number of normal collections > +end > +------------------------------------------------------------------------- > +-- test for userdata vals > +do > + local a = {}; local lim = 30 > + for i=0,lim do a[i] = T.pushuserdata(i) end > + for i=0,lim do assert(T.udataval(a[i]) == i) end > + for i=0,lim do assert(T.pushuserdata(i) == a[i]) end > + for i=0,lim do a[a[i]] = i end > + for i=0,lim do a[T.pushuserdata(i)] = i end > + assert(type(tostring(a[1])) == "string") > +end > + > + > +------------------------------------------------------------------------- > +-- testing multiple states > +T.closestate(T.newstate()); > +L1 = T.newstate() > +assert(L1) > +assert(pack(T.doremote(L1, "function f () return 'alo', 3 end; f()")).n == 0) > + > +a, b = T.doremote(L1, "return f()") > +assert(a == 'alo' and b == '3') > + > +T.doremote(L1, "_ERRORMESSAGE = nil") > +-- error: `sin' is not defined > +a, b = T.doremote(L1, "return sin(1)") > +assert(a == nil and b == 2) -- 2 == run-time error > + > +-- error: syntax error > +a, b, c = T.doremote(L1, "return a+") > +assert(a == nil and b == 3 and type(c) == "string") -- 3 == syntax error > + > +T.loadlib(L1) > +a, b = T.doremote(L1, [[ > + a = strlibopen() > + a = packageopen() > + a = baselibopen(); assert(a == _G and require("_G") == a) > + a = iolibopen(); assert(type(a.read) == "function") > + assert(require("io") == a) > + a = tablibopen(); assert(type(a.insert) == "function") > + a = dblibopen(); assert(type(a.getlocal) == "function") > + a = mathlibopen(); assert(type(a.sin) == "function") > + return string.sub('okinama', 1, 2) > +]]) > +assert(a == "ok") > + > +T.closestate(L1); > + > +L1 = T.newstate() > +T.loadlib(L1) > +T.doremote(L1, "a = {}") > +T.testC(L1, [[pushstring a; gettable G; pushstring x; pushnum 1; > + settable -3]]) > +assert(T.doremote(L1, "return a.x") == "1") > + > +T.closestate(L1) > + > +L1 = nil > + > +print('+') > + > +------------------------------------------------------------------------- > +-- testing memory limits > +------------------------------------------------------------------------- > +collectgarbage() > +T.totalmem(T.totalmem()+5000) -- set low memory limit (+5k) > +assert(not pcall(loadstring"local a={}; for i=1,100000 do a[i]=i end")) > +T.totalmem(1000000000) -- restore high limit > + > + > +local function stack(x) if x>0 then stack(x-1) end end > + > +-- test memory errors; increase memory limit in small steps, so that > +-- we get memory errors in different parts of a given task, up to there > +-- is enough memory to complete the task without errors > +function testamem (s, f) > + collectgarbage() > + stack(10) -- ensure minimum stack size > + local M = T.totalmem() > + local oldM = M > + local a,b = nil > + while 1 do > + M = M+3 -- increase memory limit in small steps > + T.totalmem(M) > + a, b = pcall(f) > + if a and b then break end -- stop when no more errors > + collectgarbage() > + if not a and not string.find(b, "memory") then -- `real' error? > + T.totalmem(1000000000) -- restore high limit > + error(b, 0) > + end > + end > + T.totalmem(1000000000) -- restore high limit > + print("\nlimit for " .. s .. ": " .. M-oldM) > + return b > +end > + > + > +-- testing memory errors when creating a new state > + > +b = testamem("state creation", T.newstate) > +T.closestate(b); -- close new state > + > + > +-- testing threads > + > +function expand (n,s) > + if n==0 then return "" end > + local e = string.rep("=", n) > + return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n", > + e, s, expand(n-1,s), e) > +end > + > +G=0; collectgarbage(); a =collectgarbage("count") > +loadstring(expand(20,"G=G+1"))() > +assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1) > + > +testamem("thread creation", function () > + return T.doonnewstack("x=1") == 0 -- try to create thread > +end) > + > + > +-- testing memory x compiler > + > +testamem("loadstring", function () > + return loadstring("x=1") -- try to do a loadstring > +end) > + > + > +local testprog = [[ > +local function foo () return end > +local t = {"x"} > +a = "aaa" > +for _, v in ipairs(t) do a=a..v end > +return true > +]] > + > +-- testing memory x dofile > +_G.a = nil > +local t =os.tmpname() > +local f = assert(io.open(t, "w")) > +f:write(testprog) > +f:close() > +testamem("dofile", function () > + local a = loadfile(t) > + return a and a() > +end) > +assert(os.remove(t)) > +assert(_G.a == "aaax") > + > + > +-- other generic tests > + > +testamem("string creation", function () > + local a, b = string.gsub("alo alo", "(a)", function (x) return x..'b' end) > + return (a == 'ablo ablo') > +end) > + > +testamem("dump/undump", function () > + local a = loadstring(testprog) > + local b = a and string.dump(a) > + a = b and loadstring(b) > + return a and a() > +end) > + > +local t = os.tmpname() > +testamem("file creation", function () > + local f = assert(io.open(t, 'w')) > + assert (not io.open"nomenaoexistente") > + io.close(f); > + return not loadfile'nomenaoexistente' > +end) > +assert(os.remove(t)) > + > +testamem("table creation", function () > + local a, lim = {}, 10 > + for i=1,lim do a[i] = i; a[i..'a'] = {} end > + return (type(a[lim..'a']) == 'table' and a[lim] == lim) > +end) > + > +local a = 1 > +close = nil > +testamem("closure creation", function () > + function close (b,c) > + return function (x) return a+b+c+x end > + end > + return (close(2,3)(4) == 10) > +end) > + > +testamem("coroutines", function () > + local a = coroutine.wrap(function () > + coroutine.yield(string.rep("a", 10)) > + return {} > + end) > + assert(string.len(a()) == 10) > + return a() > +end) > + > +print'+' > + > +-- testing some auxlib functions > +assert(T.gsub("alo.alo.uhuh.", ".", "//") == "alo//alo//uhuh//") > +assert(T.gsub("alo.alo.uhuh.", "alo", "//") == "//.//.uhuh.") > +assert(T.gsub("", "alo", "//") == "") > +assert(T.gsub("...", ".", "/.") == "/././.") > +assert(T.gsub("...", "...", "") == "") > + > + > +print'OK' > + > diff --git a/test/PUC-Lua-5.1-tests/attrib.lua b/test/PUC-Lua-5.1-tests/attrib.lua > new file mode 100644 > index 0000000..655669b > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/attrib.lua > @@ -0,0 +1,339 @@ > +do --[ > + > +print "testing require" > + > +assert(require"string" == string) > +assert(require"math" == math) > +assert(require"table" == table) > +assert(require"io" == io) > +assert(require"os" == os) > +assert(require"debug" == debug) > +assert(require"coroutine" == coroutine) > + > +assert(type(package.path) == "string") > +assert(type(package.cpath) == "string") > +assert(type(package.loaded) == "table") > +assert(type(package.preload) == "table") > + > + > +local DIR = "libs/" > + > +local function createfiles (files, preextras, posextras) > + for n,c in pairs(files) do > + io.output(DIR..n) > + io.write(string.format(preextras, n)) > + io.write(c) > + io.write(string.format(posextras, n)) > + io.close(io.output()) > + end > +end > + > +function removefiles (files) > + for n in pairs(files) do > + os.remove(DIR..n) > + end > +end > + > +local files = { > + ["A.lua"] = "", > + ["B.lua"] = "assert(...=='B');require 'A'", > + ["A.lc"] = "", > + ["A"] = "", > + ["L"] = "", > + ["XXxX"] = "", > + ["C.lua"] = "package.loaded[...] = 25; require'C'" > +} > + > +AA = nil > +local extras = [[ > +NAME = '%s' > +REQUIRED = ... > +return AA]] > + > +createfiles(files, "", extras) > + > + > +local oldpath = package.path > + > +package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR) > + > +local try = function (p, n, r) > + NAME = nil > + local rr = require(p) > + assert(NAME == n) > + assert(REQUIRED == p) > + assert(rr == r) > +end > + > +assert(require"C" == 25) > +assert(require"C" == 25) > +AA = nil > +try('B', 'B.lua', true) > +assert(package.loaded.B) > +assert(require"B" == true) > +assert(package.loaded.A) > +package.loaded.A = nil > +try('B', nil, true) -- should not reload package > +try('A', 'A.lua', true) > +package.loaded.A = nil > +os.remove(DIR..'A.lua') > +AA = {} > +try('A', 'A.lc', AA) -- now must find second option > +assert(require("A") == AA) > +AA = false > +try('K', 'L', false) -- default option > +try('K', 'L', false) -- default option (should reload it) > +assert(rawget(_G, "_REQUIREDNAME") == nil) > + > +AA = "x" > +try("X", "XXxX", AA) > + > + > +removefiles(files) > + > + > +-- testing require of sub-packages > + > +package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) > + > +files = { > + ["P1/init.lua"] = "AA = 10", > + ["P1/xuxu.lua"] = "AA = 20", > +} > + > +createfiles(files, "module(..., package.seeall)\n", "") > +AA = 0 > + > +local m = assert(require"P1") > +assert(m == P1 and m._NAME == "P1" and AA == 0 and m.AA == 10) > +assert(require"P1" == P1 and P1 == m) > +assert(require"P1" == P1) > +assert(P1._PACKAGE == "") > + > +local m = assert(require"P1.xuxu") > +assert(m == P1.xuxu and m._NAME == "P1.xuxu" and AA == 0 and m.AA == 20) > +assert(require"P1.xuxu" == P1.xuxu and P1.xuxu == m) > +assert(require"P1.xuxu" == P1.xuxu) > +assert(require"P1" == P1) > +assert(P1.xuxu._PACKAGE == "P1.") > +assert(P1.AA == 10 and P1._PACKAGE == "") > +assert(P1._G == _G and P1.xuxu._G == _G) > + > + > + > +removefiles(files) > + > + > +package.path = "" > +assert(not pcall(require, "file_does_not_exist")) > +package.path = "??\0?" > +assert(not pcall(require, "file_does_not_exist1")) > + > +package.path = oldpath > + > +-- check 'require' error message > +local fname = "file_does_not_exist2" > +local m, err = pcall(require, fname) > +for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do > + t = string.gsub(t, "?", fname) > + assert(string.find(err, t, 1, true)) > +end > + > + > +local function import(...) > + local f = {...} > + return function (m) > + for i=1, #f do m[f[i]] = _G[f[i]] end > + end > +end > + > +local assert, module, package = assert, module, package > +X = nil; x = 0; assert(_G.x == 0) -- `x' must be a global variable > +module"X"; x = 1; assert(_M.x == 1) > +module"X.a.b.c"; x = 2; assert(_M.x == 2) > +module("X.a.b", package.seeall); x = 3 > +assert(X._NAME == "X" and X.a.b.c._NAME == "X.a.b.c" and X.a.b._NAME == "X.a.b") > +assert(X._M == X and X.a.b.c._M == X.a.b.c and X.a.b._M == X.a.b) > +assert(X.x == 1 and X.a.b.c.x == 2 and X.a.b.x == 3) > +assert(X._PACKAGE == "" and X.a.b.c._PACKAGE == "X.a.b." and > + X.a.b._PACKAGE == "X.a.") > +assert(_PACKAGE.."c" == "X.a.c") > +assert(X.a._NAME == nil and X.a._M == nil) > +module("X.a", import("X")) ; x = 4 > +assert(X.a._NAME == "X.a" and X.a.x == 4 and X.a._M == X.a) > +module("X.a.b", package.seeall); assert(x == 3); x = 5 > +assert(_NAME == "X.a.b" and X.a.b.x == 5) > + > +assert(X._G == nil and X.a._G == nil and X.a.b._G == _G and X.a.b.c._G == nil) > + > +setfenv(1, _G) > +assert(x == 0) > + > +assert(not pcall(module, "x")) > +assert(not pcall(module, "math.sin")) > + > + > +-- testing C libraries > + > + > +local p = "" -- On Mac OS X, redefine this to "_" > + > +-- assert(loadlib == package.loadlib) -- only for compatibility > +local f, err, when = package.loadlib("libs/lib1.so", p.."luaopen_lib1") > +if not f then > + (Message or print)('\a\n >>> cannot load dynamic library <<<\n\a') > + print(err, when) > +else > + f() -- open library > + assert(require("lib1") == lib1) > + collectgarbage() > + assert(lib1.id("x") == "x") > + f = assert(package.loadlib("libs/lib1.so", p.."anotherfunc")) > + assert(f(10, 20) == "1020\n") > + f, err, when = package.loadlib("libs/lib1.so", p.."xuxu") > + assert(not f and type(err) == "string" and when == "init") > + package.cpath = "libs/?.so" > + require"lib2" > + assert(lib2.id("x") == "x") > + local fs = require"lib1.sub" > + assert(fs == lib1.sub and next(lib1.sub) == nil) > + module("lib2", package.seeall) > + f = require"-lib2" > + assert(f.id("x") == "x" and _M == f and _NAME == "lib2") > + module("lib1.sub", package.seeall) > + assert(_M == fs) > + setfenv(1, _G) > + > +end > +f, err, when = package.loadlib("donotexist", p.."xuxu") > +assert(not f and type(err) == "string" and (when == "open" or when == "absent")) > + > + > +-- testing preload > + > +do > + local p = package > + package = {} > + p.preload.pl = function (...) > + module(...) > + function xuxu (x) return x+20 end > + end > + > + require"pl" > + assert(require"pl" == pl) > + assert(pl.xuxu(10) == 30) > + > + package = p > + assert(type(package.path) == "string") > +end > + > + > + > +end --] > + > +print('+') > + > +print("testing assignments, logical operators, and constructors") > + > +local res, res2 = 27 > + > +a, b = 1, 2+3 > +assert(a==1 and b==5) > +a={} > +function f() return 10, 11, 12 end > +a.x, b, a[1] = 1, 2, f() > +assert(a.x==1 and b==2 and a[1]==10) > +a[f()], b, a[f()+3] = f(), a, 'x' > +assert(a[10] == 10 and b == a and a[13] == 'x') > + > +do > + local f = function (n) local x = {}; for i=1,n do x[i]=i end; > + return unpack(x) end; > + local a,b,c > + a,b = 0, f(1) > + assert(a == 0 and b == 1) > + A,b = 0, f(1) > + assert(A == 0 and b == 1) > + a,b,c = 0,5,f(4) > + assert(a==0 and b==5 and c==1) > + a,b,c = 0,5,f(0) > + assert(a==0 and b==5 and c==nil) > +end > + > + > +a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6 > +assert(not a and b and c and d==6) > + > +d = 20 > +a, b, c, d = f() > +assert(a==10 and b==11 and c==12 and d==nil) > +a,b = f(), 1, 2, 3, f() > +assert(a==10 and b==1) > + > +assert(a<b == false and a>b == true) > +assert((10 and 2) == 2) > +assert((10 or 2) == 10) > +assert((10 or assert(nil)) == 10) > +assert(not (nil and assert(nil))) > +assert((nil or "alo") == "alo") > +assert((nil and 10) == nil) > +assert((false and 10) == false) > +assert((true or 10) == true) > +assert((false or 10) == 10) > +assert(false ~= nil) > +assert(nil ~= false) > +assert(not nil == true) > +assert(not not nil == false) > +assert(not not 1 == true) > +assert(not not a == true) > +assert(not not (6 or nil) == true) > +assert(not not (nil and 56) == false) > +assert(not not (nil and true) == false) > +print('+') > + > +a = {} > +a[true] = 20 > +a[false] = 10 > +assert(a[1<2] == 20 and a[1>2] == 10) > + > +function f(a) return a end > + > +local a = {} > +for i=3000,-3000,-1 do a[i] = i; end > +a[10e30] = "alo"; a[true] = 10; a[false] = 20 > +assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10) > +for i=3000,-3000,-1 do assert(a[i] == i); end > +a[print] = assert > +a[f] = print > +a[a] = a > +assert(a[a][a][a][a][print] == assert) > +a[print](a[a[f]] == a[print]) > +a = nil > + > +a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'} > +a, a.x, a.y = a, a[-3] > +assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y) > +a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 > +a[1].alo(a[2]==10 and b==10 and c==print) > + > +a[2^31] = 10; a[2^31+1] = 11; a[-2^31] = 12; > +a[2^32] = 13; a[-2^32] = 14; a[2^32+1] = 15; a[10^33] = 16; > + > +assert(a[2^31] == 10 and a[2^31+1] == 11 and a[-2^31] == 12 and > + a[2^32] == 13 and a[-2^32] == 14 and a[2^32+1] == 15 and > + a[10^33] == 16) > + > +a = nil > + > + > +do > + local a,i,j,b > + a = {'a', 'b'}; i=1; j=2; b=a > + i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i > + assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and > + b[3] == 1) > +end > + > +print('OK') > + > +return res > diff --git a/test/PUC-Lua-5.1-tests/big.lua b/test/PUC-Lua-5.1-tests/big.lua > new file mode 100644 > index 0000000..9261288 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/big.lua > @@ -0,0 +1,381 @@ > +print "testing string length overflow" > + > +local longs = string.rep("\0", 2^25) > +local function catter (i) > + return assert(loadstring( > + string.format("return function(a) return a%s end", > + string.rep("..a", i-1))))() > +end > +rep129 = catter(129) > +local a, b = pcall(rep129, longs) > +assert(not a and string.find(b, "overflow")) > +print('+') > + > + > +require "checktable" > + > +--[[ lots of empty lines (to force SETLINEW) > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > + > +--]] > + > + > +a,b = nil,nil > +while not b do > +if a then > +b = { -- lots of strings (to force JMPW and PUSHCONSTANTW) > +"n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10", > +"n11", "n12", "j301", "j302", "j303", "j304", "j305", "j306", "j307", "j308", > +"j309", "a310", "n311", "n312", "n313", "n314", "n315", "n316", "n317", "n318", > +"n319", "n320", "n321", "n322", "n323", "n324", "n325", "n326", "n327", "n328", > +"a329", "n330", "n331", "n332", "n333", "n334", "n335", "n336", "n337", "n338", > +"n339", "n340", "n341", "z342", "n343", "n344", "n345", "n346", "n347", "n348", > +"n349", "n350", "n351", "n352", "r353", "n354", "n355", "n356", "n357", "n358", > +"n359", "n360", "n361", "n362", "n363", "n364", "n365", "n366", "z367", "n368", > +"n369", "n370", "n371", "n372", "n373", "n374", "n375", "a376", "n377", "n378", > +"n379", "n380", "n381", "n382", "n383", "n384", "n385", "n386", "n387", "n388", > +"n389", "n390", "n391", "n392", "n393", "n394", "n395", "n396", "n397", "n398", > +"n399", "n400", "n13", "n14", "n15", "n16", "n17", "n18", "n19", "n20", > +"n21", "n22", "n23", "a24", "n25", "n26", "n27", "n28", "n29", "j30", > +"n31", "n32", "n33", "n34", "n35", "n36", "n37", "n38", "n39", "n40", > +"n41", "n42", "n43", "n44", "n45", "n46", "n47", "n48", "n49", "n50", > +"n51", "n52", "n53", "n54", "n55", "n56", "n57", "n58", "n59", "n60", > +"n61", "n62", "n63", "n64", "n65", "a66", "z67", "n68", "n69", "n70", > +"n71", "n72", "n73", "n74", "n75", "n76", "n77", "n78", "n79", "n80", > +"n81", "n82", "n83", "n84", "n85", "n86", "n87", "n88", "n89", "n90", > +"n91", "n92", "n93", "n94", "n95", "n96", "n97", "n98", "n99", "n100", > +"n201", "n202", "n203", "n204", "n205", "n206", "n207", "n208", "n209", "n210", > +"n211", "n212", "n213", "n214", "n215", "n216", "n217", "n218", "n219", "n220", > +"n221", "n222", "n223", "n224", "n225", "n226", "n227", "n228", "n229", "n230", > +"n231", "n232", "n233", "n234", "n235", "n236", "n237", "n238", "n239", "a240", > +"a241", "a242", "a243", "a244", "a245", "a246", "a247", "a248", "a249", "n250", > +"n251", "n252", "n253", "n254", "n255", "n256", "n257", "n258", "n259", "n260", > +"n261", "n262", "n263", "n264", "n265", "n266", "n267", "n268", "n269", "n270", > +"n271", "n272", "n273", "n274", "n275", "n276", "n277", "n278", "n279", "n280", > +"n281", "n282", "n283", "n284", "n285", "n286", "n287", "n288", "n289", "n290", > +"n291", "n292", "n293", "n294", "n295", "n296", "n297", "n298", "n299" > +; x=23} > +else a = 1 end > + > + > +end > + > +assert(b.x == 23) > +print('+') > + > +stat(b) > + > +repeat > +a = { > +n1 = 1.5, n2 = 2.5, n3 = 3.5, n4 = 4.5, n5 = 5.5, n6 = 6.5, n7 = 7.5, > +n8 = 8.5, n9 = 9.5, n10 = 10.5, n11 = 11.5, n12 = 12.5, > +j301 = 301.5, j302 = 302.5, j303 = 303.5, j304 = 304.5, j305 = 305.5, > +j306 = 306.5, j307 = 307.5, j308 = 308.5, j309 = 309.5, a310 = 310.5, > +n311 = 311.5, n312 = 312.5, n313 = 313.5, n314 = 314.5, n315 = 315.5, > +n316 = 316.5, n317 = 317.5, n318 = 318.5, n319 = 319.5, n320 = 320.5, > +n321 = 321.5, n322 = 322.5, n323 = 323.5, n324 = 324.5, n325 = 325.5, > +n326 = 326.5, n327 = 327.5, n328 = 328.5, a329 = 329.5, n330 = 330.5, > +n331 = 331.5, n332 = 332.5, n333 = 333.5, n334 = 334.5, n335 = 335.5, > +n336 = 336.5, n337 = 337.5, n338 = 338.5, n339 = 339.5, n340 = 340.5, > +n341 = 341.5, z342 = 342.5, n343 = 343.5, n344 = 344.5, n345 = 345.5, > +n346 = 346.5, n347 = 347.5, n348 = 348.5, n349 = 349.5, n350 = 350.5, > +n351 = 351.5, n352 = 352.5, r353 = 353.5, n354 = 354.5, n355 = 355.5, > +n356 = 356.5, n357 = 357.5, n358 = 358.5, n359 = 359.5, n360 = 360.5, > +n361 = 361.5, n362 = 362.5, n363 = 363.5, n364 = 364.5, n365 = 365.5, > +n366 = 366.5, z367 = 367.5, n368 = 368.5, n369 = 369.5, n370 = 370.5, > +n371 = 371.5, n372 = 372.5, n373 = 373.5, n374 = 374.5, n375 = 375.5, > +a376 = 376.5, n377 = 377.5, n378 = 378.5, n379 = 379.5, n380 = 380.5, > +n381 = 381.5, n382 = 382.5, n383 = 383.5, n384 = 384.5, n385 = 385.5, > +n386 = 386.5, n387 = 387.5, n388 = 388.5, n389 = 389.5, n390 = 390.5, > +n391 = 391.5, n392 = 392.5, n393 = 393.5, n394 = 394.5, n395 = 395.5, > +n396 = 396.5, n397 = 397.5, n398 = 398.5, n399 = 399.5, n400 = 400.5, > +n13 = 13.5, n14 = 14.5, n15 = 15.5, n16 = 16.5, n17 = 17.5, > +n18 = 18.5, n19 = 19.5, n20 = 20.5, n21 = 21.5, n22 = 22.5, > +n23 = 23.5, a24 = 24.5, n25 = 25.5, n26 = 26.5, n27 = 27.5, > +n28 = 28.5, n29 = 29.5, j30 = 30.5, n31 = 31.5, n32 = 32.5, > +n33 = 33.5, n34 = 34.5, n35 = 35.5, n36 = 36.5, n37 = 37.5, > +n38 = 38.5, n39 = 39.5, n40 = 40.5, n41 = 41.5, n42 = 42.5, > +n43 = 43.5, n44 = 44.5, n45 = 45.5, n46 = 46.5, n47 = 47.5, > +n48 = 48.5, n49 = 49.5, n50 = 50.5, n51 = 51.5, n52 = 52.5, > +n53 = 53.5, n54 = 54.5, n55 = 55.5, n56 = 56.5, n57 = 57.5, > +n58 = 58.5, n59 = 59.5, n60 = 60.5, n61 = 61.5, n62 = 62.5, > +n63 = 63.5, n64 = 64.5, n65 = 65.5, a66 = 66.5, z67 = 67.5, > +n68 = 68.5, n69 = 69.5, n70 = 70.5, n71 = 71.5, n72 = 72.5, > +n73 = 73.5, n74 = 74.5, n75 = 75.5, n76 = 76.5, n77 = 77.5, > +n78 = 78.5, n79 = 79.5, n80 = 80.5, n81 = 81.5, n82 = 82.5, > +n83 = 83.5, n84 = 84.5, n85 = 85.5, n86 = 86.5, n87 = 87.5, > +n88 = 88.5, n89 = 89.5, n90 = 90.5, n91 = 91.5, n92 = 92.5, > +n93 = 93.5, n94 = 94.5, n95 = 95.5, n96 = 96.5, n97 = 97.5, > +n98 = 98.5, n99 = 99.5, n100 = 100.5, n201 = 201.5, n202 = 202.5, > +n203 = 203.5, n204 = 204.5, n205 = 205.5, n206 = 206.5, n207 = 207.5, > +n208 = 208.5, n209 = 209.5, n210 = 210.5, n211 = 211.5, n212 = 212.5, > +n213 = 213.5, n214 = 214.5, n215 = 215.5, n216 = 216.5, n217 = 217.5, > +n218 = 218.5, n219 = 219.5, n220 = 220.5, n221 = 221.5, n222 = 222.5, > +n223 = 223.5, n224 = 224.5, n225 = 225.5, n226 = 226.5, n227 = 227.5, > +n228 = 228.5, n229 = 229.5, n230 = 230.5, n231 = 231.5, n232 = 232.5, > +n233 = 233.5, n234 = 234.5, n235 = 235.5, n236 = 236.5, n237 = 237.5, > +n238 = 238.5, n239 = 239.5, a240 = 240.5, a241 = 241.5, a242 = 242.5, > +a243 = 243.5, a244 = 244.5, a245 = 245.5, a246 = 246.5, a247 = 247.5, > +a248 = 248.5, a249 = 249.5, n250 = 250.5, n251 = 251.5, n252 = 252.5, > +n253 = 253.5, n254 = 254.5, n255 = 255.5, n256 = 256.5, n257 = 257.5, > +n258 = 258.5, n259 = 259.5, n260 = 260.5, n261 = 261.5, n262 = 262.5, > +n263 = 263.5, n264 = 264.5, n265 = 265.5, n266 = 266.5, n267 = 267.5, > +n268 = 268.5, n269 = 269.5, n270 = 270.5, n271 = 271.5, n272 = 272.5, > +n273 = 273.5, n274 = 274.5, n275 = 275.5, n276 = 276.5, n277 = 277.5, > +n278 = 278.5, n279 = 279.5, n280 = 280.5, n281 = 281.5, n282 = 282.5, > +n283 = 283.5, n284 = 284.5, n285 = 285.5, n286 = 286.5, n287 = 287.5, > +n288 = 288.5, n289 = 289.5, n290 = 290.5, n291 = 291.5, n292 = 292.5, > +n293 = 293.5, n294 = 294.5, n295 = 295.5, n296 = 296.5, n297 = 297.5, > +n298 = 298.5, n299 = 299.5, j300 = 300} or 1 > +until 1 > + > +assert(a.n299 == 299.5) > +xxx = 1 > +assert(xxx == 1) > + > +stat(a) > + > +function a:findfield (f) > + local i,v = next(self, nil) > + while i ~= f do > + if not i then return end > + i,v = next(self, i) > + end > + return v > +end > + > +local ii = 0 > +i = 1 > +while b[i] do > + local r = a:findfield(b[i]); > + assert(a[b[i]] == r) > + ii = math.max(ii,i) > + i = i+1 > +end > + > +assert(ii == 299) > + > +function xxxx (x) coroutine.yield('b'); return ii+x end > + > +assert(xxxx(10) == 309) > + > +a = nil > +b = nil > +a1 = nil > + > +print("tables with table indices:") > +i = 1; a={} > +while i <= 1023 do a[{}] = i; i=i+1 end > +stat(a) > +a = nil > + > +print("tables with function indices:") > +a={} > +for i=1,511 do local x; a[function () return x end] = i end > +stat(a) > +a = nil > + > +print'OK' > + > +return 'a' > diff --git a/test/PUC-Lua-5.1-tests/calls.lua b/test/PUC-Lua-5.1-tests/calls.lua > new file mode 100644 > index 0000000..788f9a1 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/calls.lua > @@ -0,0 +1,294 @@ > +print("testing functions and calls") > + > +-- get the opportunity to test 'type' too ;) > + > +assert(type(1<2) == 'boolean') > +assert(type(true) == 'boolean' and type(false) == 'boolean') > +assert(type(nil) == 'nil' and type(-3) == 'number' and type'x' == 'string' and > + type{} == 'table' and type(type) == 'function') > + > +assert(type(assert) == type(print)) > +f = nil > +function f (x) return a:x (x) end > +assert(type(f) == 'function') > + > + > +-- testing local-function recursion > +fact = false > +do > + local res = 1 > + local function fact (n) > + if n==0 then return res > + else return n*fact(n-1) > + end > + end > + assert(fact(5) == 120) > +end > +assert(fact == false) > + > +-- testing declarations > +a = {i = 10} > +self = 20 > +function a:x (x) return x+self.i end > +function a.y (x) return x+self end > + > +assert(a:x(1)+10 == a.y(1)) > + > +a.t = {i=-100} > +a["t"].x = function (self, a,b) return self.i+a+b end > + > +assert(a.t:x(2,3) == -95) > + > +do > + local a = {x=0} > + function a:add (x) self.x, a.y = self.x+x, 20; return self end > + assert(a:add(10):add(20):add(30).x == 60 and a.y == 20) > +end > + > +local a = {b={c={}}} > + > +function a.b.c.f1 (x) return x+1 end > +function a.b.c:f2 (x,y) self[x] = y end > +assert(a.b.c.f1(4) == 5) > +a.b.c:f2('k', 12); assert(a.b.c.k == 12) > + > +print('+') > + > +t = nil -- 'declare' t > +function f(a,b,c) local d = 'a'; t={a,b,c,d} end > + > +f( -- this line change must be valid > + 1,2) > +assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a') > +f(1,2, -- this one too > + 3,4) > +assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') > + > +function fat(x) > + if x <= 1 then return 1 > + else return x*loadstring("return fat(" .. x-1 .. ")")() > + end > +end > + > +assert(loadstring "loadstring 'assert(fat(6)==720)' () ")() > +a = loadstring('return fat(5), 3') > +a,b = a() > +assert(a == 120 and b == 3) > +print('+') > + > +function err_on_n (n) > + if n==0 then error(); exit(1); > + else err_on_n (n-1); exit(1); > + end > +end > + > +do > + function dummy (n) > + if n > 0 then > + assert(not pcall(err_on_n, n)) > + dummy(n-1) > + end > + end > +end > + > +dummy(10) > + > +function deep (n) > + if n>0 then deep(n-1) end > +end > +deep(10) > +deep(200) > + > +-- testing tail call > +function deep (n) if n>0 then return deep(n-1) else return 101 end end > +assert(deep(30000) == 101) > +a = {} > +function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end > +assert(a:deep(30000) == 101) > + > +print('+') > + > + > +a = nil > +(function (x) a=x end)(23) > +assert(a == 23 and (function (x) return x*2 end)(20) == 40) > + > + > +local x,y,z,a > +a = {}; lim = 2000 > +for i=1, lim do a[i]=i end > +assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) > +x = unpack(a) > +assert(x == 1) > +x = {unpack(a)} > +assert(table.getn(x) == lim and x[1] == 1 and x[lim] == lim) > +x = {unpack(a, lim-2)} > +assert(table.getn(x) == 3 and x[1] == lim-2 and x[3] == lim) > +x = {unpack(a, 10, 6)} > +assert(next(x) == nil) -- no elements > +x = {unpack(a, 11, 10)} > +assert(next(x) == nil) -- no elements > +x,y = unpack(a, 10, 10) > +assert(x == 10 and y == nil) > +x,y,z = unpack(a, 10, 11) > +assert(x == 10 and y == 11 and z == nil) > +a,x = unpack{1} > +assert(a==1 and x==nil) > +a,x = unpack({1,2}, 1, 1) > +assert(a==1 and x==nil) > + > + > +-- testing closures > + > +-- fixed-point operator > +Y = function (le) > + local function a (f) > + return le(function (x) return f(f)(x) end) > + end > + return a(a) > + end > + > + > +-- non-recursive factorial > + > +F = function (f) > + return function (n) > + if n == 0 then return 1 > + else return n*f(n-1) end > + end > + end > + > +fat = Y(F) > + > +assert(fat(0) == 1 and fat(4) == 24 and Y(F)(5)==5*Y(F)(4)) > + > +local function g (z) > + local function f (a,b,c,d) > + return function (x,y) return a+b+c+d+a+x+y+z end > + end > + return f(z,z+1,z+2,z+3) > +end > + > +f = g(10) > +assert(f(9, 16) == 10+11+12+13+10+9+16+10) > + > +Y, F, f = nil > +print('+') > + > +-- testing multiple returns > + > +function unlpack (t, i) > + i = i or 1 > + if (i <= table.getn(t)) then > + return t[i], unlpack(t, i+1) > + end > +end > + > +function equaltab (t1, t2) > + assert(table.getn(t1) == table.getn(t2)) > + for i,v1 in ipairs(t1) do > + assert(v1 == t2[i]) > + end > +end > + > +local function pack (...) > + local x = {...} > + x.n = select('#', ...) > + return x > +end > + > +function f() return 1,2,30,4 end > +function ret2 (a,b) return a,b end > + > +local a,b,c,d = unlpack{1,2,3} > +assert(a==1 and b==2 and c==3 and d==nil) > +a = {1,2,3,4,false,10,'alo',false,assert} > +equaltab(pack(unlpack(a)), a) > +equaltab(pack(unlpack(a), -1), {1,-1}) > +a,b,c,d = ret2(f()), ret2(f()) > +assert(a==1 and b==1 and c==2 and d==nil) > +a,b,c,d = unlpack(pack(ret2(f()), ret2(f()))) > +assert(a==1 and b==1 and c==2 and d==nil) > +a,b,c,d = unlpack(pack(ret2(f()), (ret2(f())))) > +assert(a==1 and b==1 and c==nil and d==nil) > + > +a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} > +assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") > + > + > +-- testing calls with 'incorrect' arguments > +rawget({}, "x", 1) > +rawset({}, "x", 1, 2) > +assert(math.sin(1,2) == math.sin(1)) > +table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg") > + > + > +-- test for generic load > +x = "-- a comment\0\0\0\n x = 10 + \n23; \ > + local a = function () x = 'hi' end; \ > + return '\0'" > +local i = 0 > +function read1 (x) > + return function () > + collectgarbage() > + i=i+1 > + return string.sub(x, i, i) > + end > +end > + > +a = assert(load(read1(x), "modname")) > +assert(a() == "\0" and _G.x == 33) > +assert(debug.getinfo(a).source == "modname") > + > +x = string.dump(loadstring("x = 1; return x")) > +i = 0 > +a = assert(load(read1(x))) > +assert(a() == 1 and _G.x == 1) > + > +i = 0 > +local a, b = load(read1("*a = 123")) > +assert(not a and type(b) == "string" and i == 2) > + > +a, b = load(function () error("hhi") end) > +assert(not a and string.find(b, "hhi")) > + > +-- test generic load with nested functions > +x = [[ > + return function (x) > + return function (y) > + return function (z) > + return x+y+z > + end > + end > + end > +]] > + > +a = assert(load(read1(x))) > +assert(a()(2)(3)(10) == 15) > + > + > +-- test for dump/undump with upvalues > +local a, b = 20, 30 > +x = loadstring(string.dump(function (x) > + if x == "set" then a = 10+b; b = b+1 else > + return a > + end > +end)) > +assert(x() == nil) > +assert(debug.setupvalue(x, 1, "hi") == "a") > +assert(x() == "hi") > +assert(debug.setupvalue(x, 2, 13) == "b") > +assert(not debug.setupvalue(x, 3, 10)) -- only 2 upvalues > +x("set") > +assert(x() == 23) > +x("set") > +assert(x() == 24) > + > + > +-- test for bug in parameter adjustment > +assert((function () return nil end)(4) == nil) > +assert((function () local a; return a end)(4) == nil) > +assert((function (a) return a end)() == nil) > + > +print('OK') > +return deep > diff --git a/test/PUC-Lua-5.1-tests/checktable.lua b/test/PUC-Lua-5.1-tests/checktable.lua > new file mode 100644 > index 0000000..f0938be > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/checktable.lua > @@ -0,0 +1,77 @@ > + > +assert(rawget(_G, "stat") == nil) -- module not loaded before > + > +if T == nil then > + stat = function () print"`querytab' nao ativo" end > + return > +end > + > + > +function checktable (t) > + local asize, hsize, ff = T.querytab(t) > + local l = {} > + for i=0,hsize-1 do > + local key,val,next = T.querytab(t, i + asize) > + if key == nil then > + assert(l[i] == nil and val==nil and next==nil) > + elseif key == "<undef>" then > + assert(val==nil) > + else > + assert(t[key] == val) > + local mp = T.hash(key, t) > + if l[i] then > + assert(l[i] == mp) > + elseif mp ~= i then > + l[i] = mp > + else -- list head > + l[mp] = {mp} -- first element > + while next do > + assert(ff <= next and next < hsize) > + if l[next] then assert(l[next] == mp) else l[next] = mp end > + table.insert(l[mp], next) > + key,val,next = T.querytab(t, next) > + assert(key) > + end > + end > + end > + end > + l.asize = asize; l.hsize = hsize; l.ff = ff > + return l > +end > + > +function mostra (t) > + local asize, hsize, ff = T.querytab(t) > + print(asize, hsize, ff) > + print'------' > + for i=0,asize-1 do > + local _, v = T.querytab(t, i) > + print(string.format("[%d] -", i), v) > + end > + print'------' > + for i=0,hsize-1 do > + print(i, T.querytab(t, i+asize)) > + end > + print'-------------' > +end > + > +function stat (t) > + t = checktable(t) > + local nelem, nlist = 0, 0 > + local maxlist = {} > + for i=0,t.hsize-1 do > + if type(t[i]) == 'table' then > + local n = table.getn(t[i]) > + nlist = nlist+1 > + nelem = nelem + n > + if not maxlist[n] then maxlist[n] = 0 end > + maxlist[n] = maxlist[n]+1 > + end > + end > + print(string.format("hsize=%d elements=%d load=%.2f med.len=%.2f (asize=%d)", > + t.hsize, nelem, nelem/t.hsize, nelem/nlist, t.asize)) > + for i=1,table.getn(maxlist) do > + local n = maxlist[i] or 0 > + print(string.format("%5d %10d %.2f%%", i, n, n*100/nlist)) > + end > +end > + > diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua > new file mode 100644 > index 0000000..27ca0ad > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/closure.lua > @@ -0,0 +1,422 @@ > +print "testing closures and coroutines" > + > +local A,B = 0,{g=10} > +function f(x) > + local a = {} > + for i=1,1000 do > + local y = 0 > + do > + a[i] = function () B.g = B.g+1; y = y+x; return y+A end > + end > + end > + local dummy = function () return a[A] end > + collectgarbage() > + A = 1; assert(dummy() == a[1]); A = 0; > + assert(a[1]() == x) > + assert(a[3]() == x) > + collectgarbage() > + assert(B.g == 12) > + return a > +end > + > +a = f(10) > +-- force a GC in this level > +local x = {[1] = {}} -- to detect a GC > +setmetatable(x, {__mode = 'kv'}) > +while x[1] do -- repeat until GC > + local a = A..A..A..A -- create garbage > + A = A+1 > +end > +assert(a[1]() == 20+A) > +assert(a[1]() == 30+A) > +assert(a[2]() == 10+A) > +collectgarbage() > +assert(a[2]() == 20+A) > +assert(a[2]() == 30+A) > +assert(a[3]() == 20+A) > +assert(a[8]() == 10+A) > +assert(getmetatable(x).__mode == 'kv') > +assert(B.g == 19) > + > +-- testing closures with 'for' control variable > +a = {} > +for i=1,10 do > + a[i] = {set = function(x) i=x end, get = function () return i end} > + if i == 3 then break end > +end > +assert(a[4] == nil) > +a[1].set(10) > +assert(a[2].get() == 2) > +a[2].set('a') > +assert(a[3].get() == 3) > +assert(a[2].get() == 'a') > + > +a = {} > +for i, k in pairs{'a', 'b'} do > + a[i] = {set = function(x, y) i=x; k=y end, > + get = function () return i, k end} > + if i == 2 then break end > +end > +a[1].set(10, 20) > +local r,s = a[2].get() > +assert(r == 2 and s == 'b') > +r,s = a[1].get() > +assert(r == 10 and s == 20) > +a[2].set('a', 'b') > +r,s = a[2].get() > +assert(r == "a" and s == "b") > + > + > +-- testing closures with 'for' control variable x break > +for i=1,3 do > + f = function () return i end > + break > +end > +assert(f() == 1) > + > +for k, v in pairs{"a", "b"} do > + f = function () return k, v end > + break > +end > +assert(({f()})[1] == 1) > +assert(({f()})[2] == "a") > + > + > +-- testing closure x break x return x errors > + > +local b > +function f(x) > + local first = 1 > + while 1 do > + if x == 3 and not first then return end > + local a = 'xuxu' > + b = function (op, y) > + if op == 'set' then > + a = x+y > + else > + return a > + end > + end > + if x == 1 then do break end > + elseif x == 2 then return > + else if x ~= 3 then error() end > + end > + first = nil > + end > +end > + > +for i=1,3 do > + f(i) > + assert(b('get') == 'xuxu') > + b('set', 10); assert(b('get') == 10+i) > + b = nil > +end > + > +pcall(f, 4); > +assert(b('get') == 'xuxu') > +b('set', 10); assert(b('get') == 14) > + > + > +local w > +-- testing multi-level closure > +function f(x) > + return function (y) > + return function (z) return w+x+y+z end > + end > +end > + > +y = f(10) > +w = 1.345 > +assert(y(20)(30) == 60+w) > + > +-- testing closures x repeat-until > + > +local a = {} > +local i = 1 > +repeat > + local x = i > + a[i] = function () i = x+1; return x end > +until i > 10 or a[i]() ~= x > +assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) > + > +print'+' > + > + > +-- test for correctly closing upvalues in tail calls of vararg functions > +local function t () > + local function c(a,b) assert(a=="test" and b=="OK") end > + local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end > + local x = 1 > + return v(function() return x end) > +end > +t() > + > + > +-- coroutine tests > + > +local f > + > +assert(coroutine.running() == nil) > + > + > +-- tests for global environment > + > +local function foo (a) > + setfenv(0, a) > + coroutine.yield(getfenv()) > + assert(getfenv(0) == a) > + assert(getfenv(1) == _G) > + assert(getfenv(loadstring"") == a) > + return getfenv() > +end > + > +f = coroutine.wrap(foo) > +local a = {} > +assert(f(a) == _G) > +local a,b = pcall(f) > +assert(a and b == _G) > + > + > +-- tests for multiple yield/resume arguments > + > +local function eqtab (t1, t2) > + assert(table.getn(t1) == table.getn(t2)) > + for i,v in ipairs(t1) do > + assert(t2[i] == v) > + end > +end > + > +_G.x = nil -- declare x > +function foo (a, ...) > + assert(coroutine.running() == f) > + assert(coroutine.status(f) == "running") > + local arg = {...} > + for i=1,table.getn(arg) do > + _G.x = {coroutine.yield(unpack(arg[i]))} > + end > + return unpack(a) > +end > + > +f = coroutine.create(foo) > +assert(type(f) == "thread" and coroutine.status(f) == "suspended") > +assert(string.find(tostring(f), "thread")) > +local s,a,b,c,d > +s,a,b,c,d = coroutine.resume(f, {1,2,3}, {}, {1}, {'a', 'b', 'c'}) > +assert(s and a == nil and coroutine.status(f) == "suspended") > +s,a,b,c,d = coroutine.resume(f) > +eqtab(_G.x, {}) > +assert(s and a == 1 and b == nil) > +s,a,b,c,d = coroutine.resume(f, 1, 2, 3) > +eqtab(_G.x, {1, 2, 3}) > +assert(s and a == 'a' and b == 'b' and c == 'c' and d == nil) > +s,a,b,c,d = coroutine.resume(f, "xuxu") > +eqtab(_G.x, {"xuxu"}) > +assert(s and a == 1 and b == 2 and c == 3 and d == nil) > +assert(coroutine.status(f) == "dead") > +s, a = coroutine.resume(f, "xuxu") > +assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead") > + > + > +-- yields in tail calls > +local function foo (i) return coroutine.yield(i) end > +f = coroutine.wrap(function () > + for i=1,10 do > + assert(foo(i) == _G.x) > + end > + return 'a' > +end) > +for i=1,10 do _G.x = i; assert(f(i) == i) end > +_G.x = 'xuxu'; assert(f('xuxu') == 'a') > + > +-- recursive > +function pf (n, i) > + coroutine.yield(n) > + pf(n*i, i+1) > +end > + > +f = coroutine.wrap(pf) > +local s=1 > +for i=1,10 do > + assert(f(1, 1) == s) > + s = s*i > +end > + > +-- sieve > +function gen (n) > + return coroutine.wrap(function () > + for i=2,n do coroutine.yield(i) end > + end) > +end > + > + > +function filter (p, g) > + return coroutine.wrap(function () > + while 1 do > + local n = g() > + if n == nil then return end > + if math.mod(n, p) ~= 0 then coroutine.yield(n) end > + end > + end) > +end > + > +local x = gen(100) > +local a = {} > +while 1 do > + local n = x() > + if n == nil then break end > + table.insert(a, n) > + x = filter(n, x) > +end > + > +assert(table.getn(a) == 25 and a[table.getn(a)] == 97) > + > + > +-- errors in coroutines > +function foo () > + assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1) > + assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined) > + coroutine.yield(3) > + error(foo) > +end > + > +function goo() foo() end > +x = coroutine.wrap(goo) > +assert(x() == 3) > +local a,b = pcall(x) > +assert(not a and b == foo) > + > +x = coroutine.create(goo) > +a,b = coroutine.resume(x) > +assert(a and b == 3) > +a,b = coroutine.resume(x) > +assert(not a and b == foo and coroutine.status(x) == "dead") > +a,b = coroutine.resume(x) > +assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead") > + > + > +-- co-routines x for loop > +function all (a, n, k) > + if k == 0 then coroutine.yield(a) > + else > + for i=1,n do > + a[k] = i > + all(a, n, k-1) > + end > + end > +end > + > +local a = 0 > +for t in coroutine.wrap(function () all({}, 5, 4) end) do > + a = a+1 > +end > +assert(a == 5^4) > + > + > +-- access to locals of collected corroutines > +local C = {}; setmetatable(C, {__mode = "kv"}) > +local x = coroutine.wrap (function () > + local a = 10 > + local function f () a = a+10; return a end > + while true do > + a = a+1 > + coroutine.yield(f) > + end > + end) > + > +C[1] = x; > + > +local f = x() > +assert(f() == 21 and x()() == 32 and x() == f) > +x = nil > +collectgarbage() > +assert(C[1] == nil) > +assert(f() == 43 and f() == 53) > + > + > +-- old bug: attempt to resume itself > + > +function co_func (current_co) > + assert(coroutine.running() == current_co) > + assert(coroutine.resume(current_co) == false) > + assert(coroutine.resume(current_co) == false) > + return 10 > +end > + > +local co = coroutine.create(co_func) > +local a,b = coroutine.resume(co, co) > +assert(a == true and b == 10) > +assert(coroutine.resume(co, co) == false) > +assert(coroutine.resume(co, co) == false) > + > +-- access to locals of erroneous coroutines > +local x = coroutine.create (function () > + local a = 10 > + _G.f = function () a=a+1; return a end > + error('x') > + end) > + > +assert(not coroutine.resume(x)) > +-- overwrite previous position of local `a' > +assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1)) > +assert(_G.f() == 11) > +assert(_G.f() == 12) > + > + > +if not T then > + (Message or print)('\a\n >>> testC not active: skipping yield/hook tests <<<\n\a') > +else > + > + local turn > + > + function fact (t, x) > + assert(turn == t) > + if x == 0 then return 1 > + else return x*fact(t, x-1) > + end > + end > + > + local A,B,a,b = 0,0,0,0 > + > + local x = coroutine.create(function () > + T.setyhook("", 2) > + A = fact("A", 10) > + end) > + > + local y = coroutine.create(function () > + T.setyhook("", 3) > + B = fact("B", 11) > + end) > + > + while A==0 or B==0 do > + if A==0 then turn = "A"; T.resume(x) end > + if B==0 then turn = "B"; T.resume(y) end > + end > + > + assert(B/A == 11) > +end > + > + > +-- leaving a pending coroutine open > +_X = coroutine.wrap(function () > + local a = 10 > + local x = function () a = a+1 end > + coroutine.yield() > + end) > + > +_X() > + > + > +-- coroutine environments > +co = coroutine.create(function () > + coroutine.yield(getfenv(0)) > + return loadstring("return a")() > + end) > + > +a = {a = 15} > +debug.setfenv(co, a) > +assert(debug.getfenv(co) == a) > +assert(select(2, coroutine.resume(co)) == a) > +assert(select(2, coroutine.resume(co)) == a.a) > + > + > +print'OK' > diff --git a/test/PUC-Lua-5.1-tests/code.lua b/test/PUC-Lua-5.1-tests/code.lua > new file mode 100644 > index 0000000..875d488 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/code.lua > @@ -0,0 +1,143 @@ > + > +if T==nil then > + (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a') > + return > +end > +print "testing code generation and optimizations" > + > + > +-- this code gave an error for the code checker > +do > + local function f (a) > + for k,v,w in a do end > + end > +end > + > + > +function check (f, ...) > + local c = T.listcode(f) > + for i=1, arg.n do > + -- print(arg[i], c[i]) > + assert(string.find(c[i], '- '..arg[i]..' *%d')) > + end > + assert(c[arg.n+2] == nil) > +end > + > + > +function checkequal (a, b) > + a = T.listcode(a) > + b = T.listcode(b) > + for i = 1, table.getn(a) do > + a[i] = string.gsub(a[i], '%b()', '') -- remove line number > + b[i] = string.gsub(b[i], '%b()', '') -- remove line number > + assert(a[i] == b[i]) > + end > +end > + > + > +-- some basic instructions > +check(function () > + (function () end){f()} > +end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN') > + > + > +-- sequence of LOADNILs > +check(function () > + local a,b,c > + local d; local e; > + a = nil; d=nil > +end, 'RETURN') > + > + > +-- single return > +check (function (a,b,c) return a end, 'RETURN') > + > + > +-- infinite loops > +check(function () while true do local a = -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () while 1 do local a = -1 end end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x = 1 until false end, > +'LOADK', 'JMP', 'RETURN') > + > +check(function () repeat local x until nil end, > +'LOADNIL', 'JMP', 'RETURN') > + > +check(function () repeat local x = 1 until true end, > +'LOADK', 'RETURN') > + > + > +-- concat optimization > +check(function (a,b,c,d) return a..b..c..d end, > + 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') > + > +-- not > +check(function () return not not nil end, 'LOADBOOL', 'RETURN') > +check(function () return not not false end, 'LOADBOOL', 'RETURN') > +check(function () return not not true end, 'LOADBOOL', 'RETURN') > +check(function () return not not 1 end, 'LOADBOOL', 'RETURN') > + > +-- direct access to locals > +check(function () > + local a,b,c,d > + a = b*2 > + c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b > +end, > + 'MUL', > + 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', > + 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') > + > + > +-- direct access to constants > +check(function () > + local a,b > + a.x = 0 > + a.x = b > + a[b] = 'y' > + a = 1 - a > + b = 1/a > + b = 5+4 > + a[true] = false > +end, > + 'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK', > + 'SETTABLE', 'RETURN') > + > +local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end > + > +check(f, 'LOADK', 'RETURN') > +assert(f() == -5) > + > +check(function () > + local a,b,c > + b[c], a = c, b > + b[a], a = c, b > + a, b = c, a > + a = a > +end, > + 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', > + 'MOVE', 'MOVE', 'MOVE', > + -- no code for a = a > + 'RETURN') > + > + > +-- x == nil , x ~= nil > +checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end, > + function () if (a==9) then a=1 end; if a~=9 then a=1 end end) > + > +check(function () if a==nil then a=1 end end, > +'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN') > + > +-- de morgan > +checkequal(function () local a; if not (a or b) then b=a end end, > + function () local a; if (not a and not b) then b=a end end) > + > +checkequal(function (l) local a; return 0 <= a and a <= l end, > + function (l) local a; return not (not(a >= 0) or not(a <= l)) end) > + > + > +print 'OK' > + > diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua > new file mode 100644 > index 0000000..5fb3798 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/constructs.lua > @@ -0,0 +1,240 @@ > +print "testing syntax" > + > +-- testing priorities > + > +assert(2^3^2 == 2^(3^2)); > +assert(2^3*4 == (2^3)*4); > +assert(2^-2 == 1/4 and -2^- -2 == - - -4); > +assert(not nil and 2 and not(2>3 or 3<2)); > +assert(-3-1-5 == 0+0-9); > +assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0); > +assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33"); > +assert(not(2+1 > 3*1) and "a".."b" > "a"); > + > +assert(not ((true or false) and nil)) > +assert( true or false and nil) > + > +local a,b = 1,nil; > +assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75); > +x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x); > +x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x); > + > +x,y=1,2; > +assert((x>y) and x or y == 2); > +x,y=2,1; > +assert((x>y) and x or y == 2); > + > +assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) > + > + > +-- silly loops > +repeat until 1; repeat until true; > +while false do end; while nil do end; > + > +do -- test old bug (first name could not be an `upvalue') > + local a; function f(x) x={a=1}; x={x=1}; x={G=1} end > +end > + > +function f (i) > + if type(i) ~= 'number' then return i,'jojo'; end; > + if i > 0 then return i, f(i-1); end; > +end > + > +x = {f(3), f(5), f(10);}; > +assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1); > +assert(x[nil] == nil) > +x = {f'alo', f'xixi', nil}; > +assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil); > +x = {f'alo'..'xixi'}; > +assert(x[1] == 'aloxixi') > +x = {f{}} > +assert(x[2] == 'jojo' and type(x[1]) == 'table') > + > + > +local f = function (i) > + if i < 10 then return 'a'; > + elseif i < 20 then return 'b'; > + elseif i < 30 then return 'c'; > + end; > +end > + > +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil) > + > +for i=1,1000 do break; end; > +n=100; > +i=3; > +t = {}; > +a=nil > +while not a do > + a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end; > +end > +assert(a == n*(n+1)/2 and i==3); > +assert(t[1] and t[n] and not t[0] and not t[n+1]) > + > +function f(b) > + local x = 1; > + repeat > + local a; > + if b==1 then local b=1; x=10; break > + elseif b==2 then x=20; break; > + elseif b==3 then x=30; > + else local a,b,c,d=math.sin(1); x=x+1; > + end > + until x>=12; > + return x; > +end; > + > +assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12) > + > + > +local f = function (i) > + if i < 10 then return 'a' > + elseif i < 20 then return 'b' > + elseif i < 30 then return 'c' > + else return 8 > + end > +end > + > +assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8) > + > +local a, b = nil, 23 > +x = {f(100)*2+3 or a, a or b+2} > +assert(x[1] == 19 and x[2] == 25) > +x = {f=2+3 or a, a = b+2} > +assert(x.f == 5 and x.a == 25) > + > +a={y=1} > +x = {a.y} > +assert(x[1] == 1) > + > +function f(i) > + while 1 do > + if i>0 then i=i-1; > + else return; end; > + end; > +end; > + > +function g(i) > + while 1 do > + if i>0 then i=i-1 > + else return end > + end > +end > + > +f(10); g(10); > + > +do > + function f () return 1,2,3; end > + local a, b, c = f(); > + assert(a==1 and b==2 and c==3) > + a, b, c = (f()); > + assert(a==1 and b==nil and c==nil) > +end > + > +local a,b = 3 and f(); > +assert(a==1 and b==nil) > + > +function g() f(); return; end; > +assert(g() == nil) > +function g() return nil or f() end > +a,b = g() > +assert(a==1 and b==nil) > + > +print'+'; > + > + > +f = [[ > +return function ( a , b , c , d , e ) > + local x = a >= b or c or ( d and e ) or nil > + return x > +end , { a = 1 , b = 2 >= 1 , } or { 1 }; > +]] > +f = string.gsub(f, "%s+", "\n"); -- force a SETLINE between opcodes > +f,a = loadstring(f)(); > +assert(a.a == 1 and a.b) > + > +function g (a,b,c,d,e) > + if not (a>=b or c or d and e or nil) then return 0; else return 1; end; > +end > + > +function h (a,b,c,d,e) > + while (a>=b or c or (d and e) or nil) do return 1; end; > + return 0; > +end; > + > +assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1) > +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) > +assert(f(1,2,'a') > +~= -- force SETLINE before nil > +nil, "") > +assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) > +assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and > + h(1,2,nil,1,'x') == 1) > +assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and > + h(1,2,nil,nil,'x') == 0) > +assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and > + h(1,2,nil,1,nil) == 0) > + > +assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true) > +x = 2<3 and not 3; assert(x==false) > +x = 2<1 or (2>1 and 'a'); assert(x=='a') > + > + > +do > + local a; if nil then a=1; else a=2; end; -- this nil comes as PUSHNIL 2 > + assert(a==2) > +end > + > +function F(a) > + assert(debug.getinfo(1, "n").name == 'F') > + return a,2,3 > +end > + > +a,b = F(1)~=nil; assert(a == true and b == nil); > +a,b = F(nil)==nil; assert(a == true and b == nil) > + > +---------------------------------------------------------------- > +-- creates all combinations of > +-- [not] ([not] arg op [not] (arg op [not] arg )) > +-- and tests each one > + > +function ID(x) return x end > + > +function f(t, i) > + local b = t.n > + local res = math.mod(math.floor(i/c), b)+1 > + c = c*b > + return t[res] > +end > + > +local arg = {" ( 1 < 2 ) ", " ( 1 >= 2 ) ", " F ( ) ", " nil "; n=4} > + > +local op = {" and ", " or ", " == ", " ~= "; n=4} > + > +local neg = {" ", " not "; n=2} > + > +local i = 0 > +repeat > + c = 1 > + local s = f(neg, i)..'ID('..f(neg, i)..f(arg, i)..f(op, i).. > + f(neg, i)..'ID('..f(arg, i)..f(op, i)..f(neg, i)..f(arg, i)..'))' > + local s1 = string.gsub(s, 'ID', '') > + K,X,NX,WX1,WX2 = nil > + s = string.format([[ > + local a = %s > + local b = not %s > + K = b > + local xxx; > + if %s then X = a else X = b end > + if %s then NX = b else NX = a end > + while %s do WX1 = a; break end > + while %s do WX2 = a; break end > + repeat if (%s) then break end; assert(b) until not(%s) > + ]], s1, s, s1, s, s1, s, s1, s, s) > + assert(loadstring(s))() > + assert(X and not NX and not WX1 == K and not WX2 == K) > + if math.mod(i,4000) == 0 then print('+') end > + i = i+1 > +until i==c > + > +print'OK' > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > new file mode 100644 > index 0000000..9d2c86f > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -0,0 +1,499 @@ > +-- testing debug library > + > +local function dostring(s) return assert(loadstring(s))() end > + > +print"testing debug library and debug information" > + > +do > +local a=1 > +end > + > +function test (s, l, p) > + collectgarbage() -- avoid gc during trace > + local function f (event, line) > + assert(event == 'line') > + local l = table.remove(l, 1) > + if p then print(l, line) end > + assert(l == line, "wrong trace!!") > + end > + debug.sethook(f,"l"); loadstring(s)(); debug.sethook() > + assert(table.getn(l) == 0) > +end > + > + > +do > + local a = debug.getinfo(print) > + assert(a.what == "C" and a.short_src == "[C]") > + local b = debug.getinfo(test, "SfL") > + assert(b.name == nil and b.what == "Lua" and b.linedefined == 11 and > + b.lastlinedefined == b.linedefined + 10 and > + b.func == test and not string.find(b.short_src, "%[")) > + assert(b.activelines[b.linedefined + 1] and > + b.activelines[b.lastlinedefined]) > + assert(not b.activelines[b.linedefined] and > + not b.activelines[b.lastlinedefined + 1]) > +end > + > + > +-- test file and string names truncation > +a = "function f () end" > +local function dostring (s, x) return loadstring(s, x)() end > +dostring(a) > +assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a)) > +dostring(a..string.format("; %s\n=1", string.rep('p', 400))) > +assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$')) > +dostring("\n"..a) > +assert(debug.getinfo(f).short_src == '[string "..."]') > +dostring(a, "") > +assert(debug.getinfo(f).short_src == '[string ""]') > +dostring(a, "@xuxu") > +assert(debug.getinfo(f).short_src == "xuxu") > +dostring(a, "@"..string.rep('p', 1000)..'t') > +assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$")) > +dostring(a, "=xuxu") > +assert(debug.getinfo(f).short_src == "xuxu") > +dostring(a, string.format("=%s", string.rep('x', 500))) > +assert(string.find(debug.getinfo(f).short_src, "^x*")) > +dostring(a, "=") > +assert(debug.getinfo(f).short_src == "") > +a = nil; f = nil; > + > + > +repeat > + local g = {x = function () > + local a = debug.getinfo(2) > + assert(a.name == 'f' and a.namewhat == 'local') > + a = debug.getinfo(1) > + assert(a.name == 'x' and a.namewhat == 'field') > + return 'xixi' > + end} > + local f = function () return 1+1 and (not 1 or g.x()) end > + assert(f() == 'xixi') > + g = debug.getinfo(f) > + assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name) > + > + function f (x, name) -- local! > + name = name or 'f' > + local a = debug.getinfo(1) > + assert(a.name == name and a.namewhat == 'local') > + return x > + end > + > + -- breaks in different conditions > + if 3>4 then break end; f() > + if 3<4 then a=1 else break end; f() > + while 1 do local x=10; break end; f() > + local b = 1 > + if 3>4 then return math.sin(1) end; f() > + a = 3<4; f() > + a = 3<4 or 1; f() > + repeat local x=20; if 4>3 then f() else break end; f() until 1 > + g = {} > + f(g).x = f(2) and f(10)+f(9) > + assert(g.x == f(19)) > + function g(x) if not x then return 3 end return (x('a', 'x')) end > + assert(g(f) == 'a') > +until 1 > + > +test([[if > +math.sin(1) > +then > + a=1 > +else > + a=2 > +end > +]], {2,4,7}) > + > +test([[-- > +if nil then > + a=1 > +else > + a=2 > +end > +]], {2,5,6}) > + > +test([[a=1 > +repeat > + a=a+1 > +until a==3 > +]], {1,3,4,3,4}) > + > +test([[ do > + return > +end > +]], {2}) > + > +test([[local a > +a=1 > +while a<=3 do > + a=a+1 > +end > +]], {2,3,4,3,4,3,4,3,5}) > + > +test([[while math.sin(1) do > + if math.sin(1) > + then > + break > + end > +end > +a=1]], {1,2,4,7}) > + > +test([[for i=1,3 do > + a=i > +end > +]], {1,2,1,2,1,2,1,3}) > + > +test([[for i,v in pairs{'a','b'} do > + a=i..v > +end > +]], {1,2,1,2,1,3}) > + > +test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > + > + > + > +print'+' > + > +a = {}; L = nil > +local glob = 1 > +local oldglob = glob > +debug.sethook(function (e,l) > + collectgarbage() -- force GC during a hook > + local f, m, c = debug.gethook() > + assert(m == 'crl' and c == 0) > + if e == "line" then > + if glob ~= oldglob then > + L = l-1 -- get the first line where "glob" has changed > + oldglob = glob > + end > + elseif e == "call" then > + local f = debug.getinfo(2, "f").func > + a[f] = 1 > + else assert(e == "return") > + end > +end, "crl") > + > +function f(a,b) > + collectgarbage() > + local _, x = debug.getlocal(1, 1) > + local _, y = debug.getlocal(1, 2) > + assert(x == a and y == b) > + assert(debug.setlocal(2, 3, "pera") == "AA".."AA") > + assert(debug.setlocal(2, 4, "ma��") == "B") > + x = debug.getinfo(2) > + assert(x.func == g and x.what == "Lua" and x.name == 'g' and > + x.nups == 0 and string.find(x.source, "^@.*db%.lua")) > + glob = glob+1 > + assert(debug.getinfo(1, "l").currentline == L+1) > + assert(debug.getinfo(1, "l").currentline == L+2) > +end > + > +function foo() > + glob = glob+1 > + assert(debug.getinfo(1, "l").currentline == L+1) > +end; foo() -- set L > +-- check line counting inside strings and empty lines > + > +_ = 'alo\ > +alo' .. [[ > + > +]] > +--[[ > +]] > +assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines > + > + > +function g(...) > + do local a,b,c; a=math.sin(40); end > + local feijao > + local AAAA,B = "xuxu", "mam�o" > + f(AAAA,B) > + assert(AAAA == "pera" and B == "ma��") > + do > + local B = 13 > + local x,y = debug.getlocal(1,5) > + assert(x == 'B' and y == 13) > + end > +end > + > +g() > + > + > +assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print]) > + > + > +-- tests for manipulating non-registered locals (C and Lua temporaries) > + > +local n, v = debug.getlocal(0, 1) > +assert(v == 0 and n == "(*temporary)") > +local n, v = debug.getlocal(0, 2) > +assert(v == 2 and n == "(*temporary)") > +assert(not debug.getlocal(0, 3)) > +assert(not debug.getlocal(0, 0)) > + > +function f() > + assert(select(2, debug.getlocal(2,3)) == 1) > + assert(not debug.getlocal(2,4)) > + debug.setlocal(2, 3, 10) > + return 20 > +end > + > +function g(a,b) return (a+1) + f() end > + > +assert(g(0,0) == 30) > + > + > +debug.sethook(nil); > +assert(debug.gethook() == nil) > + > + > +-- testing access to function arguments > + > +X = nil > +a = {} > +function a:f (a, b, ...) local c = 13 end > +debug.sethook(function (e) > + assert(e == "call") > + dostring("XX = 12") -- test dostring inside hooks > + -- testing errors inside hooks > + assert(not pcall(loadstring("a='joao'+1"))) > + debug.sethook(function (e, l) > + assert(debug.getinfo(2, "l").currentline == l) > + local f,m,c = debug.gethook() > + assert(e == "line") > + assert(m == 'l' and c == 0) > + debug.sethook(nil) -- hook is called only once > + assert(not X) -- check that > + X = {}; local i = 1 > + local x,y > + while 1 do > + x,y = debug.getlocal(2, i) > + if x==nil then break end > + X[x] = y > + i = i+1 > + end > + end, "l") > +end, "c") > + > +a:f(1,2,3,4,5) > +assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) > +assert(XX == 12) > +assert(debug.gethook() == nil) > + > + > +-- testing upvalue access > +local function getupvalues (f) > + local t = {} > + local i = 1 > + while true do > + local name, value = debug.getupvalue(f, i) > + if not name then break end > + assert(not t[name]) > + t[name] = value > + i = i + 1 > + end > + return t > +end > + > +local a,b,c = 1,2,3 > +local function foo1 (a) b = a; return c end > +local function foo2 (x) a = x; return c+b end > +assert(debug.getupvalue(foo1, 3) == nil) > +assert(debug.getupvalue(foo1, 0) == nil) > +assert(debug.setupvalue(foo1, 3, "xuxu") == nil) > +local t = getupvalues(foo1) > +assert(t.a == nil and t.b == 2 and t.c == 3) > +t = getupvalues(foo2) > +assert(t.a == 1 and t.b == 2 and t.c == 3) > +assert(debug.setupvalue(foo1, 1, "xuxu") == "b") > +assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu") > +-- cannot manipulate C upvalues from Lua > +assert(debug.getupvalue(io.read, 1) == nil) > +assert(debug.setupvalue(io.read, 1, 10) == nil) > + > + > +-- testing count hooks > +local a=0 > +debug.sethook(function (e) a=a+1 end, "", 1) > +a=0; for i=1,1000 do end; assert(1000 < a and a < 1012) > +debug.sethook(function (e) a=a+1 end, "", 4) > +a=0; for i=1,1000 do end; assert(250 < a and a < 255) > +local f,m,c = debug.gethook() > +assert(m == "" and c == 4) > +debug.sethook(function (e) a=a+1 end, "", 4000) > +a=0; for i=1,1000 do end; assert(a == 0) > +debug.sethook(print, "", 2^24 - 1) -- count upperbound > +local f,m,c = debug.gethook() > +assert(({debug.gethook()})[3] == 2^24 - 1) > +debug.sethook() > + > + > +-- tests for tail calls > +local function f (x) > + if x then > + assert(debug.getinfo(1, "S").what == "Lua") > + local tail = debug.getinfo(2) > + assert(not pcall(getfenv, 3)) > + assert(tail.what == "tail" and tail.short_src == "(tail call)" and > + tail.linedefined == -1 and tail.func == nil) > + assert(debug.getinfo(3, "f").func == g1) > + assert(getfenv(3)) > + assert(debug.getinfo(4, "S").what == "tail") > + assert(not pcall(getfenv, 5)) > + assert(debug.getinfo(5, "S").what == "main") > + assert(getfenv(5)) > + print"+" > + end > +end > + > +function g(x) return f(x) end > + > +function g1(x) g(x) end > + > +local function h (x) local f=g1; return f(x) end > + > +h(true) > + > +local b = {} > +debug.sethook(function (e) table.insert(b, e) end, "cr") > +h(false) > +debug.sethook() > +local res = {"return", -- first return (from sethook) > + "call", "call", "call", "call", > + "return", "tail return", "return", "tail return", > + "call", -- last call (to sethook) > +} > +for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > + > + > +lim = 30000 > +local function foo (x) > + if x==0 then > + assert(debug.getinfo(lim+2).what == "main") > + for i=2,lim do assert(debug.getinfo(i, "S").what == "tail") end > + else return foo(x-1) > + end > +end > + > +foo(lim) > + > + > +print"+" > + > + > +-- testing traceback > + > +assert(debug.traceback(print) == print) > +assert(debug.traceback(print, 4) == print) > +assert(string.find(debug.traceback("hi", 4), "^hi\n")) > +assert(string.find(debug.traceback("hi"), "^hi\n")) > +assert(not string.find(debug.traceback("hi"), "'traceback'")) > +assert(string.find(debug.traceback("hi", 0), "'traceback'")) > +assert(string.find(debug.traceback(), "^stack traceback:\n")) > + > +-- testing debugging of coroutines > + > +local function checktraceback (co, p) > + local tb = debug.traceback(co) > + local i = 0 > + for l in string.gmatch(tb, "[^\n]+\n?") do > + assert(i == 0 or string.find(l, p[i])) > + i = i+1 > + end > + assert(p[i] == nil) > +end > + > + > +local function f (n) > + if n > 0 then return f(n-1) > + else coroutine.yield() end > +end > + > +local co = coroutine.create(f) > +coroutine.resume(co, 3) > +checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) > + > + > +co = coroutine.create(function (x) > + local a = 1 > + coroutine.yield(debug.getinfo(1, "l")) > + coroutine.yield(debug.getinfo(1, "l").currentline) > + return a > + end) > + > +local tr = {} > +local foo = function (e, l) table.insert(tr, l) end > +debug.sethook(co, foo, "l") > + > +local _, l = coroutine.resume(co, 10) > +local x = debug.getinfo(co, 1, "lfLS") > +assert(x.currentline == l.currentline and x.activelines[x.currentline]) > +assert(type(x.func) == "function") > +for i=x.linedefined + 1, x.lastlinedefined do > + assert(x.activelines[i]) > + x.activelines[i] = nil > +end > +assert(next(x.activelines) == nil) -- no 'extra' elements > +assert(debug.getinfo(co, 2) == nil) > +local a,b = debug.getlocal(co, 1, 1) > +assert(a == "x" and b == 10) > +a,b = debug.getlocal(co, 1, 2) > +assert(a == "a" and b == 1) > +debug.setlocal(co, 1, 2, "hi") > +assert(debug.gethook(co) == foo) > +assert(table.getn(tr) == 2 and > + tr[1] == l.currentline-1 and tr[2] == l.currentline) > + > +a,b,c = pcall(coroutine.resume, co) > +assert(a and b and c == l.currentline+1) > +checktraceback(co, {"yield", "in function <"}) > + > +a,b = coroutine.resume(co) > +assert(a and b == "hi") > +assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) > +assert(debug.gethook(co) == foo) > +assert(debug.gethook() == nil) > +checktraceback(co, {}) > + > + > +-- check traceback of suspended (or dead with error) coroutines > + > +function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end > + > +co = coroutine.create(function (x) f(x) end) > +a, b = coroutine.resume(co, 3) > +t = {"'yield'", "'f'", "in function <"} > +while coroutine.status(co) == "suspended" do > + checktraceback(co, t) > + a, b = coroutine.resume(co) > + table.insert(t, 2, "'f'") -- one more recursive call to 'f' > +end > +t[1] = "'error'" > +checktraceback(co, t) > + > + > +-- test acessing line numbers of a coroutine from a resume inside > +-- a C function (this is a known bug in Lua 5.0) > + > +local function g(x) > + coroutine.yield(x) > +end > + > +local function f (i) > + debug.sethook(function () end, "l") > + for j=1,1000 do > + g(i+j) > + end > +end > + > +local co = coroutine.wrap(f) > +co(10) > +pcall(co) > +pcall(co) > + > + > +assert(type(debug.getregistry()) == "table") > + > + > +print"OK" > + > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > new file mode 100644 > index 0000000..e881211 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -0,0 +1,250 @@ > +print("testing errors") > + > +function doit (s) > + local f, msg = loadstring(s) > + if f == nil then return msg end > + local cond, msg = pcall(f) > + return (not cond) and msg > +end > + > + > +function checkmessage (prog, msg) > + assert(string.find(doit(prog), msg, 1, true)) > +end > + > +function checksyntax (prog, extra, token, line) > + local msg = doit(prog) > + token = string.gsub(token, "(%p)", "%%%1") > + local pt = string.format([[^%%[string ".*"%%]:%d: .- near '%s'$]], > + line, token) > + assert(string.find(msg, pt)) > + assert(string.find(msg, msg, 1, true)) > +end > + > + > +-- test error message with no extra info > +assert(doit("error('hi', 0)") == 'hi') > + > +-- test error message with no info > +assert(doit("error()") == nil) > + > + > +-- test common errors/errors that crashed in the past > +assert(doit("unpack({}, 1, n=2^30)")) > +assert(doit("a=math.sin()")) > +assert(not doit("tostring(1)") and doit("tostring()")) > +assert(doit"tonumber()") > +assert(doit"repeat until 1; a") > +checksyntax("break label", "", "label", 1) > +assert(doit";") > +assert(doit"a=1;;") > +assert(doit"return;;") > +assert(doit"assert(false)") > +assert(doit"assert(nil)") > +assert(doit"a=math.sin\n(3)") > +assert(doit("function a (... , ...) end")) > +assert(doit("function a (, ...) end")) > + > +checksyntax([[ > + local a = {4 > + > +]], "'}' expected (to close '{' at line 1)", "<eof>", 3) > + > + > +-- tests for better error messages > + > +checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'") > +checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)", > + "local 'bbbb'") > +checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'") > +checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'") > +assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'")) > +checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number") > + > +aaa = nil > +checkmessage("aaa.bbb:ddd(9)", "global 'aaa'") > +checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'") > +checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'") > +checkmessage("local a,b,c; (function () a = b+1 end)()", "upvalue 'b'") > +assert(not doit"local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)") > + > +checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > +checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > +checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > +checkmessage("aaa={}; x=-aaa", "global 'aaa'") > +assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > +assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > + > +checkmessage([[aaa=9 > +repeat until 3==3 > +local x=math.sin(math.cos(3)) > +if math.sin(1) == x then return math.sin(1) end -- tail call > +local a,b = 1, { > + {x='a'..'b'..'c', y='b', z=x}, > + {1,2,3,4,5} or 3+3<=3+3, > + 3+1>3+1, > + {d = x and aaa[x or y]}} > +]], "global 'aaa'") > + > +checkmessage([[ > +local x,y = {},1 > +if math.sin(1) == 0 then return 3 end -- return > +x.a()]], "field 'a'") > + > +checkmessage([[ > +prefix = nil > +insert = nil > +while 1 do > + local a > + if nil then break end > + insert(prefix, a) > +end]], "global 'insert'") > + > +checkmessage([[ -- tail call > + return math.sin("a") > +]], "'sin'") > + > +checkmessage([[collectgarbage("nooption")]], "invalid option") > + > +checkmessage([[x = print .. "a"]], "concatenate") > + > +checkmessage("getmetatable(io.stdin).__gc()", "no value") > + > +print'+' > + > + > +-- testing line error > + > +function lineerror (s) > + local err,msg = pcall(loadstring(s)) > + local line = string.match(msg, ":(%d+):") > + return line and line+0 > +end > + > +assert(lineerror"local a\n for i=1,'a' do \n print(i) \n end" == 2) > +assert(lineerror"\n local a \n for k,v in 3 \n do \n print(k) \n end" == 3) > +assert(lineerror"\n\n for k,v in \n 3 \n do \n print(k) \n end" == 4) > +assert(lineerror"function a.x.y ()\na=a+1\nend" == 1) > + > +local p = [[ > +function g() f() end > +function f(x) error('a', X) end > +g() > +]] > +X=3;assert(lineerror(p) == 3) > +X=0;assert(lineerror(p) == nil) > +X=1;assert(lineerror(p) == 2) > +X=2;assert(lineerror(p) == 1) > + > +lineerror = nil > + > +C = 0 > +local l = debug.getinfo(1, "l").currentline; function y () C=C+1; y() end > + > +local function checkstackmessage (m) > + return (string.find(m, "^.-:%d+: stack overflow")) > +end > +assert(checkstackmessage(doit('y()'))) > +assert(checkstackmessage(doit('y()'))) > +assert(checkstackmessage(doit('y()'))) > +-- teste de linhas em erro > +C = 0 > +local l1 > +local function g() > + l1 = debug.getinfo(1, "l").currentline; y() > +end > +local _, stackmsg = xpcall(g, debug.traceback) > +local stack = {} > +for line in string.gmatch(stackmsg, "[^\n]*") do > + local curr = string.match(line, ":(%d+):") > + if curr then table.insert(stack, tonumber(curr)) end > +end > +local i=1 > +while stack[i] ~= l1 do > + assert(stack[i] == l) > + i = i+1 > +end > +assert(i > 15) > + > + > +-- error in error handling > +local res, msg = xpcall(error, error) > +assert(not res and type(msg) == 'string') > + > +local function f (x) > + if x==0 then error('a\n') > + else > + local aux = function () return f(x-1) end > + local a,b = xpcall(aux, aux) > + return a,b > + end > +end > +f(3) > + > +-- non string messages > +function f() error{msg='x'} end > +res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) > +assert(msg.msg == 'xy') > + > +print('+') > +checksyntax("syntax error", "", "error", 1) > +checksyntax("1.000", "", "1.000", 1) > +checksyntax("[[a]]", "", "[[a]]", 1) > +checksyntax("'aa'", "", "'aa'", 1) > + > +-- test 255 as first char in a chunk > +checksyntax("\255a = 1", "", "\255", 1) > + > +doit('I = loadstring("a=9+"); a=3') > +assert(a==3 and I == nil) > +print('+') > + > +lim = 1000 > +if rawget(_G, "_soft") then lim = 100 end > +for i=1,lim do > + doit('a = ') > + doit('a = 4+nil') > +end > + > + > +-- testing syntax limits > +local function testrep (init, rep) > + local s = "local a; "..init .. string.rep(rep, 400) > + local a,b = loadstring(s) > + assert(not a and string.find(b, "syntax levels")) > +end > +testrep("a=", "{") > +testrep("a=", "(") > +testrep("", "a(") > +testrep("", "do ") > +testrep("", "while a do ") > +testrep("", "if a then else ") > +testrep("", "function foo () ") > +testrep("a=", "a..") > +testrep("a=", "a^") > + > + > +-- testing other limits > +-- upvalues > +local s = "function foo ()\n local " > +for j = 1,70 do > + s = s.."a"..j..", " > +end > +s = s.."b\n" > +for j = 1,70 do > + s = s.."function foo"..j.." ()\n a"..j.."=3\n" > +end > +local a,b = loadstring(s) > +assert(string.find(b, "line 3")) > + > +-- local variables > +s = "\nfunction foo ()\n local " > +for j = 1,300 do > + s = s.."a"..j..", " > +end > +s = s.."b\n" > +local a,b = loadstring(s) > +assert(string.find(b, "line 2")) > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.c b/test/PUC-Lua-5.1-tests/etc/ltests.c > new file mode 100644 > index 0000000..be949e5 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/etc/ltests.c > @@ -0,0 +1,1147 @@ > +/* > +** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp $ > +** Internal Module for Debugging of the Lua Implementation > +** See Copyright Notice in lua.h > +*/ > + > + > +#include <ctype.h> > +#include <limits.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > + > +#define ltests_c > +#define LUA_CORE > + > +#include "lua.h" > + > +#include "lapi.h" > +#include "lauxlib.h" > +#include "lcode.h" > +#include "ldebug.h" > +#include "ldo.h" > +#include "lfunc.h" > +#include "lmem.h" > +#include "lopcodes.h" > +#include "lstate.h" > +#include "lstring.h" > +#include "ltable.h" > +#include "lualib.h" > + > + > + > +/* > +** The whole module only makes sense with LUA_DEBUG on > +*/ > +#if defined(LUA_DEBUG) > + > + > +int Trick = 0; > + > + > +static lua_State *lua_state = NULL; > + > +int islocked = 0; > + > + > +#define obj_at(L,k) (L->ci->base+(k) - 1) > + > + > +static void setnameval (lua_State *L, const char *name, int val) { > + lua_pushstring(L, name); > + lua_pushinteger(L, val); > + lua_settable(L, -3); > +} > + > + > +/* > +** {====================================================================== > +** Controlled version for realloc. > +** ======================================================================= > +*/ > + > +#define MARK 0x55 /* 01010101 (a nice pattern) */ > + > +#ifndef EXTERNMEMCHECK > +/* full memory check */ > +#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ > +#define MARKSIZE 16 /* size of marks after each block */ > +#define blockhead(b) (cast(char *, b) - HEADER) > +#define setsize(newblock, size) (*cast(size_t *, newblock) = size) > +#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) > +#define fillmem(mem,size) memset(mem, -MARK, size) > +#else > +/* external memory check: don't do it twice */ > +#define HEADER 0 > +#define MARKSIZE 0 > +#define blockhead(b) (b) > +#define setsize(newblock, size) /* empty */ > +#define checkblocksize(b,size) (1) > +#define fillmem(mem,size) /* empty */ > +#endif > + > + > +Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX}; > + > + > +static void *checkblock (void *block, size_t size) { > + void *b = blockhead(block); > + int i; > + for (i=0;i<MARKSIZE;i++) > + lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ > + return b; > +} > + > + > +static void freeblock (Memcontrol *mc, void *block, size_t size) { > + if (block) { > + lua_assert(checkblocksize(block, size)); > + block = checkblock(block, size); > + fillmem(block, size+HEADER+MARKSIZE); /* erase block */ > + free(block); /* free original block */ > + mc->numblocks--; > + mc->total -= size; > + } > +} > + > + > +void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { > + Memcontrol *mc = cast(Memcontrol *, ud); > + lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); > + if (size == 0) { > + freeblock(mc, block, oldsize); > + return NULL; > + } > + else if (size > oldsize && mc->total+size-oldsize > mc->memlimit) > + return NULL; /* to test memory allocation errors */ > + else { > + void *newblock; > + int i; > + size_t realsize = HEADER+size+MARKSIZE; > + size_t commonsize = (oldsize < size) ? oldsize : size; > + if (realsize < size) return NULL; /* overflow! */ > + newblock = malloc(realsize); /* alloc a new block */ > + if (newblock == NULL) return NULL; > + if (block) { > + memcpy(cast(char *, newblock)+HEADER, block, commonsize); > + freeblock(mc, block, oldsize); /* erase (and check) old copy */ > + } > + /* initialize new part of the block with something `weird' */ > + fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); > + mc->total += size; > + if (mc->total > mc->maxmem) > + mc->maxmem = mc->total; > + mc->numblocks++; > + setsize(newblock, size); > + for (i=0;i<MARKSIZE;i++) > + *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); > + return cast(char *, newblock)+HEADER; > + } > +} > + > + > +/* }====================================================================== */ > + > + > + > +/* > +** {====================================================== > +** Functions to check memory consistency > +** ======================================================= > +*/ > + > +static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { > + if (isdead(g,t)) return 0; > + if (g->gcstate == GCSpropagate) > + return !isblack(f) || !iswhite(t); > + else if (g->gcstate == GCSfinalize) > + return iswhite(f); > + else > + return 1; > +} > + > + > +static void printobj (global_State *g, GCObject *o) { > + int i = 0; > + GCObject *p; > + for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++; > + if (p == NULL) i = -1; > + printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o, > + isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked); > +} > + > + > +static int testobjref (global_State *g, GCObject *f, GCObject *t) { > + int r = testobjref1(g,f,t); > + if (!r) { > + printf("%d(%02X) - ", g->gcstate, g->currentwhite); > + printobj(g, f); > + printf("\t-> "); > + printobj(g, t); > + printf("\n"); > + } > + return r; > +} > + > +#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) > + > +#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \ > + ((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t)))) > + > + > + > +static void checktable (global_State *g, Table *h) { > + int i; > + int weakkey = 0; > + int weakvalue = 0; > + const TValue *mode; > + GCObject *hgc = obj2gco(h); > + if (h->metatable) > + checkobjref(g, hgc, h->metatable); > + mode = gfasttm(g, h->metatable, TM_MODE); > + if (mode && ttisstring(mode)) { /* is there a weak mode? */ > + weakkey = (strchr(svalue(mode), 'k') != NULL); > + weakvalue = (strchr(svalue(mode), 'v') != NULL); > + } > + i = h->sizearray; > + while (i--) > + checkvalref(g, hgc, &h->array[i]); > + i = sizenode(h); > + while (i--) { > + Node *n = gnode(h, i); > + if (!ttisnil(gval(n))) { > + lua_assert(!ttisnil(gkey(n))); > + checkvalref(g, hgc, gkey(n)); > + checkvalref(g, hgc, gval(n)); > + } > + } > +} > + > + > +/* > +** All marks are conditional because a GC may happen while the > +** prototype is still being created > +*/ > +static void checkproto (global_State *g, Proto *f) { > + int i; > + GCObject *fgc = obj2gco(f); > + if (f->source) checkobjref(g, fgc, f->source); > + for (i=0; i<f->sizek; i++) { > + if (ttisstring(f->k+i)) > + checkobjref(g, fgc, rawtsvalue(f->k+i)); > + } > + for (i=0; i<f->sizeupvalues; i++) { > + if (f->upvalues[i]) > + checkobjref(g, fgc, f->upvalues[i]); > + } > + for (i=0; i<f->sizep; i++) { > + if (f->p[i]) > + checkobjref(g, fgc, f->p[i]); > + } > + for (i=0; i<f->sizelocvars; i++) { > + if (f->locvars[i].varname) > + checkobjref(g, fgc, f->locvars[i].varname); > + } > +} > + > + > + > +static void checkclosure (global_State *g, Closure *cl) { > + GCObject *clgc = obj2gco(cl); > + checkobjref(g, clgc, cl->l.env); > + if (cl->c.isC) { > + int i; > + for (i=0; i<cl->c.nupvalues; i++) > + checkvalref(g, clgc, &cl->c.upvalue[i]); > + } > + else { > + int i; > + lua_assert(cl->l.nupvalues == cl->l.p->nups); > + checkobjref(g, clgc, cl->l.p); > + for (i=0; i<cl->l.nupvalues; i++) { > + if (cl->l.upvals[i]) { > + lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL); > + checkobjref(g, clgc, cl->l.upvals[i]); > + } > + } > + } > +} > + > + > +static void checkstack (global_State *g, lua_State *L1) { > + StkId o; > + CallInfo *ci; > + GCObject *uvo; > + lua_assert(!isdead(g, obj2gco(L1))); > + for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) { > + UpVal *uv = gco2uv(uvo); > + lua_assert(uv->v != &uv->u.value); /* must be open */ > + lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ > + } > + checkliveness(g, gt(L1)); > + if (L1->base_ci) { > + for (ci = L1->base_ci; ci <= L1->ci; ci++) { > + lua_assert(ci->top <= L1->stack_last); > + lua_assert(lua_checkpc(L1, ci)); > + } > + } > + else lua_assert(L1->size_ci == 0); > + if (L1->stack) { > + for (o = L1->stack; o < L1->top; o++) > + checkliveness(g, o); > + } > + else lua_assert(L1->stacksize == 0); > +} > + > + > +static void checkobject (global_State *g, GCObject *o) { > + if (isdead(g, o)) > +/* lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/ > +{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep)) > +printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked); > +} > + else { > + if (g->gcstate == GCSfinalize) > + lua_assert(iswhite(o)); > + switch (o->gch.tt) { > + case LUA_TUPVAL: { > + UpVal *uv = gco2uv(o); > + lua_assert(uv->v == &uv->u.value); /* must be closed */ > + lua_assert(!isgray(o)); /* closed upvalues are never gray */ > + checkvalref(g, o, uv->v); > + break; > + } > + case LUA_TUSERDATA: { > + Table *mt = gco2u(o)->metatable; > + if (mt) checkobjref(g, o, mt); > + break; > + } > + case LUA_TTABLE: { > + checktable(g, gco2h(o)); > + break; > + } > + case LUA_TTHREAD: { > + checkstack(g, gco2th(o)); > + break; > + } > + case LUA_TFUNCTION: { > + checkclosure(g, gco2cl(o)); > + break; > + } > + case LUA_TPROTO: { > + checkproto(g, gco2p(o)); > + break; > + } > + default: lua_assert(0); > + } > + } > +} > + > + > +int lua_checkpc (lua_State *L, pCallInfo ci) { > + if (ci == L->base_ci || !f_isLua(ci)) return 1; > + else { > + Proto *p = ci_func(ci)->l.p; > + if (ci < L->ci) > + return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; > + else > + return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; > + } > +} > + > + > +int lua_checkmemory (lua_State *L) { > + global_State *g = G(L); > + GCObject *o; > + UpVal *uv; > + checkstack(g, g->mainthread); > + for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next) > + checkobject(g, o); > + for (o = o->gch.next; o != NULL; o = o->gch.next) { > + lua_assert(o->gch.tt == LUA_TUSERDATA); > + checkobject(g, o); > + } > + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { > + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); > + lua_assert(uv->v != &uv->u.value); /* must be open */ > + lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */ > + checkvalref(g, obj2gco(uv), uv->v); > + } > + return 0; > +} > + > +/* }====================================================== */ > + > + > + > +/* > +** {====================================================== > +** Disassembler > +** ======================================================= > +*/ > + > + > +static char *buildop (Proto *p, int pc, char *buff) { > + Instruction i = p->code[pc]; > + OpCode o = GET_OPCODE(i); > + const char *name = luaP_opnames[o]; > + int line = getline(p, pc); > + sprintf(buff, "(%4d) %4d - ", line, pc); > + switch (getOpMode(o)) { > + case iABC: > + sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, > + GETARG_A(i), GETARG_B(i), GETARG_C(i)); > + break; > + case iABx: > + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); > + break; > + case iAsBx: > + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); > + break; > + } > + return buff; > +} > + > + > +#if 0 > +void luaI_printcode (Proto *pt, int size) { > + int pc; > + for (pc=0; pc<size; pc++) { > + char buff[100]; > + printf("%s\n", buildop(pt, pc, buff)); > + } > + printf("-------\n"); > +} > +#endif > + > + > +static int listcode (lua_State *L) { > + int pc; > + Proto *p; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + lua_newtable(L); > + setnameval(L, "maxstack", p->maxstacksize); > + setnameval(L, "numparams", p->numparams); > + for (pc=0; pc<p->sizecode; pc++) { > + char buff[100]; > + lua_pushinteger(L, pc+1); > + lua_pushstring(L, buildop(p, pc, buff)); > + lua_settable(L, -3); > + } > + return 1; > +} > + > + > +static int listk (lua_State *L) { > + Proto *p; > + int i; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + lua_createtable(L, p->sizek, 0); > + for (i=0; i<p->sizek; i++) { > + luaA_pushobject(L, p->k+i); > + lua_rawseti(L, -2, i+1); > + } > + return 1; > +} > + > + > +static int listlocals (lua_State *L) { > + Proto *p; > + int pc = luaL_checkint(L, 2) - 1; > + int i = 0; > + const char *name; > + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), > + 1, "Lua function expected"); > + p = clvalue(obj_at(L, 1))->l.p; > + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) > + lua_pushstring(L, name); > + return i-1; > +} > + > +/* }====================================================== */ > + > + > + > + > +static int get_limits (lua_State *L) { > + lua_createtable(L, 0, 5); > + setnameval(L, "BITS_INT", LUAI_BITSINT); > + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); > + setnameval(L, "MAXVARS", LUAI_MAXVARS); > + setnameval(L, "MAXSTACK", MAXSTACK); > + setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES); > + setnameval(L, "NUM_OPCODES", NUM_OPCODES); > + return 1; > +} > + > + > +static int mem_query (lua_State *L) { > + if (lua_isnone(L, 1)) { > + lua_pushinteger(L, memcontrol.total); > + lua_pushinteger(L, memcontrol.numblocks); > + lua_pushinteger(L, memcontrol.maxmem); > + return 3; > + } > + else { > + memcontrol.memlimit = luaL_checkint(L, 1); > + return 0; > + } > +} > + > + > +static int settrick (lua_State *L) { > + Trick = lua_tointeger(L, 1); > + return 0; > +} > + > + > +/*static int set_gcstate (lua_State *L) { > + static const char *const state[] = {"propagate", "sweep", "finalize"}; > + return 0; > +}*/ > + > + > +static int get_gccolor (lua_State *L) { > + TValue *o; > + luaL_checkany(L, 1); > + o = obj_at(L, 1); > + if (!iscollectable(o)) > + lua_pushstring(L, "no collectable"); > + else > + lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : > + isblack(gcvalue(o)) ? "black" : "grey"); > + return 1; > +} > + > + > +static int gcstate (lua_State *L) { > + switch(G(L)->gcstate) { > + case GCSpropagate: lua_pushstring(L, "propagate"); break; > + case GCSsweepstring: lua_pushstring(L, "sweep strings"); break; > + case GCSsweep: lua_pushstring(L, "sweep"); break; > + case GCSfinalize: lua_pushstring(L, "finalize"); break; > + } > + return 1; > +} > + > + > +static int hash_query (lua_State *L) { > + if (lua_isnone(L, 2)) { > + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); > + lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash); > + } > + else { > + TValue *o = obj_at(L, 1); > + Table *t; > + luaL_checktype(L, 2, LUA_TTABLE); > + t = hvalue(obj_at(L, 2)); > + lua_pushinteger(L, luaH_mainposition(t, o) - t->node); > + } > + return 1; > +} > + > + > +static int stacklevel (lua_State *L) { > + unsigned long a = 0; > + lua_pushinteger(L, (L->top - L->stack)); > + lua_pushinteger(L, (L->stack_last - L->stack)); > + lua_pushinteger(L, (L->ci - L->base_ci)); > + lua_pushinteger(L, (L->end_ci - L->base_ci)); > + lua_pushinteger(L, (unsigned long)&a); > + return 5; > +} > + > + > +static int table_query (lua_State *L) { > + const Table *t; > + int i = luaL_optint(L, 2, -1); > + luaL_checktype(L, 1, LUA_TTABLE); > + t = hvalue(obj_at(L, 1)); > + if (i == -1) { > + lua_pushinteger(L, t->sizearray); > + lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t)); > + lua_pushinteger(L, t->lastfree - t->node); > + } > + else if (i < t->sizearray) { > + lua_pushinteger(L, i); > + luaA_pushobject(L, &t->array[i]); > + lua_pushnil(L); > + } > + else if ((i -= t->sizearray) < sizenode(t)) { > + if (!ttisnil(gval(gnode(t, i))) || > + ttisnil(gkey(gnode(t, i))) || > + ttisnumber(gkey(gnode(t, i)))) { > + luaA_pushobject(L, key2tval(gnode(t, i))); > + } > + else > + lua_pushliteral(L, "<undef>"); > + luaA_pushobject(L, gval(gnode(t, i))); > + if (gnext(&t->node[i])) > + lua_pushinteger(L, gnext(&t->node[i]) - t->node); > + else > + lua_pushnil(L); > + } > + return 3; > +} > + > + > +static int string_query (lua_State *L) { > + stringtable *tb = &G(L)->strt; > + int s = luaL_optint(L, 2, 0) - 1; > + if (s==-1) { > + lua_pushinteger(L ,tb->nuse); > + lua_pushinteger(L ,tb->size); > + return 2; > + } > + else if (s < tb->size) { > + GCObject *ts; > + int n = 0; > + for (ts = tb->hash[s]; ts; ts = ts->gch.next) { > + setsvalue2s(L, L->top, gco2ts(ts)); > + incr_top(L); > + n++; > + } > + return n; > + } > + return 0; > +} > + > + > +static int tref (lua_State *L) { > + int level = lua_gettop(L); > + int lock = luaL_optint(L, 2, 1); > + luaL_checkany(L, 1); > + lua_pushvalue(L, 1); > + lua_pushinteger(L, lua_ref(L, lock)); > + lua_assert(lua_gettop(L) == level+1); /* +1 for result */ > + return 1; > +} > + > +static int getref (lua_State *L) { > + int level = lua_gettop(L); > + lua_getref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) == level+1); > + return 1; > +} > + > +static int unref (lua_State *L) { > + int level = lua_gettop(L); > + lua_unref(L, luaL_checkint(L, 1)); > + lua_assert(lua_gettop(L) == level); > + return 0; > +} > + > + > +static int upvalue (lua_State *L) { > + int n = luaL_checkint(L, 2); > + luaL_checktype(L, 1, LUA_TFUNCTION); > + if (lua_isnone(L, 3)) { > + const char *name = lua_getupvalue(L, 1, n); > + if (name == NULL) return 0; > + lua_pushstring(L, name); > + return 2; > + } > + else { > + const char *name = lua_setupvalue(L, 1, n); > + lua_pushstring(L, name); > + return 1; > + } > +} > + > + > +static int newuserdata (lua_State *L) { > + size_t size = luaL_checkint(L, 1); > + char *p = cast(char *, lua_newuserdata(L, size)); > + while (size--) *p++ = '\0'; > + return 1; > +} > + > + > +static int pushuserdata (lua_State *L) { > + lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); > + return 1; > +} > + > + > +static int udataval (lua_State *L) { > + lua_pushinteger(L, cast(long, lua_touserdata(L, 1))); > + return 1; > +} > + > + > +static int doonnewstack (lua_State *L) { > + lua_State *L1 = lua_newthread(L); > + size_t l; > + const char *s = luaL_checklstring(L, 1, &l); > + int status = luaL_loadbuffer(L1, s, l, s); > + if (status == 0) > + status = lua_pcall(L1, 0, 0, 0); > + lua_pushinteger(L, status); > + return 1; > +} > + > + > +static int s2d (lua_State *L) { > + lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); > + return 1; > +} > + > + > +static int d2s (lua_State *L) { > + double d = luaL_checknumber(L, 1); > + lua_pushlstring(L, cast(char *, &d), sizeof(d)); > + return 1; > +} > + > + > +static int num2int (lua_State *L) { > + lua_pushinteger(L, lua_tointeger(L, 1)); > + return 1; > +} > + > + > +static int newstate (lua_State *L) { > + void *ud; > + lua_Alloc f = lua_getallocf(L, &ud); > + lua_State *L1 = lua_newstate(f, ud); > + if (L1) > + lua_pushinteger(L, (unsigned long)L1); > + else > + lua_pushnil(L); > + return 1; > +} > + > + > +static int loadlib (lua_State *L) { > + static const luaL_Reg libs[] = { > + {"baselibopen", luaopen_base}, > + {"dblibopen", luaopen_debug}, > + {"iolibopen", luaopen_io}, > + {"mathlibopen", luaopen_math}, > + {"strlibopen", luaopen_string}, > + {"tablibopen", luaopen_table}, > + {"packageopen", luaopen_package}, > + {NULL, NULL} > + }; > + lua_State *L1 = cast(lua_State *, > + cast(unsigned long, luaL_checknumber(L, 1))); > + lua_pushvalue(L1, LUA_GLOBALSINDEX); > + luaL_register(L1, NULL, libs); > + return 0; > +} > + > +static int closestate (lua_State *L) { > + lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1))); > + lua_close(L1); > + return 0; > +} > + > +static int doremote (lua_State *L) { > + lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); > + size_t lcode; > + const char *code = luaL_checklstring(L, 2, &lcode); > + int status; > + lua_settop(L1, 0); > + status = luaL_loadbuffer(L1, code, lcode, code); > + if (status == 0) > + status = lua_pcall(L1, 0, LUA_MULTRET, 0); > + if (status != 0) { > + lua_pushnil(L); > + lua_pushinteger(L, status); > + lua_pushstring(L, lua_tostring(L1, -1)); > + return 3; > + } > + else { > + int i = 0; > + while (!lua_isnone(L1, ++i)) > + lua_pushstring(L, lua_tostring(L1, i)); > + lua_pop(L1, i-1); > + return i-1; > + } > +} > + > + > +static int log2_aux (lua_State *L) { > + lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1))); > + return 1; > +} > + > +static int int2fb_aux (lua_State *L) { > + int b = luaO_int2fb(luaL_checkint(L, 1)); > + lua_pushinteger(L, b); > + lua_pushinteger(L, luaO_fb2int(b)); > + return 2; > +} > + > + > + > +/* > +** {====================================================== > +** function to test the API with C. It interprets a kind of assembler > +** language with calls to the API, so the test can be driven by Lua code > +** ======================================================= > +*/ > + > +static const char *const delimits = " \t\n,;"; > + > +static void skip (const char **pc) { > + while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; > +} > + > +static int getnum_aux (lua_State *L, const char **pc) { > + int res = 0; > + int sig = 1; > + skip(pc); > + if (**pc == '.') { > + res = cast_int(lua_tonumber(L, -1)); > + lua_pop(L, 1); > + (*pc)++; > + return res; > + } > + else if (**pc == '-') { > + sig = -1; > + (*pc)++; > + } > + while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0'; > + return sig*res; > +} > + > +static const char *getname_aux (char *buff, const char **pc) { > + int i = 0; > + skip(pc); > + while (**pc != '\0' && !strchr(delimits, **pc)) > + buff[i++] = *(*pc)++; > + buff[i] = '\0'; > + return buff; > +} > + > + > +static int getindex_aux (lua_State *L, const char **pc) { > + skip(pc); > + switch (*(*pc)++) { > + case 'R': return LUA_REGISTRYINDEX; > + case 'G': return LUA_GLOBALSINDEX; > + case 'E': return LUA_ENVIRONINDEX; > + case 'U': return lua_upvalueindex(getnum_aux(L, pc)); > + default: (*pc)--; return getnum_aux(L, pc); > + } > +} > + > +#define EQ(s1) (strcmp(s1, inst) == 0) > + > +#define getnum (getnum_aux(L, &pc)) > +#define getname (getname_aux(buff, &pc)) > +#define getindex (getindex_aux(L, &pc)) > + > + > +static int testC (lua_State *L) { > + char buff[30]; > + lua_State *L1; > + const char *pc; > + if (lua_isnumber(L, 1)) { > + L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); > + pc = luaL_checkstring(L, 2); > + } > + else { > + L1 = L; > + pc = luaL_checkstring(L, 1); > + } > + for (;;) { > + const char *inst = getname; > + if EQ("") return 0; > + else if EQ("isnumber") { > + lua_pushinteger(L1, lua_isnumber(L1, getindex)); > + } > + else if EQ("isstring") { > + lua_pushinteger(L1, lua_isstring(L1, getindex)); > + } > + else if EQ("istable") { > + lua_pushinteger(L1, lua_istable(L1, getindex)); > + } > + else if EQ("iscfunction") { > + lua_pushinteger(L1, lua_iscfunction(L1, getindex)); > + } > + else if EQ("isfunction") { > + lua_pushinteger(L1, lua_isfunction(L1, getindex)); > + } > + else if EQ("isuserdata") { > + lua_pushinteger(L1, lua_isuserdata(L1, getindex)); > + } > + else if EQ("isudataval") { > + lua_pushinteger(L1, lua_islightuserdata(L1, getindex)); > + } > + else if EQ("isnil") { > + lua_pushinteger(L1, lua_isnil(L1, getindex)); > + } > + else if EQ("isnull") { > + lua_pushinteger(L1, lua_isnone(L1, getindex)); > + } > + else if EQ("tonumber") { > + lua_pushnumber(L1, lua_tonumber(L1, getindex)); > + } > + else if EQ("tostring") { > + const char *s = lua_tostring(L1, getindex); > + lua_pushstring(L1, s); > + } > + else if EQ("objsize") { > + lua_pushinteger(L1, lua_objlen(L1, getindex)); > + } > + else if EQ("tocfunction") { > + lua_pushcfunction(L1, lua_tocfunction(L1, getindex)); > + } > + else if EQ("return") { > + return getnum; > + } > + else if EQ("gettop") { > + lua_pushinteger(L1, lua_gettop(L1)); > + } > + else if EQ("settop") { > + lua_settop(L1, getnum); > + } > + else if EQ("pop") { > + lua_pop(L1, getnum); > + } > + else if EQ("pushnum") { > + lua_pushinteger(L1, getnum); > + } > + else if EQ("pushstring") { > + lua_pushstring(L1, getname); > + } > + else if EQ("pushnil") { > + lua_pushnil(L1); > + } > + else if EQ("pushbool") { > + lua_pushboolean(L1, getnum); > + } > + else if EQ("newuserdata") { > + lua_newuserdata(L1, getnum); > + } > + else if EQ("tobool") { > + lua_pushinteger(L1, lua_toboolean(L1, getindex)); > + } > + else if EQ("pushvalue") { > + lua_pushvalue(L1, getindex); > + } > + else if EQ("pushcclosure") { > + lua_pushcclosure(L1, testC, getnum); > + } > + else if EQ("remove") { > + lua_remove(L1, getnum); > + } > + else if EQ("insert") { > + lua_insert(L1, getnum); > + } > + else if EQ("replace") { > + lua_replace(L1, getindex); > + } > + else if EQ("gettable") { > + lua_gettable(L1, getindex); > + } > + else if EQ("settable") { > + lua_settable(L1, getindex); > + } > + else if EQ("next") { > + lua_next(L1, -2); > + } > + else if EQ("concat") { > + lua_concat(L1, getnum); > + } > + else if EQ("lessthan") { > + int a = getindex; > + lua_pushboolean(L1, lua_lessthan(L1, a, getindex)); > + } > + else if EQ("equal") { > + int a = getindex; > + lua_pushboolean(L1, lua_equal(L1, a, getindex)); > + } > + else if EQ("rawcall") { > + int narg = getnum; > + int nres = getnum; > + lua_call(L1, narg, nres); > + } > + else if EQ("call") { > + int narg = getnum; > + int nres = getnum; > + lua_pcall(L1, narg, nres, 0); > + } > + else if EQ("loadstring") { > + size_t sl; > + const char *s = luaL_checklstring(L1, getnum, &sl); > + luaL_loadbuffer(L1, s, sl, s); > + } > + else if EQ("loadfile") { > + luaL_loadfile(L1, luaL_checkstring(L1, getnum)); > + } > + else if EQ("setmetatable") { > + lua_setmetatable(L1, getindex); > + } > + else if EQ("getmetatable") { > + if (lua_getmetatable(L1, getindex) == 0) > + lua_pushnil(L1); > + } > + else if EQ("type") { > + lua_pushstring(L1, luaL_typename(L1, getnum)); > + } > + else if EQ("getn") { > + int i = getindex; > + lua_pushinteger(L1, luaL_getn(L1, i)); > + } > +#ifndef luaL_setn > + else if EQ("setn") { > + int i = getindex; > + int n = cast_int(lua_tonumber(L1, -1)); > + luaL_setn(L1, i, n); > + lua_pop(L1, 1); > + } > +#endif > + else if EQ("throw") { > +#if defined(__cplusplus) > +static struct X { int x; } x; > + throw x; > +#else > + luaL_error(L1, "C++"); > +#endif > + break; > + } > + else luaL_error(L, "unknown instruction %s", buff); > + } > + return 0; > +} > + > +/* }====================================================== */ > + > + > +/* > +** {====================================================== > +** tests for yield inside hooks > +** ======================================================= > +*/ > + > +static void yieldf (lua_State *L, lua_Debug *ar) { > + lua_yield(L, 0); > +} > + > +static int setyhook (lua_State *L) { > + if (lua_isnoneornil(L, 1)) > + lua_sethook(L, NULL, 0, 0); /* turn off hooks */ > + else { > + const char *smask = luaL_checkstring(L, 1); > + int count = luaL_optint(L, 2, 0); > + int mask = 0; > + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; > + if (count > 0) mask |= LUA_MASKCOUNT; > + lua_sethook(L, yieldf, mask, count); > + } > + return 0; > +} > + > + > +static int coresume (lua_State *L) { > + int status; > + lua_State *co = lua_tothread(L, 1); > + luaL_argcheck(L, co, 1, "coroutine expected"); > + status = lua_resume(co, 0); > + if (status != 0) { > + lua_pushboolean(L, 0); > + lua_insert(L, -2); > + return 2; /* return false + error message */ > + } > + else { > + lua_pushboolean(L, 1); > + return 1; > + } > +} > + > +/* }====================================================== */ > + > + > + > +/* > +** {====================================================== > +** tests auxlib functions > +** ======================================================= > +*/ > + > +static int auxgsub (lua_State *L) { > + const char *s1 = luaL_checkstring(L, 1); > + const char *s2 = luaL_checkstring(L, 2); > + const char *s3 = luaL_checkstring(L, 3); > + lua_settop(L, 3); > + luaL_gsub(L, s1, s2, s3); > + lua_assert(lua_gettop(L) == 4); > + return 1; > +} > + > + > +/* }====================================================== */ > + > + > + > +static const struct luaL_Reg tests_funcs[] = { > + {"checkmemory", lua_checkmemory}, > + {"closestate", closestate}, > + {"d2s", d2s}, > + {"doonnewstack", doonnewstack}, > + {"doremote", doremote}, > + {"gccolor", get_gccolor}, > + {"gcstate", gcstate}, > + {"getref", getref}, > + {"gsub", auxgsub}, > + {"hash", hash_query}, > + {"int2fb", int2fb_aux}, > + {"limits", get_limits}, > + {"listcode", listcode}, > + {"listk", listk}, > + {"listlocals", listlocals}, > + {"loadlib", loadlib}, > + {"log2", log2_aux}, > + {"newstate", newstate}, > + {"newuserdata", newuserdata}, > + {"num2int", num2int}, > + {"pushuserdata", pushuserdata}, > + {"querystr", string_query}, > + {"querytab", table_query}, > + {"ref", tref}, > + {"resume", coresume}, > + {"s2d", s2d}, > + {"setyhook", setyhook}, > + {"stacklevel", stacklevel}, > + {"testC", testC}, > + {"totalmem", mem_query}, > + {"trick", settrick}, > + {"udataval", udataval}, > + {"unref", unref}, > + {"upvalue", upvalue}, > + {NULL, NULL} > +}; > + > + > +int luaB_opentests (lua_State *L) { > + void *ud; > + lua_assert(lua_getallocf(L, &ud) == debug_realloc); > + lua_assert(ud == cast(void *, &memcontrol)); > + lua_setallocf(L, lua_getallocf(L, NULL), ud); > + lua_state = L; /* keep first state to be opened */ > + luaL_register(L, "T", tests_funcs); > + return 0; > +} > + > + > +#undef main > +int main (int argc, char *argv[]) { > + int ret; > + char *limit = getenv("MEMLIMIT"); > + if (limit) > + memcontrol.memlimit = strtoul(limit, NULL, 10); > + ret = l_main(argc, argv); > + lua_assert(memcontrol.numblocks == 0); > + lua_assert(memcontrol.total == 0); > + return ret; > +} > + > +#endif > diff --git a/test/PUC-Lua-5.1-tests/etc/ltests.h b/test/PUC-Lua-5.1-tests/etc/ltests.h > new file mode 100644 > index 0000000..e570212 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/etc/ltests.h > @@ -0,0 +1,92 @@ > +/* > +** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp $ > +** Internal Header for Debugging of the Lua Implementation > +** See Copyright Notice in lua.h > +*/ > + > +#ifndef ltests_h > +#define ltests_h > + > + > +#include <stdlib.h> > + > + > +#define LUA_DEBUG > + > +#undef NDEBUG > +#include <assert.h> > +#define lua_assert(c) assert(c) > + > + > +/* to avoid warnings, and to make sure value is really unused */ > +#define UNUSED(x) (x=0, (void)(x)) > + > + > +/* memory allocator control variables */ > +typedef struct Memcontrol { > + unsigned long numblocks; > + unsigned long total; > + unsigned long maxmem; > + unsigned long memlimit; > +} Memcontrol; > + > +LUAI_DATA Memcontrol memcontrol; > + > + > +/* > +** generic variable for debug tricks > +*/ > +LUAI_DATA int Trick; > + > + > +void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize); > + > +#ifdef lua_c > +#define luaL_newstate() lua_newstate(debug_realloc, &memcontrol) > +#endif > + > + > +typedef struct CallInfo *pCallInfo; > + > +int lua_checkmemory (lua_State *L); > +int lua_checkpc (lua_State *L, pCallInfo ci); > + > + > +/* test for lock/unlock */ > +#undef luai_userstateopen > +#undef luai_userstatethread > +#undef lua_lock > +#undef lua_unlock > +#undef LUAI_EXTRASPACE > + > +struct L_EXTRA { int lock; int *plock; }; > +#define LUAI_EXTRASPACE sizeof(struct L_EXTRA) > +#define getlock(l) (cast(struct L_EXTRA *, l) - 1) > +#define luai_userstateopen(l) \ > + (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) > +#define luai_userstatethread(l,l1) (getlock(l1)->plock = getlock(l)->plock) > +#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) > +#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) > + > + > +int luaB_opentests (lua_State *L); > + > +#ifdef lua_c > +#define luaL_openlibs(L) { (luaL_openlibs)(L); luaB_opentests(L); } > +#endif > + > + > + > +/* real main will be defined at `ltests.c' */ > +int l_main (int argc, char *argv[]); > +#define main l_main > + > + > + > +/* change some sizes to give some bugs a chance */ > + > +#undef LUAL_BUFFERSIZE > +#define LUAL_BUFFERSIZE 27 > +#define MINSTRTABSIZE 2 > + > +#endif > diff --git a/test/PUC-Lua-5.1-tests/events.lua b/test/PUC-Lua-5.1-tests/events.lua > new file mode 100644 > index 0000000..5234b00 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/events.lua > @@ -0,0 +1,360 @@ > +print('testing metatables') > + > +X = 20; B = 30 > + > +setfenv(1, setmetatable({}, {__index=_G})) > + > +collectgarbage() > + > +X = X+10 > +assert(X == 30 and _G.X == 20) > +B = false > +assert(B == false) > +B = nil > +assert(B == 30) > + > +assert(getmetatable{} == nil) > +assert(getmetatable(4) == nil) > +assert(getmetatable(nil) == nil) > +a={}; setmetatable(a, {__metatable = "xuxu", > + __tostring=function(x) return x.name end}) > +assert(getmetatable(a) == "xuxu") > +assert(tostring(a) == nil) > +-- cannot change a protected metatable > +assert(pcall(setmetatable, a, {}) == false) > +a.name = "gororoba" > +assert(tostring(a) == "gororoba") > + > +local a, t = {10,20,30; x="10", y="20"}, {} > +assert(setmetatable(a,t) == a) > +assert(getmetatable(a) == t) > +assert(setmetatable(a,nil) == a) > +assert(getmetatable(a) == nil) > +assert(setmetatable(a,t) == a) > + > + > +function f (t, i, e) > + assert(not e) > + local p = rawget(t, "parent") > + return (p and p[i]+3), "dummy return" > +end > + > +t.__index = f > + > +a.parent = {z=25, x=12, [4] = 24} > +assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") > + > +collectgarbage() > + > +a = setmetatable({}, t) > +function f(t, i, v) rawset(t, i, v-3) end > +t.__newindex = f > +a[1] = 30; a.x = "101"; a[5] = 200 > +assert(a[1] == 27 and a.x == 98 and a[5] == 197) > + > + > +local c = {} > +a = setmetatable({}, t) > +t.__newindex = c > +a[1] = 10; a[2] = 20; a[3] = 90 > +assert(c[1] == 10 and c[2] == 20 and c[3] == 90) > + > + > +do > + local a; > + a = setmetatable({}, {__index = setmetatable({}, > + {__index = setmetatable({}, > + {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) > + a[0] = 20 > + for i=0,10 do > + assert(a[i*3] == 20 + i*4) > + end > +end > + > + > +do -- newindex > + local foi > + local a = {} > + for i=1,10 do a[i] = 0; a['a'..i] = 0; end > + setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) > + foi = false; a[1]=0; assert(not foi) > + foi = false; a['a1']=0; assert(not foi) > + foi = false; a['a11']=0; assert(foi) > + foi = false; a[11]=0; assert(foi) > + foi = false; a[1]=nil; assert(not foi) > + foi = false; a[1]=nil; assert(foi) > +end > + > + > +function f (t, ...) return t, {...} end > +t.__call = f > + > +do > + local x,y = a(unpack{'a', 1}) > + assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) > + x,y = a() > + assert(x==a and y[1]==nil) > +end > + > + > +local b = setmetatable({}, t) > +setmetatable(b,t) > + > +function f(op) > + return function (...) cap = {[0] = op, ...} ; return (...) end > +end > +t.__add = f("add") > +t.__sub = f("sub") > +t.__mul = f("mul") > +t.__div = f("div") > +t.__mod = f("mod") > +t.__unm = f("unm") > +t.__pow = f("pow") > + > +assert(b+5 == b) > +assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) > +assert(b+'5' == b) > +assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) > +assert(5+b == 5) > +assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) > +assert('5'+b == '5') > +assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) > +b=b-3; assert(getmetatable(b) == t) > +assert(5-a == 5) > +assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) > +assert('5'-a == '5') > +assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) > +assert(a*a == a) > +assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) > +assert(a/0 == a) > +assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) > +assert(a%2 == a) > +assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) > +assert(-a == a) > +assert(cap[0] == "unm" and cap[1] == a) > +assert(a^4 == a) > +assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) > +assert(a^'4' == a) > +assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) > +assert(4^a == 4) > +assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) > +assert('4'^a == '4') > +assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) > + > + > +t = {} > +t.__lt = function (a,b,c) > + collectgarbage() > + assert(c == nil) > + if type(a) == 'table' then a = a.x end > + if type(b) == 'table' then b = b.x end > + return a<b, "dummy" > +end > + > +function Op(x) return setmetatable({x=x}, t) end > + > +local function test () > + assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) > + assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) > + assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) > + assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) > + assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) > + assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) > + assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) > + assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) > +end > + > +test() > + > +t.__le = function (a,b,c) > + assert(c == nil) > + if type(a) == 'table' then a = a.x end > + if type(b) == 'table' then b = b.x end > + return a<=b, "dummy" > +end > + > +test() -- retest comparisons, now using both `lt' and `le' > + > + > +-- test `partial order' > + > +local function Set(x) > + local y = {} > + for _,k in pairs(x) do y[k] = 1 end > + return setmetatable(y, t) > +end > + > +t.__lt = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] = nil > + end > + return next(b) ~= nil > +end > + > +t.__le = nil > + > +assert(Set{1,2,3} < Set{1,2,3,4}) > +assert(not(Set{1,2,3,4} < Set{1,2,3,4})) > +assert((Set{1,2,3,4} <= Set{1,2,3,4})) > +assert((Set{1,2,3,4} >= Set{1,2,3,4})) > +assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) > + > +t.__le = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + end > + return true > +end > + > +assert(not (Set{1,3} <= Set{3,5})) -- now its OK! > +assert(not(Set{1,3} <= Set{3,5})) > +assert(not(Set{1,3} >= Set{3,5})) > + > +t.__eq = function (a,b) > + for k in pairs(a) do > + if not b[k] then return false end > + b[k] = nil > + end > + return next(b) == nil > +end > + > +local s = Set{1,3,5} > +assert(s == Set{3,5,1}) > +assert(not rawequal(s, Set{3,5,1})) > +assert(rawequal(s, s)) > +assert(Set{1,3,5,1} == Set{3,5,1}) > +assert(Set{1,3,5} ~= Set{3,5,1,6}) > +t[Set{1,3,5}] = 1 > +assert(t[Set{1,3,5}] == nil) -- `__eq' is not valid for table accesses > + > + > +t.__concat = function (a,b,c) > + assert(c == nil) > + if type(a) == 'table' then a = a.val end > + if type(b) == 'table' then b = b.val end > + if A then return a..b > + else > + return setmetatable({val=a..b}, t) > + end > +end > + > +c = {val="c"}; setmetatable(c, t) > +d = {val="d"}; setmetatable(d, t) > + > +A = true > +assert(c..d == 'cd') > +assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") > + > +A = false > +x = c..d > +assert(getmetatable(x) == t and x.val == 'cd') > +x = 0 .."a".."b"..c..d.."e".."f".."g" > +assert(x.val == "0abcdefg") > + > + > +-- test comparison compatibilities > +local t1, t2, c, d > +t1 = {}; c = {}; setmetatable(c, t1) > +d = {} > +t1.__eq = function () return true end > +t1.__lt = function () return true end > +assert(c ~= d and not pcall(function () return c < d end)) > +setmetatable(d, t1) > +assert(c == d and c < d and not(d <= c)) > +t2 = {} > +t2.__eq = t1.__eq > +t2.__lt = t1.__lt > +setmetatable(d, t2) > +assert(c == d and c < d and not(d <= c)) > + > + > + > +-- test for several levels of calls > +local i > +local tt = { > + __call = function (t, ...) > + i = i+1 > + if t.f then return t.f(...) > + else return {...} > + end > + end > +} > + > +local a = setmetatable({}, tt) > +local b = setmetatable({f=a}, tt) > +local c = setmetatable({f=b}, tt) > + > +i = 0 > +x = c(3,4,5) > +assert(i == 3 and x[1] == 3 and x[3] == 5) > + > + > +assert(_G.X == 20) > +assert(_G == getfenv(0)) > + > +print'+' > + > +local _g = _G > +setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end})) > + > +-- testing proxies > +assert(getmetatable(newproxy()) == nil) > +assert(getmetatable(newproxy(false)) == nil) > + > +local u = newproxy(true) > + > +getmetatable(u).__newindex = function (u,k,v) > + getmetatable(u)[k] = v > +end > + > +getmetatable(u).__index = function (u,k) > + return getmetatable(u)[k] > +end > + > +for i=1,10 do u[i] = i end > +for i=1,10 do assert(u[i] == i) end > + > +local k = newproxy(u) > +assert(getmetatable(k) == getmetatable(u)) > + > + > +a = {} > +rawset(a, "x", 1, 2, 3) > +assert(a.x == 1 and rawget(a, "x", 3) == 1) > + > +print '+' > + > +-- testing metatables for basic types > +mt = {} > +debug.setmetatable(10, mt) > +assert(getmetatable(-2) == mt) > +mt.__index = function (a,b) return a+b end > +assert((10)[3] == 13) > +assert((10)["3"] == 13) > +debug.setmetatable(23, nil) > +assert(getmetatable(-2) == nil) > + > +debug.setmetatable(true, mt) > +assert(getmetatable(false) == mt) > +mt.__index = function (a,b) return a or b end > +assert((true)[false] == true) > +assert((false)[false] == false) > +debug.setmetatable(false, nil) > +assert(getmetatable(true) == nil) > + > +debug.setmetatable(nil, mt) > +assert(getmetatable(nil) == mt) > +mt.__add = function (a,b) return (a or 0) + (b or 0) end > +assert(10 + nil == 10) > +assert(nil + 23 == 23) > +assert(nil + nil == 0) > +debug.setmetatable(nil, nil) > +assert(getmetatable(nil) == nil) > + > +debug.setmetatable(nil, {}) > + > + > +print 'OK' > + > +return 12 > diff --git a/test/PUC-Lua-5.1-tests/files.lua b/test/PUC-Lua-5.1-tests/files.lua > new file mode 100644 > index 0000000..903488c > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/files.lua > @@ -0,0 +1,324 @@ > + > +print('testing i/o') > + > +assert(io.input(io.stdin) == io.stdin) > +assert(io.output(io.stdout) == io.stdout) > + > + > +assert(type(io.input()) == "userdata" and io.type(io.output()) == "file") > +assert(io.type(8) == nil) > +local a = {}; setmetatable(a, {}) > +assert(io.type(a) == nil) > + > +local a,b,c = io.open('xuxu_nao_existe') > +assert(not a and type(b) == "string" and type(c) == "number") > + > +a,b,c = io.open('/a/b/c/d', 'w') > +assert(not a and type(b) == "string" and type(c) == "number") > + > +local file = os.tmpname() > +local otherfile = os.tmpname() > + > +assert(os.setlocale('C', 'all')) > + > +io.input(io.stdin); io.output(io.stdout); > + > +os.remove(file) > +assert(loadfile(file) == nil) > +assert(io.open(file) == nil) > +io.output(file) > +assert(io.output() ~= io.stdout) > + > +assert(io.output():seek() == 0) > +assert(io.write("alo alo")) > +assert(io.output():seek() == string.len("alo alo")) > +assert(io.output():seek("cur", -3) == string.len("alo alo")-3) > +assert(io.write("joao")) > +assert(io.output():seek("end") == string.len("alo joao")) > + > +assert(io.output():seek("set") == 0) > + > +assert(io.write('"�lo"', "{a}\n", "second line\n", "third line \n")) > +assert(io.write('�fourth_line')) > +io.output(io.stdout) > +collectgarbage() -- file should be closed by GC > +assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) > +print('+') > + > +-- test GC for files > +collectgarbage() > +for i=1,120 do > + for i=1,5 do > + io.input(file) > + assert(io.open(file, 'r')) > + io.lines(file) > + end > + collectgarbage() > +end > + > +assert(os.rename(file, otherfile)) > +assert(os.rename(file, otherfile) == nil) > + > +io.output(io.open(otherfile, "a")) > +assert(io.write("\n\n\t\t 3450\n")); > +io.close() > + > +-- test line generators > +assert(os.rename(otherfile, file)) > +io.output(otherfile) > +local f = io.lines(file) > +while f() do end; > +assert(not pcall(f)) -- read lines after EOF > +assert(not pcall(f)) -- read lines after EOF > +-- copy from file to otherfile > +for l in io.lines(file) do io.write(l, "\n") end > +io.close() > +-- copy from otherfile back to file > +local f = assert(io.open(otherfile)) > +assert(io.type(f) == "file") > +io.output(file) > +assert(io.output():read() == nil) > +for l in f:lines() do io.write(l, "\n") end > +assert(f:close()); io.close() > +assert(not pcall(io.close, f)) -- error trying to close again > +assert(tostring(f) == "file (closed)") > +assert(io.type(f) == "closed file") > +io.input(file) > +f = io.open(otherfile):lines() > +for l in io.lines() do assert(l == f()) end > +assert(os.remove(otherfile)) > + > +io.input(file) > +do -- test error returns > + local a,b,c = io.input():write("xuxu") > + assert(not a and type(b) == "string" and type(c) == "number") > +end > +assert(io.read(0) == "") -- not eof > +assert(io.read(5, '*l') == '"�lo"') > +assert(io.read(0) == "") > +assert(io.read() == "second line") > +local x = io.input():seek() > +assert(io.read() == "third line ") > +assert(io.input():seek("set", x)) > +assert(io.read('*l') == "third line ") > +assert(io.read(1) == "�") > +assert(io.read(string.len"fourth_line") == "fourth_line") > +assert(io.input():seek("cur", -string.len"fourth_line")) > +assert(io.read() == "fourth_line") > +assert(io.read() == "") -- empty line > +assert(io.read('*n') == 3450) > +assert(io.read(1) == '\n') > +assert(io.read(0) == nil) -- end of file > +assert(io.read(1) == nil) -- end of file > +assert(({io.read(1)})[2] == nil) > +assert(io.read() == nil) -- end of file > +assert(({io.read()})[2] == nil) > +assert(io.read('*n') == nil) -- end of file > +assert(({io.read('*n')})[2] == nil) > +assert(io.read('*a') == '') -- end of file (OK for `*a') > +assert(io.read('*a') == '') -- end of file (OK for `*a') > +collectgarbage() > +print('+') > +io.close(io.input()) > +assert(not pcall(io.read)) > + > +assert(os.remove(file)) > + > +local t = '0123456789' > +for i=1,12 do t = t..t; end > +assert(string.len(t) == 10*2^12) > + > +io.output(file) > +io.write("alo\n") > +io.close() > +assert(not pcall(io.write)) > +local f = io.open(file, "a") > +io.output(f) > +collectgarbage() > + > +assert(io.write(' ' .. t .. ' ')) > +assert(io.write(';', 'end of file\n')) > +f:flush(); io.flush() > +f:close() > +print('+') > + > +io.input(file) > +assert(io.read() == "alo") > +assert(io.read(1) == ' ') > +assert(io.read(string.len(t)) == t) > +assert(io.read(1) == ' ') > +assert(io.read(0)) > +assert(io.read('*a') == ';end of file\n') > +assert(io.read(0) == nil) > +assert(io.close(io.input())) > + > +assert(os.remove(file)) > +print('+') > + > +local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'" > +io.output(file) > +assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1))) > +io.close() > +assert(loadfile(file))() > +assert(x1 == x2) > +print('+') > +assert(os.remove(file)) > +assert(os.remove(file) == nil) > +assert(os.remove(otherfile) == nil) > + > +io.output(file) > +assert(io.write("qualquer coisa\n")) > +assert(io.write("mais qualquer coisa")) > +io.close() > +io.output(assert(io.open(otherfile, 'wb'))) > +assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0")) > +io.close() > + > +local filehandle = assert(io.open(file, 'r')) > +local otherfilehandle = assert(io.open(otherfile, 'rb')) > +assert(filehandle ~= otherfilehandle) > +assert(type(filehandle) == "userdata") > +assert(filehandle:read('*l') == "qualquer coisa") > +io.input(otherfilehandle) > +assert(io.read(string.len"outra coisa") == "outra coisa") > +assert(filehandle:read('*l') == "mais qualquer coisa") > +filehandle:close(); > +assert(type(filehandle) == "userdata") > +io.input(otherfilehandle) > +assert(io.read(4) == "\0\1\3\0") > +assert(io.read(3) == "\0\0\0") > +assert(io.read(0) == "") -- 255 is not eof > +assert(io.read(1) == "\255") > +assert(io.read('*a') == "\0") > +assert(not io.read(0)) > +assert(otherfilehandle == io.input()) > +otherfilehandle:close() > +assert(os.remove(file)) > +assert(os.remove(otherfile)) > +collectgarbage() > + > +io.output(file) > +io.write[[ > + 123.4 -56e-2 not a number > +second line > +third line > + > +and the rest of the file > +]] > +io.close() > +io.input(file) > +local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10) > +assert(io.close(io.input())) > +assert(_ == ' ' and __ == nil) > +assert(type(a) == 'number' and a==123.4 and b==-56e-2) > +assert(d=='second line' and e=='third line') > +assert(h==[[ > + > +and the rest of the file > +]]) > +assert(os.remove(file)) > +collectgarbage() > + > +-- testing buffers > +do > + local f = assert(io.open(file, "w")) > + local fr = assert(io.open(file, "r")) > + assert(f:setvbuf("full", 2000)) > + f:write("x") > + assert(fr:read("*all") == "") -- full buffer; output not written yet > + f:close() > + fr:seek("set") > + assert(fr:read("*all") == "x") -- `close' flushes it > + f = assert(io.open(file), "w") > + assert(f:setvbuf("no")) > + f:write("x") > + fr:seek("set") > + assert(fr:read("*all") == "x") -- no buffer; output is ready > + f:close() > + f = assert(io.open(file, "a")) > + assert(f:setvbuf("line")) > + f:write("x") > + fr:seek("set", 1) > + assert(fr:read("*all") == "") -- line buffer; no output without `\n' > + f:write("a\n") > + fr:seek("set", 1) > + assert(fr:read("*all") == "xa\n") -- now we have a whole line > + f:close(); fr:close() > +end > + > + > +-- testing large files (> BUFSIZ) > +io.output(file) > +for i=1,5001 do io.write('0123456789123') end > +io.write('\n12346') > +io.close() > +io.input(file) > +local x = io.read('*a') > +io.input():seek('set', 0) > +local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003) > +assert(x == y and string.len(x) == 5001*13 + 6) > +io.input():seek('set', 0) > +y = io.read() -- huge line > +assert(x == y..'\n'..io.read()) > +assert(io.read() == nil) > +io.close(io.input()) > +assert(os.remove(file)) > +x = nil; y = nil > + > +x, y = pcall(io.popen, "ls") > +if x then > + assert(y:read("*a")) > + assert(y:close()) > +else > + (Message or print)('\a\n >>> popen not available<<<\n\a') > +end > + > +print'+' > + > +local t = os.time() > +T = os.date("*t", t) > +loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and > + T.hour==%H and T.min==%M and T.sec==%S and > + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() > + > +assert(os.time(T) == t) > + > +T = os.date("!*t", t) > +loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and > + T.hour==%H and T.min==%M and T.sec==%S and > + T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))() > + > +do > + local T = os.date("*t") > + local t = os.time(T) > + assert(type(T.isdst) == 'boolean') > + T.isdst = nil > + local t1 = os.time(T) > + assert(t == t1) -- if isdst is absent uses correct default > +end > + > +t = os.time(T) > +T.year = T.year-1; > +local t1 = os.time(T) > +-- allow for leap years > +assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2) > + > +t = os.time() > +t1 = os.time(os.date("*t")) > +assert(os.difftime(t1,t) <= 2) > + > +local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17} > +local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19} > +assert(os.difftime(t1,t2) == 60*2-2) > + > +io.output(io.stdout) > +local d = os.date('%d') > +local m = os.date('%m') > +local a = os.date('%Y') > +local ds = os.date('%w') + 1 > +local h = os.date('%H') > +local min = os.date('%M') > +local s = os.date('%S') > +io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a)) > +io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s)) > +io.write(string.format('%s\n', _VERSION)) > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua > new file mode 100644 > index 0000000..86a9f75 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/gc.lua > @@ -0,0 +1,312 @@ > +print('testing garbage collection') > + > +collectgarbage() > + > +_G["while"] = 234 > + > +limit = 5000 > + > + > + > +contCreate = 0 > + > +print('tables') > +while contCreate <= limit do > + local a = {}; a = nil > + contCreate = contCreate+1 > +end > + > +a = "a" > + > +contCreate = 0 > +print('strings') > +while contCreate <= limit do > + a = contCreate .. "b"; > + a = string.gsub(a, '(%d%d*)', string.upper) > + a = "a" > + contCreate = contCreate+1 > +end > + > + > +contCreate = 0 > + > +a = {} > + > +print('functions') > +function a:test () > + while contCreate <= limit do > + loadstring(string.format("function temp(a) return 'a%d' end", contCreate))() > + assert(temp() == string.format('a%d', contCreate)) > + contCreate = contCreate+1 > + end > +end > + > +a:test() > + > +-- collection of functions without locals, globals, etc. > +do local f = function () end end > + > + > +print("functions with errors") > +prog = [[ > +do > + a = 10; > + function foo(x,y) > + a = sin(a+0.456-0.23e-12); > + return function (z) return sin(%x+z) end > + end > + local x = function (w) a=a+w; end > +end > +]] > +do > + local step = 1 > + if rawget(_G, "_soft") then step = 13 end > + for i=1, string.len(prog), step do > + for j=i, string.len(prog), step do > + pcall(loadstring(string.sub(prog, i, j))) > + end > + end > +end > + > +print('long strings') > +x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789" > +assert(string.len(x)==80) > +s = '' > +n = 0 > +k = 300 > +while n < k do s = s..x; n=n+1; j=tostring(n) end > +assert(string.len(s) == k*80) > +s = string.sub(s, 1, 20000) > +s, i = string.gsub(s, '(%d%d%d%d)', math.sin) > +assert(i==20000/4) > +s = nil > +x = nil > + > +assert(_G["while"] == 234) > + > + > +local bytes = gcinfo() > +while 1 do > + local nbytes = gcinfo() > + if nbytes < bytes then break end -- run until gc > + bytes = nbytes > + a = {} > +end > + > + > +local function dosteps (siz) > + collectgarbage() > + collectgarbage"stop" > + local a = {} > + for i=1,100 do a[i] = {{}}; local b = {} end > + local x = gcinfo() > + local i = 0 > + repeat > + i = i+1 > + until collectgarbage("step", siz) > + assert(gcinfo() < x) > + return i > +end > + > +assert(dosteps(0) > 10) > +assert(dosteps(6) < dosteps(2)) > +assert(dosteps(10000) == 1) > +assert(collectgarbage("step", 1000000) == true) > +assert(collectgarbage("step", 1000000)) > + > + > +do > + local x = gcinfo() > + collectgarbage() > + collectgarbage"stop" > + repeat > + local a = {} > + until gcinfo() > 1000 > + collectgarbage"restart" > + repeat > + local a = {} > + until gcinfo() < 1000 > +end > + > +lim = 15 > +a = {} > +-- fill a with `collectable' indices > +for i=1,lim do a[{}] = i end > +b = {} > +for k,v in pairs(a) do b[k]=v end > +-- remove all indices and collect them > +for n in pairs(b) do > + a[n] = nil > + assert(type(n) == 'table' and next(n) == nil) > + collectgarbage() > +end > +b = nil > +collectgarbage() > +for n in pairs(a) do error'cannot be here' end > +for i=1,lim do a[i] = i end > +for i=1,lim do assert(a[i] == i) end > + > + > +print('weak tables') > +a = {}; setmetatable(a, {__mode = 'k'}); > +-- fill a with some `collectable' indices > +for i=1,lim do a[{}] = i end > +-- and some non-collectable ones > +for i=1,lim do local t={}; a[t]=t end > +for i=1,lim do a[i] = i end > +for i=1,lim do local s=string.rep('@', i); a[s] = s..'#' end > +collectgarbage() > +local i = 0 > +for k,v in pairs(a) do assert(k==v or k..'#'==v); i=i+1 end > +assert(i == 3*lim) > + > +a = {}; setmetatable(a, {__mode = 'v'}); > +a[1] = string.rep('b', 21) > +collectgarbage() > +assert(a[1]) -- strings are *values* > +a[1] = nil > +-- fill a with some `collectable' values (in both parts of the table) > +for i=1,lim do a[i] = {} end > +for i=1,lim do a[i..'x'] = {} end > +-- and some non-collectable ones > +for i=1,lim do local t={}; a[t]=t end > +for i=1,lim do a[i+lim]=i..'x' end > +collectgarbage() > +local i = 0 > +for k,v in pairs(a) do assert(k==v or k-lim..'x' == v); i=i+1 end > +assert(i == 2*lim) > + > +a = {}; setmetatable(a, {__mode = 'vk'}); > +local x, y, z = {}, {}, {} > +-- keep only some items > +a[1], a[2], a[3] = x, y, z > +a[string.rep('$', 11)] = string.rep('$', 11) > +-- fill a with some `collectable' values > +for i=4,lim do a[i] = {} end > +for i=1,lim do a[{}] = i end > +for i=1,lim do local t={}; a[t]=t end > +collectgarbage() > +assert(next(a) ~= nil) > +local i = 0 > +for k,v in pairs(a) do > + assert((k == 1 and v == x) or > + (k == 2 and v == y) or > + (k == 3 and v == z) or k==v); > + i = i+1 > +end > +assert(i == 4) > +x,y,z=nil > +collectgarbage() > +assert(next(a) == string.rep('$', 11)) > + > + > +-- testing userdata > +collectgarbage("stop") -- stop collection > +local u = newproxy(true) > +local s = 0 > +local a = {[u] = 0}; setmetatable(a, {__mode = 'vk'}) > +for i=1,10 do a[newproxy(u)] = i end > +for k in pairs(a) do assert(getmetatable(k) == getmetatable(u)) end > +local a1 = {}; for k,v in pairs(a) do a1[k] = v end > +for k,v in pairs(a1) do a[v] = k end > +for i =1,10 do assert(a[i]) end > +getmetatable(u).a = a1 > +getmetatable(u).u = u > +do > + local u = u > + getmetatable(u).__gc = function (o) > + assert(a[o] == 10-s) > + assert(a[10-s] == nil) -- udata already removed from weak table > + assert(getmetatable(o) == getmetatable(u)) > + assert(getmetatable(o).a[o] == 10-s) > + s=s+1 > + end > +end > +a1, u = nil > +assert(next(a) ~= nil) > +collectgarbage() > +assert(s==11) > +collectgarbage() > +assert(next(a) == nil) -- finalized keys are removed in two cycles > + > + > +-- __gc x weak tables > +local u = newproxy(true) > +setmetatable(getmetatable(u), {__mode = "v"}) > +getmetatable(u).__gc = function (o) os.exit(1) end -- cannot happen > +collectgarbage() > + > +local u = newproxy(true) > +local m = getmetatable(u) > +m.x = {[{0}] = 1; [0] = {1}}; setmetatable(m.x, {__mode = "kv"}); > +m.__gc = function (o) > + assert(next(getmetatable(o).x) == nil) > + m = 10 > +end > +u, m = nil > +collectgarbage() > +assert(m==10) > + > + > +-- errors during collection > +u = newproxy(true) > +getmetatable(u).__gc = function () error "!!!" end > +u = nil > +assert(not pcall(collectgarbage)) > + > + > +if not rawget(_G, "_soft") then > + print("deep structures") > + local a = {} > + for i = 1,200000 do > + a = {next = a} > + end > + collectgarbage() > +end > + > +-- create many threads with self-references and open upvalues > +local thread_id = 0 > +local threads = {} > + > +function fn(thread) > + local x = {} > + threads[thread_id] = function() > + thread = x > + end > + coroutine.yield() > +end > + > +while thread_id < 1000 do > + local thread = coroutine.create(fn) > + coroutine.resume(thread, thread) > + thread_id = thread_id + 1 > +end > + > + > + > +-- create a userdata to be collected when state is closed > +do > + local newproxy,assert,type,print,getmetatable = > + newproxy,assert,type,print,getmetatable > + local u = newproxy(true) > + local tt = getmetatable(u) > + ___Glob = {u} -- avoid udata being collected before program end > + tt.__gc = function (o) > + assert(getmetatable(o) == tt) > + -- create new objects during GC > + local a = 'xuxu'..(10+3)..'joao', {} > + ___Glob = o -- ressurect object! > + newproxy(o) -- creates a new one with same metatable > + print(">>> closing state " .. "<<<\n") > + end > +end > + > +-- create several udata to raise errors when collected while closing state > +do > + local u = newproxy(true) > + getmetatable(u).__gc = function (o) return o + 1 end > + table.insert(___Glob, u) -- preserve udata until the end > + for i = 1,10 do table.insert(___Glob, newproxy(u)) end > +end > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > new file mode 100644 > index 0000000..f24e7f3 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > @@ -0,0 +1,18 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +# The original tarball contains subdirectory "libs" with an empty > +# subdirectory "libs/P1", to be used by tests. > +# Instead of tracking empty directory with some anchor-file for > +# git, create this directory via CMake. > +add_custom_target(PUC-Lua-5.1-tests-prepare) > +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare > + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > + COMMAND ${CMAKE_COMMAND} -E make_directory P1 > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 > diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c > new file mode 100644 > index 0000000..812bb9a > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c > @@ -0,0 +1,40 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > +#include "lauxlib.h" > + > +static int id (lua_State *L) { > + return lua_gettop(L); > +} > + > + > +static const struct luaL_reg funcs[] = { > + {"id", id}, > + {NULL, NULL} > +}; > + > + > +int anotherfunc (lua_State *L) { > + lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2)); > + return 1; > +} > + > + > +int luaopen_lib1_sub (lua_State *L) { > + luaL_register(L, "lib1.sub", funcs + 1); > + return 1; > +} > + > + > +int luaopen_lib1 (lua_State *L) { > + luaL_register(L, "lib1", funcs); > + return 1; > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib11.c b/test/PUC-Lua-5.1-tests/libs/lib11.c > new file mode 100644 > index 0000000..3efa3d3 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib11.c > @@ -0,0 +1,18 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > + > + > +int luaopen_lib1 (lua_State *L); > + > +int luaopen_lib11 (lua_State *L) { > + return luaopen_lib1(L); > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c > new file mode 100644 > index 0000000..9972cbe > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c > @@ -0,0 +1,28 @@ > +/* > +** compile with > +** gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > +#include "lauxlib.h" > + > +static int id (lua_State *L) { > + return lua_gettop(L); > +} > + > + > +static const struct luaL_reg funcs[] = { > + {"id", id}, > + {NULL, NULL} > +}; > + > + > +int luaopen_lib2 (lua_State *L) { > + luaL_register(L, "lib2", funcs); > + lua_pushnumber(L, 0.5); > + lua_setglobal(L, "x"); > + return 1; > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/libs/lib21.c b/test/PUC-Lua-5.1-tests/libs/lib21.c > new file mode 100644 > index 0000000..167507f > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/lib21.c > @@ -0,0 +1,18 @@ > +/* > +** compile with > +** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c > +** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 > +** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c > +*/ > + > + > +#include "lua.h" > + > + > +int luaopen_lib2 (lua_State *L); > + > +int luaopen_lib21 (lua_State *L) { > + return luaopen_lib2(L); > +} > + > + > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua > new file mode 100644 > index 0000000..01d84d5 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/literals.lua > @@ -0,0 +1,176 @@ > +print('testing scanner') > + > +local function dostring (x) return assert(loadstring(x))() end > + > +dostring("x = 'a\0a'") > +assert(x == 'a\0a' and string.len(x) == 3) > + > +-- escape sequences > +assert('\n\"\'\\' == [[ > + > +"'\]]) > + > +assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$")) > + > +-- assume ASCII just for tests: > +assert("\09912" == 'c12') > +assert("\99ab" == 'cab') > +assert("\099" == '\99') > +assert("\099\n" == 'c\10') > +assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo') > + > +assert(010 .. 020 .. -030 == "1020-30") > + > +-- long variable names > + > +var = string.rep('a', 15000) > +prog = string.format("%s = 5", var) > +dostring(prog) > +assert(_G[var] == 5) > +var = nil > +print('+') > + > +-- escapes -- > +assert("\n\t" == [[ > + > + ]]) > +assert([[ > + > + $debug]] == "\n $debug") > +assert([[ [ ]] ~= [[ ] ]]) > +-- long strings -- > +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" > +assert(string.len(b) == 960) > +prog = [=[ > +print('+') > + > +a1 = [["isto e' um string com v�rias 'aspas'"]] > +a2 = "'aspas'" > + > +assert(string.find(a1, a2) == 31) > +print('+') > + > +a1 = [==[temp = [[um valor qualquer]]; ]==] > +assert(loadstring(a1))() > +assert(temp == 'um valor qualquer') > +-- long strings -- > +b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" > +assert(string.len(b) == 960) > +print('+') > + > +a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +00123456789012345678901234567890123456789123456789012345678901234567890123456789 > +]] > +assert(string.len(a) == 1863) > +assert(string.sub(a, 1, 40) == string.sub(b, 1, 40)) > +x = 1 > +]=] > + > +print('+') > +x = nil > +dostring(prog) > +assert(x) > + > +prog = nil > +a = nil > +b = nil > + > + > +-- testing line ends > +prog = [[ > +a = 1 -- a comment > +b = 2 > + > + > +x = [=[ > +hi > +]=] > +y = "\ > +hello\r\n\ > +" > +return debug.getinfo(1).currentline > +]] > + > +for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do > + local prog, nn = string.gsub(prog, "\n", n) > + assert(dostring(prog) == nn) > + assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n") > +end > + > + > +-- testing comments and strings with long brackets > +a = [==[]=]==] > +assert(a == "]=") > + > +a = [==[[===[[=[]]=][====[]]===]===]==] > +assert(a == "[===[[=[]]=][====[]]===]===") > + > +a = [====[[===[[=[]]=][====[]]===]===]====] > +assert(a == "[===[[=[]]=][====[]]===]===") > + > +a = [=[]]]]]]]]]=] > +assert(a == "]]]]]]]]") > + > + > +--[===[ > +x y z [==[ blu foo > +]== > +] > +]=]==] > +error error]=]===] > + > +-- generate all strings of four of these chars > +local x = {"=", "[", "]", "\n"} > +local len = 4 > +local function gen (c, n) > + if n==0 then coroutine.yield(c) > + else > + for _, a in pairs(x) do > + gen(c..a, n-1) > + end > + end > +end > + > +for s in coroutine.wrap(function () gen("", len) end) do > + assert(s == loadstring("return [====[\n"..s.."]====]")()) > +end > + > + > +-- testing decimal point locale > +if os.setlocale("pt_BR") or os.setlocale("ptb") then > + assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) > + assert(assert(loadstring("return 3.4"))() == 3.4) > + assert(assert(loadstring("return .4,3"))() == .4) > + assert(assert(loadstring("return 4."))() == 4.) > + assert(assert(loadstring("return 4.+.5"))() == 4.5) > + local a,b = loadstring("return 4.5.") > + assert(string.find(b, "'4%.5%.'")) > + assert(os.setlocale("C")) > +else > + (Message or print)( > + '\a\n >>> pt_BR locale not available: skipping decimal point tests <<<\n\a') > +end > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/locals.lua b/test/PUC-Lua-5.1-tests/locals.lua > new file mode 100644 > index 0000000..011645a > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/locals.lua > @@ -0,0 +1,127 @@ > +print('testing local variables plus some extra stuff') > + > +do > + local i = 10 > + do local i = 100; assert(i==100) end > + do local i = 1000; assert(i==1000) end > + assert(i == 10) > + if i ~= 10 then > + local i = 20 > + else > + local i = 30 > + assert(i == 30) > + end > +end > + > + > + > +f = nil > + > +local f > +x = 1 > + > +a = nil > +loadstring('local a = {}')() > +assert(type(a) ~= 'table') > + > +function f (a) > + local _1, _2, _3, _4, _5 > + local _6, _7, _8, _9, _10 > + local x = 3 > + local b = a > + local c,d = a,b > + if (d == b) then > + local x = 'q' > + x = b > + assert(x == 2) > + else > + assert(nil) > + end > + assert(x == 3) > + local f = 10 > +end > + > +local b=10 > +local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3 > + > + > +assert(x == 1) > + > +f(2) > +assert(type(f) == 'function') > + > + > +-- testing globals ;-) > +do > + local f = {} > + local _G = _G > + for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end > + A=10; assert(f[1]() == 11) > + for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end > + assert(f[3]() == 4 and A == 11) > + local a,b = f[8](1) > + assert(b.A == 9) > + a,b = f[8](0) > + assert(b.A == 11) -- `real' global > + local g > + local function f () assert(setfenv(2, {a='10'}) == g) end > + g = function () f(); _G.assert(_G.getfenv(1).a == '10') end > + g(); assert(getfenv(g).a == '10') > +end > + > +-- test for global table of loaded chunks > +local function foo (s) > + return loadstring(s) > +end > + > +assert(getfenv(foo("")) == _G) > +local a = {loadstring = loadstring} > +setfenv(foo, a) > +assert(getfenv(foo("")) == _G) > +setfenv(0, a) -- change global environment > +assert(getfenv(foo("")) == a) > +setfenv(0, _G) > + > + > +-- testing limits for special instructions > + > +local a > +local p = 4 > +for i=2,31 do > + for j=-3,3 do > + assert(loadstring(string.format([[local a=%s;a=a+ > + %s; > + assert(a > + ==2^%s)]], j, p-j, i))) () > + assert(loadstring(string.format([[local a=%s; > + a=a-%s; > + assert(a==-2^%s)]], -j, p-j, i))) () > + assert(loadstring(string.format([[local a,b=0,%s; > + a=b-%s; > + assert(a==-2^%s)]], -j, p-j, i))) () > + end > + p =2*p > +end > + > +print'+' > + > + > +if rawget(_G, "querytab") then > + -- testing clearing of dead elements from tables > + collectgarbage("stop") -- stop GC > + local a = {[{}] = 4, [3] = 0, alo = 1, > + a1234567890123456789012345678901234567890 = 10} > + > + local t = querytab(a) > + > + for k,_ in pairs(a) do a[k] = nil end > + collectgarbage() -- restore GC and collect dead fiels in `a' > + for i=0,t-1 do > + local k = querytab(a, i) > + assert(k == nil or type(k) == 'number' or k == 'alo') > + end > +end > + > +print('OK') > + > +return 5,f > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > new file mode 100644 > index 0000000..f520896 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -0,0 +1,159 @@ > +# testing special comment on first line > + > +print ("testing lua.c options") > + > +assert(os.execute() ~= 0) -- machine has a system command > + > +prog = os.tmpname() > +otherprog = os.tmpname() > +out = os.tmpname() > + > +do > + local i = 0 > + while arg[i] do i=i-1 end > + progname = '"'..arg[i+1]..'"' > +end > +print(progname) > + > +local prepfile = function (s, p) > + p = p or prog > + io.output(p) > + io.write(s) > + assert(io.close()) > +end > + > +function checkout (s) > + io.input(out) > + local t = io.read("*a") > + io.input():close() > + assert(os.remove(out)) > + if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end > + assert(s == t) > + return t > +end > + > +function auxrun (...) > + local s = string.format(...) > + s = string.gsub(s, "lua", progname, 1) > + return os.execute(s) > +end > + > +function RUN (...) > + assert(auxrun(...) == 0) > +end > + > +function NoRun (...) > + print("\n(the next error is expected by the test)") > + assert(auxrun(...) ~= 0) > +end > + > +-- test 2 files > +prepfile("print(1); a=2") > +prepfile("print(a)", otherprog) > +RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out) > +checkout("1\n2\n2\n") > + > +local a = [[ > + assert(table.getn(arg) == 3 and arg[1] == 'a' and > + arg[2] == 'b' and arg[3] == 'c') > + assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s) > + assert(arg[4] == nil and arg[-4] == nil) > + local a, b, c = ... > + assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') > +]] > +a = string.format(a, progname) > +prepfile(a) > +RUN('lua "-e " -- %s a b c', prog) > + > +prepfile"assert(arg==nil)" > +prepfile("assert(arg)", otherprog) > +RUN("lua -l%s - < %s", prog, otherprog) > + > +prepfile"" > +RUN("lua - < %s > %s", prog, out) > +checkout("") > + > +-- test many arguments > +prepfile[[print(({...})[30])]] > +RUN("lua %s %s > %s", prog, string.rep(" a", 30), out) > +checkout("a\n") > + > +RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) > +checkout("1\n3\n") > + > +prepfile[[ > + print( > +1, a > +) > +]] > +RUN("lua - < %s > %s", prog, out) > +checkout("1\tnil\n") > + > +prepfile[[ > += (6*2-6) -- === > +a > += 10 > +print(a) > += a]] > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("6\n10\n10\n\n") > + > +prepfile("a = [[b\nc\nd\ne]]\n=a") > +print(prog) > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("b\nc\nd\ne\n\n") > + > +prompt = "alo" > +prepfile[[ -- > +a = 2 > +]] > +RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > +checkout(string.rep(prompt, 3).."\n") > + > +s = [=[ -- > +function f ( x ) > + local a = [[ > +xuxu > +]] > + local b = "\ > +xuxu\n" > + if x == 11 then return 1 , 2 end --[[ test multiple returns ]] > + return x + 1 > + --\\ > +end > +=( f( 10 ) ) > +assert( a == b ) > +=f( 11 ) ]=] > +s = string.gsub(s, ' ', '\n\n') > +prepfile(s) > +RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +checkout("11\n1\t2\n\n") > + > +prepfile[[#comment in 1st line without \n at the end]] > +RUN("lua %s", prog) > + > +prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)"))) > +RUN("lua %s > %s", prog, out) > +checkout("1\n") > + > +prepfile("#comment with a binary file\r\n"..string.dump(loadstring("print(1)"))) > +RUN("lua %s > %s", prog, out) > +checkout("1\n") > + > +-- close Lua with an open file > +prepfile(string.format([[io.output(%q); io.write('alo')]], out)) > +RUN("lua %s", prog) > +checkout('alo') > + > +assert(os.remove(prog)) > +assert(os.remove(otherprog)) > +assert(not os.remove(out)) > + > +RUN("lua -v") > + > +NoRun("lua -h") > +NoRun("lua -e") > +NoRun("lua -e a") > +NoRun("lua -f") > + > +print("OK") > diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua > new file mode 100644 > index 0000000..5076f38 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/math.lua > @@ -0,0 +1,208 @@ > +print("testing numbers and math lib") > + > +do > + local a,b,c = "2", " 3e0 ", " 10 " > + assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0) > + assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string') > + assert(a == "2" and b == " 3e0 " and c == " 10 " and -c == -" 10 ") > + assert(c%a == 0 and a^b == 8) > +end > + > + > +do > + local a,b = math.modf(3.5) > + assert(a == 3 and b == 0.5) > + assert(math.huge > 10e30) > + assert(-math.huge < -10e30) > +end > + > +function f(...) > + if select('#', ...) == 1 then > + return (...) > + else > + return "***" > + end > +end > + > +assert(tonumber{} == nil) > +assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and > + tonumber'.01' == 0.01 and tonumber'-1.' == -1 and > + tonumber'+1.' == 1) > +assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and > + tonumber'1e' == nil and tonumber'1.0e+' == nil and > + tonumber'.' == nil) > +assert(tonumber('-12') == -10-2) > +assert(tonumber('-1.2e2') == - - -120) > +assert(f(tonumber('1 a')) == nil) > +assert(f(tonumber('e1')) == nil) > +assert(f(tonumber('e 1')) == nil) > +assert(f(tonumber(' 3.4.5 ')) == nil) > +assert(f(tonumber('')) == nil) > +assert(f(tonumber('', 8)) == nil) > +assert(f(tonumber(' ')) == nil) > +assert(f(tonumber(' ', 9)) == nil) > +assert(f(tonumber('99', 8)) == nil) > +assert(tonumber(' 1010 ', 2) == 10) > +assert(tonumber('10', 36) == 36) > +--assert(tonumber('\n -10 \n', 36) == -36) > +--assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) > +assert(tonumber('fFfa', 15) == nil) > +--assert(tonumber(string.rep('1', 42), 2) + 1 == 2^42) > +assert(tonumber(string.rep('1', 32), 2) + 1 == 2^32) > +--assert(tonumber('-fffffFFFFF', 16)-1 == -2^40) > +assert(tonumber('ffffFFFF', 16)+1 == 2^32) > + > +assert(1.1 == 1.+.1) > +assert(100.0 == 1E2 and .01 == 1e-2) > +assert(1111111111111111-1111111111111110== 1000.00e-03) > +-- 1234567890123456 > +assert(1.1 == '1.'+'.1') > +assert('1111111111111111'-'1111111111111110' == tonumber" +0.001e+3 \n\t") > + > +function eq (a,b,limit) > + if not limit then limit = 10E-10 end > + return math.abs(a-b) <= limit > +end > + > +assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31) > + > +assert(0.123456 > 0.123455) > + > +assert(tonumber('+1.23E30') == 1.23*10^30) > + > +-- testing order operators > +assert(not(1<1) and (1<2) and not(2<1)) > +assert(not('a'<'a') and ('a'<'b') and not('b'<'a')) > +assert((1<=1) and (1<=2) and not(2<=1)) > +assert(('a'<='a') and ('a'<='b') and not('b'<='a')) > +assert(not(1>1) and not(1>2) and (2>1)) > +assert(not('a'>'a') and not('a'>'b') and ('b'>'a')) > +assert((1>=1) and not(1>=2) and (2>=1)) > +assert(('a'>='a') and not('a'>='b') and ('b'>='a')) > + > +-- testing mod operator > +assert(-4%3 == 2) > +assert(4%-3 == -2) > +assert(math.pi - math.pi % 1 == 3) > +assert(math.pi - math.pi % 0.001 == 3.141) > + > +local function testbit(a, n) > + return a/2^n % 2 >= 1 > +end > + > +assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1)) > +assert(eq(math.tan(math.pi/4), 1)) > +assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0)) > +assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and > + eq(math.asin(1), math.pi/2)) > +assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2)) > +assert(math.abs(-10) == 10) > +assert(eq(math.atan2(1,0), math.pi/2)) > +assert(math.ceil(4.5) == 5.0) > +assert(math.floor(4.5) == 4.0) > +assert(math.mod(10,3) == 1) > +assert(eq(math.sqrt(10)^2, 10)) > +assert(eq(math.log10(2), math.log(2)/math.log(10))) > +assert(eq(math.exp(0), 1)) > +assert(eq(math.sin(10), math.sin(10%(2*math.pi)))) > +local v,e = math.frexp(math.pi) > +assert(eq(math.ldexp(v,e), math.pi)) > + > +assert(eq(math.tanh(3.5), math.sinh(3.5)/math.cosh(3.5))) > + > +assert(tonumber(' 1.3e-2 ') == 1.3e-2) > +assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) > + > +-- testing constant limits > +-- 2^23 = 8388608 > +assert(8388609 + -8388609 == 0) > +assert(8388608 + -8388608 == 0) > +assert(8388607 + -8388607 == 0) > + > +if rawget(_G, "_soft") then return end > + > +f = io.tmpfile() > +assert(f) > +f:write("a = {") > +i = 1 > +repeat > + f:write("{", math.sin(i), ", ", math.cos(i), ", ", i/3, "},\n") > + i=i+1 > +until i > 1000 > +f:write("}") > +f:seek("set", 0) > +assert(loadstring(f:read('*a')))() > +assert(f:close()) > + > +assert(eq(a[300][1], math.sin(300))) > +assert(eq(a[600][1], math.sin(600))) > +assert(eq(a[500][2], math.cos(500))) > +assert(eq(a[800][2], math.cos(800))) > +assert(eq(a[200][3], 200/3)) > +assert(eq(a[1000][3], 1000/3, 0.001)) > +print('+') > + > +do -- testing NaN > + local NaN = 10e500 - 10e400 > + assert(NaN ~= NaN) > + assert(not (NaN < NaN)) > + assert(not (NaN <= NaN)) > + assert(not (NaN > NaN)) > + assert(not (NaN >= NaN)) > + assert(not (0 < NaN)) > + assert(not (NaN < 0)) > + local a = {} > + assert(not pcall(function () a[NaN] = 1 end)) > + assert(a[NaN] == nil) > + a[1] = 1 > + assert(not pcall(function () a[NaN] = 1 end)) > + assert(a[NaN] == nil) > +end > + > +require "checktable" > +stat(a) > + > +a = nil > + > +-- testing implicit convertions > + > +local a,b = '10', '20' > +assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20) > +assert(a == '10' and b == '20') > + > + > +math.randomseed(0) > + > +local i = 0 > +local Max = 0 > +local Min = 2 > +repeat > + local t = math.random() > + Max = math.max(Max, t) > + Min = math.min(Min, t) > + i=i+1 > + flag = eq(Max, 1, 0.001) and eq(Min, 0, 0.001) > +until flag or i>10000 > +assert(0 <= Min and Max<1) > +assert(flag); > + > +for i=1,10 do > + local t = math.random(5) > + assert(1 <= t and t <= 5) > +end > + > +i = 0 > +Max = -200 > +Min = 200 > +repeat > + local t = math.random(-10,0) > + Max = math.max(Max, t) > + Min = math.min(Min, t) > + i=i+1 > + flag = (Max == 0 and Min == -10) > +until flag or i>10000 > +assert(-10 <= Min and Max<=0) > +assert(flag); > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua > new file mode 100644 > index 0000000..7ceaa75 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/nextvar.lua > @@ -0,0 +1,396 @@ > +print('testing tables, next, and for') > + > +local a = {} > + > +-- make sure table has lots of space in hash part > +for i=1,100 do a[i.."+"] = true end > +for i=1,100 do a[i.."+"] = nil end > +-- fill hash part with numeric indices testing size operator > +for i=1,100 do > + a[i] = true > + assert(#a == i) > +end > + > + > +if T then > +-- testing table sizes > + > +local l2 = math.log(2) > +local function log2 (x) return math.log(x)/l2 end > + > +local function mp2 (n) -- minimum power of 2 >= n > + local mp = 2^math.ceil(log2(n)) > + assert(n == 0 or (mp/2 < n and n <= mp)) > + return mp > +end > + > +local function fb (n) > + local r, nn = T.int2fb(n) > + assert(r < 256) > + return nn > +end > + > +-- test fb function > +local a = 1 > +local lim = 2^30 > +while a < lim do > + local n = fb(a) > + assert(a <= n and n <= a*1.125) > + a = math.ceil(a*1.3) > +end > + > + > +local function check (t, na, nh) > + local a, h = T.querytab(t) > + if a ~= na or h ~= nh then > + print(na, nh, a, h) > + assert(nil) > + end > +end > + > +-- testing constructor sizes > +local lim = 40 > +local s = 'return {' > +for i=1,lim do > + s = s..i..',' > + local s = s > + for k=0,lim do > + local t = loadstring(s..'}')() > + assert(#t == i) > + check(t, fb(i), mp2(k)) > + s = string.format('%sa%d=%d,', s, k, k) > + end > +end > + > + > +-- tests with unknown number of elements > +local a = {} > +for i=1,lim do a[i] = i end -- build auxiliary table > +for k=0,lim do > + local a = {unpack(a,1,k)} > + assert(#a == k) > + check(a, k, 0) > + a = {1,2,3,unpack(a,1,k)} > + check(a, k+3, 0) > + assert(#a == k + 3) > +end > + > + > +print'+' > + > +-- testing tables dynamically built > +local lim = 130 > +local a = {}; a[2] = 1; check(a, 0, 1) > +a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) > +a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) > +a = {} > +for i = 1,lim do > + a[i] = 1 > + assert(#a == i) > + check(a, mp2(i), 0) > +end > + > +a = {} > +for i = 1,lim do > + a['a'..i] = 1 > + assert(#a == 0) > + check(a, 0, mp2(i)) > +end > + > +a = {} > +for i=1,16 do a[i] = i end > +check(a, 16, 0) > +for i=1,11 do a[i] = nil end > +for i=30,40 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 8) > +a[10] = 1 > +for i=30,40 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 8) > +for i=1,14 do a[i] = nil end > +for i=30,50 do a[i] = nil end -- force a rehash (?) > +check(a, 0, 4) > + > +-- reverse filling > +for i=1,lim do > + local a = {} > + for i=i,1,-1 do a[i] = i end -- fill in reverse > + check(a, mp2(i), 0) > +end > + > +-- size tests for vararg > +lim = 35 > +function foo (n, ...) > + local arg = {...} > + check(arg, n, 0) > + assert(select('#', ...) == n) > + arg[n+1] = true > + check(arg, mp2(n+1), 0) > + arg.x = true > + check(arg, mp2(n+1), 1) > +end > +local a = {} > +for i=1,lim do a[i] = true; foo(i, unpack(a)) end > + > +end > + > + > +-- test size operation on empty tables > +assert(#{} == 0) > +assert(#{nil} == 0) > +assert(#{nil, nil} == 0) > +assert(#{nil, nil, nil} == 0) > +assert(#{nil, nil, nil, nil} == 0) > +print'+' > + > + > +local nofind = {} > + > +a,b,c = 1,2,3 > +a,b,c = nil > + > +local function find (name) > + local n,v > + while 1 do > + n,v = next(_G, n) > + if not n then return nofind end > + assert(v ~= nil) > + if n == name then return v end > + end > +end > + > +local function find1 (name) > + for n,v in pairs(_G) do > + if n==name then return v end > + end > + return nil -- not found > +end > + > +do -- create 10000 new global variables > + for i=1,10000 do _G[i] = i end > +end > + > + > +a = {x=90, y=8, z=23} > +assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90) > +assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil) > +table.foreach({}, error) > + > +table.foreachi({x=10, y=20}, error) > +local a = {n = 1} > +table.foreachi({n=3}, function (i, v) > + assert(a.n == i and not v) > + a.n=a.n+1 > +end) > +a = {10,20,30,nil,50} > +table.foreachi(a, function (i,v) assert(a[i] == v) end) > +assert(table.foreachi({'a', 'b', 'c'}, function (i,v) > + if i==2 then return v end > + end) == 'b') > + > + > +assert(print==find("print") and print == find1("print")) > +assert(_G["print"]==find("print")) > +assert(assert==find1("assert")) > +assert(nofind==find("return")) > +assert(not find1("return")) > +_G["ret" .. "urn"] = nil > +assert(nofind==find("return")) > +_G["xxx"] = 1 > +assert(xxx==find("xxx")) > +print('+') > + > +a = {} > +for i=0,10000 do > + if math.mod(i,10) ~= 0 then > + a['x'..i] = i > + end > +end > + > +n = {n=0} > +for i,v in pairs(a) do > + n.n = n.n+1 > + assert(i and v and a[i] == v) > +end > +assert(n.n == 9000) > +a = nil > + > +-- remove those 10000 new global variables > +for i=1,10000 do _G[i] = nil end > + > +do -- clear global table > + local a = {} > + local preserve = {io = 1, string = 1, debug = 1, os = 1, > + coroutine = 1, table = 1, math = 1} > + for n,v in pairs(_G) do a[n]=v end > + for n,v in pairs(a) do > + if not preserve[n] and type(v) ~= "function" and > + not string.find(n, "^[%u_]") then > + _G[n] = nil > + end > + collectgarbage() > + end > +end > + > +local function foo () > + local getfenv, setfenv, assert, next = > + getfenv, setfenv, assert, next > + local n = {gl1=3} > + setfenv(foo, n) > + assert(getfenv(foo) == getfenv(1)) > + assert(getfenv(foo) == n) > + assert(print == nil and gl1 == 3) > + gl1 = nil > + gl = 1 > + assert(n.gl == 1 and next(n, 'gl') == nil) > +end > +foo() > + > +print'+' > + > +local function checknext (a) > + local b = {} > + table.foreach(a, function (k,v) b[k] = v end) > + for k,v in pairs(b) do assert(a[k] == v) end > + for k,v in pairs(a) do assert(b[k] == v) end > + b = {} > + do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end > + for k,v in pairs(b) do assert(a[k] == v) end > + for k,v in pairs(a) do assert(b[k] == v) end > +end > + > +checknext{1,x=1,y=2,z=3} > +checknext{1,2,x=1,y=2,z=3} > +checknext{1,2,3,x=1,y=2,z=3} > +checknext{1,2,3,4,x=1,y=2,z=3} > +checknext{1,2,3,4,5,x=1,y=2,z=3} > + > +assert(table.getn{} == 0) > +assert(table.getn{[-1] = 2} == 0) > +assert(table.getn{1,2,3,nil,nil} == 3) > +for i=0,40 do > + local a = {} > + for j=1,i do a[j]=j end > + assert(table.getn(a) == i) > +end > + > + > +assert(table.maxn{} == 0) > +assert(table.maxn{["1000"] = true} == 0) > +assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) > +assert(table.maxn{[1000] = true} == 1000) > +assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) > + > + > +-- int overflow > +a = {} > +for i=0,50 do a[math.pow(2,i)] = true end > +assert(a[table.getn(a)]) > + > +print("+") > + > + > +-- erasing values > +local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, > + [100.3] = 4, [4] = 5} > + > +local n = 0 > +for k, v in pairs( t ) do > + n = n+1 > + assert(t[k] == v) > + t[k] = nil > + collectgarbage() > + assert(t[k] == nil) > +end > +assert(n == 5) > + > + > +local function test (a) > + table.insert(a, 10); table.insert(a, 2, 20); > + table.insert(a, 1, -1); table.insert(a, 40); > + table.insert(a, table.getn(a)+1, 50) > + table.insert(a, 2, -2) > + assert(table.remove(a,1) == -1) > + assert(table.remove(a,1) == -2) > + assert(table.remove(a,1) == 10) > + assert(table.remove(a,1) == 20) > + assert(table.remove(a,1) == 40) > + assert(table.remove(a,1) == 50) > + assert(table.remove(a,1) == nil) > +end > + > +a = {n=0, [-7] = "ban"} > +test(a) > +assert(a.n == 0 and a[-7] == "ban") > + > +a = {[-7] = "ban"}; > +test(a) > +assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban") > + > + > +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) > +assert(table.remove(a) == 10) > +assert(table.remove(a) == 20) > +assert(table.remove(a) == -1) > + > +a = {'c', 'd'} > +table.insert(a, 3, 'a') > +table.insert(a, 'b') > +assert(table.remove(a, 1) == 'c') > +assert(table.remove(a, 1) == 'd') > +assert(table.remove(a, 1) == 'a') > +assert(table.remove(a, 1) == 'b') > +assert(table.getn(a) == 0 and a.n == nil) > +print("+") > + > +a = {} > +for i=1,1000 do > + a[i] = i; a[i-1] = nil > +end > +assert(next(a,nil) == 1000 and next(a,1000) == nil) > + > +assert(next({}) == nil) > +assert(next({}, nil) == nil) > + > +for a,b in pairs{} do error"not here" end > +for i=1,0 do error'not here' end > +for i=0,1,-1 do error'not here' end > +a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) > +a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) > + > +a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11) > +-- precision problems > +--a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101) > +a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) > +a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) > +a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1) > +a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) > +a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0) > +a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) > + > +-- conversion > +a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) > + > + > +collectgarbage() > + > + > +-- testing generic 'for' > + > +local function f (n, p) > + local t = {}; for i=1,p do t[i] = i*10 end > + return function (_,n) > + if n > 0 then > + n = n-1 > + return n, unpack(t) > + end > + end, nil, n > +end > + > +local x = 0 > +for n,a,b,c,d in f(5,3) do > + x = x+1 > + assert(a == 10 and b == 20 and c == 30 and d == nil) > +end > +assert(x == 5) > + > +print"OK" > diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua > new file mode 100644 > index 0000000..fa125dc > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/pm.lua > @@ -0,0 +1,273 @@ > +print('testing pattern matching') > + > +function f(s, p) > + local i,e = string.find(s, p) > + if i then return string.sub(s, i, e) end > +end > + > +function f1(s, p) > + p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end) > + p = string.gsub(p, "^(^?)", "%1()", 1) > + p = string.gsub(p, "($?)$", "()%1", 1) > + local t = {string.match(s, p)} > + return string.sub(s, t[1], t[#t] - 1) > +end > + > +a,b = string.find('', '') -- empty patterns are tricky > +assert(a == 1 and b == 0); > +a,b = string.find('alo', '') > +assert(a == 1 and b == 0) > +a,b = string.find('a\0o a\0o a\0o', 'a', 1) -- first position > +assert(a == 1 and b == 1) > +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 2) -- starts in the midle > +assert(a == 5 and b == 7) > +a,b = string.find('a\0o a\0o a\0o', 'a\0o', 9) -- starts in the midle > +assert(a == 9 and b == 11) > +a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end > +assert(a == 9 and b == 11); > +a,b = string.find('a\0a\0a\0a\0\0ab', 'b') -- last position > +assert(a == 11 and b == 11) > +assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil) -- check ending > +assert(string.find('', '\0') == nil) > +assert(string.find('alo123alo', '12') == 4) > +assert(string.find('alo123alo', '^12') == nil) > + > +assert(f('aloALO', '%l*') == 'alo') > +assert(f('aLo_ALO', '%a*') == 'aLo') > + > +assert(f('aaab', 'a*') == 'aaa'); > +assert(f('aaa', '^.*$') == 'aaa'); > +assert(f('aaa', 'b*') == ''); > +assert(f('aaa', 'ab*a') == 'aa') > +assert(f('aba', 'ab*a') == 'aba') > +assert(f('aaab', 'a+') == 'aaa') > +assert(f('aaa', '^.+$') == 'aaa') > +assert(f('aaa', 'b+') == nil) > +assert(f('aaa', 'ab+a') == nil) > +assert(f('aba', 'ab+a') == 'aba') > +assert(f('a$a', '.$') == 'a') > +assert(f('a$a', '.%$') == 'a$') > +assert(f('a$a', '.$.') == 'a$a') > +assert(f('a$a', '$$') == nil) > +assert(f('a$b', 'a$') == nil) > +assert(f('a$a', '$') == '') > +assert(f('', 'b*') == '') > +assert(f('aaa', 'bb*') == nil) > +assert(f('aaab', 'a-') == '') > +assert(f('aaa', '^.-$') == 'aaa') > +assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') > +assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') > +assert(f('alo xo', '.o$') == 'xo') > +assert(f(' \n isto � assim', '%S%S*') == 'isto') > +assert(f(' \n isto � assim', '%S*$') == 'assim') > +assert(f(' \n isto � assim', '[a-z]*$') == 'assim') > +assert(f('um caracter ? extra', '[^%sa-z]') == '?') > +assert(f('', 'a?') == '') > +assert(f('�', '�?') == '�') > +assert(f('�bl', '�?b?l?') == '�bl') > +assert(f(' �bl', '�?b?l?') == '') > +assert(f('aa', '^aa?a?a') == 'aa') > +assert(f(']]]�b', '[^]]') == '�') > +assert(f("0alo alo", "%x*") == "0a") > +assert(f("alo alo", "%C+") == "alo alo") > +print('+') > + > +assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o") > +assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3') > +assert(f1('=======', '^(=*)=%1$') == '=======') > +assert(string.match('==========', '^([=]*)=%1$') == nil) > + > +local function range (i, j) > + if i <= j then > + return i, range(i+1, j) > + end > +end > + > +local abc = string.char(range(0, 255)); > + > +assert(string.len(abc) == 256) > + > +function strset (p) > + local res = {s=''} > + string.gsub(abc, p, function (c) res.s = res.s .. c end) > + return res.s > +end; > + > +assert(string.len(strset('[\200-\210]')) == 11) > + > +assert(strset('[a-z]') == "abcdefghijklmnopqrstuvwxyz") > +assert(strset('[a-z%d]') == strset('[%da-uu-z]')) > +assert(strset('[a-]') == "-a") > +assert(strset('[^%W]') == strset('[%w]')) > +assert(strset('[]%%]') == '%]') > +assert(strset('[a%-z]') == '-az') > +assert(strset('[%^%[%-a%]%-b]') == '-[]^ab') > +assert(strset('%Z') == strset('[\1-\255]')) > +assert(strset('.') == strset('[\1-\255%z]')) > +print('+'); > + > +assert(string.match("alo xyzK", "(%w+)K") == "xyz") > +assert(string.match("254 K", "(%d*)K") == "") > +assert(string.match("alo ", "(%w*)$") == "") > +assert(string.match("alo ", "(%w+)$") == nil) > +assert(string.find("(�lo)", "%(�") == 1) > +local a, b, c, d, e = string.match("�lo alo", "^(((.).).* (%w*))$") > +assert(a == '�lo alo' and b == '�l' and c == '�' and d == 'alo' and e == nil) > +a, b, c, d = string.match('0123456789', '(.+(.?)())') > +assert(a == '0123456789' and b == '' and c == 11 and d == nil) > +print('+') > + > +assert(string.gsub('�lo �lo', '�', 'x') == 'xlo xlo') > +assert(string.gsub('alo �lo ', ' +$', '') == 'alo �lo') -- trim > +assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim > +assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') > +t = "ab� d" > +a, b = string.gsub(t, '(.)', '%1@') > +assert('@'..a == string.gsub(t, '', '@') and b == 5) > +a, b = string.gsub('ab�d', '(.)', '%0@', 2) > +assert(a == 'a@b@�d' and b == 2) > +assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') > +assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == > + "xyz=abc-abc=xyz") > +assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") > +assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") > +assert(string.gsub('���', '$', '\0�') == '���\0�') > +assert(string.gsub('', '^', 'r') == 'r') > +assert(string.gsub('', '$', 'r') == 'r') > +print('+') > + > +assert(string.gsub("um (dois) tres (quatro)", "(%(%w+%))", string.upper) == > + "um (DOIS) tres (QUATRO)") > + > +do > + local function setglobal (n,v) rawset(_G, n, v) end > + string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal) > + assert(_G.a=="roberto" and _G.roberto=="a") > +end > + > +function f(a,b) return string.gsub(a,'.',b) end > +assert(string.gsub("trocar tudo em |teste|b| � |beleza|al|", "|([^|]*)|([^|]*)|", f) == > + "trocar tudo em bbbbb � alalalalalal") > + > +local function dostring (s) return loadstring(s)() or "" end > +assert(string.gsub("alo $a=1$ novamente $return a$", "$([^$]*)%$", dostring) == > + "alo novamente 1") > + > +x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$", > + "$([^$]*)%$", dostring) > +assert(x == ' assim vai para ALO') > + > +t = {} > +s = 'a alo jose joao' > +r = string.gsub(s, '()(%w+)()', function (a,w,b) > + assert(string.len(w) == b-a); > + t[a] = b-a; > + end) > +assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4) > + > + > +function isbalanced (s) > + return string.find(string.gsub(s, "%b()", ""), "[()]") == nil > +end > + > +assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a")) > +assert(not isbalanced("(9 ((8) 7) a b (\0 c) a")) > +assert(string.gsub("alo 'oi' alo", "%b''", '"') == 'alo " alo') > + > + > +local t = {"apple", "orange", "lime"; n=0} > +assert(string.gsub("x and x and x", "x", function () t.n=t.n+1; return t[t.n] end) > + == "apple and orange and lime") > + > +t = {n=0} > +string.gsub("first second word", "%w%w*", function (w) t.n=t.n+1; t[t.n] = w end) > +assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3) > + > +t = {n=0} > +assert(string.gsub("first second word", "%w+", > + function (w) t.n=t.n+1; t[t.n] = w end, 2) == "first second word") > +assert(t[1] == "first" and t[2] == "second" and t[3] == nil) > + > +assert(not pcall(string.gsub, "alo", "(.", print)) > +assert(not pcall(string.gsub, "alo", ".)", print)) > +assert(not pcall(string.gsub, "alo", "(.", {})) > +assert(not pcall(string.gsub, "alo", "(.)", "%2")) > +assert(not pcall(string.gsub, "alo", "(%1)", "a")) > +assert(not pcall(string.gsub, "alo", "(%0)", "a")) > + > +-- big strings > +local a = string.rep('a', 300000) > +assert(string.find(a, '^a*.?$')) > +assert(not string.find(a, '^a*.?b$')) > +assert(string.find(a, '^a-.?$')) > + > +-- deep nest of gsubs > +function rev (s) > + return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end) > +end > + > +local x = string.rep('012345', 10) > +assert(rev(rev(x)) == x) > + > + > +-- gsub with tables > +assert(string.gsub("alo alo", ".", {}) == "alo alo") > +assert(string.gsub("alo alo", "(.)", {a="AA", l=""}) == "AAo AAo") > +assert(string.gsub("alo alo", "(.).", {a="AA", l="K"}) == "AAo AAo") > +assert(string.gsub("alo alo", "((.)(.?))", {al="AA", o=false}) == "AAo AAo") > + > +assert(string.gsub("alo alo", "().", {2,5,6}) == "256 alo") > + > +t = {}; setmetatable(t, {__index = function (t,s) return string.upper(s) end}) > +assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") > + > + > +-- tests for gmatch > +assert(string.gfind == string.gmatch) > +local a = 0 > +for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end > +assert(a==6) > + > +t = {n=0} > +for w in string.gmatch("first second word", "%w+") do > + t.n=t.n+1; t[t.n] = w > +end > +assert(t[1] == "first" and t[2] == "second" and t[3] == "word") > + > +t = {3, 6, 9} > +for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do > + assert(i == table.remove(t, 1)) > +end > +assert(table.getn(t) == 0) > + > +t = {} > +for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do > + t[i] = j > +end > +a = 0 > +for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end > +assert(a == 3) > + > + > +-- tests for `%f' (`frontiers') > + > +assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") > +assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[") > +assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3") > +assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.") > +assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction") > +assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.") > + > +local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]") > +assert(i == 2 and e == 5) > +local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])") > +assert(k == 'alo ') > + > +local a = {1, 5, 9, 14, 17,} > +for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do > + assert(table.remove(a, 1) == k) > +end > +assert(table.getn(a) == 0) > + > + > +print('OK') > diff --git a/test/PUC-Lua-5.1-tests/sort.lua b/test/PUC-Lua-5.1-tests/sort.lua > new file mode 100644 > index 0000000..6fccd49 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/sort.lua > @@ -0,0 +1,74 @@ > +print"testing sort" > + > + > +function check (a, f) > + f = f or function (x,y) return x<y end; > + for n=table.getn(a),2,-1 do > + assert(not f(a[n], a[n-1])) > + end > +end > + > +a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", > + "Oct", "Nov", "Dec"} > + > +table.sort(a) > +check(a) > + > +limit = 30000 > +if rawget(_G, "_soft") then limit = 5000 end > + > +a = {} > +for i=1,limit do > + a[i] = math.random() > +end > + > +local x = os.clock() > +table.sort(a) > +print(string.format("Sorting %d elements in %.2f sec.", limit, os.clock()-x)) > +check(a) > + > +x = os.clock() > +table.sort(a) > +print(string.format("Re-sorting %d elements in %.2f sec.", limit, os.clock()-x)) > +check(a) > + > +a = {} > +for i=1,limit do > + a[i] = math.random() > +end > + > +x = os.clock(); i=0 > +table.sort(a, function(x,y) i=i+1; return y<x end) > +print(string.format("Invert-sorting other %d elements in %.2f sec., with %i comparisons", > + limit, os.clock()-x, i)) > +check(a, function(x,y) return y<x end) > + > + > +table.sort{} -- empty array > + > +for i=1,limit do a[i] = false end > +x = os.clock(); > +table.sort(a, function(x,y) return nil end) > +print(string.format("Sorting %d equal elements in %.2f sec.", limit, os.clock()-x)) > +check(a, function(x,y) return nil end) > +for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end > + > +a = {"�lo", "\0first :-)", "alo", "then this one", "45", "and a new"} > +table.sort(a) > +check(a) > + > +table.sort(a, function (x, y) > + loadstring(string.format("a[%q] = ''", x))() > + collectgarbage() > + return x<y > + end) > + > + > +tt = {__lt = function (a,b) return a.val < b.val end} > +a = {} > +for i=1,10 do a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end > +table.sort(a) > +check(a, tt.__lt) > +check(a) > + > +print"OK" > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > new file mode 100644 > index 0000000..237dbad > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/strings.lua > @@ -0,0 +1,176 @@ > +print('testing strings and string library') > + > +assert('alo' < 'alo1') > +assert('' < 'a') > +assert('alo\0alo' < 'alo\0b') > +assert('alo\0alo\0\0' > 'alo\0alo\0') > +assert('alo' < 'alo\0') > +assert('alo\0' > 'alo') > +assert('\0' < '\1') > +assert('\0\0' < '\0\1') > +assert('\1\0a\0a' <= '\1\0a\0a') > +assert(not ('\1\0a\0b' <= '\1\0a\0a')) > +assert('\0\0\0' < '\0\0\0\0') > +assert(not('\0\0\0\0' < '\0\0\0')) > +assert('\0\0\0' <= '\0\0\0\0') > +assert(not('\0\0\0\0' <= '\0\0\0')) > +assert('\0\0\0' <= '\0\0\0') > +assert('\0\0\0' >= '\0\0\0') > +assert(not ('\0\0b' < '\0\0a\0')) > +print('+') > + > +assert(string.sub("123456789",2,4) == "234") > +assert(string.sub("123456789",7) == "789") > +assert(string.sub("123456789",7,6) == "") > +assert(string.sub("123456789",7,7) == "7") > +assert(string.sub("123456789",0,0) == "") > +assert(string.sub("123456789",-10,10) == "123456789") > +assert(string.sub("123456789",1,9) == "123456789") > +assert(string.sub("123456789",-10,-20) == "") > +assert(string.sub("123456789",-1) == "9") > +assert(string.sub("123456789",-4) == "6789") > +assert(string.sub("123456789",-6, -4) == "456") > +assert(string.sub("\000123456789",3,5) == "234") > +assert(("\000123456789"):sub(8) == "789") > +print('+') > + > +assert(string.find("123456789", "345") == 3) > +a,b = string.find("123456789", "345") > +assert(string.sub("123456789", a, b) == "345") > +assert(string.find("1234567890123456789", "345", 3) == 3) > +assert(string.find("1234567890123456789", "345", 4) == 13) > +assert(string.find("1234567890123456789", "346", 4) == nil) > +assert(string.find("1234567890123456789", ".45", -9) == 13) > +assert(string.find("abcdefg", "\0", 5, 1) == nil) > +assert(string.find("", "") == 1) > +assert(string.find('', 'aaa', 1) == nil) > +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) > +print('+') > + > +assert(string.len("") == 0) > +assert(string.len("\0\0\0") == 3) > +assert(string.len("1234567890") == 10) > + > +assert(#"" == 0) > +assert(#"\0\0\0" == 3) > +assert(#"1234567890" == 10) > + > +assert(string.byte("a") == 97) > +assert(string.byte("�") > 127) > +assert(string.byte(string.char(255)) == 255) > +assert(string.byte(string.char(0)) == 0) > +assert(string.byte("\0") == 0) > +assert(string.byte("\0\0alo\0x", -1) == string.byte('x')) > +assert(string.byte("ba", 2) == 97) > +assert(string.byte("\n\n", 2, -1) == 10) > +assert(string.byte("\n\n", 2, 2) == 10) > +assert(string.byte("") == nil) > +assert(string.byte("hi", -3) == nil) > +assert(string.byte("hi", 3) == nil) > +assert(string.byte("hi", 9, 10) == nil) > +assert(string.byte("hi", 2, 1) == nil) > +assert(string.char() == "") > +assert(string.char(0, 255, 0) == "\0\255\0") > +assert(string.char(0, string.byte("�"), 0) == "\0�\0") > +assert(string.char(string.byte("�l\0�u", 1, -1)) == "�l\0�u") > +assert(string.char(string.byte("�l\0�u", 1, 0)) == "") > +assert(string.char(string.byte("�l\0�u", -10, 100)) == "�l\0�u") > +print('+') > + > +assert(string.upper("ab\0c") == "AB\0C") > +assert(string.lower("\0ABCc%$") == "\0abcc%$") > +assert(string.rep('teste', 0) == '') > +assert(string.rep('t�s\00t�', 2) == 't�s\0t�t�s\000t�') > +assert(string.rep('', 10) == '') > + > +assert(string.reverse"" == "") > +assert(string.reverse"\0\1\2\3" == "\3\2\1\0") > +assert(string.reverse"\0001234" == "4321\0") > + > +for i=0,30 do assert(string.len(string.rep('a', i)) == i) end > + > +assert(type(tostring(nil)) == 'string') > +assert(type(tostring(12)) == 'string') > +assert(''..12 == '12' and type(12 .. '') == 'string') > +assert(string.find(tostring{}, 'table:')) > +assert(string.find(tostring(print), 'function:')) > +assert(tostring(1234567890123) == '1234567890123') > +assert(#tostring('\0') == 1) > +assert(tostring(true) == "true") > +assert(tostring(false) == "false") > +print('+') > + > +x = '"�lo"\n\\' > +assert(string.format('%q%s', x, x) == '"\\"�lo\\"\\\n\\\\""�lo"\n\\') > +assert(string.format('%q', "\0") == [["\000"]]) > +assert(string.format("\0%c\0%c%x\0", string.byte("�"), string.byte("b"), 140) == > + "\0�\0b8c\0") > +assert(string.format('') == "") > +assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == > + string.format("%c%c%c%c", 34, 48, 90, 100)) > +assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') > +assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") > +assert(tonumber(string.format("%f", 10.3)) == 10.3) > +x = string.format('"%-50s"', 'a') > +assert(#x == 52) > +assert(string.sub(x, 1, 4) == '"a ') > + > +assert(string.format("-%.20s.20s", string.rep("%", 2000)) == "-"..string.rep("%", 20)..".20s") > +assert(string.format('"-%20s.20s"', string.rep("%", 2000)) == > + string.format("%q", "-"..string.rep("%", 2000)..".20s")) > + > + > +-- longest number that can be formated > +assert(string.len(string.format('%99.99f', -1e308)) >= 100) > + > +assert(loadstring("return 1\n--coment�rio sem EOL no final")() == 1) > + > + > +assert(table.concat{} == "") > +assert(table.concat({}, 'x') == "") > +assert(table.concat({'\0', '\0\1', '\0\1\2'}, '.\0.') == "\0.\0.\0\1.\0.\0\1\2") > +local a = {}; for i=1,3000 do a[i] = "xuxu" end > +assert(table.concat(a, "123").."123" == string.rep("xuxu123", 3000)) > +assert(table.concat(a, "b", 20, 20) == "xuxu") > +assert(table.concat(a, "", 20, 21) == "xuxuxuxu") > +assert(table.concat(a, "", 22, 21) == "") > +assert(table.concat(a, "3", 2999) == "xuxu3xuxu") > + > +a = {"a","b","c"} > +assert(table.concat(a, ",", 1, 0) == "") > +assert(table.concat(a, ",", 1, 1) == "a") > +assert(table.concat(a, ",", 1, 2) == "a,b") > +assert(table.concat(a, ",", 2) == "b,c") > +assert(table.concat(a, ",", 3) == "c") > +assert(table.concat(a, ",", 4) == "") > + > +local locales = { "ptb", "ISO-8859-1", "pt_BR" } > +local function trylocale (w) > + for _, l in ipairs(locales) do > + if os.setlocale(l, w) then return true end > + end > + return false > +end > + > +if not trylocale("collate") then > + print("locale not supported") > +else > + assert("alo" < "�lo" and "�lo" < "amo") > +end > + > +if not trylocale("ctype") then > + print("locale not supported") > +else > + assert(string.gsub("����", "%a", "x") == "xxxxx") > + assert(string.gsub("����", "%l", "x") == "x�x�") > + assert(string.gsub("����", "%u", "x") == "�x�x") > + assert(string.upper"���{xuxu}��o" == "���{XUXU}��O") > +end > + > +os.setlocale("C") > +assert(os.setlocale() == 'C') > +assert(os.setlocale(nil, "numeric") == 'C') > + > +print('OK') > + > + > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > new file mode 100644 > index 0000000..ae068fa > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > @@ -0,0 +1,126 @@ > +print('testing vararg') > + > +_G.arg = nil > + > +function f(a, ...) > + assert(type(arg) == 'table') > + assert(type(arg.n) == 'number') > + for i=1,arg.n do assert(a[i]==arg[i]) end > + return arg.n > +end > + > +function c12 (...) > + assert(arg == nil) > + local x = {...}; x.n = table.getn(x) > + local res = (x.n==2 and x[1] == 1 and x[2] == 2) > + if res then res = 55 end > + return res, 2 > +end > + > +function vararg (...) return arg end > + > +local call = function (f, args) return f(unpack(args, 1, args.n)) end > + > +assert(f() == 0) > +assert(f({1,2,3}, 1, 2, 3) == 3) > +assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) > + > +assert(c12(1,2)==55) > +a,b = assert(call(c12, {1,2})) > +assert(a == 55 and b == 2) > +a = call(c12, {1,2;n=2}) > +assert(a == 55 and b == 2) > +a = call(c12, {1,2;n=1}) > +assert(not a) > +assert(c12(1,2,3) == false) > +local a = vararg(call(next, {_G,nil;n=2})) > +local b,c = next(_G) > +assert(a[1] == b and a[2] == c and a.n == 2) > +a = vararg(call(call, {c12, {1,2}})) > +assert(a.n == 2 and a[1] == 55 and a[2] == 2) > +a = call(print, {'+'}) > +assert(a == nil) > + > +local t = {1, 10} > +function t:f (...) return self[arg[1]]+arg.n end > +assert(t:f(1,4) == 3 and t:f(2) == 11) > +print('+') > + > +lim = 20 > +local i, a = 1, {} > +while i <= lim do a[i] = i+0.3; i=i+1 end > + > +function f(a, b, c, d, ...) > + local more = {...} > + assert(a == 1.3 and more[1] == 5.3 and > + more[lim-4] == lim+0.3 and not more[lim-3]) > +end > + > +function g(a,b,c) > + assert(a == 1.3 and b == 2.3 and c == 3.3) > +end > + > +call(f, a) > +call(g, a) > + > +a = {} > +i = 1 > +while i <= lim do a[i] = i; i=i+1 end > +assert(call(math.max, a) == lim) > + > +print("+") > + > + > +-- new-style varargs > + > +function oneless (a, ...) return ... end > + > +function f (n, a, ...) > + local b > + assert(arg == nil) > + if n == 0 then > + local b, c, d = ... > + return a, b, c, d, oneless(oneless(oneless(...))) > + else > + n, b, a = n-1, ..., a > + assert(b == ...) > + return f(n, a, ...) > + end > +end > + > +a,b,c,d,e = assert(f(10,5,4,3,2,1)) > +assert(a==5 and b==4 and c==3 and d==2 and e==1) > + > +a,b,c,d,e = f(4) > +assert(a==nil and b==nil and c==nil and d==nil and e==nil) > + > + > +-- varargs for main chunks > +f = loadstring[[ return {...} ]] > +x = f(2,3) > +assert(x[1] == 2 and x[2] == 3 and x[3] == nil) > + > + > +f = loadstring[[ > + local x = {...} > + for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end > + assert(x[select('#', ...)+1] == nil) > + return true > +]] > + > +assert(f("a", "b", nil, {}, assert)) > +assert(f()) > + > +a = {select(3, unpack{10,20,30,40})} > +assert(table.getn(a) == 2 and a[1] == 30 and a[2] == 40) > +a = {select(1)} > +assert(next(a) == nil) > +a = {select(-1, 3, 5, 7)} > +assert(a[1] == 7 and a[2] == nil) > +a = {select(-2, 3, 5, 7)} > +assert(a[1] == 5 and a[2] == 7 and a[3] == nil) > +pcall(select, 10000) > +pcall(select, -10000) > + > +print('OK') > + > diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua > new file mode 100644 > index 0000000..59e0142 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/verybig.lua > @@ -0,0 +1,100 @@ > +if rawget(_G, "_soft") then return 10 end > + > +print "testing large programs (>64k)" > + > +-- template to create a very big test file > +prog = [[$ > + > +local a,b > + > +b = {$1$ > + b30009 = 65534, > + b30010 = 65535, > + b30011 = 65536, > + b30012 = 65537, > + b30013 = 16777214, > + b30014 = 16777215, > + b30015 = 16777216, > + b30016 = 16777217, > + b30017 = 4294967294, > + b30018 = 4294967295, > + b30019 = 4294967296, > + b30020 = 4294967297, > + b30021 = -65534, > + b30022 = -65535, > + b30023 = -65536, > + b30024 = -4294967297, > + b30025 = 15012.5, > + $2$ > +}; > + > +assert(b.a50008 == 25004 and b["a11"] == 5.5) > +assert(b.a33007 == 16503.5 and b.a50009 == 25004.5) > +assert(b["b"..30024] == -4294967297) > + > +function b:xxx (a,b) return a+b end > +assert(b:xxx(10, 12) == 22) -- pushself with non-constant index > +b.xxx = nil > + > +s = 0; n=0 > +for a,b in pairs(b) do s=s+b; n=n+1 end > +assert(s==13977183656.5 and n==70001) > + > +require "checktable" > +stat(b) > + > +a = nil; b = nil > +print'+' > + > +function f(x) b=x end > + > +a = f{$3$} or 10 > + > +assert(a==10) > +assert(b[1] == "a10" and b[2] == 5 and b[table.getn(b)-1] == "a50009") > + > + > +function xxxx (x) return b[x] end > + > +assert(xxxx(3) == "a11") > + > +a = nil; b=nil > +xxxx = nil > + > +return 10 > + > +]] > + > +-- functions to fill in the $n$ > +F = { > +function () -- $1$ > + for i=10,50009 do > + io.write('a', i, ' = ', 5+((i-10)/2), ',\n') > + end > +end, > + > +function () -- $2$ > + for i=30026,50009 do > + io.write('b', i, ' = ', 15013+((i-30026)/2), ',\n') > + end > +end, > + > +function () -- $3$ > + for i=10,50009 do > + io.write('"a', i, '", ', 5+((i-10)/2), ',\n') > + end > +end, > +} > + > +file = os.tmpname() > +io.output(file) > +for s in string.gmatch(prog, "$([^$]+)") do > + local n = tonumber(s) > + if not n then io.write(s) else F[n]() end > +end > +io.close() > +result = dofile(file) > +assert(os.remove(file)) > +print'OK' > +return result > + > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches 2021-03-26 10:14 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:13 ` Igor Munkin via Tarantool-patches 2021-04-01 8:11 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:13 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test > suite. Source code taken verbatim (except trailing whitespaces) from Typo: s/code taken/code is taken/. Typo: I believe it's always singular: whitespace. > https://www.lua.org/tests/lua5.1-tests.tar.gz. > > Some tests may fail after this commit. They will be disabled > or adapted in the next patches. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > .luacheckrc | 5 +- > test/CMakeLists.txt | 2 + > test/PUC-Lua-5.1-tests/CMakeLists.txt | 45 + > test/PUC-Lua-5.1-tests/README | 41 + > test/PUC-Lua-5.1-tests/all.lua | 137 +++ > test/PUC-Lua-5.1-tests/api.lua | 711 ++++++++++++ > test/PUC-Lua-5.1-tests/attrib.lua | 339 ++++++ > test/PUC-Lua-5.1-tests/big.lua | 381 +++++++ > test/PUC-Lua-5.1-tests/calls.lua | 294 +++++ > test/PUC-Lua-5.1-tests/checktable.lua | 77 ++ > test/PUC-Lua-5.1-tests/closure.lua | 422 +++++++ > test/PUC-Lua-5.1-tests/code.lua | 143 +++ > test/PUC-Lua-5.1-tests/constructs.lua | 240 ++++ > test/PUC-Lua-5.1-tests/db.lua | 499 +++++++++ > test/PUC-Lua-5.1-tests/errors.lua | 250 +++++ > test/PUC-Lua-5.1-tests/etc/ltests.c | 1147 ++++++++++++++++++++ > test/PUC-Lua-5.1-tests/etc/ltests.h | 92 ++ > test/PUC-Lua-5.1-tests/events.lua | 360 ++++++ > test/PUC-Lua-5.1-tests/files.lua | 324 ++++++ > test/PUC-Lua-5.1-tests/gc.lua | 312 ++++++ > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 18 + > test/PUC-Lua-5.1-tests/libs/lib1.c | 40 + > test/PUC-Lua-5.1-tests/libs/lib11.c | 18 + > test/PUC-Lua-5.1-tests/libs/lib2.c | 28 + > test/PUC-Lua-5.1-tests/libs/lib21.c | 18 + > test/PUC-Lua-5.1-tests/literals.lua | 176 +++ > test/PUC-Lua-5.1-tests/locals.lua | 127 +++ > test/PUC-Lua-5.1-tests/main.lua | 159 +++ > test/PUC-Lua-5.1-tests/math.lua | 208 ++++ > test/PUC-Lua-5.1-tests/nextvar.lua | 396 +++++++ > test/PUC-Lua-5.1-tests/pm.lua | 273 +++++ > test/PUC-Lua-5.1-tests/sort.lua | 74 ++ > test/PUC-Lua-5.1-tests/strings.lua | 176 +++ > test/PUC-Lua-5.1-tests/vararg.lua | 126 +++ > test/PUC-Lua-5.1-tests/verybig.lua | 100 ++ > 35 files changed, 7756 insertions(+), 2 deletions(-) > create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/README > create mode 100755 test/PUC-Lua-5.1-tests/all.lua Minor: I doubt all.lua need to be an executable. Feel free to ignore. > create mode 100644 test/PUC-Lua-5.1-tests/api.lua > create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua > create mode 100644 test/PUC-Lua-5.1-tests/big.lua > create mode 100644 test/PUC-Lua-5.1-tests/calls.lua > create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua > create mode 100644 test/PUC-Lua-5.1-tests/closure.lua > create mode 100644 test/PUC-Lua-5.1-tests/code.lua > create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua > create mode 100644 test/PUC-Lua-5.1-tests/db.lua > create mode 100644 test/PUC-Lua-5.1-tests/errors.lua > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h > create mode 100644 test/PUC-Lua-5.1-tests/events.lua > create mode 100644 test/PUC-Lua-5.1-tests/files.lua > create mode 100644 test/PUC-Lua-5.1-tests/gc.lua > create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c > create mode 100644 test/PUC-Lua-5.1-tests/literals.lua > create mode 100644 test/PUC-Lua-5.1-tests/locals.lua > create mode 100644 test/PUC-Lua-5.1-tests/main.lua > create mode 100644 test/PUC-Lua-5.1-tests/math.lua > create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua > create mode 100644 test/PUC-Lua-5.1-tests/pm.lua > create mode 100644 test/PUC-Lua-5.1-tests/sort.lua > create mode 100644 test/PUC-Lua-5.1-tests/strings.lua > create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua > create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua > <snipped> > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > new file mode 100644 > index 0000000..773db0d > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -0,0 +1,45 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + > +# XXX: There are two ways to set up the proper environment > +# described in the suite's README: > +# * set LUA_PATH to "?;./?.lua" > +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to > +# "package.path = '?;'..package.path" > +# Unfortunately, Tarantool doesn't support LUA_INIT and most > +# likely it never will. For more info, see > +# https://github.com/tarantool/tarantool/issues/5744 > +# Hence, there is no way other than set LUA_PATH environment > +# variable as proposed in the first case. > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > + > +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> Minor: IMHO, "set" fits worse here than "create" or "introduce". Feel free to ignore. > +# subdirectory. > +add_subdirectory(libs) > + > +# TODO: PUC-Rio Lua 5.1 test suite also has special header > +# <ltests.h> and <ltests.c> translation unit to check some > +# internal behaviour of the Lua implementation (see etc/ > +# directory). It modifies realloc function to check memory > +# consistency and also contains tests for yield in hooks > +# and for the Lua C API. > +# But, unfortunately, <ltests.c> depends on specific PUC-Rio > +# Lua 5.1 internal headers and should be adapted for LuaJIT. > + > +add_custom_target(PUC-Lua-5.1-tests > + DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare > +) > + > +add_custom_command(TARGET PUC-Lua-5.1-tests > + COMMENT "Running PUC-Rio Lua 5.1 tests" > + COMMAND > + env > + LUA_PATH="${LUA_PATH}\;\;" > + ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 <snipped> > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > new file mode 100644 > index 0000000..f24e7f3 > --- /dev/null > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > @@ -0,0 +1,18 @@ > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > + > +# See the rationale in the root CMakeLists.txt. > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > + Minor: What about TODO for building libs/*.c sources? Anyway, you did it in the following patch, so feel free to ignore. > +# The original tarball contains subdirectory "libs" with an empty > +# subdirectory "libs/P1", to be used by tests. > +# Instead of tracking empty directory with some anchor-file for > +# git, create this directory via CMake. > +add_custom_target(PUC-Lua-5.1-tests-prepare) > +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare > + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > + COMMAND ${CMAKE_COMMAND} -E make_directory P1 > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > + > +# vim: expandtab tabstop=2 shiftwidth=2 <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 01/30] test: add PUC-Rio Lua 5.1 test suite 2021-03-30 22:13 ` Igor Munkin via Tarantool-patches @ 2021-04-01 8:11 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 8:11 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > This patch adds PUC-Rio Lua 5.1 test suite as a part of the LuaJIT test > > suite. Source code taken verbatim (except trailing whitespaces) from > > Typo: s/code taken/code is taken/. > Typo: I believe it's always singular: whitespace. Fixed. > > > https://www.lua.org/tests/lua5.1-tests.tar.gz. > > > > Some tests may fail after this commit. They will be disabled > > or adapted in the next patches. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > .luacheckrc | 5 +- > > test/CMakeLists.txt | 2 + > > test/PUC-Lua-5.1-tests/CMakeLists.txt | 45 + > > test/PUC-Lua-5.1-tests/README | 41 + > > test/PUC-Lua-5.1-tests/all.lua | 137 +++ > > test/PUC-Lua-5.1-tests/api.lua | 711 ++++++++++++ > > test/PUC-Lua-5.1-tests/attrib.lua | 339 ++++++ > > test/PUC-Lua-5.1-tests/big.lua | 381 +++++++ > > test/PUC-Lua-5.1-tests/calls.lua | 294 +++++ > > test/PUC-Lua-5.1-tests/checktable.lua | 77 ++ > > test/PUC-Lua-5.1-tests/closure.lua | 422 +++++++ > > test/PUC-Lua-5.1-tests/code.lua | 143 +++ > > test/PUC-Lua-5.1-tests/constructs.lua | 240 ++++ > > test/PUC-Lua-5.1-tests/db.lua | 499 +++++++++ > > test/PUC-Lua-5.1-tests/errors.lua | 250 +++++ > > test/PUC-Lua-5.1-tests/etc/ltests.c | 1147 ++++++++++++++++++++ > > test/PUC-Lua-5.1-tests/etc/ltests.h | 92 ++ > > test/PUC-Lua-5.1-tests/events.lua | 360 ++++++ > > test/PUC-Lua-5.1-tests/files.lua | 324 ++++++ > > test/PUC-Lua-5.1-tests/gc.lua | 312 ++++++ > > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 18 + > > test/PUC-Lua-5.1-tests/libs/lib1.c | 40 + > > test/PUC-Lua-5.1-tests/libs/lib11.c | 18 + > > test/PUC-Lua-5.1-tests/libs/lib2.c | 28 + > > test/PUC-Lua-5.1-tests/libs/lib21.c | 18 + > > test/PUC-Lua-5.1-tests/literals.lua | 176 +++ > > test/PUC-Lua-5.1-tests/locals.lua | 127 +++ > > test/PUC-Lua-5.1-tests/main.lua | 159 +++ > > test/PUC-Lua-5.1-tests/math.lua | 208 ++++ > > test/PUC-Lua-5.1-tests/nextvar.lua | 396 +++++++ > > test/PUC-Lua-5.1-tests/pm.lua | 273 +++++ > > test/PUC-Lua-5.1-tests/sort.lua | 74 ++ > > test/PUC-Lua-5.1-tests/strings.lua | 176 +++ > > test/PUC-Lua-5.1-tests/vararg.lua | 126 +++ > > test/PUC-Lua-5.1-tests/verybig.lua | 100 ++ > > 35 files changed, 7756 insertions(+), 2 deletions(-) > > create mode 100644 test/PUC-Lua-5.1-tests/CMakeLists.txt > > create mode 100644 test/PUC-Lua-5.1-tests/README > > create mode 100755 test/PUC-Lua-5.1-tests/all.lua > > Minor: I doubt all.lua need to be an executable. Feel free to ignore. The suite is taken with no change; this file was executable, and I see no reason to change it. Also, it highlights this file as the suite runner. Ignoring for now. > > > create mode 100644 test/PUC-Lua-5.1-tests/api.lua > > create mode 100644 test/PUC-Lua-5.1-tests/attrib.lua > > create mode 100644 test/PUC-Lua-5.1-tests/big.lua > > create mode 100644 test/PUC-Lua-5.1-tests/calls.lua > > create mode 100644 test/PUC-Lua-5.1-tests/checktable.lua > > create mode 100644 test/PUC-Lua-5.1-tests/closure.lua > > create mode 100644 test/PUC-Lua-5.1-tests/code.lua > > create mode 100644 test/PUC-Lua-5.1-tests/constructs.lua > > create mode 100644 test/PUC-Lua-5.1-tests/db.lua > > create mode 100644 test/PUC-Lua-5.1-tests/errors.lua > > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.c > > create mode 100644 test/PUC-Lua-5.1-tests/etc/ltests.h > > create mode 100644 test/PUC-Lua-5.1-tests/events.lua > > create mode 100644 test/PUC-Lua-5.1-tests/files.lua > > create mode 100644 test/PUC-Lua-5.1-tests/gc.lua > > create mode 100644 test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib1.c > > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib11.c > > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib2.c > > create mode 100644 test/PUC-Lua-5.1-tests/libs/lib21.c > > create mode 100644 test/PUC-Lua-5.1-tests/literals.lua > > create mode 100644 test/PUC-Lua-5.1-tests/locals.lua > > create mode 100644 test/PUC-Lua-5.1-tests/main.lua > > create mode 100644 test/PUC-Lua-5.1-tests/math.lua > > create mode 100644 test/PUC-Lua-5.1-tests/nextvar.lua > > create mode 100644 test/PUC-Lua-5.1-tests/pm.lua > > create mode 100644 test/PUC-Lua-5.1-tests/sort.lua > > create mode 100644 test/PUC-Lua-5.1-tests/strings.lua > > create mode 100644 test/PUC-Lua-5.1-tests/vararg.lua > > create mode 100644 test/PUC-Lua-5.1-tests/verybig.lua > > > > <snipped> > > > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > > new file mode 100644 > > index 0000000..773db0d > > --- /dev/null > > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > > @@ -0,0 +1,45 @@ > > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > > + > > +# See the rationale in the root CMakeLists.txt. > > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > + > > +# XXX: There are two ways to set up the proper environment > > +# described in the suite's README: > > +# * set LUA_PATH to "?;./?.lua" > > +# * or, better yet, set LUA_PATH to "./?.lua;;" and LUA_INIT to > > +# "package.path = '?;'..package.path" > > +# Unfortunately, Tarantool doesn't support LUA_INIT and most > > +# likely it never will. For more info, see > > +# https://github.com/tarantool/tarantool/issues/5744 > > +# Hence, there is no way other than set LUA_PATH environment > > +# variable as proposed in the first case. > > +set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > > + > > +# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> > > Minor: IMHO, "set" fits worse here than "create" or "introduce". Feel > free to ignore. Changed to "Establish" ("Introduce" fits more for the new functionality, not single target, in my opinion). I wanted to use "Create" first, but it invokes a tautology with "creates" later in the sentence. May be "Set up" will be better here. > > > +# subdirectory. > > +add_subdirectory(libs) > > + > > +# TODO: PUC-Rio Lua 5.1 test suite also has special header > > +# <ltests.h> and <ltests.c> translation unit to check some > > +# internal behaviour of the Lua implementation (see etc/ > > +# directory). It modifies realloc function to check memory > > +# consistency and also contains tests for yield in hooks > > +# and for the Lua C API. > > +# But, unfortunately, <ltests.c> depends on specific PUC-Rio > > +# Lua 5.1 internal headers and should be adapted for LuaJIT. > > + > > +add_custom_target(PUC-Lua-5.1-tests > > + DEPENDS ${LUAJIT_TEST_BINARY} PUC-Lua-5.1-tests-prepare > > +) > > + > > +add_custom_command(TARGET PUC-Lua-5.1-tests > > + COMMENT "Running PUC-Rio Lua 5.1 tests" > > + COMMAND > > + env > > + LUA_PATH="${LUA_PATH}\;\;" > > + ${LUAJIT_TEST_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/all.lua > > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > > +) > > + > > +# vim: expandtab tabstop=2 shiftwidth=2 > > <snipped> > > > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > new file mode 100644 > > index 0000000..f24e7f3 > > --- /dev/null > > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > @@ -0,0 +1,18 @@ > > +# Test suite that has been added from PUC-Rio Lua 5.1 test archive > > +# in scope of https://github.com/tarantool/tarantool/issues/5845. > > + > > +# See the rationale in the root CMakeLists.txt. > > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > + > > Minor: What about TODO for building libs/*.c sources? Anyway, you did it > in the following patch, so feel free to ignore. Yep, ignoring, because the are added in the next patch for consistency. > > > +# The original tarball contains subdirectory "libs" with an empty > > +# subdirectory "libs/P1", to be used by tests. > > +# Instead of tracking empty directory with some anchor-file for > > +# git, create this directory via CMake. > > +add_custom_target(PUC-Lua-5.1-tests-prepare) > > +add_custom_command(TARGET PUC-Lua-5.1-tests-prepare > > + COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > > + COMMAND ${CMAKE_COMMAND} -E make_directory P1 > > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > > +) > > + > > +# vim: expandtab tabstop=2 shiftwidth=2 > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:01 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches ` (29 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches This patch adds commands to create additional LuaC libraries for tests in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c> and <lib2.c> to be consistent with the current LuaJIT's LuaC API. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/CMakeLists.txt | 3 +- test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++- test/PUC-Lua-5.1-tests/libs/lib1.c | 2 +- test/PUC-Lua-5.1-tests/libs/lib2.c | 2 +- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt index 773db0d..3c31aae 100644 --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) # variable as proposed in the first case. set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") -# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> +# Set PUC-Lua-5.1-tests-prepare target that contains rules +# for <libs/*> libraries compilation and creates <libs/P1> # subdirectory. add_subdirectory(libs) diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt index f24e7f3..aa64a44 100644 --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt @@ -4,11 +4,57 @@ # See the rationale in the root CMakeLists.txt. cmake_minimum_required(VERSION 3.1 FATAL_ERROR) +# Build additional C libraries for tests. +macro(BuildTestCLib 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 "${CMAKE_CURRENT_BINARY_DIR}" + PREFIX "" + ) + # XXX: The dynamic libraries are loaded with LuaJIT binary and + # use symbols from it. So it is totally OK to have unresolved + # symbols at build time. + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set_target_properties(${lib} PROPERTIES + LINK_FLAGS "-undefined dynamic_lookup" + ) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # XXX: This is necessary mostly for openSUSE builds, see also + # https://bugzilla.suse.com/show_bug.cgi?id=1012388. + # Just strip out the linker flag to suppress this linker + # option. + string(REPLACE "-Wl,--no-undefined" "" + CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" + ) + endif() + list(APPEND TESTLIBS ${lib}) +endmacro() + +BuildTestCLib(lib1 lib1.c) +BuildTestCLib(lib11 lib1.c lib11.c) +BuildTestCLib(lib2 lib2.c) +BuildTestCLib(lib21 lib2.c lib21.c) + +# Create exact copy of the lib2 library for tests in attrib.lua. +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") +add_custom_command( + OUTPUT ${LIB2COPY} + COMMENT "Copying lib2 to -lib2 for PUC-Rio Lua 5.1 tests" + COMMAND ${CMAKE_COMMAND} -E copy ${LIB2ORIG} ${LIB2COPY} + DEPENDS ${TESTLIBS} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) +list(APPEND TESTLIBS ${LIB2COPY}) + # The original tarball contains subdirectory "libs" with an empty # subdirectory "libs/P1", to be used by tests. # Instead of tracking empty directory with some anchor-file for # git, create this directory via CMake. -add_custom_target(PUC-Lua-5.1-tests-prepare) +add_custom_target(PUC-Lua-5.1-tests-prepare DEPENDS ${TESTLIBS}) add_custom_command(TARGET PUC-Lua-5.1-tests-prepare COMMENT "Create directory for PUC-Rio Lua 5.1 tests" COMMAND ${CMAKE_COMMAND} -E make_directory P1 diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c index 812bb9a..22fe6de 100644 --- a/test/PUC-Lua-5.1-tests/libs/lib1.c +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c @@ -14,7 +14,7 @@ static int id (lua_State *L) { } -static const struct luaL_reg funcs[] = { +static const struct luaL_Reg funcs[] = { {"id", id}, {NULL, NULL} }; diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c index 9972cbe..876a212 100644 --- a/test/PUC-Lua-5.1-tests/libs/lib2.c +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c @@ -12,7 +12,7 @@ static int id (lua_State *L) { } -static const struct luaL_reg funcs[] = { +static const struct luaL_Reg funcs[] = { {"id", id}, {NULL, NULL} }; -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:01 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:01 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > This patch adds commands to create additional LuaC libraries for tests > in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c> > and <lib2.c> to be consistent with the current LuaJIT's LuaC API. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/CMakeLists.txt | 3 +- > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++- > test/PUC-Lua-5.1-tests/libs/lib1.c | 2 +- > test/PUC-Lua-5.1-tests/libs/lib2.c | 2 +- > 4 files changed, 51 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > index 773db0d..3c31aae 100644 > --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > # variable as proposed in the first case. > set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > > -# Set PUC-Lua-5.1-tests-prepare target that creates <libs/P1> > +# Set PUC-Lua-5.1-tests-prepare target that contains rules > +# for <libs/*> libraries compilation and creates <libs/P1> > # subdirectory. > add_subdirectory(libs) > > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > index f24e7f3..aa64a44 100644 > --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > @@ -4,11 +4,57 @@ > # See the rationale in the root CMakeLists.txt. > cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > +# Build additional C libraries for tests. > +macro(BuildTestCLib 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 "${CMAKE_CURRENT_BINARY_DIR}" > + PREFIX "" > + ) > + # XXX: The dynamic libraries are loaded with LuaJIT binary and > + # use symbols from it. So it is totally OK to have unresolved > + # symbols at build time. > + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") > + set_target_properties(${lib} PROPERTIES > + LINK_FLAGS "-undefined dynamic_lookup" > + ) > + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") > + # XXX: This is necessary mostly for openSUSE builds, see also > + # https://bugzilla.suse.com/show_bug.cgi?id=1012388. > + # Just strip out the linker flag to suppress this linker > + # option. > + string(REPLACE "-Wl,--no-undefined" "" > + CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" > + ) > + endif() > + list(APPEND TESTLIBS ${lib}) > +endmacro() > + > +BuildTestCLib(lib1 lib1.c) > +BuildTestCLib(lib11 lib1.c lib11.c) > +BuildTestCLib(lib2 lib2.c) > +BuildTestCLib(lib21 lib2.c lib21.c) > + > +# Create exact copy of the lib2 library for tests in attrib.lua. > +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > +add_custom_command( > + OUTPUT ${LIB2COPY} > + COMMENT "Copying lib2 to -lib2 for PUC-Rio Lua 5.1 tests" > + COMMAND ${CMAKE_COMMAND} -E copy ${LIB2ORIG} ${LIB2COPY} > + DEPENDS ${TESTLIBS} > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > +) > +list(APPEND TESTLIBS ${LIB2COPY}) > + > # The original tarball contains subdirectory "libs" with an empty > # subdirectory "libs/P1", to be used by tests. > # Instead of tracking empty directory with some anchor-file for > # git, create this directory via CMake. > -add_custom_target(PUC-Lua-5.1-tests-prepare) > +add_custom_target(PUC-Lua-5.1-tests-prepare DEPENDS ${TESTLIBS}) > add_custom_command(TARGET PUC-Lua-5.1-tests-prepare > COMMENT "Create directory for PUC-Rio Lua 5.1 tests" > COMMAND ${CMAKE_COMMAND} -E make_directory P1 > diff --git a/test/PUC-Lua-5.1-tests/libs/lib1.c b/test/PUC-Lua-5.1-tests/libs/lib1.c > index 812bb9a..22fe6de 100644 > --- a/test/PUC-Lua-5.1-tests/libs/lib1.c > +++ b/test/PUC-Lua-5.1-tests/libs/lib1.c > @@ -14,7 +14,7 @@ static int id (lua_State *L) { > } > > > -static const struct luaL_reg funcs[] = { > +static const struct luaL_Reg funcs[] = { > {"id", id}, > {NULL, NULL} > }; > diff --git a/test/PUC-Lua-5.1-tests/libs/lib2.c b/test/PUC-Lua-5.1-tests/libs/lib2.c > index 9972cbe..876a212 100644 > --- a/test/PUC-Lua-5.1-tests/libs/lib2.c > +++ b/test/PUC-Lua-5.1-tests/libs/lib2.c > @@ -12,7 +12,7 @@ static int id (lua_State *L) { > } > > > -static const struct luaL_reg funcs[] = { > +static const struct luaL_Reg funcs[] = { > {"id", id}, > {NULL, NULL} > }; > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches 2021-03-26 11:01 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 8:21 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. I propose the following rewording for commit subject: | test: build auxiliary C libs from PUC-Rio-Lua5.1 On 26.03.21, Sergey Kaplun wrote: > This patch adds commands to create additional LuaC libraries for tests Minor: these are not "commands" but "rules". > in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c> > and <lib2.c> to be consistent with the current LuaJIT's LuaC API. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/CMakeLists.txt | 3 +- > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++- > test/PUC-Lua-5.1-tests/libs/lib1.c | 2 +- > test/PUC-Lua-5.1-tests/libs/lib2.c | 2 +- > 4 files changed, 51 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > index 773db0d..3c31aae 100644 > --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > # variable as proposed in the first case. > set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") Side note: I see no LUA_CPATH, but I grepped the spots where lib*.so are required and found that package.cpath is tweaked right there. Hence LUA_CPATH is excess, isn't it? > <snipped> > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > index f24e7f3..aa64a44 100644 > --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > @@ -4,11 +4,57 @@ > # See the rationale in the root CMakeLists.txt. > cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > +# Build additional C libraries for tests. > +macro(BuildTestCLib lib sources) <snipped> > + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") Minor: I personally would strip this option out for all remaining systems (i.e. *BSD too), since we have no guarantee the CMake defaults won't be broken on other distros sometime. Feel free to ignore (but it'll be on your conscience). > + # XXX: This is necessary mostly for openSUSE builds, see also > + # https://bugzilla.suse.com/show_bug.cgi?id=1012388. > + # Just strip out the linker flag to suppress this linker > + # option. > + string(REPLACE "-Wl,--no-undefined" "" > + CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" > + ) > + endif() <snipped> > +endmacro() > + > +BuildTestCLib(lib1 lib1.c) Typo: excess whitespace. > +BuildTestCLib(lib11 lib1.c lib11.c) > +BuildTestCLib(lib2 lib2.c) Typo: excess whitespace. > +BuildTestCLib(lib21 lib2.c lib21.c) > + > +# Create exact copy of the lib2 library for tests in attrib.lua. Typo: s/create exact copy/create the exact copy/. > +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches @ 2021-04-01 8:21 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 8:21 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > I propose the following rewording for commit subject: > | test: build auxiliary C libs from PUC-Rio-Lua5.1 Applied, thanks. > > On 26.03.21, Sergey Kaplun wrote: > > This patch adds commands to create additional LuaC libraries for tests > > Minor: these are not "commands" but "rules". Fixed. > > > in <attrib.lua>. Also, it renames `luaL_reg` to `luaL_Reg` in <lib1.c> > > and <lib2.c> to be consistent with the current LuaJIT's LuaC API. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/CMakeLists.txt | 3 +- > > test/PUC-Lua-5.1-tests/libs/CMakeLists.txt | 48 +++++++++++++++++++++- > > test/PUC-Lua-5.1-tests/libs/lib1.c | 2 +- > > test/PUC-Lua-5.1-tests/libs/lib2.c | 2 +- > > 4 files changed, 51 insertions(+), 4 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/CMakeLists.txt b/test/PUC-Lua-5.1-tests/CMakeLists.txt > > index 773db0d..3c31aae 100644 > > --- a/test/PUC-Lua-5.1-tests/CMakeLists.txt > > +++ b/test/PUC-Lua-5.1-tests/CMakeLists.txt > > @@ -16,7 +16,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > # variable as proposed in the first case. > > set(LUA_PATH "?\;${CMAKE_CURRENT_SOURCE_DIR}/?.lua") > > Side note: I see no LUA_CPATH, but I grepped the spots where lib*.so are > required and found that package.cpath is tweaked right there. Hence > LUA_CPATH is excess, isn't it? Yep. Also, `LUA_CPATH` isn't mentioned in suite's README. > > > > > <snipped> > > > diff --git a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > index f24e7f3..aa64a44 100644 > > --- a/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > +++ b/test/PUC-Lua-5.1-tests/libs/CMakeLists.txt > > @@ -4,11 +4,57 @@ > > # See the rationale in the root CMakeLists.txt. > > cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > > > +# Build additional C libraries for tests. > > +macro(BuildTestCLib lib sources) > > <snipped> > > > + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") > > Minor: I personally would strip this option out for all remaining > systems (i.e. *BSD too), since we have no guarantee the CMake defaults > won't be broken on other distros sometime. Feel free to ignore (but > it'll be on your conscience). I prefer not to do this -- if there is another one system with the same behaviour, it should be mentioned explicitly here, to avoid questions in the future. Ignoring. > > > + # XXX: This is necessary mostly for openSUSE builds, see also > > + # https://bugzilla.suse.com/show_bug.cgi?id=1012388. > > + # Just strip out the linker flag to suppress this linker > > + # option. > > + string(REPLACE "-Wl,--no-undefined" "" > > + CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" > > + ) > > + endif() > > <snipped> > > > +endmacro() > > + > > +BuildTestCLib(lib1 lib1.c) > > Typo: excess whitespace. > > > +BuildTestCLib(lib11 lib1.c lib11.c) > > +BuildTestCLib(lib2 lib2.c) > > Typo: excess whitespace. Strictly saying they are not excess -- I want to align library sources for easier reading :). Removed. > > > +BuildTestCLib(lib21 lib2.c lib21.c) > > + > > +# Create exact copy of the lib2 library for tests in attrib.lua. > > Typo: s/create exact copy/create the exact copy/. Fixed. > > > +set(LIB2ORIG "${CMAKE_CURRENT_BINARY_DIR}/lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > > +set(LIB2COPY "${CMAKE_CURRENT_BINARY_DIR}/-lib2${CMAKE_SHARED_LIBRARY_SUFFIX}") > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 01/30] test: add " Sergey Kaplun via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 02/30] test: add compiling for C libs from PUC-Rio-Lua5.1 Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:07 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches ` (28 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches When tests are run out-of-source redefined `dofile()` function failed to find file to load. So, fullpath is detected considering `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their argument is adjusted to the full path to the files. However, test in <verybig.lua> creates a temporary file and executes it via `dofile()` too, so this case is handled by the second argument -- `prefix` equals an empty string for current working directory. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/all.lua | 17 +++++++++++++---- test/PUC-Lua-5.1-tests/verybig.lua | 4 +++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua index 8c4afac..85beff8 100755 --- a/test/PUC-Lua-5.1-tests/all.lua +++ b/test/PUC-Lua-5.1-tests/all.lua @@ -58,9 +58,18 @@ end -- -- redefine dofile to run files through dump/undump -- -dofile = function (n) +-- LuaJIT: Adapt tests for testing with out-of-source build. +-- XXX: Test in <verybig.lua> creates a temporary file +-- and executes it via `dofile()` too, so this case is handled by +-- the second argument -- `prefix` equals an empty string for +-- current working directory. +-- <all.lua> is in the same directory, where are other common +-- executed files situated. +local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '') +dofile = function (n, prefix) + local pr = prefix or path_to_sources showmem() - local f = assert(loadfile(n)) + local f = assert(loadfile(pr..n)) local b = string.dump(f) f = assert(loadstring(b)) return f() @@ -77,7 +86,7 @@ do end end -local f = assert(loadfile('gc.lua')) +local f = assert(loadfile(path_to_sources..'gc.lua')) f() dofile('db.lua') assert(dofile('calls.lua') == deep and deep) @@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5) dofile('constructs.lua') dofile('code.lua') do - local f = coroutine.wrap(assert(loadfile('big.lua'))) + local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua'))) assert(f() == 'b') assert(f() == 'a') end diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua index 59e0142..edb170d 100644 --- a/test/PUC-Lua-5.1-tests/verybig.lua +++ b/test/PUC-Lua-5.1-tests/verybig.lua @@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do if not n then io.write(s) else F[n]() end end io.close() -result = dofile(file) +-- LuaJIT: Adapt test for testing with out-of-source build. +-- See comment in <all.lua> near `dofile()` redefinition. +result = dofile(file, "") assert(os.remove(file)) print'OK' return result -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:07 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:25 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:07 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM, just minor changes to commit message. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > When tests are run out-of-source redefined `dofile()` function ^ I had problem reading here the ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate place at the end of the sentence? ’The redefined … when … ‘ > failed to find file to load. So, fullpath is detected considering > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so > their argument is adjusted to the full path to the files. > > However, test in <verybig.lua> creates a temporary file > and executes it via `dofile()` too, so this case is handled by > the second argument -- `prefix` equals an empty string for > current working directory. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/all.lua | 17 +++++++++++++---- > test/PUC-Lua-5.1-tests/verybig.lua | 4 +++- > 2 files changed, 16 insertions(+), 5 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua > index 8c4afac..85beff8 100755 > --- a/test/PUC-Lua-5.1-tests/all.lua > +++ b/test/PUC-Lua-5.1-tests/all.lua > @@ -58,9 +58,18 @@ end > -- > -- redefine dofile to run files through dump/undump > -- > -dofile = function (n) > +-- LuaJIT: Adapt tests for testing with out-of-source build. > +-- XXX: Test in <verybig.lua> creates a temporary file > +-- and executes it via `dofile()` too, so this case is handled by > +-- the second argument -- `prefix` equals an empty string for > +-- current working directory. > +-- <all.lua> is in the same directory, where are other common > +-- executed files situated. > +local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '') > +dofile = function (n, prefix) > + local pr = prefix or path_to_sources > showmem() > - local f = assert(loadfile(n)) > + local f = assert(loadfile(pr..n)) > local b = string.dump(f) > f = assert(loadstring(b)) > return f() > @@ -77,7 +86,7 @@ do > end > end > > -local f = assert(loadfile('gc.lua')) > +local f = assert(loadfile(path_to_sources..'gc.lua')) > f() > dofile('db.lua') > assert(dofile('calls.lua') == deep and deep) > @@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5) > dofile('constructs.lua') > dofile('code.lua') > do > - local f = coroutine.wrap(assert(loadfile('big.lua'))) > + local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua'))) > assert(f() == 'b') > assert(f() == 'a') > end > diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua > index 59e0142..edb170d 100644 > --- a/test/PUC-Lua-5.1-tests/verybig.lua > +++ b/test/PUC-Lua-5.1-tests/verybig.lua > @@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do > if not n then io.write(s) else F[n]() end > end > io.close() > -result = dofile(file) > +-- LuaJIT: Adapt test for testing with out-of-source build. > +-- See comment in <all.lua> near `dofile()` redefinition. > +result = dofile(file, "") > assert(os.remove(file)) > print'OK' > return result > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-26 11:07 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:25 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:25 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi! Thanks for the review! On 26.03.21, Sergey Ostanevich wrote: > LGTM, just minor changes to commit message. > > Sergos > > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > When tests are run out-of-source redefined `dofile()` function > ^ I had problem reading here the > ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate > place at the end of the sentence? ’The redefined … when … ‘ Fixed. The new committ message is the following (branch is force-pushed): =================================================================== test: adapt Lua 5.1 suite for out-of-source build When tests are run out-of-source redefined `dofile()` function failed to find the test file to load. So, fullpath is detected considering `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their argument is adjusted to the full path to the files. However, test in <verybig.lua> creates a temporary file and executes it via `dofile()` too, so this case is handled by the second argument -- `prefix` equals an empty string for current working directory. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== > > > failed to find file to load. So, fullpath is detected considering > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so > > their argument is adjusted to the full path to the files. > > > > However, test in <verybig.lua> creates a temporary file > > and executes it via `dofile()` too, so this case is handled by > > the second argument -- `prefix` equals an empty string for > > current working directory. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/all.lua | 17 +++++++++++++---- > > test/PUC-Lua-5.1-tests/verybig.lua | 4 +++- > > 2 files changed, 16 insertions(+), 5 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/all.lua b/test/PUC-Lua-5.1-tests/all.lua > > index 8c4afac..85beff8 100755 > > --- a/test/PUC-Lua-5.1-tests/all.lua > > +++ b/test/PUC-Lua-5.1-tests/all.lua > > @@ -58,9 +58,18 @@ end > > -- > > -- redefine dofile to run files through dump/undump > > -- > > -dofile = function (n) > > +-- LuaJIT: Adapt tests for testing with out-of-source build. > > +-- XXX: Test in <verybig.lua> creates a temporary file > > +-- and executes it via `dofile()` too, so this case is handled by > > +-- the second argument -- `prefix` equals an empty string for > > +-- current working directory. > > +-- <all.lua> is in the same directory, where are other common > > +-- executed files situated. > > +local path_to_sources = arg[0]:gsub('([^/]+)%.lua$', '') > > +dofile = function (n, prefix) > > + local pr = prefix or path_to_sources > > showmem() > > - local f = assert(loadfile(n)) > > + local f = assert(loadfile(pr..n)) > > local b = string.dump(f) > > f = assert(loadstring(b)) > > return f() > > @@ -77,7 +86,7 @@ do > > end > > end > > > > -local f = assert(loadfile('gc.lua')) > > +local f = assert(loadfile(path_to_sources..'gc.lua')) > > f() > > dofile('db.lua') > > assert(dofile('calls.lua') == deep and deep) > > @@ -88,7 +97,7 @@ assert(dofile('locals.lua') == 5) > > dofile('constructs.lua') > > dofile('code.lua') > > do > > - local f = coroutine.wrap(assert(loadfile('big.lua'))) > > + local f = coroutine.wrap(assert(loadfile(path_to_sources..'big.lua'))) > > assert(f() == 'b') > > assert(f() == 'a') > > end > > diff --git a/test/PUC-Lua-5.1-tests/verybig.lua b/test/PUC-Lua-5.1-tests/verybig.lua > > index 59e0142..edb170d 100644 > > --- a/test/PUC-Lua-5.1-tests/verybig.lua > > +++ b/test/PUC-Lua-5.1-tests/verybig.lua > > @@ -93,7 +93,9 @@ for s in string.gmatch(prog, "$([^$]+)") do > > if not n then io.write(s) else F[n]() end > > end > > io.close() > > -result = dofile(file) > > +-- LuaJIT: Adapt test for testing with out-of-source build. > > +-- See comment in <all.lua> near `dofile()` redefinition. > > +result = dofile(file, "") > > assert(os.remove(file)) > > print'OK' > > return result > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-26 14:25 ` Sergey Kaplun via Tarantool-patches @ 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:43 ` Sergey Kaplun via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 26.03.21, Sergey Kaplun wrote: > Hi! > > Thanks for the review! > > On 26.03.21, Sergey Ostanevich wrote: > > LGTM, just minor changes to commit message. > > > > Sergos > > > > > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > > > When tests are run out-of-source redefined `dofile()` function > > ^ I had problem reading here the > > ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate > > place at the end of the sentence? ’The redefined … when … ‘ > > Fixed. > > The new committ message is the following (branch is force-pushed): But what is fixed in the new version? I see the sentence Sergos asked to reword is left intact. > > =================================================================== > test: adapt Lua 5.1 suite for out-of-source build > > When tests are run out-of-source redefined `dofile()` function failed to > find the test file to load. So, fullpath is detected considering > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their > argument is adjusted to the full path to the files. > > However, test in <verybig.lua> creates a temporary file > and executes it via `dofile()` too, so this case is handled by > the second argument -- `prefix` equals an empty string for > current working directory. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > =================================================================== > > > > > > failed to find file to load. So, fullpath is detected considering > > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so > > > their argument is adjusted to the full path to the files. > > > > > > However, test in <verybig.lua> creates a temporary file > > > and executes it via `dofile()` too, so this case is handled by > > > the second argument -- `prefix` equals an empty string for > > > current working directory. > > > > > > Part of tarantool/tarantool#5845 > > > Part of tarantool/tarantool#4473 <snipped> > > > -- > > > 2.31.0 > > > > > > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches @ 2021-04-01 8:43 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 8:43 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, On 01.04.21, Igor Munkin wrote: > Sergey, > > On 26.03.21, Sergey Kaplun wrote: > > Hi! > > > > Thanks for the review! > > > > On 26.03.21, Sergey Ostanevich wrote: > > > LGTM, just minor changes to commit message. > > > > > > Sergos > > > > > > > > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > > > > > When tests are run out-of-source redefined `dofile()` function > > > ^ I had problem reading here the > > > ‘out-of-source redefined’. Can you put the ‘when..’ to the appropriate > > > place at the end of the sentence? ’The redefined … when … ‘ > > > > Fixed. > > > > The new committ message is the following (branch is force-pushed): > > But what is fixed in the new version? I see the sentence Sergos asked to > reword is left intact. Brr, sorry. Looks like I changed it twice. Thanks for the catch! The new version (checked twice): =================================================================== test: adapt Lua 5.1 suite for out-of-source build The redefined `dofile()` function failed to find the test file to load, when tests are run out-of-source. So, fullpath is detected considering `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their argument is adjusted to the full path to the files. However, test in <verybig.lua> creates a temporary file and executes it via `dofile()` too, so this case is handled by the second argument -- `prefix` equals an empty string for current working directory. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== > > > > > =================================================================== > > test: adapt Lua 5.1 suite for out-of-source build > > > > When tests are run out-of-source redefined `dofile()` function failed to > > find the test file to load. So, fullpath is detected considering > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so their > > argument is adjusted to the full path to the files. > > > > However, test in <verybig.lua> creates a temporary file > > and executes it via `dofile()` too, so this case is handled by > > the second argument -- `prefix` equals an empty string for > > current working directory. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > =================================================================== > > > > > > > > > failed to find file to load. So, fullpath is detected considering > > > > `arg[0]` value. Moreover, some tests use `loadfile()` instead, so > > > > their argument is adjusted to the full path to the files. > > > > > > > > However, test in <verybig.lua> creates a temporary file > > > > and executes it via `dofile()` too, so this case is handled by > > > > the second argument -- `prefix` equals an empty string for > > > > current working directory. > > > > > > > > Part of tarantool/tarantool#5845 > > > > Part of tarantool/tarantool#4473 > > <snipped> > > > > > -- > > > > 2.31.0 > > > > > > > > > > > -- > > Best regards, > > Sergey Kaplun > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches 2021-03-26 11:07 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:40 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! Honestly, I'm not fond of the solution you implemented, though it allows to make as little changes as possible. I propose to implement something similar to the solution you've made within lua-Harness series: * You need two <dofile> functions: one for launching source files for additional checks and another one for running temporary Lua chunks. * You also need two <loadstring> functions for the same reason. Mind the fact <dofile> is implemented via <loadstring>, so basically, there might be no so much changes made for <dofile>. Thoughts? -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches @ 2021-04-01 8:40 ` Sergey Kaplun via Tarantool-patches 2021-04-06 16:56 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 8:40 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 01.04.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! Honestly, I'm not fond of the solution you > implemented, though it allows to make as little changes as possible. > I propose to implement something similar to the solution you've made > within lua-Harness series: > * You need two <dofile> functions: one for launching source files for > additional checks and another one for running temporary Lua chunks. > * You also need two <loadstring> functions for the same reason. > > Mind the fact <dofile> is implemented via <loadstring>, so basically, > there might be no so much changes made for <dofile>. Thoughts? I prefer to use one function, and two wrappers around it. For example, let it be `absolute_dofile()` and `cwd_dofile()`. But honestly, it is not the single one problem of this suite (no test isolation, global variables, huge excess output, hardcoded limit values, etc). It looks like we need to refactor this suite later (plus adapt test for LuaJIT extensions from Lua 5.2+). I propose to do all this work via that refactoring, not now. Otherwise, it looks like a patch, which will still need to be refactored later. Thoughts? > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build 2021-04-01 8:40 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 16:56 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 16:56 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 01.04.21, Sergey Kaplun wrote: > Igor, > > Thanks for the review! > > On 01.04.21, Igor Munkin wrote: > > Sergey, > > > > Thanks for the patch! Honestly, I'm not fond of the solution you > > implemented, though it allows to make as little changes as possible. > > I propose to implement something similar to the solution you've made > > within lua-Harness series: > > * You need two <dofile> functions: one for launching source files for > > additional checks and another one for running temporary Lua chunks. > > * You also need two <loadstring> functions for the same reason. > > > > Mind the fact <dofile> is implemented via <loadstring>, so basically, > > there might be no so much changes made for <dofile>. Thoughts? > > I prefer to use one function, and two wrappers around it. > For example, let it be `absolute_dofile()` and `cwd_dofile()`. Why do you need the second one? > > But honestly, it is not the single one problem of this suite (no test > isolation, global variables, huge excess output, hardcoded limit > values, etc). Yes, the whole suite is a single problem, but you've already fixed something. This patch can fix the base problem we've resolved while adopting lua-Harness. Why do you want to omit it here? > It looks like we need to refactor this suite later (plus adapt test > for LuaJIT extensions from Lua 5.2+). I propose to do all this work > via that refactoring, not now. Otherwise, it looks like a patch, which > will still need to be refactored later. It's not about refactoring, it's about the general approach. François proposed an elegant solution with <_dofile> that can be overloaded in luajit-test-init.lua (and we have to introduce one into LuaJIT then), so I see no reason to postpone such simple change. Of course this issue can be done within #5790 (or not, again, since it relates to another suite), so if you don't want to do this, let's close the eyes and leave such unsighty workaround. Consider you have my LGTM here if nobody else is bothered. I'll just glance the patch once more. > > Thoughts? > > > > > -- > > Best regards, > > IM > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (2 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 03/30] test: adapt Lua 5.1 suite for out-of-source build Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches ` (27 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches When LUAJIT_TEST_COMMAND extend the least `arg` with some string containing double quotes, bash failed to exec this command for child test. This patch removes edged '"' to be able run extended command containing '"' and run other test suites. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/main.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua index f520896..4f8b8bf 100644 --- a/test/PUC-Lua-5.1-tests/main.lua +++ b/test/PUC-Lua-5.1-tests/main.lua @@ -11,7 +11,9 @@ out = os.tmpname() do local i = 0 while arg[i] do i=i-1 end - progname = '"'..arg[i+1]..'"' + -- LuaJIT: remove edged '"' to be able run extended command + -- containing '"' and run other test suites. + progname = arg[i+1] end print(progname) @@ -53,10 +55,12 @@ prepfile("print(a)", otherprog) RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out) checkout("1\n2\n2\n") +-- LuaJIT: test file is adapted for LuaJIT's test system, see +-- the comment near `progname` initialization. local a = [[ assert(table.getn(arg) == 3 and arg[1] == 'a' and arg[2] == 'b' and arg[3] == 'c') - assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s) + assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s') assert(arg[4] == nil and arg[-4] == nil) local a, b, c = ... assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:12 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > When LUAJIT_TEST_COMMAND extend the least `arg` with > some string containing double quotes, bash failed to exec this > command for child test. > > This patch removes edged '"' to be able run extended command > containing '"' and run other test suites. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index f520896..4f8b8bf 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -11,7 +11,9 @@ out = os.tmpname() > do > local i = 0 > while arg[i] do i=i-1 end > - progname = '"'..arg[i+1]..'"' > + -- LuaJIT: remove edged '"' to be able run extended command > + -- containing '"' and run other test suites. > + progname = arg[i+1] > end > print(progname) > > @@ -53,10 +55,12 @@ prepfile("print(a)", otherprog) > RUN("lua -l %s -l%s -lstring -l io %s > %s", prog, otherprog, otherprog, out) > checkout("1\n2\n2\n") > > +-- LuaJIT: test file is adapted for LuaJIT's test system, see > +-- the comment near `progname` initialization. > local a = [[ > assert(table.getn(arg) == 3 and arg[1] == 'a' and > arg[2] == 'b' and arg[3] == 'c') > - assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == %s) > + assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s') > assert(arg[4] == nil and arg[-4] == nil) > local a, b, c = ... > assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches 2021-03-26 11:12 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 8:50 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > When LUAJIT_TEST_COMMAND extend the least `arg` with Typo: s/LUAJIT_TEST_COMMAND extend/LUAJIT_TEST_COMMAND extends/. Typo: s/the least `arg`/the least `arg` slot/. > some string containing double quotes, bash failed to exec this Minor: I believe you're not talking about bash here, but rather about <os.execute> and hence system(3) command, IIRC. > command for child test. > > This patch removes edged '"' to be able run extended command Minor: I guess "framing" fits better than "edging". Typo: s/to be able run extended/to be able to run an extended/. > containing '"' and run other test suites. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index f520896..4f8b8bf 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -11,7 +11,9 @@ out = os.tmpname() > do > local i = 0 > while arg[i] do i=i-1 end > - progname = '"'..arg[i+1]..'"' > + -- LuaJIT: remove edged '"' to be able run extended command Minor: I guess "framing" fits better than "edging". Typo: s/to be able run extended/to be able to run an extended/. > + -- containing '"' and run other test suites. > + progname = arg[i+1] > end > print(progname) > <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches @ 2021-04-01 8:50 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 8:50 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 01.04.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > When LUAJIT_TEST_COMMAND extend the least `arg` with > > Typo: s/LUAJIT_TEST_COMMAND extend/LUAJIT_TEST_COMMAND extends/. > Typo: s/the least `arg`/the least `arg` slot/. Fixed. > > > some string containing double quotes, bash failed to exec this > > Minor: I believe you're not talking about bash here, but rather > about <os.execute> and hence system(3) command, IIRC. Fixed. Thanks! > > > command for child test. > > > > This patch removes edged '"' to be able run extended command > > Minor: I guess "framing" fits better than "edging". > Typo: s/to be able run extended/to be able to run an extended/. Fixed. > > > containing '"' and run other test suites. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/main.lua | 8 ++++++-- > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > > index f520896..4f8b8bf 100644 > > --- a/test/PUC-Lua-5.1-tests/main.lua > > +++ b/test/PUC-Lua-5.1-tests/main.lua > > @@ -11,7 +11,9 @@ out = os.tmpname() > > do > > local i = 0 > > while arg[i] do i=i-1 end > > - progname = '"'..arg[i+1]..'"' > > + -- LuaJIT: remove edged '"' to be able run extended command > > Minor: I guess "framing" fits better than "edging". > Typo: s/to be able run extended/to be able to run an extended/. Fixed. > > > + -- containing '"' and run other test suites. > > + progname = arg[i+1] > > end > > print(progname) > > > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (3 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 04/30] test: remove quotes in progname from <main.lua> Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:22 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches ` (26 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches The argument table `arg` can be read (and modified) by `LUA_INIT` and `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce (Set arg table before evaluating LUA_INIT and -e chunks.). This behaviour is similar to Lua 5.3, so the test was adapted considering PUC-Rio Lua 5.3 test suite taken from https://www.lua.org/tests/lua-5.3.0-tests.tar.gz. Closes tarantool/tarantool#5686 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua index 4f8b8bf..c11a576 100644 --- a/test/PUC-Lua-5.1-tests/main.lua +++ b/test/PUC-Lua-5.1-tests/main.lua @@ -69,9 +69,19 @@ a = string.format(a, progname) prepfile(a) RUN('lua "-e " -- %s a b c', prog) -prepfile"assert(arg==nil)" +-- test 'arg' availability in libraries +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3: +-- The argument table `arg` can be read (and modified) +-- by `LUA_INIT` and `-e` chunks. +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce +-- (Set arg table before evaluating LUA_INIT and -e chunks.). +-- See also https://github.com/tarantool/tarantool/issues/5686. +-- In Lua 5.3 this feature was introduced via commit +-- 23f0ff95177eda2e0a80e3a48562cc6837705735. +-- Test is adapted from PUC-Rio Lua 5.3 test suite. +prepfile"assert(arg)" prepfile("assert(arg)", otherprog) -RUN("lua -l%s - < %s", prog, otherprog) +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) prepfile"" RUN("lua - < %s > %s", prog, out) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:22 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:22 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches [-- Attachment #1: Type: text/plain, Size: 1944 bytes --] LGTM. Although, I can’t support the `s = string.gsub(s, "lua", progname, 1)` technique. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > The argument table `arg` can be read (and modified) by `LUA_INIT` and > `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce > (Set arg table before evaluating LUA_INIT and -e chunks.). > > This behaviour is similar to Lua 5.3, so the test was adapted > considering PUC-Rio Lua 5.3 test suite taken from > https://www.lua.org/tests/lua-5.3.0-tests.tar.gz. > > Closes tarantool/tarantool#5686 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index 4f8b8bf..c11a576 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -69,9 +69,19 @@ a = string.format(a, progname) > prepfile(a) > RUN('lua "-e " -- %s a b c', prog) > > -prepfile"assert(arg==nil)" > +-- test 'arg' availability in libraries > +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3: > +-- The argument table `arg` can be read (and modified) > +-- by `LUA_INIT` and `-e` chunks. > +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce > +-- (Set arg table before evaluating LUA_INIT and -e chunks.). > +-- See also https://github.com/tarantool/tarantool/issues/5686. > +-- In Lua 5.3 this feature was introduced via commit > +-- 23f0ff95177eda2e0a80e3a48562cc6837705735. > +-- Test is adapted from PUC-Rio Lua 5.3 test suite. > +prepfile"assert(arg)" > prepfile("assert(arg)", otherprog) > -RUN("lua -l%s - < %s", prog, otherprog) > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) > > prepfile"" > RUN("lua - < %s > %s", prog, out) > -- > 2.31.0 > [-- Attachment #2: Type: text/html, Size: 4252 bytes --] ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 11:22 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 9:37 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! Please consider the comments below. On 26.03.21, Sergey Kaplun wrote: > The argument table `arg` can be read (and modified) by `LUA_INIT` and > `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce > (Set arg table before evaluating LUA_INIT and -e chunks.). > > This behaviour is similar to Lua 5.3, so the test was adapted > considering PUC-Rio Lua 5.3 test suite taken from > https://www.lua.org/tests/lua-5.3.0-tests.tar.gz. > > Closes tarantool/tarantool#5686 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index 4f8b8bf..c11a576 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -69,9 +69,19 @@ a = string.format(a, progname) > prepfile(a) > RUN('lua "-e " -- %s a b c', prog) > > -prepfile"assert(arg==nil)" > +-- test 'arg' availability in libraries > +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3: > +-- The argument table `arg` can be read (and modified) > +-- by `LUA_INIT` and `-e` chunks. > +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce > +-- (Set arg table before evaluating LUA_INIT and -e chunks.). > +-- See also https://github.com/tarantool/tarantool/issues/5686. > +-- In Lua 5.3 this feature was introduced via commit > +-- 23f0ff95177eda2e0a80e3a48562cc6837705735. > +-- Test is adapted from PUC-Rio Lua 5.3 test suite. > +prepfile"assert(arg)" > prepfile("assert(arg)", otherprog) > -RUN("lua -l%s - < %s", prog, otherprog) > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) Why LUA_PATH is tweaked here? > > prepfile"" > RUN("lua - < %s > %s", prog, out) > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches @ 2021-04-01 9:37 ` Sergey Kaplun via Tarantool-patches 2021-04-06 15:24 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 9:37 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 01.04.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! Please consider the comments below. > > On 26.03.21, Sergey Kaplun wrote: > > The argument table `arg` can be read (and modified) by `LUA_INIT` and > > `-e` chunks since the commit 92d9ff211ae864777a8580b5a7326d5f408161ce > > (Set arg table before evaluating LUA_INIT and -e chunks.). > > > > This behaviour is similar to Lua 5.3, so the test was adapted > > considering PUC-Rio Lua 5.3 test suite taken from > > https://www.lua.org/tests/lua-5.3.0-tests.tar.gz. > > > > Closes tarantool/tarantool#5686 > > As we discussed before: s/Closes/Resolves/. I used here Closes intentionly: I suppose, that the issue is not appeared in Tarantool's repo, so it is closed as far as the final version of patchset does not contain the issue. Looks that it is confusing, changed back to Resolves. Here and in the patches later. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/main.lua | 14 ++++++++++++-- > > 1 file changed, 12 insertions(+), 2 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > > index 4f8b8bf..c11a576 100644 > > --- a/test/PUC-Lua-5.1-tests/main.lua > > +++ b/test/PUC-Lua-5.1-tests/main.lua > > @@ -69,9 +69,19 @@ a = string.format(a, progname) > > prepfile(a) > > RUN('lua "-e " -- %s a b c', prog) > > > > -prepfile"assert(arg==nil)" > > +-- test 'arg' availability in libraries > > +-- LuaJIT: LuaJIT v2.1.0-beta3 has extension from Lua 5.3: > > +-- The argument table `arg` can be read (and modified) > > +-- by `LUA_INIT` and `-e` chunks. > > +-- See commit 92d9ff211ae864777a8580b5a7326d5f408161ce > > +-- (Set arg table before evaluating LUA_INIT and -e chunks.). > > +-- See also https://github.com/tarantool/tarantool/issues/5686. > > +-- In Lua 5.3 this feature was introduced via commit > > +-- 23f0ff95177eda2e0a80e3a48562cc6837705735. > > +-- Test is adapted from PUC-Rio Lua 5.3 test suite. > > +prepfile"assert(arg)" > > prepfile("assert(arg)", otherprog) > > -RUN("lua -l%s - < %s", prog, otherprog) > > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) > > Why LUA_PATH is tweaked here? Looks like Roberto avoids to load some files with the same name that can be loaded by the old `LUA_PATH`. I preferred to take it intact from the Lua 5.3 test suite (even comment about `arg` availability). > > > > > prepfile"" > > RUN("lua - < %s > %s", prog, out) > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite 2021-04-01 9:37 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 15:24 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 15:24 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 01.04.21, Sergey Kaplun wrote: > Igor, > <snipped> > > > -RUN("lua -l%s - < %s", prog, otherprog) > > > +RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) > > > > Why LUA_PATH is tweaked here? > > Looks like Roberto avoids to load some files with the same name > that can be loaded by the old `LUA_PATH`. I preferred to take it intact > from the Lua 5.3 test suite (even comment about `arg` availability). OK, then LGTM. > <snipped> > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (4 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 05/30] test: adapt arg availability test from Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:26 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches ` (25 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches Version and status are printed in stdout instead stderr since LuaJIT-2.0.0-beta11 (as it is not an error message). See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 (Print version and JIT status to stdout, not stderr.). This behavior is the same as in Lua 5.2. This patch disables tests confused by unexpected -v output to stdout. Relates to tarantool/tarantool#5687 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua index c11a576..56f56a0 100644 --- a/test/PUC-Lua-5.1-tests/main.lua +++ b/test/PUC-Lua-5.1-tests/main.lua @@ -103,26 +103,37 @@ prepfile[[ RUN("lua - < %s > %s", prog, out) checkout("1\tnil\n") +-- Version and status are printed in stdout instead stderr since +-- LuaJIT-2.0.0-beta11 (as it is not an error message). +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 +-- (Print version and JIT status to stdout, not stderr.). +-- This behavior is the same as in Lua 5.2. +-- In Lua 5.2 this feature was introduced via commit +-- 9e7de9473c65baee1f567852a778f2d33a47ea83. +-- See also https://github.com/tarantool/tarantool/issues/5687. prepfile[[ = (6*2-6) -- === a = 10 print(a) = a]] -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) -checkout("6\n10\n10\n\n") +-- FIXME: Behavior is different for LuaJIT. See the comment above. +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +-- checkout("6\n10\n10\n\n") prepfile("a = [[b\nc\nd\ne]]\n=a") print(prog) -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) -checkout("b\nc\nd\ne\n\n") +-- FIXME: Behavior is different for LuaJIT. See the comment above. +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +-- checkout("b\nc\nd\ne\n\n") prompt = "alo" prepfile[[ -- a = 2 ]] -RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) -checkout(string.rep(prompt, 3).."\n") +-- FIXME: Behavior is different for LuaJIT. See the comment above. +-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) +-- checkout(string.rep(prompt, 3).."\n") s = [=[ -- function f ( x ) @@ -140,8 +151,9 @@ assert( a == b ) =f( 11 ) ]=] s = string.gsub(s, ' ', '\n\n') prepfile(s) -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) -checkout("11\n1\t2\n\n") +-- FIXME: Behavior is different for LuaJIT. See the comment above. +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) +-- checkout("11\n1\t2\n\n") prepfile[[#comment in 1st line without \n at the end]] RUN("lua %s", prog) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:26 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:31 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:26 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Any follow-up ticket for this? Mention it in the commit message, and it's LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > Version and status are printed in stdout instead stderr since > LuaJIT-2.0.0-beta11 (as it is not an error message). > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > (Print version and JIT status to stdout, not stderr.). > This behavior is the same as in Lua 5.2. > > This patch disables tests confused by unexpected -v output to stdout. > > Relates to tarantool/tarantool#5687 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++-------- > 1 file changed, 20 insertions(+), 8 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index c11a576..56f56a0 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -103,26 +103,37 @@ prepfile[[ > RUN("lua - < %s > %s", prog, out) > checkout("1\tnil\n") > > +-- Version and status are printed in stdout instead stderr since > +-- LuaJIT-2.0.0-beta11 (as it is not an error message). > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > +-- (Print version and JIT status to stdout, not stderr.). > +-- This behavior is the same as in Lua 5.2. > +-- In Lua 5.2 this feature was introduced via commit > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83. > +-- See also https://github.com/tarantool/tarantool/issues/5687. > prepfile[[ > = (6*2-6) -- === > a > = 10 > print(a) > = a]] > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > -checkout("6\n10\n10\n\n") > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +-- checkout("6\n10\n10\n\n") > > prepfile("a = [[b\nc\nd\ne]]\n=a") > print(prog) > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > -checkout("b\nc\nd\ne\n\n") > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +-- checkout("b\nc\nd\ne\n\n") > > prompt = "alo" > prepfile[[ -- > a = 2 > ]] > -RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > -checkout(string.rep(prompt, 3).."\n") > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > +-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > +-- checkout(string.rep(prompt, 3).."\n") > > s = [=[ -- > function f ( x ) > @@ -140,8 +151,9 @@ assert( a == b ) > =f( 11 ) ]=] > s = string.gsub(s, ' ', '\n\n') > prepfile(s) > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > -checkout("11\n1\t2\n\n") > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > +-- checkout("11\n1\t2\n\n") > > prepfile[[#comment in 1st line without \n at the end]] > RUN("lua %s", prog) > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output 2021-03-26 11:26 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:31 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:31 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi! Thanks for the review! On 26.03.21, Sergey Ostanevich wrote: > Any follow-up ticket for this? Mention it in the commit message, and it's It is mentioned via the folowing line: | Relates to tarantool/tarantool#5687 > > LGTM. > > Sergos > > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > Version and status are printed in stdout instead stderr since > > LuaJIT-2.0.0-beta11 (as it is not an error message). > > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > > (Print version and JIT status to stdout, not stderr.). > > This behavior is the same as in Lua 5.2. > > > > This patch disables tests confused by unexpected -v output to stdout. > > > > Relates to tarantool/tarantool#5687 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++-------- > > 1 file changed, 20 insertions(+), 8 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > > index c11a576..56f56a0 100644 > > --- a/test/PUC-Lua-5.1-tests/main.lua > > +++ b/test/PUC-Lua-5.1-tests/main.lua > > @@ -103,26 +103,37 @@ prepfile[[ > > RUN("lua - < %s > %s", prog, out) > > checkout("1\tnil\n") > > > > +-- Version and status are printed in stdout instead stderr since > > +-- LuaJIT-2.0.0-beta11 (as it is not an error message). > > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > > +-- (Print version and JIT status to stdout, not stderr.). > > +-- This behavior is the same as in Lua 5.2. > > +-- In Lua 5.2 this feature was introduced via commit > > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83. > > +-- See also https://github.com/tarantool/tarantool/issues/5687. > > prepfile[[ > > = (6*2-6) -- === > > a > > = 10 > > print(a) > > = a]] > > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > -checkout("6\n10\n10\n\n") > > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > +-- checkout("6\n10\n10\n\n") > > > > prepfile("a = [[b\nc\nd\ne]]\n=a") > > print(prog) > > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > -checkout("b\nc\nd\ne\n\n") > > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > +-- checkout("b\nc\nd\ne\n\n") > > > > prompt = "alo" > > prepfile[[ -- > > a = 2 > > ]] > > -RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > > -checkout(string.rep(prompt, 3).."\n") > > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > > +-- RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) > > +-- checkout(string.rep(prompt, 3).."\n") > > > > s = [=[ -- > > function f ( x ) > > @@ -140,8 +151,9 @@ assert( a == b ) > > =f( 11 ) ]=] > > s = string.gsub(s, ' ', '\n\n') > > prepfile(s) > > -RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > -checkout("11\n1\t2\n\n") > > +-- FIXME: Behavior is different for LuaJIT. See the comment above. > > +-- RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) > > +-- checkout("11\n1\t2\n\n") > > > > prepfile[[#comment in 1st line without \n at the end]] > > RUN("lua %s", prog) > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches 2021-03-26 11:26 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches 2021-04-01 9:56 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > Version and status are printed in stdout instead stderr since Typo: s/printed in stdout/printed to stdout/. Typo: s/instead stderr/instead of stderr/. > LuaJIT-2.0.0-beta11 (as it is not an error message). > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > (Print version and JIT status to stdout, not stderr.). > This behavior is the same as in Lua 5.2. > > This patch disables tests confused by unexpected -v output to stdout. > > Relates to tarantool/tarantool#5687 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++-------- > 1 file changed, 20 insertions(+), 8 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index c11a576..56f56a0 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -103,26 +103,37 @@ prepfile[[ > RUN("lua - < %s > %s", prog, out) > checkout("1\tnil\n") > > +-- Version and status are printed in stdout instead stderr since > +-- LuaJIT-2.0.0-beta11 (as it is not an error message). Typo: s/printed in stdout/printed to stdout/. Typo: s/instead stderr/instead of stderr/. > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > +-- (Print version and JIT status to stdout, not stderr.). > +-- This behavior is the same as in Lua 5.2. > +-- In Lua 5.2 this feature was introduced via commit > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83. > +-- See also https://github.com/tarantool/tarantool/issues/5687. <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output 2021-03-31 22:58 ` Igor Munkin via Tarantool-patches @ 2021-04-01 9:56 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 9:56 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 01.04.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > Version and status are printed in stdout instead stderr since > > Typo: s/printed in stdout/printed to stdout/. > Typo: s/instead stderr/instead of stderr/. Fixed. > > > LuaJIT-2.0.0-beta11 (as it is not an error message). > > See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > > (Print version and JIT status to stdout, not stderr.). > > This behavior is the same as in Lua 5.2. > > > > This patch disables tests confused by unexpected -v output to stdout. > > > > Relates to tarantool/tarantool#5687 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/main.lua | 28 ++++++++++++++++++++-------- > > 1 file changed, 20 insertions(+), 8 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > > index c11a576..56f56a0 100644 > > --- a/test/PUC-Lua-5.1-tests/main.lua > > +++ b/test/PUC-Lua-5.1-tests/main.lua > > @@ -103,26 +103,37 @@ prepfile[[ > > RUN("lua - < %s > %s", prog, out) > > checkout("1\tnil\n") > > > > +-- Version and status are printed in stdout instead stderr since > > +-- LuaJIT-2.0.0-beta11 (as it is not an error message). > > Typo: s/printed in stdout/printed to stdout/. > Typo: s/instead stderr/instead of stderr/. Fixed. > > > +-- See commit 0bd1a66f2f055211ef55834ccebca3b82d03c735 > > +-- (Print version and JIT status to stdout, not stderr.). > > +-- This behavior is the same as in Lua 5.2. > > +-- In Lua 5.2 this feature was introduced via commit > > +-- 9e7de9473c65baee1f567852a778f2d33a47ea83. > > +-- See also https://github.com/tarantool/tarantool/issues/5687. > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (5 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 06/30] test: disable PUC Lua tests confused by -v output Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:30 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches ` (24 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches Loading bytecode with an extra header (BOM or "#") is disabled for security reasons since LuaJIT-2.0.0-beta10. For more information see comment for `lj_lex_setup()` in <src/lj_lex.c>. Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47 (Disable loading bytecode with an extra header (BOM or #!).). These tests are disabled for LuaJIT. Relates to tarantool/tarantool#5691 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/main.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua index 56f56a0..cf6d533 100644 --- a/test/PUC-Lua-5.1-tests/main.lua +++ b/test/PUC-Lua-5.1-tests/main.lua @@ -158,13 +158,23 @@ prepfile(s) prepfile[[#comment in 1st line without \n at the end]] RUN("lua %s", prog) +-- Loading bytecode with an extra header (BOM or "#") is disabled +-- for security reasons since LuaJIT-2.0.0-beta10. +-- For more information see comment for `lj_lex_setup()` +-- in <src/lj_lex.c>. +-- Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47 +-- (Disable loading bytecode with an extra header (BOM or #!).). +-- See also https://github.com/tarantool/tarantool/issues/5691. +-- FIXME: test is disabled for LuaJIT. prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)"))) -RUN("lua %s > %s", prog, out) -checkout("1\n") +-- 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") +-- Behavior is different for LuaJIT. See the comment above. +-- FIXME: test is disabled for LuaJIT. +-- 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)) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:30 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:30 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > Loading bytecode with an extra header (BOM or "#") is disabled > for security reasons since LuaJIT-2.0.0-beta10. > For more information see comment for `lj_lex_setup()` > in <src/lj_lex.c>. > Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47 > (Disable loading bytecode with an extra header (BOM or #!).). > > These tests are disabled for LuaJIT. > > Relates to tarantool/tarantool#5691 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/main.lua | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/main.lua b/test/PUC-Lua-5.1-tests/main.lua > index 56f56a0..cf6d533 100644 > --- a/test/PUC-Lua-5.1-tests/main.lua > +++ b/test/PUC-Lua-5.1-tests/main.lua > @@ -158,13 +158,23 @@ prepfile(s) > prepfile[[#comment in 1st line without \n at the end]] > RUN("lua %s", prog) > > +-- Loading bytecode with an extra header (BOM or "#") is disabled > +-- for security reasons since LuaJIT-2.0.0-beta10. > +-- For more information see comment for `lj_lex_setup()` > +-- in <src/lj_lex.c>. > +-- Also see commit 53a285c0c3544ff5dea7c67b741c3c2d06d22b47 > +-- (Disable loading bytecode with an extra header (BOM or #!).). > +-- See also https://github.com/tarantool/tarantool/issues/5691. > +-- FIXME: test is disabled for LuaJIT. > prepfile("#comment with a binary file\n"..string.dump(loadstring("print(1)"))) > -RUN("lua %s > %s", prog, out) > -checkout("1\n") > +-- 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") > +-- Behavior is different for LuaJIT. See the comment above. > +-- FIXME: test is disabled for LuaJIT. > +-- 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)) > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches 2021-03-26 11:30 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:59 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM. -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (6 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 07/30] test: disable Lua tests for bytecode with header Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:32 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches ` (23 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches JIT compilation can unpredictable allocate or reference objects (or traces itself). So, the amount of GC steps can vary from run to run. This patch disables JIT machinery, if it is enabled, for stable GC results. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua index 86a9f75..072bbe9 100644 --- a/test/PUC-Lua-5.1-tests/gc.lua +++ b/test/PUC-Lua-5.1-tests/gc.lua @@ -108,11 +108,21 @@ local function dosteps (siz) return i end +-- LuaJIT: JIT compilation can unpredictable allocate or reference +-- objects (or traces itself). Disable it if necessary for +-- this chunk for stable GC results. +local jit_is_enabled = jit.status() +if jit_is_enabled then + jit.off() +end assert(dosteps(0) > 10) assert(dosteps(6) < dosteps(2)) assert(dosteps(10000) == 1) assert(collectgarbage("step", 1000000) == true) assert(collectgarbage("step", 1000000)) +if jit_is_enabled then + jit.on() +end do -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:32 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:32 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > JIT compilation can unpredictable allocate or reference objects (or > traces itself). So, the amount of GC steps can vary from run to run. > > This patch disables JIT machinery, if it is enabled, for stable GC > results. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua > index 86a9f75..072bbe9 100644 > --- a/test/PUC-Lua-5.1-tests/gc.lua > +++ b/test/PUC-Lua-5.1-tests/gc.lua > @@ -108,11 +108,21 @@ local function dosteps (siz) > return i > end > > +-- LuaJIT: JIT compilation can unpredictable allocate or reference > +-- objects (or traces itself). Disable it if necessary for > +-- this chunk for stable GC results. > +local jit_is_enabled = jit.status() > +if jit_is_enabled then > + jit.off() > +end > assert(dosteps(0) > 10) > assert(dosteps(6) < dosteps(2)) > assert(dosteps(10000) == 1) > assert(collectgarbage("step", 1000000) == true) > assert(collectgarbage("step", 1000000)) > +if jit_is_enabled then > + jit.on() > +end > > > do > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches 2021-03-26 11:32 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 10:10 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. I propose the following rewording for commit subject: | test: disable JIT for the tests counting GC steps On 26.03.21, Sergey Kaplun wrote: > JIT compilation can unpredictable allocate or reference objects (or Typo: s/unpredictable/unpredictably/. > traces itself). So, the amount of GC steps can vary from run to run. > > This patch disables JIT machinery, if it is enabled, for stable GC > results. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua > index 86a9f75..072bbe9 100644 > --- a/test/PUC-Lua-5.1-tests/gc.lua > +++ b/test/PUC-Lua-5.1-tests/gc.lua > @@ -108,11 +108,21 @@ local function dosteps (siz) > return i > end > > +-- LuaJIT: JIT compilation can unpredictable allocate or reference Typo: s/unpredictable/unpredictably/. > +-- objects (or traces itself). Disable it if necessary for > +-- this chunk for stable GC results. <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches @ 2021-04-01 10:10 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:10 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > I propose the following rewording for commit subject: > | test: disable JIT for the tests counting GC steps Thanks, applied! > > On 26.03.21, Sergey Kaplun wrote: > > JIT compilation can unpredictable allocate or reference objects (or > > Typo: s/unpredictable/unpredictably/. Fixed, thanks. > > > traces itself). So, the amount of GC steps can vary from run to run. > > > > This patch disables JIT machinery, if it is enabled, for stable GC > > results. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/gc.lua | 10 ++++++++++ > > 1 file changed, 10 insertions(+) > > > > diff --git a/test/PUC-Lua-5.1-tests/gc.lua b/test/PUC-Lua-5.1-tests/gc.lua > > index 86a9f75..072bbe9 100644 > > --- a/test/PUC-Lua-5.1-tests/gc.lua > > +++ b/test/PUC-Lua-5.1-tests/gc.lua > > @@ -108,11 +108,21 @@ local function dosteps (siz) > > return i > > end > > > > +-- LuaJIT: JIT compilation can unpredictable allocate or reference > > Typo: s/unpredictable/unpredictably/. Fixed. > > > +-- objects (or traces itself). Disable it if necessary for > > +-- this chunk for stable GC results. > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (7 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 08/30] test: disable JIT for GC step counting tests Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:35 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches ` (22 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches FIXME: LuaJIT interprets a return from a new function loaded by `loadstring()` with a change line number for bytecode position unlike Lua does. This looks like "implementation-defined behaviour" mentioned in https://luajit.org/status.html. All tests checked the debug hook for a new line of code are affected and disabled by this patch. Relates to tarantool/tarantool#5693 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index 9d2c86f..a8c7196 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -95,6 +95,23 @@ repeat assert(g(f) == 'a') until 1 +-- FIXME: LuaJIT interprets a return from calling result of +-- `loadstring()` with a new line number unlike Lua does. +-- Here is an example (it is joined in one line intend): +--[[ +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook() +--]] +-- This chunk prints for LuaJIT: +--[[ +LINE: 3 +LINE: 1 +--]] +-- But for Lua 5.1 it is only "LINE: 3" in the output. +-- See also https://github.com/tarantool/tarantool/issues/5693. +-- Considering implementation-defined behaviour diference +-- (see also https://luajit.org/status.html) test is disabled for +-- LuaJIT. +--[=[ test([[if math.sin(1) then @@ -149,7 +166,7 @@ end ]], {1,2,1,2,1,3}) test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) - +--]=] print'+' -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:35 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:33 ` Sergey Kaplun via Tarantool-patches 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:35 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Follow-up ticket ? LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > FIXME: LuaJIT interprets a return from a new function loaded by > `loadstring()` with a change line number for bytecode position > unlike Lua does. This looks like "implementation-defined behaviour" > mentioned in https://luajit.org/status.html. > > All tests checked the debug hook for a new line of code are affected > and disabled by this patch. > > Relates to tarantool/tarantool#5693 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++- > 1 file changed, 18 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index 9d2c86f..a8c7196 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -95,6 +95,23 @@ repeat > assert(g(f) == 'a') > until 1 > > +-- FIXME: LuaJIT interprets a return from calling result of > +-- `loadstring()` with a new line number unlike Lua does. > +-- Here is an example (it is joined in one line intend): > +--[[ > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook() > +--]] > +-- This chunk prints for LuaJIT: > +--[[ > +LINE: 3 > +LINE: 1 > +--]] > +-- But for Lua 5.1 it is only "LINE: 3" in the output. > +-- See also https://github.com/tarantool/tarantool/issues/5693. > +-- Considering implementation-defined behaviour diference > +-- (see also https://luajit.org/status.html) test is disabled for > +-- LuaJIT. > +--[=[ > test([[if > math.sin(1) > then > @@ -149,7 +166,7 @@ end > ]], {1,2,1,2,1,3}) > > test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > - > +--]=] > > > print'+' > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-03-26 11:35 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:33 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:33 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi! Thanks for the review! On 26.03.21, Sergey Ostanevich wrote: > Follow-up ticket ? It is mentioned by this line (IIUYC): | Relates to tarantool/tarantool#5693 > > LGTM. > Sergos > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > FIXME: LuaJIT interprets a return from a new function loaded by > > `loadstring()` with a change line number for bytecode position > > unlike Lua does. This looks like "implementation-defined behaviour" > > mentioned in https://luajit.org/status.html. > > > > All tests checked the debug hook for a new line of code are affected > > and disabled by this patch. > > > > Relates to tarantool/tarantool#5693 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index 9d2c86f..a8c7196 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -95,6 +95,23 @@ repeat > > assert(g(f) == 'a') > > until 1 > > > > +-- FIXME: LuaJIT interprets a return from calling result of > > +-- `loadstring()` with a new line number unlike Lua does. > > +-- Here is an example (it is joined in one line intend): > > +--[[ > > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook() > > +--]] > > +-- This chunk prints for LuaJIT: > > +--[[ > > +LINE: 3 > > +LINE: 1 > > +--]] > > +-- But for Lua 5.1 it is only "LINE: 3" in the output. > > +-- See also https://github.com/tarantool/tarantool/issues/5693. > > +-- Considering implementation-defined behaviour diference > > +-- (see also https://luajit.org/status.html) test is disabled for > > +-- LuaJIT. > > +--[=[ > > test([[if > > math.sin(1) > > then > > @@ -149,7 +166,7 @@ end > > ]], {1,2,1,2,1,3}) > > > > test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > > - > > +--]=] > > > > > > print'+' > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches 2021-03-26 11:35 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches 2021-04-01 10:06 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 22:59 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! Please consider the comments below. On 26.03.21, Sergey Kaplun wrote: > FIXME: LuaJIT interprets a return from a new function loaded by Typo: FIXME is excess here (looks like the comment copy-paste). > `loadstring()` with a change line number for bytecode position > unlike Lua does. This looks like "implementation-defined behaviour" Sorry, I can't understand what is written here, though I understand that there is a difference between Lua and LuaJIT behaviour and the example below. Could you please clarify the sentence above? > mentioned in https://luajit.org/status.html. > > All tests checked the debug hook for a new line of code are affected Typo: s/tests checked/tests checking/. > and disabled by this patch. > > Relates to tarantool/tarantool#5693 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++- > 1 file changed, 18 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index 9d2c86f..a8c7196 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -95,6 +95,23 @@ repeat > assert(g(f) == 'a') > until 1 > > +-- FIXME: LuaJIT interprets a return from calling result of > +-- `loadstring()` with a new line number unlike Lua does. Meh, I also failed to understand the wording here... > +-- Here is an example (it is joined in one line intend): > +--[[ > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook() > +--]] > +-- This chunk prints for LuaJIT: > +--[[ > +LINE: 3 > +LINE: 1 > +--]] > +-- But for Lua 5.1 it is only "LINE: 3" in the output. > +-- See also https://github.com/tarantool/tarantool/issues/5693. > +-- Considering implementation-defined behaviour diference Typo: s/diference/difference/. > +-- (see also https://luajit.org/status.html) test is disabled for > +-- LuaJIT. > +--[=[ > test([[if > math.sin(1) > then > @@ -149,7 +166,7 @@ end > ]], {1,2,1,2,1,3}) > > test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > - > +--]=] > > > print'+' > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-03-31 22:59 ` Igor Munkin via Tarantool-patches @ 2021-04-01 10:06 ` Sergey Kaplun via Tarantool-patches 2021-04-06 19:45 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:06 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 01.04.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! Please consider the comments below. > > On 26.03.21, Sergey Kaplun wrote: > > FIXME: LuaJIT interprets a return from a new function loaded by > > Typo: FIXME is excess here (looks like the comment copy-paste). Fixed. > > > `loadstring()` with a change line number for bytecode position > > unlike Lua does. This looks like "implementation-defined behaviour" > > Sorry, I can't understand what is written here, though I understand that > there is a difference between Lua and LuaJIT behaviour and the example > below. Could you please clarify the sentence above? =================================================================== test: disable Lua suite tests for line hook The LuaJIT's virtual machine interprets the bytecode following the return from function (i.e. the one succeeding the call made) and located on the line other than that return bytecode, as a new line trigger for line hooks, unlike Lua does. This looks like "implementation-defined behaviour" mentioned in https://luajit.org/status.html. All tests checking the debug hook for a new line of code are affected and disabled by this patch. Relates to tarantool/tarantool#5693 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== > > > mentioned in https://luajit.org/status.html. > > > > All tests checked the debug hook for a new line of code are affected > > Typo: s/tests checked/tests checking/. Fixed. > > > and disabled by this patch. > > > > Relates to tarantool/tarantool#5693 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index 9d2c86f..a8c7196 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -95,6 +95,23 @@ repeat > > assert(g(f) == 'a') > > until 1 > > > > +-- FIXME: LuaJIT interprets a return from calling result of > > +-- `loadstring()` with a new line number unlike Lua does. > > Meh, I also failed to understand the wording here... Reformulated as: =================================================================== -- FIXME: The LuaJIT's virtual machine interprets the bytecode -- following the return from function (i.e. the one succeeding -- the call made) and located on the line other than that return -- bytecode, as a new line trigger for line hooks, -- unlike Lua does. =================================================================== > > > +-- Here is an example (it is joined in one line intend): > > +--[[ > > +debug.sethook(function(_, l) print("LINE: "..l) end, "l") loadstring("\n\ns=nil")() debug.sethook() > > +--]] > > +-- This chunk prints for LuaJIT: > > +--[[ > > +LINE: 3 > > +LINE: 1 > > +--]] > > +-- But for Lua 5.1 it is only "LINE: 3" in the output. > > +-- See also https://github.com/tarantool/tarantool/issues/5693. > > +-- Considering implementation-defined behaviour diference > > Typo: s/diference/difference/. Fixed, thanks! > > > +-- (see also https://luajit.org/status.html) test is disabled for > > +-- LuaJIT. > > +--[=[ > > test([[if > > math.sin(1) > > then > > @@ -149,7 +166,7 @@ end > > ]], {1,2,1,2,1,3}) > > > > test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) > > - > > +--]=] > > > > > > print'+' > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook 2021-04-01 10:06 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 19:45 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 19:45 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the fixes! LGTM now. -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (8 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 09/30] test: disable Lua suite tests for line hook Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches ` (21 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1262 bytes --] LuaJIT: Lua 5.1 interprets `...` in the vararg functions like an additional first argument unlike LuaJIT does. This behaviour is extension is from Lua 5.2. This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. The test is adapted like it done in Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Closes tarantool/tarantool#5694 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index a8c7196..e5d8885 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines function g(...) + -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like + -- an additional first argument unlike LuaJIT does. + -- This extension is from Lua 5.2. + -- See also https://github.com/tarantool/tarantool/issues/5694. + -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding + -- additional variable `arg`. + local arg = {...} do local a,b,c; a=math.sin(40); end local feijao local AAAA,B = "xuxu", "mamão" -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:45 ` Sergey Kaplun via Tarantool-patches 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:44 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM, minor update to message Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > an additional first argument unlike LuaJIT does. ^^^^^^^^^^^ means local? So, that getlocal() later in g() works as expected? > This behaviour is extension is from Lua 5.2. > > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. > The test is adapted like it done in Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5694 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index a8c7196..e5d8885 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines > > > function g(...) > + -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > + -- an additional first argument unlike LuaJIT does. > + -- This extension is from Lua 5.2. > + -- See also https://github.com/tarantool/tarantool/issues/5694. > + -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding > + -- additional variable `arg`. > + local arg = {...} > do local a,b,c; a=math.sin(40); end > local feijao > local AAAA,B = "xuxu", "mam�o" > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite 2021-03-26 11:44 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:45 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:45 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi, thanks for the review! On 26.03.21, Sergey Ostanevich wrote: > LGTM, minor update to message > > Sergos > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > > an additional first argument unlike LuaJIT does. > ^^^^^^^^^^^ means local? > So, that getlocal() later in g() works as expected? Yes, local is correct. Update commit message and the comment, branch is force-pushed. See the iterative patch below. The new commit message is: =================================================================== test: adapt test for debug.setlocal in Lua suite LuaJIT: Lua 5.1 interprets `...` in the vararg functions like an additional local argument unlike LuaJIT does. This behaviour is extension is from Lua 5.2. This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. The test is adapted like it done in Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Part of tarantool/tarantool#5694 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== =================================================================== diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index e5d8885..6535594 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -222,7 +222,7 @@ assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines function g(...) -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like - -- an additional first argument unlike LuaJIT does. + -- an additional local argument unlike LuaJIT does. -- This extension is from Lua 5.2. -- See also https://github.com/tarantool/tarantool/issues/5694. -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding =================================================================== > > > This behaviour is extension is from Lua 5.2. > > > > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. > > The test is adapted like it done in Lua 5.2 test suite taken from > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Closes tarantool/tarantool#5694 Part of is more correct here. > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 7 +++++++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index a8c7196..e5d8885 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -221,6 +221,13 @@ assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines > > > > > > function g(...) > > + -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > > + -- an additional first argument unlike LuaJIT does. > > + -- This extension is from Lua 5.2. > > + -- See also https://github.com/tarantool/tarantool/issues/5694. > > + -- Test is adapted from PUC-Rio Lua 5.2 test suite by adding > > + -- additional variable `arg`. > > + local arg = {...} > > do local a,b,c; a=math.sin(40); end > > local feijao > > local AAAA,B = "xuxu", "mam�o" > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 11:44 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches 2021-04-01 10:16 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:14 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, considering your changes on the branch. Also consider the comments below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like Looks like you just copied the comment below. There is no need for 'LuaJIT:' here. > an additional first argument unlike LuaJIT does. > This behaviour is extension is from Lua 5.2. Typo: s/is extension is/is extension/. > > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. Side note: Here it is -- you wrote LuaJIT's but Lua 5.2 (neither Lua's 5.2 nor Lua 5.2's). How come? > The test is adapted like it done in Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5694 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite 2021-03-30 22:14 ` Igor Munkin via Tarantool-patches @ 2021-04-01 10:16 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 10:16 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, considering your changes on the branch. Also > consider the comments below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > > Looks like you just copied the comment below. There is no need for > 'LuaJIT:' here. > > > an additional first argument unlike LuaJIT does. > > This behaviour is extension is from Lua 5.2. > > Typo: s/is extension is/is extension/. > > > > > This patch adapted test considering LuaJIT's and Lua 5.2 behaviour. > > Side note: Here it is -- you wrote LuaJIT's but Lua 5.2 (neither Lua's > 5.2 nor Lua 5.2's). How come? > > > The test is adapted like it done in Lua 5.2 test suite taken from > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Closes tarantool/tarantool#5694 > > As we discussed before: s/Closes/Resolves/. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- The new version of the commit message: =================================================================== test: adapt test for debug.setlocal in Lua suite Lua 5.1 interprets `...` in the vararg functions like an additional local argument unlike LuaJIT does. This behaviour is extension from Lua 5.2. This patch adapted test considering behaviour of LuaJIT and Lua 5.2. The test is adapted like it done in Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Part of tarantool/tarantool#5694 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (9 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 10/30] test: adapt test for debug.setlocal in Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:47 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches ` (20 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches Lua 5.1 interprets `...` in the vararg functions like an additional first argument unlike LuaJIT does. So, `a:f()` function will not set corresponding table `arg`, as test expects. Implicit `arg` parameter for old-style vararg functions was finally removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite by removing additional check for amountt of arguments via `arg.n`. Lua 5.2 test suite is taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index e5d8885..6985c29 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -300,7 +300,16 @@ debug.sethook(function (e) end, "c") a:f(1,2,3,4,5) -assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) + +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like +-- an additional first argument unlike LuaJIT does. +-- So, `a:f()` function will not set corresponding table `arg`, +-- as test expects. +-- Implicit `arg` parameter for old-style vararg functions was +-- finally removed in Lua 5.2 +-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing +-- additional `arg.n == 3` check. +assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil) assert(XX == 12) assert(debug.gethook() == nil) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:47 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 14:52 ` Sergey Kaplun via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:47 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > Lua 5.1 interprets `...` in the vararg functions like an additional > first argument unlike LuaJIT does. So, `a:f()` function will not set > corresponding table `arg`, as test expects. > > Implicit `arg` parameter for old-style vararg functions was finally > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite > by removing additional check for amountt of arguments via `arg.n`. > Lua 5.2 test suite is taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index e5d8885..6985c29 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -300,7 +300,16 @@ debug.sethook(function (e) > end, "c") > > a:f(1,2,3,4,5) > -assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) > + > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > +-- an additional first argument unlike LuaJIT does. > +-- So, `a:f()` function will not set corresponding table `arg`, > +-- as test expects. > +-- Implicit `arg` parameter for old-style vararg functions was > +-- finally removed in Lua 5.2 > +-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing > +-- additional `arg.n == 3` check. > +assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil) > assert(XX == 12) > assert(debug.gethook() == nil) > > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-03-26 11:47 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:52 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:52 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi, thanks for the review! I've changed s/first/local/ in the commit message and the comment, considering your comment for the previous patch. Also, I've added link to the issue to close. =================================================================== test: adapt getlocal PUC test for vararg func Lua 5.1 interprets `...` in the vararg functions like an additional local argument unlike LuaJIT does. So, `a:f()` function will not set corresponding table `arg`, as test expects. Implicit `arg` parameter for old-style vararg functions was finally removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite by removing additional check for amountt of arguments via `arg.n`. Lua 5.2 test suite is taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Closes tarantool/tarantool#5694 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== =================================================================== diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index 8ea6af7..69e19b6 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -302,7 +302,7 @@ end, "c") a:f(1,2,3,4,5) -- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like --- an additional first argument unlike LuaJIT does. +-- an additional local argument unlike LuaJIT does. -- So, `a:f()` function will not set corresponding table `arg`, -- as test expects. -- Implicit `arg` parameter for old-style vararg functions was =================================================================== On 26.03.21, Sergey Ostanevich wrote: > LGTM > > Sergos > > > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > Lua 5.1 interprets `...` in the vararg functions like an additional > > first argument unlike LuaJIT does. So, `a:f()` function will not set > > corresponding table `arg`, as test expects. > > > > Implicit `arg` parameter for old-style vararg functions was finally > > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite > > by removing additional check for amountt of arguments via `arg.n`. > > Lua 5.2 test suite is taken from > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++- > > 1 file changed, 10 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index e5d8885..6985c29 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -300,7 +300,16 @@ debug.sethook(function (e) > > end, "c") > > > > a:f(1,2,3,4,5) > > -assert(X.self == a and X.a == 1 and X.b == 2 and X.arg.n == 3 and X.c == nil) > > + > > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > > +-- an additional first argument unlike LuaJIT does. > > +-- So, `a:f()` function will not set corresponding table `arg`, > > +-- as test expects. > > +-- Implicit `arg` parameter for old-style vararg functions was > > +-- finally removed in Lua 5.2 > > +-- The test is adapted from PUC-Rio Lua 5.2 test suite by removing > > +-- additional `arg.n == 3` check. > > +assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil) > > assert(XX == 12) > > assert(debug.gethook() == nil) > > > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches 2021-03-26 11:47 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:37 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! I can't understand why this patch is separated from the previous one. Could you provide a rationale for this, please? BTW as we discussed before: s/Closes/Resolves/, considering your changes on the branch. Also consider the comments below. On 26.03.21, Sergey Kaplun wrote: > Lua 5.1 interprets `...` in the vararg functions like an additional Typo: s/like/as/. > first argument unlike LuaJIT does. So, `a:f()` function will not set > corresponding table `arg`, as test expects. Typo: s/set corresponding table `arg`/set the corresponding `arg` table/. > > Implicit `arg` parameter for old-style vararg functions was finally > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite > by removing additional check for amountt of arguments via `arg.n`. Typo: s/amountt/amount/. > Lua 5.2 test suite is taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index e5d8885..6985c29 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -300,7 +300,16 @@ debug.sethook(function (e) <snipped> > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like Typo: s/like/as/. > +-- an additional first argument unlike LuaJIT does. > +-- So, `a:f()` function will not set corresponding table `arg`, Typo: s/set corresponding table `arg`/set the corresponding `arg` table/. > +-- as test expects. <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches @ 2021-04-01 11:37 ` Sergey Kaplun via Tarantool-patches 2021-04-06 20:09 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:37 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! I can't understand why this patch is separated > from the previous one. Could you provide a rationale for this, please? > BTW as we discussed before: s/Closes/Resolves/, considering your changes > on the branch. Also consider the comments below. The root reason of the previous patch is about counting of local variable in caller. Here this local variable is used for counting arguments amount. > > On 26.03.21, Sergey Kaplun wrote: > > Lua 5.1 interprets `...` in the vararg functions like an additional > > Typo: s/like/as/. Fixed. > > > first argument unlike LuaJIT does. So, `a:f()` function will not set > > corresponding table `arg`, as test expects. > > Typo: s/set corresponding table `arg`/set the corresponding `arg` table/. Fixed. > > > > > Implicit `arg` parameter for old-style vararg functions was finally > > removed in Lua 5.2. The test is adapted from PUC-Rio Lua 5.2 test suite > > by removing additional check for amountt of arguments via `arg.n`. > > Typo: s/amountt/amount/. Fixed. > > > Lua 5.2 test suite is taken from > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 11 ++++++++++- > > 1 file changed, 10 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index e5d8885..6985c29 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -300,7 +300,16 @@ debug.sethook(function (e) > > <snipped> > > > +-- LuaJIT: Lua 5.1 interprets `...` in the vararg functions like > > Typo: s/like/as/. Fixed. > > > +-- an additional first argument unlike LuaJIT does. > > +-- So, `a:f()` function will not set corresponding table `arg`, > > Typo: s/set corresponding table `arg`/set the corresponding `arg` table/. Fixed. > > > +-- as test expects. > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-04-01 11:37 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 20:09 ` Igor Munkin via Tarantool-patches 2021-04-06 20:40 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:09 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 01.04.21, Sergey Kaplun wrote: > Igor, > > Thanks for the review! > > On 31.03.21, Igor Munkin wrote: > > Sergey, > > > > Thanks for the patch! I can't understand why this patch is separated > > from the previous one. Could you provide a rationale for this, please? > > BTW as we discussed before: s/Closes/Resolves/, considering your changes > > on the branch. Also consider the comments below. > > The root reason of the previous patch is about counting of local > variable in caller. Here this local variable is used for counting > arguments amount. OK, now I get it. Let's then squash 11 and 16 patches, since they solves the one problem and leave 10 as is, since it fixes a different one. BTW, I'm even fine if you leave everything as is. So, here is my LGTM and feel free to adjust these patches on your own. > <snipped> > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func 2021-04-06 20:09 ` Igor Munkin via Tarantool-patches @ 2021-04-06 20:40 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:40 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches On 06.04.21, Igor Munkin wrote: > Sergey, > > On 01.04.21, Sergey Kaplun wrote: > > Igor, > > > > Thanks for the review! > > > > On 31.03.21, Igor Munkin wrote: > > > Sergey, > > > > > > Thanks for the patch! I can't understand why this patch is separated > > > from the previous one. Could you provide a rationale for this, please? > > > BTW as we discussed before: s/Closes/Resolves/, considering your changes > > > on the branch. Also consider the comments below. > > > > The root reason of the previous patch is about counting of local > > variable in caller. Here this local variable is used for counting > > arguments amount. > > OK, now I get it. Let's then squash 11 and 16 patches, since they solves It's a typo: s/16/20/ while reading please. > the one problem and leave 10 as is, since it fixes a different one. BTW, > I'm even fine if you leave everything as is. So, here is my LGTM and > feel free to adjust these patches on your own. > > > > > <snipped> > > > > > -- > > Best regards, > > Sergey Kaplun > > -- > Best regards, > IM -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (10 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 11/30] test: adapt getlocal PUC test for vararg func Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 11:49 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches ` (19 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT does not check hooks at traces without defined -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c> or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). This patch adapts these tests for LuaJIT by disabling JIT while testing count hooks. Closes tarantool/tarantool#5701 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index 6985c29..c1a635a 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -347,6 +347,18 @@ assert(debug.setupvalue(io.read, 1, 10) == nil) -- testing count hooks local a=0 +-- LuaJIT: LuaJIT does not check hooks at traces without defined +-- -DLUAJIT_ENABLE_CHECKHOOK. +-- For more information see <src/lj_record.c> or commit +-- 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time +-- option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). +-- See also https://github.com/tarantool/tarantool/issues/5701 +-- Test is adapted for LuaJIT by disabling JIT while +-- testing count hooks. +local jit_is_enabled = jit.status() +if jit_is_enabled then + jit.off() +end debug.sethook(function (e) a=a+1 end, "", 1) a=0; for i=1,1000 do end; assert(1000 < a and a < 1012) debug.sethook(function (e) a=a+1 end, "", 4) @@ -359,6 +371,9 @@ debug.sethook(print, "", 2^24 - 1) -- count upperbound local f,m,c = debug.gethook() assert(({debug.gethook()})[3] == 2^24 - 1) debug.sethook() +if jit_is_enabled then + jit.on() +end -- tests for tail calls -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches @ 2021-03-26 11:49 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 11:49 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT does not check hooks at traces without defined > -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c> > or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time > option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). > > This patch adapts these tests for LuaJIT by disabling JIT while testing > count hooks. > > Closes tarantool/tarantool#5701 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index 6985c29..c1a635a 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -347,6 +347,18 @@ assert(debug.setupvalue(io.read, 1, 10) == nil) > > -- testing count hooks > local a=0 > +-- LuaJIT: LuaJIT does not check hooks at traces without defined > +-- -DLUAJIT_ENABLE_CHECKHOOK. > +-- For more information see <src/lj_record.c> or commit > +-- 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time > +-- option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). > +-- See also https://github.com/tarantool/tarantool/issues/5701 > +-- Test is adapted for LuaJIT by disabling JIT while > +-- testing count hooks. > +local jit_is_enabled = jit.status() > +if jit_is_enabled then > + jit.off() > +end > debug.sethook(function (e) a=a+1 end, "", 1) > a=0; for i=1,1000 do end; assert(1000 < a and a < 1012) > debug.sethook(function (e) a=a+1 end, "", 4) > @@ -359,6 +371,9 @@ debug.sethook(print, "", 2^24 - 1) -- count upperbound > local f,m,c = debug.gethook() > assert(({debug.gethook()})[3] == 2^24 - 1) > debug.sethook() > +if jit_is_enabled then > + jit.on() > +end > > > -- tests for tail calls > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches 2021-03-26 11:49 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:42 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the single nit below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT does not check hooks at traces without defined > -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c> > or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time > option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). > > This patch adapts these tests for LuaJIT by disabling JIT while testing > count hooks. > > Closes tarantool/tarantool#5701 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches @ 2021-04-01 11:42 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:42 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the single nit below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT does not check hooks at traces without defined > > -DLUAJIT_ENABLE_CHECKHOOK. For more information see <src/lj_record.c> > > or commit 6bce6b118eeb2bb7f36157de158e5cccf0ea68e5 (Add compile-time > > option LUAJIT_ENABLE_CHECKHOOK. Disabled by default.). > > > > This patch adapts these tests for LuaJIT by disabling JIT while testing > > count hooks. > > > > Closes tarantool/tarantool#5701 > > As we discussed before: s/Closes/Resolves/. Fixed. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (11 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 12/30] test: adapt PUC Lua test with count hooks Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:43 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches ` (18 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT does not provide information about tail calls in debug.getinfo(), unlike Lua does. This missed feature is described in https://luajit.org/status.html. This patch disables tests for tail call checks and getfenv() checks, because tail calls do not provide an additional level for LuaJIT and level number given to getfenv() should be changed. Relates to tarantool/tarantool#5702 Relates to tarantool/tarantool#5703 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index c1a635a..b363abc 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -400,19 +400,29 @@ function g1(x) g(x) end local function h (x) local f=g1; return f(x) end -h(true) +-- LuaJIT does not provide information about tail calls, +-- unlike Lua does. See also https://luajit.org/status.html. +-- getfenv() behaviour is also different here, +-- because tail calls do not provide additional level for LuaJIT +-- and level number should be changed. +-- FIXME: Test is disabled for LuaJIT. +-- See also https://github.com/tarantool/tarantool/issues/5702. +-- h(true) local b = {} -debug.sethook(function (e) table.insert(b, e) end, "cr") -h(false) -debug.sethook() +-- Behavior is different for LuaJIT. See the comment above. +-- FIXME: Test is disabled for LuaJIT. +-- debug.sethook(function (e) table.insert(b, e) end, "cr") +-- h(false) +-- debug.sethook() local res = {"return", -- first return (from sethook) "call", "call", "call", "call", "return", "tail return", "return", "tail return", "call", -- last call (to sethook) } -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end - +-- Behavior is different for LuaJIT. See the comment above. +-- FIXME: Test is disabled for LuaJIT. +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end lim = 30000 local function foo (x) @@ -423,7 +433,9 @@ local function foo (x) end end -foo(lim) +-- Behavior is different for LuaJIT. See the comment above. +-- FIXME: Test is disabled for LuaJIT. +-- foo(lim) print"+" @@ -459,7 +471,9 @@ end local co = coroutine.create(f) coroutine.resume(co, 3) -checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) +-- Behavior is different for LuaJIT. See the comment to h() above. +-- FIXME: Test is disabled for LuaJIT. +-- checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) co = coroutine.create(function (x) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:43 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:43 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT does not provide information about tail calls in debug.getinfo(), > unlike Lua does. This missed feature is described in > https://luajit.org/status.html. > > This patch disables tests for tail call checks and getfenv() checks, > because tail calls do not provide an additional level for LuaJIT > and level number given to getfenv() should be changed. > > Relates to tarantool/tarantool#5702 > Relates to tarantool/tarantool#5703 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++-------- > 1 file changed, 22 insertions(+), 8 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index c1a635a..b363abc 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -400,19 +400,29 @@ function g1(x) g(x) end > > local function h (x) local f=g1; return f(x) end > > -h(true) > +-- LuaJIT does not provide information about tail calls, > +-- unlike Lua does. See also https://luajit.org/status.html. > +-- getfenv() behaviour is also different here, > +-- because tail calls do not provide additional level for LuaJIT > +-- and level number should be changed. > +-- FIXME: Test is disabled for LuaJIT. > +-- See also https://github.com/tarantool/tarantool/issues/5702. > +-- h(true) > > local b = {} > -debug.sethook(function (e) table.insert(b, e) end, "cr") > -h(false) > -debug.sethook() > +-- Behavior is different for LuaJIT. See the comment above. > +-- FIXME: Test is disabled for LuaJIT. > +-- debug.sethook(function (e) table.insert(b, e) end, "cr") > +-- h(false) > +-- debug.sethook() > local res = {"return", -- first return (from sethook) > "call", "call", "call", "call", > "return", "tail return", "return", "tail return", > "call", -- last call (to sethook) > } > -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > - > +-- Behavior is different for LuaJIT. See the comment above. > +-- FIXME: Test is disabled for LuaJIT. > +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > > lim = 30000 > local function foo (x) > @@ -423,7 +433,9 @@ local function foo (x) > end > end > > -foo(lim) > +-- Behavior is different for LuaJIT. See the comment above. > +-- FIXME: Test is disabled for LuaJIT. > +-- foo(lim) > > > print"+" > @@ -459,7 +471,9 @@ end > > local co = coroutine.create(f) > coroutine.resume(co, 3) > -checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) > +-- Behavior is different for LuaJIT. See the comment to h() above. > +-- FIXME: Test is disabled for LuaJIT. > +-- checktraceback(co, {"yield", "db.lua", "tail", "tail", "tail"}) > > > co = coroutine.create(function (x) > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches 2021-03-26 14:43 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:52 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT does not provide information about tail calls in debug.getinfo(), > unlike Lua does. This missed feature is described in > https://luajit.org/status.html. > > This patch disables tests for tail call checks and getfenv() checks, > because tail calls do not provide an additional level for LuaJIT It's not "level", but "call frame", AFAIU. > and level number given to getfenv() should be changed. > > Relates to tarantool/tarantool#5702 > Relates to tarantool/tarantool#5703 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++-------- > 1 file changed, 22 insertions(+), 8 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index c1a635a..b363abc 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -400,19 +400,29 @@ function g1(x) g(x) end > > local function h (x) local f=g1; return f(x) end > > -h(true) > +-- LuaJIT does not provide information about tail calls, > +-- unlike Lua does. See also https://luajit.org/status.html. > +-- getfenv() behaviour is also different here, Typo: looks like line underfull (in LaTeX terms, heh). > +-- because tail calls do not provide additional level for LuaJIT > +-- and level number should be changed. > +-- FIXME: Test is disabled for LuaJIT. > +-- See also https://github.com/tarantool/tarantool/issues/5702. > +-- h(true) <snipped> > -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > - Typo: excess whitespace change. > +-- Behavior is different for LuaJIT. See the comment above. > +-- FIXME: Test is disabled for LuaJIT. > +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches @ 2021-04-01 11:52 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:52 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT does not provide information about tail calls in debug.getinfo(), > > unlike Lua does. This missed feature is described in > > https://luajit.org/status.html. > > > > This patch disables tests for tail call checks and getfenv() checks, > > because tail calls do not provide an additional level for LuaJIT > > It's not "level", but "call frame", AFAIU. Fixed. > > > and level number given to getfenv() should be changed. > > > > Relates to tarantool/tarantool#5702 > > Relates to tarantool/tarantool#5703 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 30 ++++++++++++++++++++++-------- > > 1 file changed, 22 insertions(+), 8 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index c1a635a..b363abc 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -400,19 +400,29 @@ function g1(x) g(x) end > > > > local function h (x) local f=g1; return f(x) end > > > > -h(true) > > +-- LuaJIT does not provide information about tail calls, > > +-- unlike Lua does. See also https://luajit.org/status.html. > > +-- getfenv() behaviour is also different here, > > Typo: looks like line underfull (in LaTeX terms, heh). Fixed. > > > +-- because tail calls do not provide additional level for LuaJIT > > +-- and level number should be changed. > > +-- FIXME: Test is disabled for LuaJIT. > > +-- See also https://github.com/tarantool/tarantool/issues/5702. > > +-- h(true) > > <snipped> > > > -for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > > - > > Typo: excess whitespace change. Fixed. > > > +-- Behavior is different for LuaJIT. See the comment above. > > +-- FIXME: Test is disabled for LuaJIT. > > +-- for _, k in ipairs(res) do assert(k == table.remove(b, 1)) end > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (12 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 13/30] test: disable PUC Lua test for tail call info Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:50 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches ` (17 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT does not report line with single "end" statement (the last line of the function) as an active line in debug.getinfo(), unlike Lua does. There is no bytecode related to this line, so it is "unreachable" and may be considered not active. This patch excludes the last line of a function from the check, considering LuaJIT's behaviour. Closes tarantool/tarantool#5708 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index b363abc..c704877 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10) local x = debug.getinfo(co, 1, "lfLS") assert(x.currentline == l.currentline and x.activelines[x.currentline]) assert(type(x.func) == "function") -for i=x.linedefined + 1, x.lastlinedefined do +-- LuaJIT does not report line with single "end" statement +-- (the last line of the function) as an active line in +-- debug.getinfo(), unlike Lua does. There is no bytecode +-- related to this line, so it is "unreachable" and +-- may be considered not active. +-- See also https://github.com/tarantool/tarantool/issues/5708. +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding +-- the last line check. +for i=x.linedefined + 1, x.lastlinedefined - 1 do assert(x.activelines[i]) x.activelines[i] = nil end -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:50 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:50 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT does not report line with single "end" statement > (the last line of the function) as an active line in > debug.getinfo(), unlike Lua does. There is no bytecode > related to this line, so it is "unreachable” and > c be considered not active. > > This patch excludes the last line of a function from the check, > considering LuaJIT's behaviour. > > Closes tarantool/tarantool#5708 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index b363abc..c704877 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10) > local x = debug.getinfo(co, 1, "lfLS") > assert(x.currentline == l.currentline and x.activelines[x.currentline]) > assert(type(x.func) == "function") > -for i=x.linedefined + 1, x.lastlinedefined do > +-- LuaJIT does not report line with single "end" statement > +-- (the last line of the function) as an active line in > +-- debug.getinfo(), unlike Lua does. There is no bytecode > +-- related to this line, so it is "unreachable" and > +-- may be considered not active. > +-- See also https://github.com/tarantool/tarantool/issues/5708. > +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding > +-- the last line check. > +for i=x.linedefined + 1, x.lastlinedefined - 1 do > assert(x.activelines[i]) > x.activelines[i] = nil > end > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches 2021-03-26 14:50 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches 2021-04-01 11:58 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:15 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT does not report line with single "end" statement Typo: s/report line/report the line/. > (the last line of the function) as an active line in > debug.getinfo(), unlike Lua does. There is no bytecode > related to this line, so it is "unreachable" and > may be considered not active. > > This patch excludes the last line of a function from the check, Typo: s/a function/the function/. > considering LuaJIT's behaviour. > > Closes tarantool/tarantool#5708 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index b363abc..c704877 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10) > local x = debug.getinfo(co, 1, "lfLS") > assert(x.currentline == l.currentline and x.activelines[x.currentline]) > assert(type(x.func) == "function") > -for i=x.linedefined + 1, x.lastlinedefined do > +-- LuaJIT does not report line with single "end" statement Typo: s/report line/report the line/. > +-- (the last line of the function) as an active line in > +-- debug.getinfo(), unlike Lua does. There is no bytecode > +-- related to this line, so it is "unreachable" and > +-- may be considered not active. > +-- See also https://github.com/tarantool/tarantool/issues/5708. > +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding > +-- the last line check. > +for i=x.linedefined + 1, x.lastlinedefined - 1 do > assert(x.activelines[i]) > x.activelines[i] = nil > end > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test 2021-03-30 22:15 ` Igor Munkin via Tarantool-patches @ 2021-04-01 11:58 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 11:58 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT does not report line with single "end" statement > > Typo: s/report line/report the line/. Fixed. > > > (the last line of the function) as an active line in > > debug.getinfo(), unlike Lua does. There is no bytecode > > related to this line, so it is "unreachable" and > > may be considered not active. > > > > This patch excludes the last line of a function from the check, > > Typo: s/a function/the function/. Fixed. > > > considering LuaJIT's behaviour. > > > > Closes tarantool/tarantool#5708 > > As we discussed before: s/Closes/Resolves/. Fixed. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/db.lua | 10 +++++++++- > > 1 file changed, 9 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > > index b363abc..c704877 100644 > > --- a/test/PUC-Lua-5.1-tests/db.lua > > +++ b/test/PUC-Lua-5.1-tests/db.lua > > @@ -491,7 +491,15 @@ local _, l = coroutine.resume(co, 10) > > local x = debug.getinfo(co, 1, "lfLS") > > assert(x.currentline == l.currentline and x.activelines[x.currentline]) > > assert(type(x.func) == "function") > > -for i=x.linedefined + 1, x.lastlinedefined do > > +-- LuaJIT does not report line with single "end" statement > > Typo: s/report line/report the line/. Fixed. > > > +-- (the last line of the function) as an active line in > > +-- debug.getinfo(), unlike Lua does. There is no bytecode > > +-- related to this line, so it is "unreachable" and > > +-- may be considered not active. > > +-- See also https://github.com/tarantool/tarantool/issues/5708. > > +-- LuaJIT: Test is adapted for LuaJIT's behaviour by avoiding > > +-- the last line check. > > +for i=x.linedefined + 1, x.lastlinedefined - 1 do > > assert(x.activelines[i]) > > x.activelines[i] = nil > > end > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (13 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 14/30] test: adapt activeline check in the PUC Lua test Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches ` (16 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT does not support per-coroutine hooks. See actual status at https://luajit.org/status.html. This patch disables tests for per-coroutine hooks in <db.lua>. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua index c704877..8ea6af7 100644 --- a/test/PUC-Lua-5.1-tests/db.lua +++ b/test/PUC-Lua-5.1-tests/db.lua @@ -511,8 +511,11 @@ a,b = debug.getlocal(co, 1, 2) assert(a == "a" and b == 1) debug.setlocal(co, 1, 2, "hi") assert(debug.gethook(co) == foo) -assert(table.getn(tr) == 2 and - tr[1] == l.currentline-1 and tr[2] == l.currentline) +-- LuaJIT does not support per-coroutine hooks. +-- See also https://luajit.org/status.html. +-- LuaJIT: Test is disabled for LuaJIT. +-- assert(table.getn(tr) == 2 and +-- tr[1] == l.currentline-1 and tr[2] == l.currentline) a,b,c = pcall(coroutine.resume, co) assert(a and b and c == l.currentline+1) @@ -520,9 +523,13 @@ checktraceback(co, {"yield", "in function <"}) a,b = coroutine.resume(co) assert(a and b == "hi") -assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) +-- Behavior is different for LuaJIT. See the comment above. +-- LuaJIT: Test is disabled for LuaJIT. +-- assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) assert(debug.gethook(co) == foo) -assert(debug.gethook() == nil) +-- Behavior is different for LuaJIT. See the comment above. +-- LuaJIT: Test is disabled for LuaJIT. +-- assert(debug.gethook() == nil) checktraceback(co, {}) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:54 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:54 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT does not support per-coroutine hooks. > See actual status at https://luajit.org/status.html. > > This patch disables tests for per-coroutine hooks in <db.lua>. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/db.lua | 15 +++++++++++---- > 1 file changed, 11 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/db.lua b/test/PUC-Lua-5.1-tests/db.lua > index c704877..8ea6af7 100644 > --- a/test/PUC-Lua-5.1-tests/db.lua > +++ b/test/PUC-Lua-5.1-tests/db.lua > @@ -511,8 +511,11 @@ a,b = debug.getlocal(co, 1, 2) > assert(a == "a" and b == 1) > debug.setlocal(co, 1, 2, "hi") > assert(debug.gethook(co) == foo) > -assert(table.getn(tr) == 2 and > - tr[1] == l.currentline-1 and tr[2] == l.currentline) > +-- LuaJIT does not support per-coroutine hooks. > +-- See also https://luajit.org/status.html. > +-- LuaJIT: Test is disabled for LuaJIT. > +-- assert(table.getn(tr) == 2 and > +-- tr[1] == l.currentline-1 and tr[2] == l.currentline) > > a,b,c = pcall(coroutine.resume, co) > assert(a and b and c == l.currentline+1) > @@ -520,9 +523,13 @@ checktraceback(co, {"yield", "in function <"}) > > a,b = coroutine.resume(co) > assert(a and b == "hi") > -assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) > +-- Behavior is different for LuaJIT. See the comment above. > +-- LuaJIT: Test is disabled for LuaJIT. > +-- assert(table.getn(tr) == 4 and tr[4] == l.currentline+2) > assert(debug.gethook(co) == foo) > -assert(debug.gethook() == nil) > +-- Behavior is different for LuaJIT. See the comment above. > +-- LuaJIT: Test is disabled for LuaJIT. > +-- assert(debug.gethook() == nil) > checktraceback(co, {}) > > > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 12:03 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the one nit: I would explicitly mention that hook is set *but* for the whole VM instead of the given coroutine. Hence hooks work, but assertions are disabled. -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches @ 2021-04-01 12:03 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 12:03 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the one nit: I would explicitly > mention that hook is set *but* for the whole VM instead of the given > coroutine. Hence hooks work, but assertions are disabled. Added to the commit message and the comment in the code. > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (14 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 15/30] test: disable PUC-Lua test for per-coroutine hooks Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:56 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches ` (15 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:42 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1945 bytes --] LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: string.format(): %q reversible. See also https://luajit.org/extensions.html#lua52. In Lua 5.1 string.format() does not accept string values containing embedded zeros, except as arguments to the '%q' option. In Lua 5.2 '\0' is not handled differently from other control chars in string.format('%q', ...). See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d (string.format("%q", str) is now fully reversible (from Lua 5.2).). This patch adapts test for LuaJIT and Lua 5.2 behaviour considering test from Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Closes tarantool/tarantool#5710 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua index 237dbad..7c1dfb8 100644 --- a/test/PUC-Lua-5.1-tests/strings.lua +++ b/test/PUC-Lua-5.1-tests/strings.lua @@ -102,7 +102,17 @@ print('+') x = '"ílo"\n\\' assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\') -assert(string.format('%q', "\0") == [["\000"]]) +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: +-- string.format(): %q reversible. +-- In Lua 5.1 string.format() does not accept string values +-- containing embedded zeros, except as arguments to the q option. +-- In Lua 5.2 '\0' is not handled differently from other +-- control chars in string.format('%q', ...). +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d +-- (string.format("%q", str) is now fully reversible +-- (from Lua 5.2).). +-- Test is adapted from PUC-Rio Lua 5.2 test suite. +assert(string.format('%q', "\0") == [["\0"]]) assert(string.format("\0%c\0%c%x\0", string.byte("á"), string.byte("b"), 140) == "\0á\0b8c\0") assert(string.format('') == "") -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:56 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:56 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:42, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: > string.format(): %q reversible. > See also https://luajit.org/extensions.html#lua52. > > In Lua 5.1 string.format() does not accept string values containing > embedded zeros, except as arguments to the '%q' option. > In Lua 5.2 '\0' is not handled differently from other > control chars in string.format('%q', ...). > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > (string.format("%q", str) is now fully reversible > (from Lua 5.2).). > > This patch adapts test for LuaJIT and Lua 5.2 behaviour considering > test from Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5710 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > index 237dbad..7c1dfb8 100644 > --- a/test/PUC-Lua-5.1-tests/strings.lua > +++ b/test/PUC-Lua-5.1-tests/strings.lua > @@ -102,7 +102,17 @@ print('+') > > x = '"�lo"\n\\' > assert(string.format('%q%s', x, x) == '"\\"�lo\\"\\\n\\\\""�lo"\n\\') > -assert(string.format('%q', "\0") == [["\000"]]) > +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: > +-- string.format(): %q reversible. > +-- In Lua 5.1 string.format() does not accept string values > +-- containing embedded zeros, except as arguments to the q option. > +-- In Lua 5.2 '\0' is not handled differently from other > +-- control chars in string.format('%q', ...). > +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > +-- (string.format("%q", str) is now fully reversible > +-- (from Lua 5.2).). > +-- Test is adapted from PUC-Rio Lua 5.2 test suite. > +assert(string.format('%q', "\0") == [["\0"]]) > assert(string.format("\0%c\0%c%x\0", string.byte("�"), string.byte("b"), 140) == > "\0�\0b8c\0") > assert(string.format('') == "") > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches 2021-03-26 14:56 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 12:33 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for your patch! Please consider my comments below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: Looks like you just copied the comment below. There is no need for 'LuaJIT:' here. > string.format(): %q reversible. > See also https://luajit.org/extensions.html#lua52. > > In Lua 5.1 string.format() does not accept string values containing > embedded zeros, except as arguments to the '%q' option. > In Lua 5.2 '\0' is not handled differently from other > control chars in string.format('%q', ...). > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > (string.format("%q", str) is now fully reversible > (from Lua 5.2).). Well, I honestly don't understand what is changed in *semantics*. I've tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an interpreter being tested | <interp> -e 'print(string.format("%q", "\0"))' I understand the semantics of "%q", but was it just a bug in Lua 5.1? What does "fully reversible" mean in this context? I understand only the fact the behaviour differs and you reimplemented the test assertion according to Lua 5.2 testing suite. That's all. I found not a single word regarding this issue in Lua bugs[1] page, except invalid handling of \r[2]. Is there any issue/page with a more verbose explanation what has been changed in 7cc981c? > > This patch adapts test for LuaJIT and Lua 5.2 behaviour considering > test from Lua 5.2 test suite taken from Typo: s/considering test/considering the test/. > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5710 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > index 237dbad..7c1dfb8 100644 > --- a/test/PUC-Lua-5.1-tests/strings.lua > +++ b/test/PUC-Lua-5.1-tests/strings.lua > @@ -102,7 +102,17 @@ print('+') > > x = '"?lo"\n\\' > assert(string.format('%q%s', x, x) == '"\\"?lo\\"\\\n\\\\""?lo"\n\\') > -assert(string.format('%q', "\0") == [["\000"]]) > +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: > +-- string.format(): %q reversible. > +-- In Lua 5.1 string.format() does not accept string values > +-- containing embedded zeros, except as arguments to the q option. > +-- In Lua 5.2 '\0' is not handled differently from other > +-- control chars in string.format('%q', ...). > +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > +-- (string.format("%q", str) is now fully reversible > +-- (from Lua 5.2).). > +-- Test is adapted from PUC-Rio Lua 5.2 test suite. > +assert(string.format('%q', "\0") == [["\0"]]) > assert(string.format("\0%c\0%c%x\0", string.byte("?"), string.byte("b"), 140) == > "\0?\0b8c\0") > assert(string.format('') == "") > -- > 2.31.0 > [1]: https://www.lua.org/bugs.html#5.1 [2]: https://www.lua.org/bugs.html#5.1-4 -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches @ 2021-04-01 12:33 ` Sergey Kaplun via Tarantool-patches 2021-04-06 21:37 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 12:33 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for your patch! Please consider my comments below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: > > Looks like you just copied the comment below. There is no need for > 'LuaJIT:' here. Fixed. > > > string.format(): %q reversible. > > See also https://luajit.org/extensions.html#lua52. > > > > In Lua 5.1 string.format() does not accept string values containing > > embedded zeros, except as arguments to the '%q' option. > > In Lua 5.2 '\0' is not handled differently from other > > control chars in string.format('%q', ...). > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > (string.format("%q", str) is now fully reversible > > (from Lua 5.2).). > > Well, I honestly don't understand what is changed in *semantics*. I've > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > interpreter being tested > | <interp> -e 'print(string.format("%q", "\0"))' > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? A bug with the test for it??? > What does "fully reversible" mean in this context? > > I understand only the fact the behaviour differs and you reimplemented > the test assertion according to Lua 5.2 testing suite. That's all. > > I found not a single word regarding this issue in Lua bugs[1] page, > except invalid handling of \r[2]. Is there any issue/page with a more It looks unrelated to these changes. > verbose explanation what has been changed in 7cc981c? I just read these lines in Lua 5.1 reference manual :): | This function does not accept string values containing embedded | zeros, except as arguments to the q option. As for me, it is just new behaviour of Lua 5.2 -- patterns now accept '\0' as a reqular character (see 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a regular character) from Lua repository). So, according to commit 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' differently from other control chars in format '%q')) from Lua repository, this behaviour is excess. Also, it is mentioned here [2]. > > > > > This patch adapts test for LuaJIT and Lua 5.2 behaviour considering > > test from Lua 5.2 test suite taken from > > Typo: s/considering test/considering the test/. Fixed. > > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Closes tarantool/tarantool#5710 > > As we discussed before: s/Closes/Resolves/. Fixed. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/strings.lua | 12 +++++++++++- > > 1 file changed, 11 insertions(+), 1 deletion(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > > index 237dbad..7c1dfb8 100644 > > --- a/test/PUC-Lua-5.1-tests/strings.lua > > +++ b/test/PUC-Lua-5.1-tests/strings.lua > > @@ -102,7 +102,17 @@ print('+') > > > > x = '"?lo"\n\\' > > assert(string.format('%q%s', x, x) == '"\\"?lo\\"\\\n\\\\""?lo"\n\\') > > -assert(string.format('%q', "\0") == [["\000"]]) > > +-- LuaJIT: LuaJIT since v2.0.0-beta6 has extension from Lua 5.2: > > +-- string.format(): %q reversible. > > +-- In Lua 5.1 string.format() does not accept string values > > +-- containing embedded zeros, except as arguments to the q option. > > +-- In Lua 5.2 '\0' is not handled differently from other > > +-- control chars in string.format('%q', ...). > > +-- See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > +-- (string.format("%q", str) is now fully reversible > > +-- (from Lua 5.2).). > > +-- Test is adapted from PUC-Rio Lua 5.2 test suite. > > +assert(string.format('%q', "\0") == [["\0"]]) > > assert(string.format("\0%c\0%c%x\0", string.byte("?"), string.byte("b"), 140) == > > "\0?\0b8c\0") > > assert(string.format('') == "") > > -- > > 2.31.0 > > > > [1]: https://www.lua.org/bugs.html#5.1 > [2]: https://www.lua.org/bugs.html#5.1-4 > > -- > Best regards, > IM [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format [2]: https://www.lua.org/manual/5.2/manual.html#8.2 -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-04-01 12:33 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 21:37 ` Igor Munkin via Tarantool-patches 2021-04-07 15:50 ` Sergey Kaplun via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 21:37 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 01.04.21, Sergey Kaplun wrote: > Igor, > > Thanks for the review! > > On 31.03.21, Igor Munkin wrote: > > Sergey, > > <snipped> > > > > > string.format(): %q reversible. > > > See also https://luajit.org/extensions.html#lua52. > > > > > > In Lua 5.1 string.format() does not accept string values containing > > > embedded zeros, except as arguments to the '%q' option. > > > In Lua 5.2 '\0' is not handled differently from other > > > control chars in string.format('%q', ...). > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > > (string.format("%q", str) is now fully reversible > > > (from Lua 5.2).). > > > > Well, I honestly don't understand what is changed in *semantics*. I've > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > > interpreter being tested > > | <interp> -e 'print(string.format("%q", "\0"))' > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? > > A bug with the test for it??? Well, I can remind you the bug with <tonumber> we fixed the last year. There might be no test for it though, but all in all it has not been fixed in Lua 5.1. > > > What does "fully reversible" mean in this context? This question is left unaddressed. > > > > I understand only the fact the behaviour differs and you reimplemented > > the test assertion according to Lua 5.2 testing suite. That's all. > > > > I found not a single word regarding this issue in Lua bugs[1] page, > > except invalid handling of \r[2]. Is there any issue/page with a more > > It looks unrelated to these changes. > > > verbose explanation what has been changed in 7cc981c? > > I just read these lines in Lua 5.1 reference manual :): > | This function does not accept string values containing embedded > | zeros, except as arguments to the q option. So what? This means literally nothing to me... BTW, I can pass such string to the function and it can yield any bullshit the developer wanted to. That's why we decided to comment such places in a clear and verbose way, didn't we? > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept > '\0' as a reqular character (see > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a > regular character) from Lua repository). So, according to commit > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' > differently from other control chars in format '%q')) from Lua > repository, this behaviour is excess. > > Also, it is mentioned here [2]. I see nothing regarding this change there. > <snipped> > > > > [1]: https://www.lua.org/bugs.html#5.1 > > [2]: https://www.lua.org/bugs.html#5.1-4 > > > > -- > > Best regards, > > IM > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format > [2]: https://www.lua.org/manual/5.2/manual.html#8.2 > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-04-06 21:37 ` Igor Munkin via Tarantool-patches @ 2021-04-07 15:50 ` Sergey Kaplun via Tarantool-patches 2021-04-07 16:31 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-07 15:50 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, On 07.04.21, Igor Munkin wrote: > Sergey, > > On 01.04.21, Sergey Kaplun wrote: > > Igor, > > > > Thanks for the review! > > > > On 31.03.21, Igor Munkin wrote: > > > Sergey, > > > > > <snipped> > > > > > > > > string.format(): %q reversible. > > > > See also https://luajit.org/extensions.html#lua52. > > > > > > > > In Lua 5.1 string.format() does not accept string values containing > > > > embedded zeros, except as arguments to the '%q' option. > > > > In Lua 5.2 '\0' is not handled differently from other > > > > control chars in string.format('%q', ...). > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > > > (string.format("%q", str) is now fully reversible > > > > (from Lua 5.2).). > > > > > > Well, I honestly don't understand what is changed in *semantics*. I've > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > > > interpreter being tested > > > | <interp> -e 'print(string.format("%q", "\0"))' > > > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? > > > > A bug with the test for it??? > > Well, I can remind you the bug with <tonumber> we fixed the last year. > There might be no test for it though, but all in all it has not been > fixed in Lua 5.1. I mean that this behaviour is verificated by the test. When behaviour is changed the test is changed too. > > > > > > What does "fully reversible" mean in this context? > > This question is left unaddressed. I don't know what does Mike mean by these. > > > > > > > I understand only the fact the behaviour differs and you reimplemented > > > the test assertion according to Lua 5.2 testing suite. That's all. > > > > > > I found not a single word regarding this issue in Lua bugs[1] page, > > > except invalid handling of \r[2]. Is there any issue/page with a more > > > > It looks unrelated to these changes. > > > > > verbose explanation what has been changed in 7cc981c? > > > > I just read these lines in Lua 5.1 reference manual :): > > | This function does not accept string values containing embedded > > | zeros, except as arguments to the q option. > > So what? This means literally nothing to me... BTW, I can pass such > string to the function and it can yield any bullshit the developer > wanted to. That's why we decided to comment such places in a clear and > verbose way, didn't we? Don't get you point here. AFAIU it means that `%q` is the only one option that can contain embeded zeros, so it handles it in the special way. > > > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept > > '\0' as a reqular character (see > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a > > regular character) from Lua repository). So, according to commit > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' > > differently from other control chars in format '%q')) from Lua > > repository, this behaviour is excess. > > > > Also, it is mentioned here [2]. > > I see nothing regarding this change there. I am talking about this part: | Character class %z in patterns is deprecated, as now patterns may | contain '\0' as a regular character. > > > > > <snipped> > > > > > > > [1]: https://www.lua.org/bugs.html#5.1 > > > [2]: https://www.lua.org/bugs.html#5.1-4 > > > > > > -- > > > Best regards, > > > IM > > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2 > > > > -- > > Best regards, > > Sergey Kaplun > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-04-07 15:50 ` Sergey Kaplun via Tarantool-patches @ 2021-04-07 16:31 ` Igor Munkin via Tarantool-patches 2021-04-08 8:51 ` Sergey Kaplun via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-07 16:31 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 07.04.21, Sergey Kaplun wrote: > Igor, > <snipped> > > > > > string.format(): %q reversible. > > > > > See also https://luajit.org/extensions.html#lua52. > > > > > > > > > > In Lua 5.1 string.format() does not accept string values containing > > > > > embedded zeros, except as arguments to the '%q' option. > > > > > In Lua 5.2 '\0' is not handled differently from other > > > > > control chars in string.format('%q', ...). > > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > > > > (string.format("%q", str) is now fully reversible > > > > > (from Lua 5.2).). > > > > > > > > Well, I honestly don't understand what is changed in *semantics*. I've > > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > > > > interpreter being tested > > > > | <interp> -e 'print(string.format("%q", "\0"))' > > > > > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? > > > > > > A bug with the test for it??? > > > > Well, I can remind you the bug with <tonumber> we fixed the last year. > > There might be no test for it though, but all in all it has not been > > fixed in Lua 5.1. > > I mean that this behaviour is verificated by the test. When behaviour is > changed the test is changed too. > > > > > > > > > > What does "fully reversible" mean in this context? > > > > This question is left unaddressed. > > I don't know what does Mike mean by these. Then it would be great to describe the changes on your own. I can hardly split the comment into yours words and ones taked from Lua Reference manual or git log, but you are writing that "In Lua 5.2 '\0' is not handled differently from other control chars". Could you please clarify the difference you are talking about? Or provide the links describing it? May be some parts from PIL? > > > > > > > > > > > I understand only the fact the behaviour differs and you reimplemented > > > > the test assertion according to Lua 5.2 testing suite. That's all. > > > > > > > > I found not a single word regarding this issue in Lua bugs[1] page, > > > > except invalid handling of \r[2]. Is there any issue/page with a more > > > > > > It looks unrelated to these changes. > > > > > > > verbose explanation what has been changed in 7cc981c? > > > > > > I just read these lines in Lua 5.1 reference manual :): > > > | This function does not accept string values containing embedded > > > | zeros, except as arguments to the q option. > > > > So what? This means literally nothing to me... BTW, I can pass such > > string to the function and it can yield any bullshit the developer > > wanted to. That's why we decided to comment such places in a clear and > > verbose way, didn't we? > > Don't get you point here. AFAIU it means that `%q` is the only one > option that can contain embeded zeros, so it handles it in the special > way. My point relates to the fact, nobody except you can understand the comment near the change. Hence one need to make the similar investigation you made. Then what is the sense of commenting the changes in suite? > > > > > > > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept > > > '\0' as a reqular character (see > > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a > > > regular character) from Lua repository). So, according to commit > > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' > > > differently from other control chars in format '%q')) from Lua > > > repository, this behaviour is excess. > > > > > > Also, it is mentioned here [2]. > > > > I see nothing regarding this change there. > > I am talking about this part: > > | Character class %z in patterns is deprecated, as now patterns may > | contain '\0' as a regular character. Patterns, not options, right? > <snipped> > > > > [1]: https://www.lua.org/bugs.html#5.1 > > > > [2]: https://www.lua.org/bugs.html#5.1-4 > > > > > > > > -- > > > > Best regards, > > > > IM > > > > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format > > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2 <snipped> > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-04-07 16:31 ` Igor Munkin via Tarantool-patches @ 2021-04-08 8:51 ` Sergey Kaplun via Tarantool-patches 2021-04-12 10:26 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-08 8:51 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, On 07.04.21, Igor Munkin wrote: > Sergey, > > On 07.04.21, Sergey Kaplun wrote: > > Igor, > > > > <snipped> > > > > > > > string.format(): %q reversible. > > > > > > See also https://luajit.org/extensions.html#lua52. > > > > > > > > > > > > In Lua 5.1 string.format() does not accept string values containing > > > > > > embedded zeros, except as arguments to the '%q' option. > > > > > > In Lua 5.2 '\0' is not handled differently from other > > > > > > control chars in string.format('%q', ...). > > > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > > > > > (string.format("%q", str) is now fully reversible > > > > > > (from Lua 5.2).). > > > > > > > > > > Well, I honestly don't understand what is changed in *semantics*. I've > > > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > > > > > interpreter being tested > > > > > | <interp> -e 'print(string.format("%q", "\0"))' > > > > > > > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? > > > > > > > > A bug with the test for it??? > > > > > > Well, I can remind you the bug with <tonumber> we fixed the last year. > > > There might be no test for it though, but all in all it has not been > > > fixed in Lua 5.1. > > > > I mean that this behaviour is verificated by the test. When behaviour is > > changed the test is changed too. > > > > > > > > > > > > > > What does "fully reversible" mean in this context? > > > > > > This question is left unaddressed. > > > > I don't know what does Mike mean by these. > > Then it would be great to describe the changes on your own. I can hardly > split the comment into yours words and ones taked from Lua Reference > manual or git log, but you are writing that "In Lua 5.2 '\0' is not > handled differently from other control chars". Could you please clarify > the difference you are talking about? Or provide the links describing > it? May be some parts from PIL? > > > > > > > > > > > > > > > > I understand only the fact the behaviour differs and you reimplemented > > > > > the test assertion according to Lua 5.2 testing suite. That's all. > > > > > > > > > > I found not a single word regarding this issue in Lua bugs[1] page, > > > > > except invalid handling of \r[2]. Is there any issue/page with a more > > > > > > > > It looks unrelated to these changes. > > > > > > > > > verbose explanation what has been changed in 7cc981c? > > > > > > > > I just read these lines in Lua 5.1 reference manual :): > > > > | This function does not accept string values containing embedded > > > > | zeros, except as arguments to the q option. > > > > > > So what? This means literally nothing to me... BTW, I can pass such > > > string to the function and it can yield any bullshit the developer > > > wanted to. That's why we decided to comment such places in a clear and > > > verbose way, didn't we? > > > > Don't get you point here. AFAIU it means that `%q` is the only one > > option that can contain embeded zeros, so it handles it in the special > > way. > > My point relates to the fact, nobody except you can understand the > comment near the change. Hence one need to make the similar > investigation you made. Then what is the sense of commenting the changes > in suite? > > > > > > > > > > > > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept > > > > '\0' as a reqular character (see > > > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a > > > > regular character) from Lua repository). So, according to commit > > > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' > > > > differently from other control chars in format '%q')) from Lua > > > > repository, this behaviour is excess. > > > > > > > > Also, it is mentioned here [2]. > > > > > > I see nothing regarding this change there. > > > > I am talking about this part: > > > > | Character class %z in patterns is deprecated, as now patterns may > > | contain '\0' as a regular character. > > Patterns, not options, right? > > > > > <snipped> I haven't found no more verbose descriptions about %q specifier neither in the PIL, nor in the Lua Reference Manual, nor in the Lua mailing list, nor in the LuaJIT mailing list. So, I am appealing to the commits in the Lua repository. Going back to the definition of specifier %q from Lua 5.1 Reference manual: | The q option formats a string in a form suitable to be safely read | back by the Lua interpreter: ... Answering your previous question -- "reversible" means (in my understanding now) that `string.format("% q", binary)` should return the same-looking `binary` string that was presented to the interpreter and `string.format()` first (perhaps, it can expand control characters like '\r', '\n', and turn symbol "\65" into "A"). This is why I was referencing zero-bytes in patterns (unfortunately, wrongly). Historically, in Lua 5.2, control characters are written as \nnn when needed, see d62a21b9d379a576bae7426c80039ca1a4d2bb07 ("when formatting with '%q', all control characters are coded as \nnn.") [1]. In this patch, %q specifier starts writing control characters to a new string in the same way through \n, instead of their binary representation as it is. If the control character is followed by a digit, then for the correct work of the parser, it is necessary to extend the escape sequence to 3 significant characters (otherwise, the transition "\0002" -> "\02" corrupts string). For this patch, the expansion is performed unconditionally (the check for the next symbol is not performed) if this first symbol is a zero byte. You may notice that the additional check for '\0' is unnecessary - if after it comes a digit, then a branch with expanding the format to 3 significant characters will be selected. Consistent work with the zero byte processing was added in the commit 658ea8752b979102627e2fede7b7ddfbb67ba6c9 ("no need to handle '\0' differently from other control chars in format '%q'") [2]. Note that this patch does not change the semantics of %q specifier - the new string can still be "safely read back by the Lua interpreter". As we know, in Lua 5.1, '\0' was converted to "\000" unconditionally. This was partly done to avoid unnecessary logic, as I suppose, since before the d62a21b commit, all other characters were transmitted as-is in the new string, and there was no inconsistency. Is it worth mentioning the first commit clarifying the cause of the inconsistency, because it does not directly relate to changes? The initial comment, in my opinion, reflects the reason for the failing test -- '\0' began to be processed in the same way as other controlled characters in Lua 5.2. LuaJIT has adopted this practice in a related commit. The curious reader can independently search the commit history for these changes. Please let me know, if you think these clarifications are necessary to describe the problem. > > > > > > [1]: https://www.lua.org/bugs.html#5.1 > > > > > [2]: https://www.lua.org/bugs.html#5.1-4 > > > > > > > > > > -- > > > > > Best regards, > > > > > IM > > > > > > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format > > > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2 > > <snipped> > > > > > -- > > Best regards, > > Sergey Kaplun > > -- > Best regards, > IM [1]: https://github.com/lua/lua/commit/d62a21b9d379a576bae7426c80039ca1a4d2bb07 [2]: https://github.com/lua/lua/commit/658ea8752b979102627e2fede7b7ddfbb67ba6c9 -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT 2021-04-08 8:51 ` Sergey Kaplun via Tarantool-patches @ 2021-04-12 10:26 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-12 10:26 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, On 08.04.21, Sergey Kaplun wrote: > Igor, > > On 07.04.21, Igor Munkin wrote: > > Sergey, > > > > On 07.04.21, Sergey Kaplun wrote: > > > Igor, > > > > > > > <snipped> > > > > > > > > > string.format(): %q reversible. > > > > > > > See also https://luajit.org/extensions.html#lua52. > > > > > > > > > > > > > > In Lua 5.1 string.format() does not accept string values containing > > > > > > > embedded zeros, except as arguments to the '%q' option. > > > > > > > In Lua 5.2 '\0' is not handled differently from other > > > > > > > control chars in string.format('%q', ...). > > > > > > > See commit 7cc981c14067d4b0e774a6bfb0acfc2f5c911f0d > > > > > > > (string.format("%q", str) is now fully reversible > > > > > > > (from Lua 5.2).). > > > > > > > > > > > > Well, I honestly don't understand what is changed in *semantics*. I've > > > > > > tried the following command with Lua 5.2, Lua 5.1 and LuaJIT 2.0.5 as an > > > > > > interpreter being tested > > > > > > | <interp> -e 'print(string.format("%q", "\0"))' > > > > > > > > > > > > I understand the semantics of "%q", but was it just a bug in Lua 5.1? > > > > > > > > > > A bug with the test for it??? > > > > > > > > Well, I can remind you the bug with <tonumber> we fixed the last year. > > > > There might be no test for it though, but all in all it has not been > > > > fixed in Lua 5.1. > > > > > > I mean that this behaviour is verificated by the test. When behaviour is > > > changed the test is changed too. > > > > > > > > > > > > > > > > > > What does "fully reversible" mean in this context? > > > > > > > > This question is left unaddressed. > > > > > > I don't know what does Mike mean by these. > > > > Then it would be great to describe the changes on your own. I can hardly > > split the comment into yours words and ones taked from Lua Reference > > manual or git log, but you are writing that "In Lua 5.2 '\0' is not > > handled differently from other control chars". Could you please clarify > > the difference you are talking about? Or provide the links describing > > it? May be some parts from PIL? > > > > > > > > > > > > > > > > > > > > > I understand only the fact the behaviour differs and you reimplemented > > > > > > the test assertion according to Lua 5.2 testing suite. That's all. > > > > > > > > > > > > I found not a single word regarding this issue in Lua bugs[1] page, > > > > > > except invalid handling of \r[2]. Is there any issue/page with a more > > > > > > > > > > It looks unrelated to these changes. > > > > > > > > > > > verbose explanation what has been changed in 7cc981c? > > > > > > > > > > I just read these lines in Lua 5.1 reference manual :): > > > > > | This function does not accept string values containing embedded > > > > > | zeros, except as arguments to the q option. > > > > > > > > So what? This means literally nothing to me... BTW, I can pass such > > > > string to the function and it can yield any bullshit the developer > > > > wanted to. That's why we decided to comment such places in a clear and > > > > verbose way, didn't we? > > > > > > Don't get you point here. AFAIU it means that `%q` is the only one > > > option that can contain embeded zeros, so it handles it in the special > > > way. > > > > My point relates to the fact, nobody except you can understand the > > comment near the change. Hence one need to make the similar > > investigation you made. Then what is the sense of commenting the changes > > in suite? > > > > > > > > > > > > > > > > > > > As for me, it is just new behaviour of Lua 5.2 -- patterns now accept > > > > > '\0' as a reqular character (see > > > > > 4541243355a299a9b75042d207feb87295872c3a (patterns now accept '\0' as a > > > > > regular character) from Lua repository). So, according to commit > > > > > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 (no need to handle '\0' > > > > > differently from other control chars in format '%q')) from Lua > > > > > repository, this behaviour is excess. > > > > > > > > > > Also, it is mentioned here [2]. > > > > > > > > I see nothing regarding this change there. > > > > > > I am talking about this part: > > > > > > | Character class %z in patterns is deprecated, as now patterns may > > > | contain '\0' as a regular character. > > > > Patterns, not options, right? > > > > > > > > > <snipped> > > I haven't found no more verbose descriptions about %q specifier > neither in the PIL, nor in the Lua Reference Manual, nor in the Lua > mailing list, nor in the LuaJIT mailing list. > So, I am appealing to the commits in the Lua repository. > > Going back to the definition of specifier %q from Lua 5.1 Reference > manual: > | The q option formats a string in a form suitable to be safely read > | back by the Lua interpreter: ... > > Answering your previous question -- "reversible" means (in my > understanding now) that `string.format("% q", binary)` should return > the same-looking `binary` string that was presented to the > interpreter and `string.format()` first (perhaps, it can expand > control characters like '\r', '\n', and turn symbol "\65" into "A"). > This is why I was referencing zero-bytes in patterns (unfortunately, > wrongly). > > Historically, in Lua 5.2, control characters are written as \nnn > when needed, see d62a21b9d379a576bae7426c80039ca1a4d2bb07 ("when > formatting with '%q', all control characters are coded as \nnn.") [1]. > In this patch, %q specifier starts writing control characters > to a new string in the same way through \n, instead of their binary > representation as it is. If the control character is followed by a > digit, then for the correct work of the parser, it is necessary to > extend the escape sequence to 3 significant characters (otherwise, > the transition "\0002" -> "\02" corrupts string). > For this patch, the expansion is performed unconditionally (the check > for the next symbol is not performed) if this first symbol is a zero > byte. You may notice that the additional check for '\0' is > unnecessary - if after it comes a digit, then a branch with expanding > the format to 3 significant characters will be selected. Consistent > work with the zero byte processing was added in the commit > 658ea8752b979102627e2fede7b7ddfbb67ba6c9 ("no need to handle '\0' > differently from other control chars in format '%q'") [2]. Note that > this patch does not change the semantics of %q specifier - the new > string can still be "safely read back by the Lua interpreter". > > As we know, in Lua 5.1, '\0' was converted to "\000" unconditionally. > This was partly done to avoid unnecessary logic, as I suppose, since > before the d62a21b commit, all other characters were transmitted > as-is in the new string, and there was no inconsistency. > > Is it worth mentioning the first commit clarifying the cause of the > inconsistency, because it does not directly relate to changes? The > initial comment, in my opinion, reflects the reason for the failing > test -- '\0' began to be processed in the same way as other > controlled characters in Lua 5.2. LuaJIT has adopted this practice in > a related commit. The curious reader can independently search the > commit history for these changes. Please let me know, if you think > these clarifications are necessary to describe the problem. IMHO, it's worth mentioning everything above! Thanks for such deep digging and clarification: now I understand the original semantics and your change. It was totally unclear that Lua converts \0 to \000 considering it as an octet. Please enrich the comment with some parts above (honestly, you can put the whole explanation to the comment if you want), and after this change, the patch LGTM. Again, thanks a lot for your investigation! > > > > > > > > > [1]: https://www.lua.org/bugs.html#5.1 > > > > > > [2]: https://www.lua.org/bugs.html#5.1-4 > > > > > > > > > > > > -- > > > > > > Best regards, > > > > > > IM > > > > > > > > > > [1]: https://www.lua.org/manual/5.1/manual.html#pdf-string.format > > > > > [2]: https://www.lua.org/manual/5.2/manual.html#8.2 > > > > <snipped> > > > > > > > > -- > > > Best regards, > > > Sergey Kaplun > > > > -- > > Best regards, > > IM > > [1]: https://github.com/lua/lua/commit/d62a21b9d379a576bae7426c80039ca1a4d2bb07 > [2]: https://github.com/lua/lua/commit/658ea8752b979102627e2fede7b7ddfbb67ba6c9 > > -- > Best regards, > Sergey Kaplun -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (15 preceding siblings ...) 2021-03-26 7:42 ` [Tarantool-patches] [PATCH v2 luajit 16/30] test: adapt PUC Lua test for %q in fmt for LuaJIT Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:58 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches ` (14 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1932 bytes --] LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does. So locale-depended tests in <strings.lua> are disabled. Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing, unlike Lua does. See <src/lj_strscan.c> for more info. Locale-depended tests in <literals.lua> are disabled. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/literals.lua | 5 +++++ test/PUC-Lua-5.1-tests/strings.lua | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua index 01d84d5..1b4f664 100644 --- a/test/PUC-Lua-5.1-tests/literals.lua +++ b/test/PUC-Lua-5.1-tests/literals.lua @@ -158,6 +158,10 @@ end -- testing decimal point locale +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale, +-- unlike Lua does. See <src/lj_strscan.c> for more info. +-- Tests are disabled for LuaJIT. +--[[ if os.setlocale("pt_BR") or os.setlocale("ptb") then assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) assert(assert(loadstring("return 3.4"))() == 3.4) @@ -171,6 +175,7 @@ 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/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua index 7c1dfb8..6ae3f51 100644 --- a/test/PUC-Lua-5.1-tests/strings.lua +++ b/test/PUC-Lua-5.1-tests/strings.lua @@ -162,6 +162,10 @@ local function trylocale (w) return false end +-- LuaJIT: LuaJIT doesn't compare strings by `strcoll()`, +-- like Lua 5.1 does. +-- Tests are disabled for LuaJIT. +--[[ if not trylocale("collate") then print("locale not supported") else @@ -176,6 +180,7 @@ else assert(string.gsub("áÁéÉ", "%u", "x") == "áxéx") assert(string.upper"áÁé{xuxu}ção" == "ÁÁÉ{XUXU}ÇÃO") end +--]] os.setlocale("C") assert(os.setlocale() == 'C') -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:58 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 14:58 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does. > So locale-depended tests in <strings.lua> are disabled. > > Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing, > unlike Lua does. See <src/lj_strscan.c> for more info. > Locale-depended tests in <literals.lua> are disabled. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/literals.lua | 5 +++++ > test/PUC-Lua-5.1-tests/strings.lua | 5 +++++ > 2 files changed, 10 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua > index 01d84d5..1b4f664 100644 > --- a/test/PUC-Lua-5.1-tests/literals.lua > +++ b/test/PUC-Lua-5.1-tests/literals.lua > @@ -158,6 +158,10 @@ end > > > -- testing decimal point locale > +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale, > +-- unlike Lua does. See <src/lj_strscan.c> for more info. > +-- Tests are disabled for LuaJIT. > +--[[ > if os.setlocale("pt_BR") or os.setlocale("ptb") then > assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) > assert(assert(loadstring("return 3.4"))() == 3.4) > @@ -171,6 +175,7 @@ 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/strings.lua b/test/PUC-Lua-5.1-tests/strings.lua > index 7c1dfb8..6ae3f51 100644 > --- a/test/PUC-Lua-5.1-tests/strings.lua > +++ b/test/PUC-Lua-5.1-tests/strings.lua > @@ -162,6 +162,10 @@ local function trylocale (w) > return false > end > > +-- LuaJIT: LuaJIT doesn't compare strings by `strcoll()`, > +-- like Lua 5.1 does. > +-- Tests are disabled for LuaJIT. > +--[[ > if not trylocale("collate") then > print("locale not supported") > else > @@ -176,6 +180,7 @@ else > assert(string.gsub("����", "%u", "x") == "�x�x") > assert(string.upper"���{xuxu}��o" == "���{XUXU}��O") > end > +--]] > > os.setlocale("C") > assert(os.setlocale() == 'C') > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches 2021-03-26 14:58 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 19:12 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does. > So locale-depended tests in <strings.lua> are disabled. Side note: unfortunately, this is not mentioned anywhere except the sources... Classic. > > Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing, Typo: s/depended/dependent/. > unlike Lua does. See <src/lj_strscan.c> for more info. > Locale-depended tests in <literals.lua> are disabled. Minor: Please, refer the docs[1] or the patch[2] changing the behaviour in the commit message. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/literals.lua | 5 +++++ > test/PUC-Lua-5.1-tests/strings.lua | 5 +++++ > 2 files changed, 10 insertions(+) > > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua > index 01d84d5..1b4f664 100644 > --- a/test/PUC-Lua-5.1-tests/literals.lua > +++ b/test/PUC-Lua-5.1-tests/literals.lua > @@ -158,6 +158,10 @@ end > > > -- testing decimal point locale > +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale, Typo: s/depended/dependent/. > +-- unlike Lua does. See <src/lj_strscan.c> for more info. > +-- Tests are disabled for LuaJIT. > +--[[ > if os.setlocale("pt_BR") or os.setlocale("ptb") then > assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) > assert(assert(loadstring("return 3.4"))() == 3.4) <snipped> > -- > 2.31.0 > [1]: http://luajit.org/extensions.html#tonumber [2]: https://github.com/tarantool/luajit/commit/4c882fe -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches @ 2021-04-01 19:12 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 19:12 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT doesn't compare strings by `strcoll()`, like Lua 5.1 does. > > So locale-depended tests in <strings.lua> are disabled. > > Side note: unfortunately, this is not mentioned anywhere except the > sources... Classic. > > > > > Also, LuaJIT doesn't use `strtod()` depended on the locale for parsing, > > Typo: s/depended/dependent/. Fixed. > > > unlike Lua does. See <src/lj_strscan.c> for more info. > > Locale-depended tests in <literals.lua> are disabled. > > Minor: Please, refer the docs[1] or the patch[2] changing the behaviour > in the commit message. Refered docs. > > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/literals.lua | 5 +++++ > > test/PUC-Lua-5.1-tests/strings.lua | 5 +++++ > > 2 files changed, 10 insertions(+) > > > > diff --git a/test/PUC-Lua-5.1-tests/literals.lua b/test/PUC-Lua-5.1-tests/literals.lua > > index 01d84d5..1b4f664 100644 > > --- a/test/PUC-Lua-5.1-tests/literals.lua > > +++ b/test/PUC-Lua-5.1-tests/literals.lua > > @@ -158,6 +158,10 @@ end > > > > > > -- testing decimal point locale > > +-- LuaJIT: LuaJIT doesn't use `strtod()` depended on the locale, > > Typo: s/depended/dependent/. Fixed. > > > +-- unlike Lua does. See <src/lj_strscan.c> for more info. > > +-- Tests are disabled for LuaJIT. > > +--[[ > > if os.setlocale("pt_BR") or os.setlocale("ptb") then > > assert(tonumber("3,4") == 3.4 and tonumber"3.4" == nil) > > assert(assert(loadstring("return 3.4"))() == 3.4) > > <snipped> > > > -- > > 2.31.0 > > > > [1]: http://luajit.org/extensions.html#tonumber > [2]: https://github.com/tarantool/luajit/commit/4c882fe > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (16 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 17/30] test: disable locale-depended tests for Lua suite Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches ` (2 more replies) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches ` (13 subsequent siblings) 31 siblings, 3 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without flag `-DLUA_COMPAT_MOD`. LuaJIT has math.fmod() instead old-style math.mod() built-in. This patch replaces usage of math.mod with new-style math.fmod in the following files: * closure.lua * constructs.lua * math.lua * nextvar.lua Closes tarantool/tarantool#5711 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/closure.lua | 3 ++- test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++-- test/PUC-Lua-5.1-tests/math.lua | 3 ++- test/PUC-Lua-5.1-tests/nextvar.lua | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua index 27ca0ad..7f56ab8 100644 --- a/test/PUC-Lua-5.1-tests/closure.lua +++ b/test/PUC-Lua-5.1-tests/closure.lua @@ -254,7 +254,8 @@ function filter (p, g) while 1 do local n = g() if n == nil then return end - if math.mod(n, p) ~= 0 then coroutine.yield(n) end + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. + if math.fmod(n, p) ~= 0 then coroutine.yield(n) end end end) end diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua index 5fb3798..18d1789 100644 --- a/test/PUC-Lua-5.1-tests/constructs.lua +++ b/test/PUC-Lua-5.1-tests/constructs.lua @@ -202,7 +202,8 @@ function ID(x) return x end function f(t, i) local b = t.n - local res = math.mod(math.floor(i/c), b)+1 + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. + local res = math.fmod(math.floor(i/c), b)+1 c = c*b return t[res] end @@ -233,7 +234,8 @@ repeat ]], s1, s, s1, s, s1, s, s1, s, s) assert(loadstring(s))() assert(X and not NX and not WX1 == K and not WX2 == K) - if math.mod(i,4000) == 0 then print('+') end + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. + if math.fmod(i,4000) == 0 then print('+') end i = i+1 until i==c diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua index 5076f38..8f0526f 100644 --- a/test/PUC-Lua-5.1-tests/math.lua +++ b/test/PUC-Lua-5.1-tests/math.lua @@ -100,7 +100,8 @@ assert(math.abs(-10) == 10) assert(eq(math.atan2(1,0), math.pi/2)) assert(math.ceil(4.5) == 5.0) assert(math.floor(4.5) == 4.0) -assert(math.mod(10,3) == 1) +-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. +assert(math.fmod(10,3) == 1) assert(eq(math.sqrt(10)^2, 10)) assert(eq(math.log10(2), math.log(2)/math.log(10))) assert(eq(math.exp(0), 1)) diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua index 7ceaa75..81159dc 100644 --- a/test/PUC-Lua-5.1-tests/nextvar.lua +++ b/test/PUC-Lua-5.1-tests/nextvar.lua @@ -201,7 +201,8 @@ print('+') a = {} for i=0,10000 do - if math.mod(i,10) ~= 0 then + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. + if math.fmod(i,10) ~= 0 then a['x'..i] = i end end -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-03-26 15:16 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2 siblings, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:12 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’? Sergos. > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without > flag `-DLUA_COMPAT_MOD`. > LuaJIT has math.fmod() instead old-style math.mod() built-in. > > This patch replaces usage of math.mod with new-style math.fmod > in the following files: > * closure.lua > * constructs.lua > * math.lua > * nextvar.lua > > Closes tarantool/tarantool#5711 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/closure.lua | 3 ++- > test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++-- > test/PUC-Lua-5.1-tests/math.lua | 3 ++- > test/PUC-Lua-5.1-tests/nextvar.lua | 3 ++- > 4 files changed, 10 insertions(+), 5 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua > index 27ca0ad..7f56ab8 100644 > --- a/test/PUC-Lua-5.1-tests/closure.lua > +++ b/test/PUC-Lua-5.1-tests/closure.lua > @@ -254,7 +254,8 @@ function filter (p, g) > while 1 do > local n = g() > if n == nil then return end > - if math.mod(n, p) ~= 0 then coroutine.yield(n) end > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(n, p) ~= 0 then coroutine.yield(n) end > end > end) > end > diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua > index 5fb3798..18d1789 100644 > --- a/test/PUC-Lua-5.1-tests/constructs.lua > +++ b/test/PUC-Lua-5.1-tests/constructs.lua > @@ -202,7 +202,8 @@ function ID(x) return x end > > function f(t, i) > local b = t.n > - local res = math.mod(math.floor(i/c), b)+1 > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + local res = math.fmod(math.floor(i/c), b)+1 > c = c*b > return t[res] > end > @@ -233,7 +234,8 @@ repeat > ]], s1, s, s1, s, s1, s, s1, s, s) > assert(loadstring(s))() > assert(X and not NX and not WX1 == K and not WX2 == K) > - if math.mod(i,4000) == 0 then print('+') end > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(i,4000) == 0 then print('+') end > i = i+1 > until i==c > > diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua > index 5076f38..8f0526f 100644 > --- a/test/PUC-Lua-5.1-tests/math.lua > +++ b/test/PUC-Lua-5.1-tests/math.lua > @@ -100,7 +100,8 @@ assert(math.abs(-10) == 10) > assert(eq(math.atan2(1,0), math.pi/2)) > assert(math.ceil(4.5) == 5.0) > assert(math.floor(4.5) == 4.0) > -assert(math.mod(10,3) == 1) > +-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > +assert(math.fmod(10,3) == 1) > assert(eq(math.sqrt(10)^2, 10)) > assert(eq(math.log10(2), math.log(2)/math.log(10))) > assert(eq(math.exp(0), 1)) > diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua > index 7ceaa75..81159dc 100644 > --- a/test/PUC-Lua-5.1-tests/nextvar.lua > +++ b/test/PUC-Lua-5.1-tests/nextvar.lua > @@ -201,7 +201,8 @@ print('+') > > a = {} > for i=0,10000 do > - if math.mod(i,10) ~= 0 then > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(i,10) ~= 0 then > a['x'..i] = i > end > end > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:17 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Sergos, On 26.03.21, Sergey Ostanevich wrote: > Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’? No, it's not (IMHO): <math.mod> (as well as <string.gfind>) is completely removed in scope of this patch[1]. > > Sergos. > > <snipped> > [1]: https://github.com/tarantool/luajit/commit/de5568e -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:16 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2 siblings, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:16 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Hmmm. Is it better to mokeypatch it as ‘math.mod = math.fmod or math.mod’? Sergos. > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without > flag `-DLUA_COMPAT_MOD`. > LuaJIT has math.fmod() instead old-style math.mod() built-in. > > This patch replaces usage of math.mod with new-style math.fmod > in the following files: > * closure.lua > * constructs.lua > * math.lua > * nextvar.lua > > Closes tarantool/tarantool#5711 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/closure.lua | 3 ++- > test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++-- > test/PUC-Lua-5.1-tests/math.lua | 3 ++- > test/PUC-Lua-5.1-tests/nextvar.lua | 3 ++- > 4 files changed, 10 insertions(+), 5 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua > index 27ca0ad..7f56ab8 100644 > --- a/test/PUC-Lua-5.1-tests/closure.lua > +++ b/test/PUC-Lua-5.1-tests/closure.lua > @@ -254,7 +254,8 @@ function filter (p, g) > while 1 do > local n = g() > if n == nil then return end > - if math.mod(n, p) ~= 0 then coroutine.yield(n) end > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(n, p) ~= 0 then coroutine.yield(n) end > end > end) > end > diff --git a/test/PUC-Lua-5.1-tests/constructs.lua b/test/PUC-Lua-5.1-tests/constructs.lua > index 5fb3798..18d1789 100644 > --- a/test/PUC-Lua-5.1-tests/constructs.lua > +++ b/test/PUC-Lua-5.1-tests/constructs.lua > @@ -202,7 +202,8 @@ function ID(x) return x end > > function f(t, i) > local b = t.n > - local res = math.mod(math.floor(i/c), b)+1 > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + local res = math.fmod(math.floor(i/c), b)+1 > c = c*b > return t[res] > end > @@ -233,7 +234,8 @@ repeat > ]], s1, s, s1, s, s1, s, s1, s, s) > assert(loadstring(s))() > assert(X and not NX and not WX1 == K and not WX2 == K) > - if math.mod(i,4000) == 0 then print('+') end > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(i,4000) == 0 then print('+') end > i = i+1 > until i==c > > diff --git a/test/PUC-Lua-5.1-tests/math.lua b/test/PUC-Lua-5.1-tests/math.lua > index 5076f38..8f0526f 100644 > --- a/test/PUC-Lua-5.1-tests/math.lua > +++ b/test/PUC-Lua-5.1-tests/math.lua > @@ -100,7 +100,8 @@ assert(math.abs(-10) == 10) > assert(eq(math.atan2(1,0), math.pi/2)) > assert(math.ceil(4.5) == 5.0) > assert(math.floor(4.5) == 4.0) > -assert(math.mod(10,3) == 1) > +-- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > +assert(math.fmod(10,3) == 1) > assert(eq(math.sqrt(10)^2, 10)) > assert(eq(math.log10(2), math.log(2)/math.log(10))) > assert(eq(math.exp(0), 1)) > diff --git a/test/PUC-Lua-5.1-tests/nextvar.lua b/test/PUC-Lua-5.1-tests/nextvar.lua > index 7ceaa75..81159dc 100644 > --- a/test/PUC-Lua-5.1-tests/nextvar.lua > +++ b/test/PUC-Lua-5.1-tests/nextvar.lua > @@ -201,7 +201,8 @@ print('+') > > a = {} > for i=0,10000 do > - if math.mod(i,10) ~= 0 then > + -- LuaJIT: use `math.fmod()` instead old-style `math.mod()`. > + if math.fmod(i,10) ~= 0 then > a['x'..i] = i > end > end > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches 2021-03-26 15:12 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 15:16 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches 2021-04-01 19:36 ` Sergey Kaplun via Tarantool-patches 2 siblings, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:16 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. There is a typo in commit subject: s/replace math.mod to math.fmod/replace math.mod with math.fmod/. On 26.03.21, Sergey Kaplun wrote: > In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without Typo: s/if build Lua 5.1/if Lua 5.1 is built/ or s/if build Lua 5.1/if one build Lua 5.1/. > flag `-DLUA_COMPAT_MOD`. Typo: s/flag `-DLUA_COMPAT_MOD`/`-DLUA_COMPAT_MOD` flag/. > LuaJIT has math.fmod() instead old-style math.mod() built-in. Typo: s/instead old-style/instead of old-style/. You can also mention the commit[1] where this is done. > > This patch replaces usage of math.mod with new-style math.fmod > in the following files: > * closure.lua > * constructs.lua > * math.lua > * nextvar.lua > > Closes tarantool/tarantool#5711 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/closure.lua | 3 ++- > test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++-- > test/PUC-Lua-5.1-tests/math.lua | 3 ++- > test/PUC-Lua-5.1-tests/nextvar.lua | 3 ++- > 4 files changed, 10 insertions(+), 5 deletions(-) Typo: s/instead old-style/instead of old-style/g in all chunks. > <snipped> > -- > 2.31.0 > [1]: https://github.com/tarantool/luajit/commit/de5568e -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests 2021-03-30 22:16 ` Igor Munkin via Tarantool-patches @ 2021-04-01 19:36 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-01 19:36 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > There is a typo in commit subject: > s/replace math.mod to math.fmod/replace math.mod with math.fmod/. Fixed. > > On 26.03.21, Sergey Kaplun wrote: > > In Lua 5.1 math.mod() is renamed to math.fmod() if build Lua 5.1 without > > Typo: s/if build Lua 5.1/if Lua 5.1 is built/ or > s/if build Lua 5.1/if one build Lua 5.1/. Fixed. > > > flag `-DLUA_COMPAT_MOD`. > > Typo: s/flag `-DLUA_COMPAT_MOD`/`-DLUA_COMPAT_MOD` flag/. Fixed. > > > LuaJIT has math.fmod() instead old-style math.mod() built-in. > > Typo: s/instead old-style/instead of old-style/. Fixed. > > You can also mention the commit[1] where this is done. Done. > > > > > This patch replaces usage of math.mod with new-style math.fmod > > in the following files: > > * closure.lua > > * constructs.lua > > * math.lua > > * nextvar.lua > > > > Closes tarantool/tarantool#5711 > > As we discussed before: s/Closes/Resolves/. Fixed. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/closure.lua | 3 ++- > > test/PUC-Lua-5.1-tests/constructs.lua | 6 ++++-- > > test/PUC-Lua-5.1-tests/math.lua | 3 ++- > > test/PUC-Lua-5.1-tests/nextvar.lua | 3 ++- > > 4 files changed, 10 insertions(+), 5 deletions(-) > > Typo: s/instead old-style/instead of old-style/g in all chunks. Fixed. > > > > > <snipped> > > > -- > > 2.31.0 > > > > [1]: https://github.com/tarantool/luajit/commit/de5568e > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (17 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 18/30] test: replace math.mod to math.fmod for Lua tests Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:14 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches ` (12 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`. You can use it if Lua 5.1 is built with compile-time option `-DLUA_COMPAT_GFIND`. This built-in is removed from LuaJIT. This patch removes test checking that `string.gfind()` and `string.gmatch() is the same function. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/pm.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua index fa125dc..b159b6b 100644 --- a/test/PUC-Lua-5.1-tests/pm.lua +++ b/test/PUC-Lua-5.1-tests/pm.lua @@ -223,7 +223,6 @@ assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") -- tests for gmatch -assert(string.gfind == string.gmatch) local a = 0 for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end assert(a==6) -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:14 ` Sergey Ostanevich via Tarantool-patches 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:14 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`. > You can use it if Lua 5.1 is built with compile-time option > `-DLUA_COMPAT_GFIND`. > This built-in is removed from LuaJIT. > > This patch removes test checking that `string.gfind()` and > `string.gmatch() is the same function. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/pm.lua | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/pm.lua b/test/PUC-Lua-5.1-tests/pm.lua > index fa125dc..b159b6b 100644 > --- a/test/PUC-Lua-5.1-tests/pm.lua > +++ b/test/PUC-Lua-5.1-tests/pm.lua > @@ -223,7 +223,6 @@ assert(string.gsub("a alo b hi", "%w%w+", t) == "a ALO b HI") > > > -- tests for gmatch > -assert(string.gfind == string.gmatch) > local a = 0 > for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end > assert(a==6) > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches 2021-03-26 15:14 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches 2021-04-02 7:05 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-30 22:17 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the single nit. On 26.03.21, Sergey Kaplun wrote: > In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`. > You can use it if Lua 5.1 is built with compile-time option > `-DLUA_COMPAT_GFIND`. > This built-in is removed from LuaJIT. Please mention the patch[1] where this builtin is removed. > > This patch removes test checking that `string.gfind()` and > `string.gmatch() is the same function. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/pm.lua | 1 - > 1 file changed, 1 deletion(-) > <snipped> > -- > 2.31.0 > [1]: https://github.com/tarantool/luajit/commit/de5568e -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check 2021-03-30 22:17 ` Igor Munkin via Tarantool-patches @ 2021-04-02 7:05 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-02 7:05 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the single nit. > > On 26.03.21, Sergey Kaplun wrote: > > In Lua 5.1 function `string.gfind()` was renamed to `string.gmatch()`. > > You can use it if Lua 5.1 is built with compile-time option > > `-DLUA_COMPAT_GFIND`. > > This built-in is removed from LuaJIT. > > Please mention the patch[1] where this builtin is removed. Done. > > > > > This patch removes test checking that `string.gfind()` and > > `string.gmatch() is the same function. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/pm.lua | 1 - > > 1 file changed, 1 deletion(-) > > > > <snipped> > > > -- > > 2.31.0 > > > > [1]: https://github.com/tarantool/luajit/commit/de5568e > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (18 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 19/30] test: remove assert for string.gfind check Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Kaplun via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches ` (11 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches Lua 5.1 interprets ... in the vararg functions like additional first argument, unlike LuaJIT does. All extra arguments is set into `arg` variable. Implicit `arg` parameter for old-style vararg functions was finally removed in Lua 5.2. This patch adjust tests in vararg.lua considering Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Closes tarantool/tarantool#5712 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua index ae068fa..efb76c5 100644 --- a/test/PUC-Lua-5.1-tests/vararg.lua +++ b/test/PUC-Lua-5.1-tests/vararg.lua @@ -2,9 +2,13 @@ print('testing vararg') _G.arg = nil +-- Lua 5.1 interprets ... in the vararg functions like additional +-- first argument, unlike LuaJIT does. All extra arguments is set +-- into `arg` variable. This extension is from Lua 5.2. +-- See also https://github.com/tarantool/tarantool/issues/5712. +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. function f(a, ...) - assert(type(arg) == 'table') - assert(type(arg.n) == 'number') + local arg = {n = select('#', ...), ...} for i=1,arg.n do assert(a[i]==arg[i]) end return arg.n end @@ -17,7 +21,9 @@ function c12 (...) return res, 2 end -function vararg (...) return arg end +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. +-- See the comment above. +function vararg (...) return {n = select('#', ...), ...} end local call = function (f, args) return f(unpack(args, 1, args.n)) end @@ -42,7 +48,9 @@ a = call(print, {'+'}) assert(a == nil) local t = {1, 10} -function t:f (...) return self[arg[1]]+arg.n end +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. +-- See the comment above. +function t:f (...) local arg = {...}; return self[...]+#arg end assert(t:f(1,4) == 3 and t:f(2) == 11) print('+') -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:54 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:22 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 14:54 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches I've changed s/first/local/ in the commit message and the comment, considering comment by Sergos for the previous patch. =================================================================== test: adapt PUC Lua test for args in vararg func Lua 5.1 interprets ... in the vararg functions like additional local argument, unlike LuaJIT does. All extra arguments is set into `arg` variable. Implicit `arg` parameter for old-style vararg functions was finally removed in Lua 5.2. This patch adjust tests in vararg.lua considering Lua 5.2 test suite taken from https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. Closes tarantool/tarantool#5712 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== =================================================================== diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua index efb76c5..4d6ec6d 100644 --- a/test/PUC-Lua-5.1-tests/vararg.lua +++ b/test/PUC-Lua-5.1-tests/vararg.lua @@ -3,7 +3,7 @@ print('testing vararg') _G.arg = nil -- Lua 5.1 interprets ... in the vararg functions like additional --- first argument, unlike LuaJIT does. All extra arguments is set +-- local argument, unlike LuaJIT does. All extra arguments is set -- into `arg` variable. This extension is from Lua 5.2. -- See also https://github.com/tarantool/tarantool/issues/5712. -- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. =================================================================== On 26.03.21, Sergey Kaplun wrote: > Lua 5.1 interprets ... in the vararg functions like additional first > argument, unlike LuaJIT does. All extra arguments is set into `arg` > variable. > > Implicit `arg` parameter for old-style vararg functions was finally > removed in Lua 5.2. This patch adjust tests in vararg.lua considering > Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5712 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > index ae068fa..efb76c5 100644 > --- a/test/PUC-Lua-5.1-tests/vararg.lua > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > @@ -2,9 +2,13 @@ print('testing vararg') > > _G.arg = nil > > +-- Lua 5.1 interprets ... in the vararg functions like additional > +-- first argument, unlike LuaJIT does. All extra arguments is set > +-- into `arg` variable. This extension is from Lua 5.2. > +-- See also https://github.com/tarantool/tarantool/issues/5712. > +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. > function f(a, ...) > - assert(type(arg) == 'table') > - assert(type(arg.n) == 'number') > + local arg = {n = select('#', ...), ...} > for i=1,arg.n do assert(a[i]==arg[i]) end > return arg.n > end > @@ -17,7 +21,9 @@ function c12 (...) > return res, 2 > end > > -function vararg (...) return arg end > +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. > +-- See the comment above. > +function vararg (...) return {n = select('#', ...), ...} end > > local call = function (f, args) return f(unpack(args, 1, args.n)) end > > @@ -42,7 +48,9 @@ a = call(print, {'+'}) > assert(a == nil) > > local t = {1, 10} > -function t:f (...) return self[arg[1]]+arg.n end > +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. > +-- See the comment above. > +function t:f (...) local arg = {...}; return self[...]+#arg end > assert(t:f(1,4) == 3 and t:f(2) == 11) > print('+') > > -- > 2.31.0 > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-03-26 14:54 ` Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:22 ` Sergey Ostanevich via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:22 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 17:54, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > I've changed s/first/local/ in the commit message and the comment, > considering comment by Sergos for the previous patch. > > =================================================================== > test: adapt PUC Lua test for args in vararg func > > Lua 5.1 interprets ... in the vararg functions like additional local > argument, unlike LuaJIT does. All extra arguments is set into `arg` > variable. > > Implicit `arg` parameter for old-style vararg functions was finally > removed in Lua 5.2. This patch adjust tests in vararg.lua considering > Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5712 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > =================================================================== > > =================================================================== > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > index efb76c5..4d6ec6d 100644 > --- a/test/PUC-Lua-5.1-tests/vararg.lua > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > @@ -3,7 +3,7 @@ print('testing vararg') > _G.arg = nil > > -- Lua 5.1 interprets ... in the vararg functions like additional > --- first argument, unlike LuaJIT does. All extra arguments is set > +-- local argument, unlike LuaJIT does. All extra arguments is set > -- into `arg` variable. This extension is from Lua 5.2. > -- See also https://github.com/tarantool/tarantool/issues/5712. > -- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. > =================================================================== > > > On 26.03.21, Sergey Kaplun wrote: >> Lua 5.1 interprets ... in the vararg functions like additional first >> argument, unlike LuaJIT does. All extra arguments is set into `arg` >> variable. >> >> Implicit `arg` parameter for old-style vararg functions was finally >> removed in Lua 5.2. This patch adjust tests in vararg.lua considering >> Lua 5.2 test suite taken from >> https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. >> >> Closes tarantool/tarantool#5712 >> Part of tarantool/tarantool#5845 >> Part of tarantool/tarantool#4473 >> --- >> test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++---- >> 1 file changed, 12 insertions(+), 4 deletions(-) >> >> diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua >> index ae068fa..efb76c5 100644 >> --- a/test/PUC-Lua-5.1-tests/vararg.lua >> +++ b/test/PUC-Lua-5.1-tests/vararg.lua >> @@ -2,9 +2,13 @@ print('testing vararg') >> >> _G.arg = nil >> >> +-- Lua 5.1 interprets ... in the vararg functions like additional >> +-- first argument, unlike LuaJIT does. All extra arguments is set >> +-- into `arg` variable. This extension is from Lua 5.2. >> +-- See also https://github.com/tarantool/tarantool/issues/5712. >> +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. >> function f(a, ...) >> - assert(type(arg) == 'table') >> - assert(type(arg.n) == 'number') >> + local arg = {n = select('#', ...), ...} >> for i=1,arg.n do assert(a[i]==arg[i]) end >> return arg.n >> end >> @@ -17,7 +21,9 @@ function c12 (...) >> return res, 2 >> end >> >> -function vararg (...) return arg end >> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. >> +-- See the comment above. >> +function vararg (...) return {n = select('#', ...), ...} end >> >> local call = function (f, args) return f(unpack(args, 1, args.n)) end >> >> @@ -42,7 +48,9 @@ a = call(print, {'+'}) >> assert(a == nil) >> >> local t = {1, 10} >> -function t:f (...) return self[arg[1]]+arg.n end >> +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. >> +-- See the comment above. >> +function t:f (...) local arg = {...}; return self[...]+#arg end >> assert(t:f(1,4) == 3 and t:f(2) == 11) >> print('+') >> >> -- >> 2.31.0 >> > > -- > Best regards, > Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches 2021-03-26 14:54 ` Sergey Kaplun via Tarantool-patches @ 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-04-02 7:21 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 9:51 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! I can't understand why this patch is separated from the previous two (10 and 11). Could you provide a rationale for this, please? Also consider the comments below. On 26.03.21, Sergey Kaplun wrote: > Lua 5.1 interprets ... in the vararg functions like additional first Typo: s/like additional/as an additional/. > argument, unlike LuaJIT does. All extra arguments is set into `arg` Typo: s/arguments is set/arguments are set/. > variable. > > Implicit `arg` parameter for old-style vararg functions was finally > removed in Lua 5.2. This patch adjust tests in vararg.lua considering Minor: Did LuaJIT always respect such behaviour? If no, please mention the commit where it has been changed. > Lua 5.2 test suite taken from > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > Closes tarantool/tarantool#5712 As we discussed before: s/Closes/Resolves/. > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > index ae068fa..efb76c5 100644 > --- a/test/PUC-Lua-5.1-tests/vararg.lua > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > @@ -2,9 +2,13 @@ print('testing vararg') > > _G.arg = nil > > +-- Lua 5.1 interprets ... in the vararg functions like additional Typo: s/like additional/as an additional/. > +-- first argument, unlike LuaJIT does. All extra arguments is set Typo: s/arguments is set/arguments are set/. > +-- into `arg` variable. This extension is from Lua 5.2. > +-- See also https://github.com/tarantool/tarantool/issues/5712. Side note: What is the difference between #5712 and #5694? They look like duplicates to me, and so provide another rationale for squashing all three patches into a single one. > +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. > function f(a, ...) > - assert(type(arg) == 'table') > - assert(type(arg.n) == 'number') > + local arg = {n = select('#', ...), ...} Why did you drop the assertions above? They are trivial (as many of others in this suite), but still check that everything is fine (e.g. that <select> yields a number). > for i=1,arg.n do assert(a[i]==arg[i]) end > return arg.n > end <snipped> > @@ -42,7 +48,9 @@ a = call(print, {'+'}) > assert(a == nil) > > local t = {1, 10} > -function t:f (...) return self[arg[1]]+arg.n end > +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. > +-- See the comment above. > +function t:f (...) local arg = {...}; return self[...]+#arg end Why didn't you create the same structure as elsewhere above? Why did you change <self> indexing? AFAIU, after creating the *right* <arg> variable everything should work with no other changes. > assert(t:f(1,4) == 3 and t:f(2) == 11) > print('+') > > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches @ 2021-04-02 7:21 ` Sergey Kaplun via Tarantool-patches 2021-04-06 20:45 ` Igor Munkin via Tarantool-patches 0 siblings, 1 reply; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-02 7:21 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! I can't understand why this patch is separated > from the previous two (10 and 11). Could you provide a rationale for > this, please? Also consider the comments below. Answered about difference with 10th here [1]. I'm totally OK to squash it with 11th. > > On 26.03.21, Sergey Kaplun wrote: > > Lua 5.1 interprets ... in the vararg functions like additional first > > Typo: s/like additional/as an additional/. Fixed. > > > argument, unlike LuaJIT does. All extra arguments is set into `arg` > > Typo: s/arguments is set/arguments are set/. Fixed. > > > variable. > > > > Implicit `arg` parameter for old-style vararg functions was finally > > removed in Lua 5.2. This patch adjust tests in vararg.lua considering > > Minor: Did LuaJIT always respect such behaviour? If no, please mention > the commit where it has been changed. Yes, at least since LuaJIT-2.0.0-beta1, AFAICS. | $ src/luajit -v -e 'local function f(...) print(arg) end f(1, 3, 4)' | LuaJIT 2.0.0-beta1 -- Copyright (C) 2005-2009 Mike Pall. http://luajit.org/ | nil > > > Lua 5.2 test suite taken from > > https://www.lua.org/tests/lua-5.2.0-tests.tar.gz. > > > > Closes tarantool/tarantool#5712 > > As we discussed before: s/Closes/Resolves/. Fixed. > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/vararg.lua | 16 ++++++++++++---- > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/vararg.lua b/test/PUC-Lua-5.1-tests/vararg.lua > > index ae068fa..efb76c5 100644 > > --- a/test/PUC-Lua-5.1-tests/vararg.lua > > +++ b/test/PUC-Lua-5.1-tests/vararg.lua > > @@ -2,9 +2,13 @@ print('testing vararg') > > > > _G.arg = nil > > > > +-- Lua 5.1 interprets ... in the vararg functions like additional > > Typo: s/like additional/as an additional/. Fixed. > > > +-- first argument, unlike LuaJIT does. All extra arguments is set > > Typo: s/arguments is set/arguments are set/. Fixed. > > > +-- into `arg` variable. This extension is from Lua 5.2. > > +-- See also https://github.com/tarantool/tarantool/issues/5712. > > Side note: What is the difference between #5712 and #5694? They look > like duplicates to me, and so provide another rationale for squashing > all three patches into a single one. Answered about difference with 10th here [1]. Different tickets was created to be able "to eat mamonth by parts" -- to fix later not all, but single patch. I'm totally OK to squash it with 11th. > > > +-- LuaJIT: Test is adapted from PUC-Rio Lua 5.2 test suite. > > function f(a, ...) > > - assert(type(arg) == 'table') > > - assert(type(arg.n) == 'number') > > + local arg = {n = select('#', ...), ...} > > Why did you drop the assertions above? They are trivial (as many of > others in this suite), but still check that everything is fine (e.g. > that <select> yields a number). Just following Lua 5.2 test suite behaviour. Side note: we do not test that select returns number here, and the first assert is totally redundant. > > > for i=1,arg.n do assert(a[i]==arg[i]) end > > return arg.n > > end > > <snipped> > > > @@ -42,7 +48,9 @@ a = call(print, {'+'}) > > assert(a == nil) > > > > local t = {1, 10} > > -function t:f (...) return self[arg[1]]+arg.n end > > +-- LuaJIT: Test chunk is adapted from PUC-Rio Lua 5.2 test suite. > > +-- See the comment above. > > +function t:f (...) local arg = {...}; return self[...]+#arg end > > Why didn't you create the same structure as elsewhere above? Why did you > change <self> indexing? AFAIU, after creating the *right* <arg> variable > everything should work with no other changes. Just following Lua 5.2 test suite behaviour. Your solution is good too. > > > assert(t:f(1,4) == 3 and t:f(2) == 11) > > print('+') > > > > -- > > 2.31.0 > > > > -- > Best regards, > IM [1]: https://lists.tarantool.org/pipermail/tarantool-patches/2021-April/023220.html -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func 2021-04-02 7:21 ` Sergey Kaplun via Tarantool-patches @ 2021-04-06 20:45 ` Igor Munkin via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-04-06 20:45 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the changes and clarification! LGTM now. -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (19 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 20/30] test: adapt PUC Lua test for args in vararg func Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:41 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches ` (10 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT doesn't take into account tail calls for call-level counting, so getfenv() behaviour is different from Lua 5.1 in tail calls. This patch disables test for the return result of tail call getfenv(). Default value (equals 1) of getfenv() function's argument (function level) is invalid for this tail call -- LuaJIT can't provide necessary debug information for the frame. Relates to tarantool/tarantool#5713 Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua index 7f56ab8..7af842f 100644 --- a/test/PUC-Lua-5.1-tests/closure.lua +++ b/test/PUC-Lua-5.1-tests/closure.lua @@ -174,7 +174,14 @@ f = coroutine.wrap(foo) local a = {} assert(f(a) == _G) local a,b = pcall(f) -assert(a and b == _G) +-- LuaJIT doesn't take into account tail calls for call-level +-- counting, so getfenv() behaviour is different in tail calls. +-- For example, this `pcall()` returns false, because getfenv() +-- default level is 1 which is invalid for this case when +-- is called from tail call (lj_debug_frame() returns NULL). +-- See also https://github.com/tarantool/tarantool/issues/5713. +-- FIXME: Test is disabled for LuaJIT for now. +-- assert(a and b == _G) -- tests for multiple yield/resume arguments -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:41 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:41 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT doesn't take into account tail calls for call-level counting, so > getfenv() behaviour is different from Lua 5.1 in tail calls. > > This patch disables test for the return result of tail call getfenv(). > Default value (equals 1) of getfenv() function's argument (function > level) is invalid for this tail call -- LuaJIT can't provide necessary > debug information for the frame. > > Relates to tarantool/tarantool#5713 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/test/PUC-Lua-5.1-tests/closure.lua b/test/PUC-Lua-5.1-tests/closure.lua > index 7f56ab8..7af842f 100644 > --- a/test/PUC-Lua-5.1-tests/closure.lua > +++ b/test/PUC-Lua-5.1-tests/closure.lua > @@ -174,7 +174,14 @@ f = coroutine.wrap(foo) > local a = {} > assert(f(a) == _G) > local a,b = pcall(f) > -assert(a and b == _G) > +-- LuaJIT doesn't take into account tail calls for call-level > +-- counting, so getfenv() behaviour is different in tail calls. > +-- For example, this `pcall()` returns false, because getfenv() > +-- default level is 1 which is invalid for this case when > +-- is called from tail call (lj_debug_frame() returns NULL). > +-- See also https://github.com/tarantool/tarantool/issues/5713. > +-- FIXME: Test is disabled for LuaJIT for now. > +-- assert(a and b == _G) > > > -- tests for multiple yield/resume arguments > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches 2021-03-26 15:41 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches 2021-04-02 7:40 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 9:51 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the comments related to the wording. On 26.03.21, Sergey Kaplun wrote: > LuaJIT doesn't take into account tail calls for call-level counting, so Minor: This is a good example, when the passive voice makes the sense clearer. Consider the following: | Tail calls are not taken into account for call-level counting. Otherwise it seems like LuaJIT doesn't take into account *tail calls for call-level counting* (i.e. tail calls that are not used for call-level counting are taken into). Or simply try to use another preposition. > getfenv() behaviour is different from Lua 5.1 in tail calls. Minor: You use both "tailcall" and "tail call" within this commit. Please choose one and use it everywhere. > > This patch disables test for the return result of tail call getfenv(). Typo: s/tail call getfenv()/getfenv() tail call/. > Default value (equals 1) of getfenv() function's argument (function Typo: s/equals 1/equals to 1/. > level) is invalid for this tail call -- LuaJIT can't provide necessary > debug information for the frame. Minor: I would explicitly mention, that there is no a separate frame for tail call. LuaJIT simply uses the existing one created for the caller. > > Relates to tarantool/tarantool#5713 > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > <snipped> > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall 2021-03-31 9:51 ` Igor Munkin via Tarantool-patches @ 2021-04-02 7:40 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-02 7:40 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the comments related to the wording. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT doesn't take into account tail calls for call-level counting, so > > Minor: This is a good example, when the passive voice makes the sense > clearer. Consider the following: > | Tail calls are not taken into account for call-level counting. > > Otherwise it seems like LuaJIT doesn't take into account *tail calls for > call-level counting* (i.e. tail calls that are not used for call-level > counting are taken into). Or simply try to use another preposition. Yes, see it. Thanks! Fixed. > > > getfenv() behaviour is different from Lua 5.1 in tail calls. > > Minor: You use both "tailcall" and "tail call" within this commit. > Please choose one and use it everywhere. Fixed. > > > > > This patch disables test for the return result of tail call getfenv(). > > Typo: s/tail call getfenv()/getfenv() tail call/. Fixed. > > > Default value (equals 1) of getfenv() function's argument (function > > Typo: s/equals 1/equals to 1/. Fixed. > > > level) is invalid for this tail call -- LuaJIT can't provide necessary > > debug information for the frame. > > Minor: I would explicitly mention, that there is no a separate frame for > tail call. LuaJIT simply uses the existing one created for the caller. Fixed. > > > > > Relates to tarantool/tarantool#5713 > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/closure.lua | 9 ++++++++- > > 1 file changed, 8 insertions(+), 1 deletion(-) > > > > <snipped> > > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (20 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 21/30] test: disable test for getfenv in closure tailcall Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches ` (9 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT includes variable name to the error report, when try to call non-function object without __call methamethod. Also, LuaJIT includes variable name to the error report, when try to perform unacceptable arifmetic operation with the variable. Lua 5.1 doesn't report variable name in these errors. Test ckecked that variable name aren't reported are disabled by this patch. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua index e881211..cf24e40 100644 --- a/test/PUC-Lua-5.1-tests/errors.lua +++ b/test/PUC-Lua-5.1-tests/errors.lua @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") checkmessage("aaa={}; x=3/aaa", "global 'aaa'") checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") checkmessage("aaa={}; x=-aaa", "global 'aaa'") -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) +-- LuaJIT: LuaJIT includes variable name to the error report. +-- It looks like: +-- "attempt to perform arithmetic on global 'aaa' (a table value)" +-- Lua 5.1 doesn't report variable name here. +-- Tests are disabled for LuaJIT. +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) checkmessage([[aaa=9 repeat until 3==3 -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:44 ` Sergey Ostanevich via Tarantool-patches 2021-03-26 16:01 ` Sergey Kaplun via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:44 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Nit in message, LGTM. Sergos > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT includes variable name to the error report, when try to > call non-function object without __call methamethod. > Also, LuaJIT includes variable name to the error report, when try to > perform unacceptable arifmetic operation with the variable. arithmetic > Lua 5.1 doesn't report variable name in these errors. > > Test ckecked that variable name aren't reported are disabled by > this patch. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > index e881211..cf24e40 100644 > --- a/test/PUC-Lua-5.1-tests/errors.lua > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > checkmessage("aaa={}; x=-aaa", "global 'aaa'") > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > +-- LuaJIT: LuaJIT includes variable name to the error report. > +-- It looks like: > +-- "attempt to perform arithmetic on global 'aaa' (a table value)" > +-- Lua 5.1 doesn't report variable name here. > +-- Tests are disabled for LuaJIT. > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > checkmessage([[aaa=9 > repeat until 3==3 > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error 2021-03-26 15:44 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-26 16:01 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 16:01 UTC (permalink / raw) To: Sergey Ostanevich; +Cc: tarantool-patches Hi! Thanks for the review! On 26.03.21, Sergey Ostanevich wrote: > Nit in message, LGTM. > Sergos > > > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > > > LuaJIT includes variable name to the error report, when try to > > call non-function object without __call methamethod. > > Also, LuaJIT includes variable name to the error report, when try to > > perform unacceptable arifmetic operation with the variable. > arithmetic Thanks! The new commit message is the following: =================================================================== test: disable PUC Lua test for var names in error LuaJIT includes a variable name to the error report, when try to call non-function object without __call methamethod. Also, LuaJIT includes a variable name to the error report, when try to perform unacceptable arithmetic operation with the variable. Lua 5.1 doesn't report variable name in these errors. The test checked that variable name aren't reported are disabled by this patch. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 =================================================================== > > Lua 5.1 doesn't report variable name in these errors. > > > > Test ckecked that variable name aren't reported are disabled by > > this patch. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++-- > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > > index e881211..cf24e40 100644 > > --- a/test/PUC-Lua-5.1-tests/errors.lua > > +++ b/test/PUC-Lua-5.1-tests/errors.lua > > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > > checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > > checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > > checkmessage("aaa={}; x=-aaa", "global 'aaa'") > > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > +-- LuaJIT: LuaJIT includes variable name to the error report. > > +-- It looks like: > > +-- "attempt to perform arithmetic on global 'aaa' (a table value)" > > +-- Lua 5.1 doesn't report variable name here. > > +-- Tests are disabled for LuaJIT. > > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > > > checkmessage([[aaa=9 > > repeat until 3==3 > > -- > > 2.31.0 > > > -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches 2021-03-26 15:44 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-04-02 7:48 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:23 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! LGTM, except the nits below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT includes variable name to the error report, when try to Minor: "error message" is more correct than "error report" here. > call non-function object without __call methamethod. Typo: s/methamethod/metamethod/. > Also, LuaJIT includes variable name to the error report, when try to Typo: s/includes variable name/includes the variable name/. > perform unacceptable arifmetic operation with the variable. > Lua 5.1 doesn't report variable name in these errors. > > Test ckecked that variable name aren't reported are disabled by Typo: s/Test checked/Tests checking/. Typo: s/name aren't reported/name isn't reported/. > this patch. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > index e881211..cf24e40 100644 > --- a/test/PUC-Lua-5.1-tests/errors.lua > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > checkmessage("aaa={}; x=-aaa", "global 'aaa'") > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > +-- LuaJIT: LuaJIT includes variable name to the error report. Minor: "error message" fits better than "error report". > +-- It looks like: > +-- "attempt to perform arithmetic on global 'aaa' (a table value)" > +-- Lua 5.1 doesn't report variable name here. Typo: s/report variable name/report the variable name/. > +-- Tests are disabled for LuaJIT. > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > checkmessage([[aaa=9 > repeat until 3==3 > -- > 2.31.0 > -- Best regards, IM ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches @ 2021-04-02 7:48 ` Sergey Kaplun via Tarantool-patches 0 siblings, 0 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-04-02 7:48 UTC (permalink / raw) To: Igor Munkin; +Cc: tarantool-patches Igor, Thanks for the review! On 31.03.21, Igor Munkin wrote: > Sergey, > > Thanks for the patch! LGTM, except the nits below. > > On 26.03.21, Sergey Kaplun wrote: > > LuaJIT includes variable name to the error report, when try to > > Minor: "error message" is more correct than "error report" here. Fixed. > > > call non-function object without __call methamethod. > > Typo: s/methamethod/metamethod/. Fixed. > > > Also, LuaJIT includes variable name to the error report, when try to > > Typo: s/includes variable name/includes the variable name/. Fixed. > > > perform unacceptable arifmetic operation with the variable. > > Lua 5.1 doesn't report variable name in these errors. > > > > Test ckecked that variable name aren't reported are disabled by > > Typo: s/Test checked/Tests checking/. > Typo: s/name aren't reported/name isn't reported/. Fixed. > > > this patch. > > > > Part of tarantool/tarantool#5845 > > Part of tarantool/tarantool#4473 > > --- > > test/PUC-Lua-5.1-tests/errors.lua | 9 +++++++-- > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > > index e881211..cf24e40 100644 > > --- a/test/PUC-Lua-5.1-tests/errors.lua > > +++ b/test/PUC-Lua-5.1-tests/errors.lua > > @@ -72,8 +72,13 @@ checkmessage("b=1; local aaa='a'; x=aaa+b", "local 'aaa'") > > checkmessage("aaa={}; x=3/aaa", "global 'aaa'") > > checkmessage("aaa='2'; b=nil;x=aaa*b", "global 'b'") > > checkmessage("aaa={}; x=-aaa", "global 'aaa'") > > -assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > > -assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > +-- LuaJIT: LuaJIT includes variable name to the error report. > > Minor: "error message" fits better than "error report". Fixed. > > > +-- It looks like: > > +-- "attempt to perform arithmetic on global 'aaa' (a table value)" > > +-- Lua 5.1 doesn't report variable name here. > > Typo: s/report variable name/report the variable name/. Fixed. > > > +-- Tests are disabled for LuaJIT. > > +-- assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'")) > > +-- assert(not string.find(doit"aaa={}; (aaa or aaa)()", "'aaa'")) > > > > checkmessage([[aaa=9 > > repeat until 3==3 > > -- > > 2.31.0 > > > > -- > Best regards, > IM -- Best regards, Sergey Kaplun ^ permalink raw reply [flat|nested] 153+ messages in thread
* [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name 2021-03-26 7:42 [Tarantool-patches] [PATCH v2 luajit 00/30] Adapt PUC-Rio Lua 5.1 test suite Sergey Kaplun via Tarantool-patches ` (21 preceding siblings ...) 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 22/30] test: disable PUC Lua test for var names in error Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 ` Sergey Kaplun via Tarantool-patches 2021-03-26 15:45 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 24/30] test: disable PUC Lua test for non-asci identifier Sergey Kaplun via Tarantool-patches ` (8 subsequent siblings) 31 siblings, 2 replies; 153+ messages in thread From: Sergey Kaplun via Tarantool-patches @ 2021-03-26 7:43 UTC (permalink / raw) To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches LuaJIT can't determine bytecode position for non Lua functions (in particular for fast functions) and, therefore, detect built-in function names for errors in tail calls. This patch disables test that checks name of built-in functions reported in error in tail call. Part of tarantool/tarantool#5845 Part of tarantool/tarantool#4473 --- test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua index cf24e40..af776a7 100644 --- a/test/PUC-Lua-5.1-tests/errors.lua +++ b/test/PUC-Lua-5.1-tests/errors.lua @@ -105,9 +105,13 @@ while 1 do insert(prefix, a) end]], "global 'insert'") -checkmessage([[ -- tail call - return math.sin("a") -]], "'sin'") +-- LuaJIT: Can't determine bytecode position for non Lua functions +-- (in particular for fast functions) and, therefore, detect fast +-- function names for errors in tail calls. +-- The test is disabled for LuaJIT. +-- checkmessage([[ -- tail call +-- return math.sin("a") +-- ]], "'sin'") checkmessage([[collectgarbage("nooption")]], "invalid option") -- 2.31.0 ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches @ 2021-03-26 15:45 ` Sergey Ostanevich via Tarantool-patches 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 1 sibling, 0 replies; 153+ messages in thread From: Sergey Ostanevich via Tarantool-patches @ 2021-03-26 15:45 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches LGTM. Sergos > On 26 Mar 2021, at 10:43, Sergey Kaplun <skaplun@tarantool.org> wrote: > > LuaJIT can't determine bytecode position for non Lua functions > (in particular for fast functions) and, therefore, detect built-in > function names for errors in tail calls. > > This patch disables test that checks name of built-in functions > reported in error in tail call. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > index cf24e40..af776a7 100644 > --- a/test/PUC-Lua-5.1-tests/errors.lua > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -105,9 +105,13 @@ while 1 do > insert(prefix, a) > end]], "global 'insert'") > > -checkmessage([[ -- tail call > - return math.sin("a") > -]], "'sin'") > +-- LuaJIT: Can't determine bytecode position for non Lua functions > +-- (in particular for fast functions) and, therefore, detect fast > +-- function names for errors in tail calls. > +-- The test is disabled for LuaJIT. > +-- checkmessage([[ -- tail call > +-- return math.sin("a") > +-- ]], "'sin'") > > checkmessage([[collectgarbage("nooption")]], "invalid option") > > -- > 2.31.0 > ^ permalink raw reply [flat|nested] 153+ messages in thread
* Re: [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name 2021-03-26 7:43 ` [Tarantool-patches] [PATCH v2 luajit 23/30] test: disable PUC Lua test for fast function name Sergey Kaplun via Tarantool-patches 2021-03-26 15:45 ` Sergey Ostanevich via Tarantool-patches @ 2021-03-31 19:23 ` Igor Munkin via Tarantool-patches 2021-04-02 8:14 ` Sergey Kaplun via Tarantool-patches 1 sibling, 1 reply; 153+ messages in thread From: Igor Munkin via Tarantool-patches @ 2021-03-31 19:23 UTC (permalink / raw) To: Sergey Kaplun; +Cc: tarantool-patches Sergey, Thanks for the patch! Please consider the comments below. On 26.03.21, Sergey Kaplun wrote: > LuaJIT can't determine bytecode position for non Lua functions > (in particular for fast functions) and, therefore, detect built-in > function names for errors in tail calls. Side note: here is the inconsistency in your usage of possessive nouns. > > This patch disables test that checks name of built-in functions Typo: s/disables test/disables the test/. Typo: s/checks name/checks the name/. > reported in error in tail call. > > Part of tarantool/tarantool#5845 > Part of tarantool/tarantool#4473 > --- > test/PUC-Lua-5.1-tests/errors.lua | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/test/PUC-Lua-5.1-tests/errors.lua b/test/PUC-Lua-5.1-tests/errors.lua > index cf24e40..af776a7 100644 > --- a/test/PUC-Lua-5.1-tests/errors.lua > +++ b/test/PUC-Lua-5.1-tests/errors.lua > @@ -105,9 +105,13 @@ while 1 do > insert(prefix, a) > end]], "global 'insert'") > > -checkmessage([[ -- tail call > - return math.sin("a") > -]], "'sin'") > +-- LuaJIT: Can't determine bytecode position for non Lua functions > +-- (in particular for fast functions) and, therefore, detect fast > +-- function names for errors in tail calls. This is kinda gibberish. I've tried the following snippets and can't understand what do you mean by this comment. | $ luajit -e 'function q(a) return math.sin(a) end q("a")' | luajit: (command line):1: bad argument #1 to 'q' (number expected, got string) | stack traceback: | [C]: in function 'q' | (command line):1: in main chunk | [C]: at 0x5610e8497eb0 | $ luajit -e 'loadstring("return math.sin([[a]])")()' | luajit: (command line):1: bad argument #1 to '?' (number expected, got string) | stack traceback: | [builtin#43]: at 0x7fc0f807ad10 | (command line):1: in main chunk | [C]: at 0x55c1e85c7eb0 I understand the first result. The second result surprised me, but I've never investigated how loadstring call works (it looks like specifics of VARG frame, but this is a wild guess). But neither of them fits your explanation. The root cause is the same: callee uses caller frame, since caller doe