[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: luaL_loadfilex works fine only once per session under Windows.
- From: "Cezary H. Noweta" <chn@...>
- Date: Tue, 21 Jan 2014 09:12:34 +0100
Lua5.2.3, MSWin, CC/LIBC: MSC14.0 (aka VS2005, VC8.0)
The problem can be easily reproduced by a standalone lua.exe included in
a distribution:
=============
Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio
loadfile()()
print("Hello,")
^Z
Hello,
loadfile()()
print(" world!")
stdin:1: attempt to call a nil value
stack traceback:
stdin:1: in main chunk
[C]: in ?
stdin:1: attempt to call global 'rint' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: in ?
=============
The last error comes from ,,lua.exe'' - beyond ,,luaL_loadfilex'', but
it answers the question, where does the problem lie in.
The problem has appeared just after a 5.1=>5.2 transition, where
eof-testing-before-fread was put into ,,lauxlib.c:getF()''. Here is how
it goes:
1. The first chunk (until ,,^Z'' line) causes that an end-of-file
indicator of ,,stdin'' is set on.
2. I/O operations DO NOT clear the EOF indicator, despite they return a
valid, read characters. Thus, just before ,,lua_load()'', there is a
character ,,p'', which is read by
,,lauxlib.c:skipcomment()/lauxlib.c:skipBOM()''.
3. The only character ,,p'' is returned to ,,lua_load()'', then
,,lauxlib.c:getF()'' is called, which, in turn, returns ,,NULL''
(meaning end-of-chunk) because the EOF indicator of ,,stdin'' (thus
,,feof()'' test) is still set/true. The whole chunk ,,p'' results in a
syntax error and ,,nil'' value returned by ,,loadfile()''.
4. The last error message is caused by the remaining content of an input
buffer ,,rint(" world!")\r\n'', which is read by ,,lua.exe''.
AFAIR, Unix teletype devices, once opened, allow to read data beyond
,,^D'' without reopening the device, and Unices' LIBCs are completely
responsible for EOF handling, too. (However, they handle EOF better, I
hope.)
The sole functions of MS LIBC, which clear an end-of-file
indicator are: ,,clearerr()'', ,,rewind()'', ,,fseek()'' and callers of
them such as ,,fsetpos()''. ,,clearerr()'' is called by ,,liolib.c'' so
using of that function does not extend the LIBC requirements a lot.
,,clearerr()'' can be inserted just before ,,lua_load()'' in case of ,,c
!= EOF'' or it can enclose main body of ,,luaL_loadfilex()'' as
,,fopen()/fclose()'' do:
=============
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
- lf.f = stdin;
+ clearerr((lf.f = stdin));
}
=============
if (filename) fclose(lf.f); /* close file (even in case of errors) */
+ else clearerr(lf.f);
=============
--
-- best regards
Cezary H. Noweta