--- source: src/main.rs expression: compiled input_file: test-data/lua5.3-tests/main.lua --- if _port { return } print("testing stand-alone interpreter"); assert(os.execute()); local arg = arg || _ARG local prog = os.tmpname() local otherprog = os.tmpname() local out = os.tmpname() local progname { local i = 0 while arg[(i)] { i = i - 1 } progname = arg[(i + 1)] } print("progname: " .. progname); local prepfile = fn (s, p) { p = p || prog io.output(p); io.write(s); assert(io.close()); } local fn getoutput() { io.input(out); local t = io.read("a") io.input()::close(); assert(os.remove(out)); return t } local fn checkprogout(s) { local t = getoutput() for line with string.gmatch(s, ".-\n") { assert(string.find(t, line, 1, true)); } } local fn checkout(s) { local t = getoutput() if s != t { print(string.format("'%s' - '%s'\n", s, t)); } assert(s == t); return t } local fn RUN(p, ...) { p = string.gsub(p, "lua", '"' .. progname .. '"', 1) local s = string.format(p, ...) assert(os.execute(s)); } local fn NoRun(msg, p, ...) { p = string.gsub(p, "lua", '"' .. progname .. '"', 1) local s = string.format(p, ...) s = string.format("%s 2> %s", s, out) assert(!os.execute(s)); assert(string.find(getoutput(), msg, 1, true)); } RUN('lua -v'); print(string.format("(temporary program file used in these tests: %s)", prog)); prepfile(""); RUN('lua - < %s > %s', prog, out); checkout(""); prepfile([[ print( 1, a ) ]]); RUN('lua - < %s > %s', prog, out); checkout("1\tnil\n"); RUN('echo "print(10)\nprint(2)\n" | lua > %s', out); checkout("10\n2\n"); RUN('echo "print(arg[1])" | lua - -h > %s', out); checkout("-h\n"); prepfile("print(package.path)"); RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out); checkout("x\n"); RUN('env LUA_INIT= LUA_PATH_5_3=y LUA_PATH=x lua %s > %s', prog, out); checkout("y\n"); prepfile("print(package.cpath)"); RUN('env LUA_INIT= LUA_CPATH=xuxu lua %s > %s', prog, out); checkout("xuxu\n"); RUN('env LUA_INIT= LUA_CPATH_5_3=yacc LUA_CPATH=x lua %s > %s', prog, out); checkout("yacc\n"); prepfile("print(X)"); RUN('env LUA_INIT="X=tonumber(arg[1])" lua %s 3.2 > %s', prog, out); checkout("3.2\n"); prepfile("print(X)"); RUN('env LUA_INIT_5_3="X=10" LUA_INIT="X=3" lua %s > %s', prog, out); checkout("10\n"); prepfile("x = x or 10; print(x); x = x + 1"); RUN('env LUA_INIT="@%s" lua %s > %s', prog, prog, out); checkout("10\n11\n"); NoRun('LUA_INIT:1: msg', 'env LUA_INIT="error(\'msg\')" lua'); local defaultpath, defaultCpath { prepfile("print(package.path, package.cpath)"); RUN('env LUA_INIT="error(10)" LUA_PATH=xxx LUA_CPATH=xxx lua -E %s > %s', prog, out); local out = getoutput() defaultpath = string.match(out, "^(.-)\t") defaultCpath = string.match(out, "\t(.-)$") } assert(!string.find(defaultpath, "xxx") && string.find(defaultpath, "lua") && !string.find(defaultCpath, "xxx") && string.find(defaultCpath, "lua")); local fn convert(p) { prepfile("print(package.path)"); RUN('env LUA_PATH="%s" lua %s > %s', p, prog, out); local expected = getoutput() expected = string.sub(expected, 1, -2) assert(string.gsub(p, ";;", ";" .. defaultpath .. ";") == expected); } convert(";"); convert(";;"); convert(";;;"); convert(";;;;"); convert(";;;;;"); convert(";;a;;;bc"); prepfile("print(1); a=2; return {x=15}"); prepfile(("print(a); print(_G['%s'].x)")::format(prog), otherprog); RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out); checkout("1\n2\n15\n2\n15\n"); local a = ` assert(#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)"); prepfile("assert(arg)", otherprog); RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog); RUN('echo "print(...)" | lua -e "arg[1] = 100" - > %s', out); checkout("100\n"); NoRun("'arg' is not a table", 'echo "" | lua -e "arg = 1" -'); RUN('echo 10 | lua -e "print=nil" -i > /dev/null 2> %s', out); assert(string.find(getoutput(), "error calling 'print'")); RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out); checkout("lua_debug> 1000lua_debug> "); 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([[ (6*2-6) -- === a = 10 print(a) a]]); RUN(`lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s`, prog, out); checkprogout("6\n10\n10\n\n"); prepfile("a = [[b\nc\nd\ne]]\n=a"); RUN(`lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s`, prog, out); checkprogout("b\nc\nd\ne\n\n"); prompt = "alo" prepfile([[ -- a = 2 ]]); RUN(`lua "-e_PROMPT='%s'" -i < %s > %s`, prompt, prog, out); local t = getoutput() assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)); prepfile([[ debug = require "debug" m = {x=0} setmetatable(m, {__tostring = function(x) return tostring(debug.getinfo(4).currentline + x.x) end}) error(m) ]]); NoRun(progname .. ": 6\n", `lua %s`, prog); prepfile("error{}"); NoRun("error object is a table value", `lua %s`, prog); s = ` -- function f ( x ) local a = [[ xuxu ]] local b = "\ xuxu\n" if x == 11 then return 1 + 12 , 2 + 20 end --[[ test multiple returns ]] return x + 1 --\\ end return( f( 100 ) ) assert( a == b ) do return f( 11 ) end ` s = string.gsub(s, ' ', '\n\n') prepfile(s); RUN(`lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s`, prog, out); checkprogout("101\n13\t22\n\n"); prepfile([[#comment in 1st line without \n at the end]]); RUN('lua %s', prog); prepfile([[#test line number when file starts with comment line debug = require"debug" print(debug.getinfo(1).currentline) ]]); RUN('lua %s > %s', prog, out); checkprogout('3'); prepfile(string.format(`io.output(%q); io.write('alo')`, out)); RUN('lua %s', prog); checkout('alo'); RUN(`lua -v -e"print'hello'" > %s`, out); t = getoutput() assert(string.find(t, "PUC%-Rio\nhello")); prepfile("os.exit(nil, true)"); RUN('lua %s', prog); prepfile("os.exit(0, true)"); RUN('lua %s', prog); prepfile("os.exit(true, true)"); RUN('lua %s', prog); prepfile("os.exit(1, true)"); NoRun("", "lua %s", prog); prepfile("os.exit(false, true)"); NoRun("", "lua %s", prog); assert(os.remove(prog)); assert(os.remove(otherprog)); assert(!os.remove(out)); NoRun("unrecognized option '-h'", "lua -h"); NoRun("unrecognized option '---'", "lua ---"); NoRun("unrecognized option '-Ex'", "lua -Ex"); NoRun("unrecognized option '-vv'", "lua -vv"); NoRun("unrecognized option '-iv'", "lua -iv"); NoRun("'-e' needs argument", "lua -e"); NoRun("syntax error", "lua -e a"); NoRun("'-l' needs argument", "lua -l"); if T { print("testing 'not enough memory' to create a state"); NoRun("not enough memory", "env MEMLIMIT=100 lua"); } print('+'); print('testing Ctrl C'); { local fn kill(pid) { return os.execute(string.format('kill -INT %d 2> /dev/null', pid)) } local fn runback(luaprg) { local shellprg = string.format('%s -e "%s" & echo $!', progname, luaprg) local f = io.popen(shellprg, "r") local pid = f::read() print("(if test fails now, it may leave a Lua script running in \z background, pid " .. pid .. ")"); return f, pid } local f, pid = runback([[ pcall(function () print(12); while true do end end); print(42)]]) assert(f::read() == "12"); kill(pid); assert(f::read() == "42"); assert(f::close()); print("done"); local f, pid = runback([[ print(15); string.find(string.rep('a', 100000), '.*b')]]) assert(f::read() == "15"); assert(os.execute("sleep 1")); local n = 100 for i = 0, 100 { if !kill(pid) { n = i break } } assert(f::close()); assert(n >= 2); print(string.format("done (with %d kills)", n)); } print("OK");