1local file = os.tmpname()
2local otherfile = os.tmpname()
3
4-- assert(os.setlocale('C', 'all'))
5
6io.input(io.stdin); io.output(io.stdout);
7
8os.remove(file)
9assert(loadfile(file) == nil)
10assert(io.open(file) == nil)
11io.output(file)
12assert(io.output() ~= io.stdout)
13
14assert(io.output():seek() == 0)
15assert(io.write("alo alo"))
16assert(io.output():seek() == string.len("alo alo"))
17assert(io.output():seek("cur", -3) == string.len("alo alo")-3)
18assert(io.write("joao"))
19assert(io.output():seek("end") == string.len("alo joao"))
20
21assert(io.output():seek("set") == 0)
22
23assert(io.write('"�lo"', "{a}\n", "second line\n", "third line \n"))
24assert(io.write('�fourth_line'))
25io.output():close()
26io.output(io.stdout)
27-- collectgarbage()  -- file should be closed by GC
28assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
29print('+')
30
31-- test GC for files
32-- collectgarbage()
33-- for i=1,120 do
34--   for i=1,5 do
35--     io.input(file)
36--     assert(io.open(file, 'r'))
37--     io.lines(file)
38--   end
39--   collectgarbage()
40-- end
41
42assert(os.rename(file, otherfile))
43assert(os.rename(file, otherfile) == nil)
44
45io.output(io.open(otherfile, "a"))
46assert(io.write("\n\n\t\t  3450\n"));
47io.close()
48
49-- test line generators
50assert(os.rename(otherfile, file))
51io.output(otherfile)
52local f = io.lines(file)
53while f() do end;
54assert(not pcall(f))  -- read lines after EOF
55assert(not pcall(f))  -- read lines after EOF
56-- copy from file to otherfile
57for l in io.lines(file) do io.write(l, "\n") end
58io.close()
59-- copy from otherfile back to file
60local f = assert(io.open(otherfile))
61assert(io.type(f) == "file")
62io.output(file)
63assert(io.output():read() == nil)
64for l in f:lines() do io.write(l, "\n") end
65assert(f:close()); io.close()
66assert(not pcall(io.close, f))   -- error trying to close again
67assert(tostring(f) == "file (closed)")
68assert(io.type(f) == "closed file")
69io.input(file)
70local of =io.open(otherfile)
71f = of:lines()
72for l in io.lines() do
73  assert(l == f())
74end
75of:close()
76assert(os.remove(otherfile))
77assert(io.close(io.input()))
78
79io.input(file)
80do  -- test error returns
81  local a,b,c = io.input():write("xuxu")
82  assert(not a and type(b) == "string" and type(c) == "number")
83end
84assert(io.read(0) == "")   -- not eof
85assert(io.read(5, '*l') == '"�lo"')
86assert(io.read(0) == "")
87assert(io.read() == "second line")
88local x = io.input():seek()
89assert(io.read() == "third line ")
90assert(io.input():seek("set", x))
91assert(io.read('*l') == "third line ")
92assert(io.read(1) == "�")
93assert(io.read(string.len"fourth_line") == "fourth_line")
94assert(io.input():seek("cur", -string.len"fourth_line"))
95assert(io.read() == "fourth_line")
96assert(io.read() == "")  -- empty line
97assert(io.read('*n') == 3450)
98assert(io.read(1) == '\n')
99assert(io.read(0) == nil)  -- end of file
100assert(io.read(1) == nil)  -- end of file
101assert(({io.read(1)})[2] == nil)
102assert(io.read() == nil)  -- end of file
103assert(({io.read()})[2] == nil)
104assert(io.read('*n') == nil)  -- end of file
105assert(({io.read('*n')})[2] == nil)
106assert(io.read('*a') == '')  -- end of file (OK for `*a')
107assert(io.read('*a') == '')  -- end of file (OK for `*a')
108collectgarbage()
109print('+')
110io.close(io.input())
111assert(not pcall(io.read))
112
113assert(os.remove(file))
114
115local t = '0123456789'
116for i=1,12 do t = t..t; end
117assert(string.len(t) == 10*2^12)
118
119io.output(file)
120io.write("alo\n")
121io.close()
122assert(not pcall(io.write))
123local f = io.open(file, "a")
124io.output(f)
125collectgarbage()
126
127assert(io.write(' ' .. t .. ' '))
128assert(io.write(';', 'end of file\n'))
129f:flush(); io.flush()
130f:close()
131print('+')
132
133io.input(file)
134assert(io.read() == "alo")
135assert(io.read(1) == ' ')
136assert(io.read(string.len(t)) == t)
137assert(io.read(1) == ' ')
138assert(io.read(0))
139assert(io.read('*a') == ';end of file\n')
140assert(io.read(0) == nil)
141assert(io.close(io.input()))
142
143assert(os.remove(file))
144print('+')
145
146local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'"
147io.output(file)
148assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1)))
149io.close()
150assert(loadfile(file))()
151assert(x1 == x2)
152print('+')
153assert(os.remove(file))
154assert(os.remove(file) == nil)
155assert(os.remove(otherfile) == nil)
156
157io.output(file)
158assert(io.write("qualquer coisa\n"))
159assert(io.write("mais qualquer coisa"))
160io.close()
161io.output(assert(io.open(otherfile, 'wb')))
162assert(io.write("outra coisa\0\1\3\0\0\0\0\255\0"))
163io.close()
164
165local filehandle = assert(io.open(file, 'r'))
166local otherfilehandle = assert(io.open(otherfile, 'rb'))
167assert(filehandle ~= otherfilehandle)
168assert(type(filehandle) == "userdata")
169assert(filehandle:read('*l') == "qualquer coisa")
170io.input(otherfilehandle)
171assert(io.read(string.len"outra coisa") == "outra coisa")
172assert(filehandle:read('*l') == "mais qualquer coisa")
173filehandle:close();
174assert(type(filehandle) == "userdata")
175io.input(otherfilehandle)
176assert(io.read(4) == "\0\1\3\0")
177assert(io.read(3) == "\0\0\0")
178assert(io.read(0) == "")        -- 255 is not eof
179assert(io.read(1) == "\255")
180assert(io.read('*a') == "\0")
181assert(not io.read(0))
182assert(otherfilehandle == io.input())
183otherfilehandle:close()
184assert(os.remove(file))
185assert(os.remove(otherfile))
186collectgarbage()
187
188io.output(file)
189io.write[[
190 123.4	-56e-2  not a number
191second line
192third line
193
194and the rest of the file
195]]
196io.close()
197io.input(file)
198local _,a,b,c,d,e,h,__ = io.read(1, '*n', '*n', '*l', '*l', '*l', '*a', 10)
199assert(io.close(io.input()))
200assert(_ == ' ' and __ == nil)
201assert(type(a) == 'number' and a==123.4 and b==-56e-2)
202assert(d=='second line' and e=='third line')
203assert(h==[[
204
205and the rest of the file
206]])
207assert(os.remove(file))
208collectgarbage()
209
210-- testing buffers
211do
212  local f = assert(io.open(file, "w"))
213  local fr = assert(io.open(file, "r"))
214  assert(f:setvbuf("full", 2000))
215  f:write("x")
216  assert(fr:read("*all") == "")  -- full buffer; output not written yet
217  f:close()
218  fr:seek("set")
219  assert(fr:read("*all") == "x")   -- `close' flushes it
220  f = assert(io.open(file, "w"))
221  assert(f:setvbuf("no"))
222  f:write("x")
223  fr:seek("set")
224  assert(fr:read("*all") == "x")  -- no buffer; output is ready
225  f:close()
226  fr:close()
227  -- f = assert(io.open(file, "a"))
228  -- assert(f:setvbuf("line"))
229  -- f:write("x")
230  -- fr:seek("set", 1)
231  -- assert(fr:read("*all") == "")   -- line buffer; no output without `\n'
232  -- f:write("a\n")
233  -- fr:seek("set", 1)
234  -- assert(fr:read("*all") == "xa\n")  -- now we have a whole line
235  -- f:close(); fr:close()
236end
237
238
239-- testing large files (> BUFSIZ)
240io.output(file)
241for i=1,5001 do io.write('0123456789123') end
242io.write('\n12346')
243io.close()
244io.input(file)
245local x = io.read('*a')
246io.input():seek('set', 0)
247local y = io.read(30001)..io.read(1005)..io.read(0)..io.read(1)..io.read(100003)
248assert(x == y and string.len(x) == 5001*13 + 6)
249io.input():seek('set', 0)
250y = io.read()  -- huge line
251assert(x == y..'\n'..io.read())
252assert(io.read() == nil)
253io.close(io.input())
254assert(os.remove(file))
255x = nil; y = nil
256
257x, y = pcall(io.popen, "ls")
258if x then
259  assert(y:read("*a"))
260  assert(y:close())
261else
262  (Message or print)('\a\n >>> popen not available<<<\n\a')
263end
264
265print'+'
266
267local t = os.time()
268-- T = os.date("*t", t)
269-- loadstring(os.date([[assert(T.year==%Y and T.month==%m and T.day==%d and
270--   T.hour==%H and T.min==%M and T.sec==%S and
271--   T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
272--
273-- assert(os.time(T) == t)
274--
275T = os.date("!*t", t)
276-- loadstring(os.date([[!assert(T.year==%Y and T.month==%m and T.day==%d and
277--   T.hour==%H and T.min==%M and T.sec==%S and
278--   T.wday==%w+1 and T.yday==%j and type(T.isdst) == 'boolean')]], t))()
279
280do
281  local T = os.date("*t")
282  local t = os.time(T)
283  assert(type(T.isdst) == 'boolean')
284  T.isdst = nil
285  local t1 = os.time(T)
286  assert(t == t1)   -- if isdst is absent uses correct default
287end
288
289t = os.time(T)
290T.year = T.year-1;
291local t1 = os.time(T)
292-- allow for leap years
293assert(math.abs(os.difftime(t,t1)/(24*3600) - 365) < 2)
294
295t = os.time()
296t1 = os.time(os.date("*t"))
297assert(os.difftime(t1,t) <= 2)
298
299local t1 = os.time{year=2000, month=10, day=1, hour=23, min=12, sec=17}
300local t2 = os.time{year=2000, month=10, day=1, hour=23, min=10, sec=19}
301assert(os.difftime(t1,t2) == 60*2-2)
302
303io.output(io.stdout)
304local d = os.date('%d')
305local m = os.date('%m')
306local a = os.date('%Y')
307local ds = os.date('%w') + 1
308local h = os.date('%H')
309local min = os.date('%M')
310local s = os.date('%S')
311io.write(string.format('test done on %2.2d/%2.2d/%d', d, m, a))
312io.write(string.format(', at %2.2d:%2.2d:%2.2d\n', h, min, s))
313io.write(string.format('%s\n', _VERSION))
314