---
source: src/main.rs
expression: compiled
input_file: test-data/lua5.4-tests/files.lua
---
local debug = require("debug")
local maxint = math.maxinteger
assert(type(os.getenv("PATH")) == "string");
assert(io.input(io.stdin) == io.stdin);
assert(!pcall(io.input, "non-existent-file"));
assert(io.output(io.stdout) == io.stdout);
local fn testerr(msg, f, ...) {
local stat, err = pcall(f, ...)
return (!stat && string.find(err, msg, 1, true))
}
local fn checkerr(msg, f, ...) {
assert(testerr(msg, f, ...));
}
assert(!io.close(io.stdin) && !io.stdout::close() && !io.stderr::close());
checkerr("got no value", io.stdin.close);
assert(type(io.input()) == "userdata" && io.type(io.output()) == "file");
assert(type(io.stdin) == "userdata" && io.type(io.stderr) == "file");
assert(!io.type(8));
local a = {}
setmetatable(a, {});
assert(!io.type(a));
assert(getmetatable(io.input()).__name == "FILE*");
local a, b, c = io.open('xuxu_nao_existe')
assert(!a && type(b) == "string" && type(c) == "number");
a, b, c = io.open('/a/b/c/d', 'w')
assert(!a && type(b) == "string" && type(c) == "number");
local file = os.tmpname()
local f, msg = io.open(file, "w")
if !f {
(Message || print)("'os.tmpname' file cannot be open; skipping file tests");
} else {
f::close();
print('testing i/o');
local otherfile = os.tmpname()
checkerr("invalid mode", io.open, file, "rw");
checkerr("invalid mode", io.open, file, "rb+");
checkerr("invalid mode", io.open, file, "r+bk");
checkerr("invalid mode", io.open, file, "");
checkerr("invalid mode", io.open, file, "+");
checkerr("invalid mode", io.open, file, "b");
assert(io.open(file, "r+b"))::close();
assert(io.open(file, "r+"))::close();
assert(io.open(file, "rb"))::close();
assert(os.setlocale('C', 'all'));
io.input(io.stdin);
io.output(io.stdout);
os.remove(file);
assert(!loadfile(file));
checkerr("", dofile, file);
assert(!io.open(file));
io.output(file);
assert(io.output() != io.stdout);
if !_port {
local status, msg, code = io.stdin::seek("set", 1000)
assert(!status && type(msg) == "string" && type(code) == "number");
}
assert(io.output()::seek() == 0);
assert(io.write("alo alo")::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();
assert(io.input() == io.stdin && rawequal(io.output(), io.stdout));
print('+');
collectgarbage();
for i = 1, 120 {
for i = 1, 5 {
io.input(file);
assert(io.open(file, 'r'));
io.lines(file);
}
collectgarbage();
}
io.input()::close();
io.close();
assert(os.rename(file, otherfile));
assert(!os.rename(file, otherfile));
io.output(io.open(otherfile, "ab"));
assert(io.write("\n\n\t\t ", 3450, "\n"));
io.close();
{
local F = nil
{
local f = assert(io.open(file, "w"))
F = f
getmetatable(f).__close(f);
}
assert(tostring(F) == "file (closed)");
}
assert(os.remove(file));
{
local f = assert(io.open(file, "w"))
f::write(maxint, '\n');
f::write(string.format("0X%x\n", maxint));
f::write("0xABCp-3", '\n');
f::write(0, '\n');
f::write(-maxint, '\n');
f::write(string.format("0x%X\n", -maxint));
f::write("-0xABCp-3", '\n');
assert(f::close());
local f = assert(io.open(file, "r"))
assert(f::read("n") == maxint);
assert(f::read("n") == maxint);
assert(f::read("n") == 343.5);
assert(f::read("n") == 0);
assert(f::read("*n") == -maxint);
assert(f::read("n") == -maxint);
assert(f::read("*n") == -343.5);
getmetatable(f).__close(f);
getmetatable(f).__close(f);
}
assert(os.remove(file));
{
local f = assert(io.open(file, "w"))
f::write([[
a line
another line
1234
3.45
one
two
three
]]);
local l1, l2, l3, l4, n1, n2, c, dummy
assert(f::close());
local f = assert(io.open(file, "r"))
l1, l2, n1, n2, dummy = f::read("l", "L", "n", "n")
assert(l1 == "a line" && l2 == "another line\n" && n1 == 1234 && n2 == 3.45 && dummy == nil);
assert(f::close());
local f = assert(io.open(file, "r"))
l1, l2, n1, n2, c, l3, l4, dummy = f::read(7, "l", "n", "n", 1, "l", "l")
assert(l1 == "a line\n" && l2 == "another line" && c == '\n' && n1 == 1234 && n2 == 3.45 && l3 == "one" && l4 == "two" && dummy == nil);
assert(f::close());
local f = assert(io.open(file, "r"))
l1, n1, n2, dummy = f::read("l", "n", "n", "l")
assert(l1 == "a line" && !n1);
getmetatable(f).__close(f);
getmetatable(f).__close(f);
getmetatable(f).__close(f);
getmetatable(f).__close(f);
}
assert(os.remove(file));
f = assert(io.open(file, "w"))
f::write([[
local x, z = coroutine.yield(10)
local y = coroutine.yield(20)
return x + y * z
]]);
assert(f::close());
f = coroutine.wrap(dofile)
assert(f(file) == 10);
assert(f(100, 101) == 20);
assert(f(200) == 100 + 200 * 101);
assert(os.remove(file));
f = assert(io.open(file, "w"))
f::write([[
-12.3- -0xffff+ .3|5.E-3X +234e+13E 0xDEADBEEFDEADBEEFx
0x1.13Ap+3e
]]);
f::write("1234");
for i = 1, 1000 {
f::write("0");
}
f::write("\n");
f::write([[
.e+ 0.e; --; 0xX;
]]);
assert(f::close());
f = assert(io.open(file, "r"))
assert(f::read("n") == -12.3);
assert(f::read(1) == "-");
assert(f::read("n") == -0xffff);
assert(f::read(2) == "+ ");
assert(f::read("n") == 0.3);
assert(f::read(1) == "|");
assert(f::read("n") == 5e-3);
assert(f::read(1) == "X");
assert(f::read("n") == 234e13);
assert(f::read(1) == "E");
assert(f::read("n") == 0Xdeadbeefdeadbeef);
assert(f::read(2) == "x\n");
assert(f::read("n") == 8.61328125);
assert(f::read(1) == "e");
{
assert(!f::read("n"));
local s = f::read("L")
assert(string.find(s, "^00*\n$"));
}
assert(!f::read("n"));
assert(f::read(2) == "e+");
assert(!f::read("n"));
assert(f::read(1) == ";");
assert(!f::read("n"));
assert(f::read(2) == "-;");
assert(!f::read("n"));
assert(f::read(1) == "X");
assert(!f::read("n"));
assert(f::read(1) == ";");
assert(!f::read("n"));
assert(!f::read(0));
assert(f::close());
assert(os.remove(file));
assert(!pcall(io.lines, "non-existent-file"));
assert(os.rename(otherfile, file));
io.output(otherfile);
local n = 0
local f = io.lines(file)
while f() {
n = n + 1
}
assert(n == 6);
checkerr("file is already closed", f);
checkerr("file is already closed", f);
n = 0
for l with io.lines(file) {
io.write(l, "\n");
n = n + 1
}
io.close();
assert(n == 6);
local f = assert(io.open(otherfile))
assert(io.type(f) == "file");
io.output(file);
assert(!io.output()::read());
n = 0
for l with f::lines() {
io.write(l, "\n");
n = n + 1
}
assert(tostring(f)::sub(1, 5) == "file ");
assert(f::close());
io.close();
assert(n == 6);
checkerr("closed file", io.close, f);
assert(tostring(f) == "file (closed)");
assert(io.type(f) == "closed file");
io.input(file);
f = io.open(otherfile)::lines()
n = 0
for l with io.lines() {
assert(l == f());
n = n + 1
}
f = nil
collectgarbage();
assert(n == 6);
assert(os.remove(otherfile));
{
io.output(otherfile);
io.write(string.rep("a", 300), "\n");
io.close();
local t = {}
for i = 1, 250 {
t[(i)] = 1
}
t = {
io.lines(otherfile, table.unpack(t))()
}
assert(#t == 250 && t[(1)] == 'a' && t[(#t)] == 'a');
t[(#t + 1)] = 1
checkerr("too many arguments", io.lines, otherfile, table.unpack(t));
collectgarbage();
assert(os.remove(otherfile));
}
io.input(file);
{
local a, b, c = io.input()::write("xuxu")
assert(!a && type(b) == "string" && type(c) == "number");
}
checkerr("invalid format", io.read, "x");
assert(io.read(0) == "");
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 \n");
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() == "");
assert(io.read('n') == 3450);
assert(io.read(1) == '\n');
assert(!io.read(0));
assert(!io.read(1));
assert(!io.read(30000));
assert(({
io.read(1)
})[(2)] == undef);
assert(!io.read());
assert(({
io.read()
})[(2)] == undef);
assert(!io.read('n'));
assert(({
io.read('n')
})[(2)] == undef);
assert(io.read('a') == '');
assert(io.read('a') == '');
collectgarbage();
print('+');
io.close(io.input());
checkerr(" input file is closed", io.read);
assert(os.remove(file));
local t = '0123456789'
for i = 1, 10 {
t = t .. t
}
assert(string.len(t) == 10 * 2 ^ 10);
io.output(file);
io.write("alo")::write("\n");
io.close();
checkerr(" output file is closed", io.write);
local f = io.open(file, "a+b")
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));
assert(io.close(io.input()));
{
local fn ismsg(m) {
return (type(m) == "string" && !tonumber(m))
}
local f = io.open(file, "w")
local r, m, c = f::read()
assert(!r && ismsg(m) && type(c) == "number");
assert(f::close());
f = io.open(file, "r")
r, m, c = f::write("whatever")
assert(!r && ismsg(m) && type(c) == "number");
assert(f::close());
f = io.open(file, "w")
r, m = pcall(f::lines())
assert(r == false && ismsg(m));
assert(f::close());
}
assert(os.remove(file));
io.output(file);
io.write("\n\nline\nother")::close();
io.input(file);
assert(io.read("L") == "\n");
assert(io.read("L") == "\n");
assert(io.read("L") == "line\n");
assert(io.read("L") == "other");
assert(!io.read("L"));
io.input()::close();
local f = assert(io.open(file))
local s = ""
for l with f::lines("L") {
s = s .. l
}
assert(s == "\n\nline\nother");
f::close();
io.input(file);
s = ""
for l with io.lines(nil, "L") {
s = s .. l
}
assert(s == "\n\nline\nother");
io.input()::close();
s = ""
for l with io.lines(file, "L") {
s = s .. l
}
assert(s == "\n\nline\nother");
s = ""
for l with io.lines(file, "l") {
s = s .. l
}
assert(s == "lineother");
io.output(file);
io.write("a = 10 + 34\na = 2*a\na = -a\n")::close();
local t = {}
assert(load(io.lines(file, "L"), nil, nil, t))();
assert(t.a == -((10 + 34) * 2));
{
local fn gettoclose(lv) {
lv = lv + 1
local stvar = 0
for i = 1, 1000 {
local n, v = debug.getlocal(lv, i)
if n == "(for state)" {
stvar = stvar + 1
if stvar == 4 {
return v
}
}
}
}
local f
for l with io.lines(file) {
f = gettoclose(1)
assert(io.type(f) == "file");
break
}
assert(io.type(f) == "closed file");
f = nil
local fn foo(name) {
for l with io.lines(name) {
f = gettoclose(1)
assert(io.type(f) == "file");
error(f);
}
}
local st, msg = pcall(foo, file)
assert(st == false && io.type(msg) == "closed file");
}
io.output(file);
io.write("0123456789\n")::close();
for a, b with io.lines(file, 1, 1) {
if a == "\n" {
assert(!b);
} else {
assert(tonumber(a) == tonumber(b) - 1);
}
}
for a, b, c with io.lines(file, 1, 2, "a") {
assert(a == "0" && b == "12" && c == "3456789\n");
}
for a, b, c with io.lines(file, "a", 0, 1) {
if a == "" {
break
}
assert(a == "0123456789\n" && !b && !c);
}
collectgarbage();
io.output(file);
io.write("00\n10\n20\n30\n40\n")::close();
for a, b with io.lines(file, "n", "n") {
if a == 40 {
assert(!b);
} else {
assert(a == b - 10);
}
}
io.output(file);
io.write([[
local y
= X
X =
X *
2 +
X;
X =
X
- y;
]])::close();
_G.X = 1
assert(!load((io.lines(file))));
collectgarbage();
load((io.lines(file, "L")))();
assert(_G.X == 2);
load((io.lines(file, 1)))();
assert(_G.X == 4);
load((io.lines(file, 3)))();
assert(_G.X == 8);
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));
assert(!os.remove(otherfile));
local fn testloadfile(s, expres) {
io.output(file);
if s {
io.write(s);
}
io.close();
local res = assert(loadfile(file))()
assert(os.remove(file));
assert(res == expres);
}
testloadfile(nil, nil);
testloadfile("# a non-ending comment", nil);
testloadfile("\xEF\xBB\xBF# some comment\nreturn 234", 234);
testloadfile("\xEF\xBB\xBFreturn 239", 239);
testloadfile("\xEF\xBB\xBF", nil);
testloadfile("# a comment\nreturn require'debug'.getinfo(1).currentline", 2);
io.output(io.open(file, "wb"));
assert(io.write(string.dump(fn () {
return 10, '\0alo\255', 'hi'
})));
io.close();
a, b, c = assert(loadfile(file))()
assert(a == 10 && b == "\0alo\255" && c == "hi");
assert(os.remove(file));
{
io.output(io.open(file, "wb"));
assert(io.write(string.dump(fn () {
return 1
})));
io.close();
f = assert(loadfile(file, "b", {}))
assert(type(f) == "function" && f() == 1);
assert(os.remove(file));
}
io.output(io.open(file, "wb"));
assert(io.write("#this is a comment for a binary file\0\n", string.dump(fn () {
return 20, '\0\0\0'
})));
io.close();
a, b, c = assert(loadfile(file))()
assert(a == 20 && b == "\0\0\0" && c == nil);
assert(os.remove(file));
{
local f = io.open(file, 'w')
f::write([[
if (...) then a = 15; return b, c, d
else return _ENV
end
]]);
f::close();
local t = {
b = 12,
c = "xuxu",
d = print
}
local f = assert(loadfile(file, 't', t))
local b, c, d = f(1)
assert(t.a == 15 && b == 12 && c == t.c && d == print);
assert(f() == t);
f = assert(loadfile(file, 't', nil))
assert(f() == nil);
f = assert(loadfile(file))
assert(f() == _G);
assert(os.remove(file));
}
{
io.open(file, 'w')::write("return 10")::close();
local s, m = loadfile(file, 'b')
assert(!s && string.find(m, "a text chunk"));
io.open(file, 'w')::write("\27 return 10")::close();
local s, m = loadfile(file, 't')
assert(!s && string.find(m, "a binary chunk"));
assert(os.remove(file));
}
io.output(file);
assert(io.write("qualquer coisa\n"));
assert(io.write("mais qualquer coisa"));
io.close();
assert(io.output(assert(io.open(otherfile, 'wb')))::write("outra coisa\0\1\3\0\0\0\0\255\0")::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) == "");
assert(io.read(1) == "\255");
assert(io.read('a') == "\0");
assert(!io.read(0));
assert(otherfilehandle == io.input());
otherfilehandle::close();
assert(os.remove(file));
assert(os.remove(otherfile));
collectgarbage();
io.output(file)::write([[
123.4 -56e-2 not a number
second line
third line
and the rest of the file
]])::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(_ == ' ' && !__);
assert(type(a) == 'number' && a == 123.4 && b == -56e-2);
assert(d == 'second line' && e == 'third line');
assert(h == `
and the rest of the file
`);
assert(os.remove(file));
collectgarbage();
{
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") == "");
f::close();
fr::seek("set");
assert(fr::read("all") == "x");
f = assert(io.open(file), "w")
assert(f::setvbuf("no"));
f::write("x");
fr::seek("set");
assert(fr::read("all") == "x");
f::close();
f = assert(io.open(file, "a"))
assert(f::setvbuf("line"));
f::write("x");
fr::seek("set", 1);
assert(fr::read("all") == "");
f::write("a\n")::seek("set", 1);
assert(fr::read("all") == "xa\n");
f::close();
fr::close();
assert(os.remove(file));
}
if !_soft {
print("testing large files (> BUFSIZ)");
io.output(file);
for i = 1, 5001 {
io.write('0123456789123');
}
io.write('\n12346')::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 && string.len(x) == 5001 * 13 + 6);
io.input()::seek('set', 0);
y = io.read()
assert(x == y .. '\n' .. io.read());
assert(!io.read());
io.close(io.input());
assert(os.remove(file));
x = nil
y = nil
}
if !_port {
local progname
{
local arg = arg || ARG
local i = 0
while arg[(i)] {
i = i - 1
}
progname = '"' .. arg[(i + 1)] .. '"'
}
print("testing popen/pclose and execute");
checkerr("invalid mode", io.popen, "cat", "");
checkerr("invalid mode", io.popen, "cat", "r+");
checkerr("invalid mode", io.popen, "cat", "rw");
{
local file = os.tmpname()
local f = assert(io.popen("cat - > " .. file, "w"))
f::write("a line");
assert(f::close());
local f = assert(io.popen("cat - < " .. file, "r"))
assert(f::read("a") == "a line");
assert(f::close());
assert(os.remove(file));
}
local tests = {
{
"ls > /dev/null",
"ok"
},
{
"not-to-be-found-command",
"exit"
},
{
"exit 3",
"exit",
3
},
{
"exit 129",
"exit",
129
},
{
"kill -s HUP $$",
"signal",
1
},
{
"kill -s KILL $$",
"signal",
9
},
{
"sh -c 'kill -s HUP $$'",
"exit"
},
{
progname .. ' -e " "',
"ok"
},
{
progname .. ' -e "os.exit(0, true)"',
"ok"
},
{
progname .. ' -e "os.exit(20, true)"',
"exit",
20
}
}
print("\n(some error messages are expected now)");
for _, v with ipairs(tests) {
local x, y, z = io.popen(v[(1)])::close()
local x1, y1, z1 = os.execute(v[(1)])
assert(x == x1 && y == y1 && z == z1);
if v[(2)] == "ok" {
assert(x && y == 'exit' && z == 0);
} else {
assert(!x && y == v[(2)]);
assert((v[(3)] == nil && z > 0) || v[(3)] == z);
}
}
}
f = io.tmpfile()
assert(io.type(f) == "file");
f::write("alo");
f::seek("set");
assert(f::read("a") == "alo");
}
print('+');
print("testing date/time");
assert(os.date("") == "");
assert(os.date("!") == "");
assert(os.date("\0\0") == "\0\0");
assert(os.date("!\0\0") == "\0\0");
local x = string.rep("a", 10000)
assert(os.date(x) == x);
local t = os.time()
D = os.date("*t", t)
assert(os.date(string.rep("%d", 1000), t) == string.rep(os.date("%d", t), 1000));
assert(os.date(string.rep("%", 200)) == string.rep("%", 100));
local fn checkDateTable(t) {
_G.D = os.date("*t", t)
assert(os.time(D) == t);
load(os.date(`assert(D.year==%Y and D.month==%m and D.day==%d and
D.hour==%H and D.min==%M and D.sec==%S and
D.wday==%w+1 and D.yday==%j)`, t))();
_G.D = nil
}
checkDateTable(os.time());
if !_port {
checkDateTable(0);
checkDateTable(1);
checkDateTable(1000);
checkDateTable(0x7fffffff);
checkDateTable(0x80000000);
}
checkerr("invalid conversion specifier", os.date, "%");
checkerr("invalid conversion specifier", os.date, "%9");
checkerr("invalid conversion specifier", os.date, "%");
checkerr("invalid conversion specifier", os.date, "%O");
checkerr("invalid conversion specifier", os.date, "%E");
checkerr("invalid conversion specifier", os.date, "%Ea");
checkerr("not an integer", os.time, {
year = 1000,
month = 1,
day = 1,
hour = 'x'
});
checkerr("not an integer", os.time, {
year = 1000,
month = 1,
day = 1,
hour = 1.5
});
checkerr("missing", os.time, {
hour = 12
});
if string.packsize("i") == 4 {
checkerr("field 'year' is out-of-bound", os.time, {
year = -(1 << 31) + 1899,
month = 1,
day = 1
});
}
if !_port {
assert(type(os.date("%Ex")) == 'string');
assert(type(os.date("%Oy")) == 'string');
local t0 = os.time({
year = 1970,
month = 1,
day = 0
})
local t1 = os.time({
year = 1970,
month = 1,
day = 0,
sec = (1 << 31) - 1
})
assert(t1 - t0 == (1 << 31) - 1);
t0 = os.time({
year = 1970,
month = 1,
day = 1
})
t1 = os.time({
year = 1970,
month = 1,
day = 1,
sec = -(1 << 31)
})
assert(t1 - t0 == -(1 << 31));
if maxint >= 2 ^ 62 {
checkerr("out-of-bound", os.time, {
year = -maxint,
month = 1,
day = 1
});
if string.packsize("i") == 4 {
if testerr("out-of-bound", os.date, "%Y", 2 ^ 40) {
print(" 4-byte time_t");
checkerr("cannot be represented", os.time, {
year = 4000,
month = 1,
day = 1
});
} else {
print(" 8-byte time_t");
checkerr("cannot be represented", os.date, "%Y", 2 ^ 60);
assert(tonumber(os.time({
year = (1 << 31) + 1899,
month = 12,
day = 31,
hour = 23,
min = 59,
sec = 59
})));
checkerr("represented", os.time, {
year = (1 << 31) + 1899,
month = 12,
day = 31,
hour = 23,
min = 59,
sec = 60
});
}
checkerr("field 'day' is out-of-bound", os.time, {
year = 0,
month = 1,
day = 2 ^ 32
});
checkerr("field 'month' is out-of-bound", os.time, {
year = 0,
month = -((1 << 31) + 1),
day = 1
});
checkerr("field 'year' is out-of-bound", os.time, {
year = (1 << 31) + 1900,
month = 1,
day = 1
});
} else {
print(" 8-byte time_t");
assert(tonumber(os.date("%Y", 2 ^ 60)));
checkerr("cannot be represented", os.time, {
year = 2 ^ 60,
month = 1,
day = 1
});
}
}
}
{
local D = os.date("*t")
local t = os.time(D)
if D.isdst == nil {
print("no daylight saving information");
} else {
assert(type(D.isdst) == 'boolean');
}
D.isdst = nil
local t1 = os.time(D)
assert(t == t1);
}
local D = os.date("*t")
t = os.time(D)
D.year = D.year - 1
local t1 = os.time(D)
assert(math.abs(os.difftime(t, t1) / (24 * 3600) - 365) < 2);
t = os.time()
t1 = os.time(os.date("*t"))
local diff = os.difftime(t1, t)
assert(0 <= diff && diff <= 1);
diff = os.difftime(t, t1)
assert(-1 <= diff && diff <= 0);
local t1 = os.time({
year = 2000,
month = 10,
day = 1,
hour = 23,
min = 12
})
local t2 = os.time({
year = 2000,
month = 10,
day = 1,
hour = 23,
min = 10,
sec = 19
})
assert(os.difftime(t1, t2) == 60 * 2 - 19);
t1 = {
year = 2005,
month = 1,
day = 1,
hour = 1,
min = 0,
sec = -3602
}
os.time(t1);
assert(t1.day == 31 && t1.month == 12 && t1.year == 2004 && t1.hour == 23 && t1.min == 59 && t1.sec == 58 && t1.yday == 366);
io.output(io.stdout);
local t = os.date('%d %m %Y %H %M %S')
local d, m, a, h, min, s = string.match(t, "(%d+) (%d+) (%d+) (%d+) (%d+) (%d+)")
d = tonumber(d)
m = tonumber(m)
a = tonumber(a)
h = tonumber(h)
min = tonumber(min)
s = tonumber(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));