Improve io lib error reporting and behavior.

This commit is contained in:
James Roseborough
2010-05-17 00:45:59 +00:00
parent ce13cc8621
commit 3167e3c838
3 changed files with 46 additions and 31 deletions

View File

@@ -230,7 +230,7 @@ public class IoLib extends OneArgFunction {
case IO_TYPE: return iolib._io_type(args.arg1()); case IO_TYPE: return iolib._io_type(args.arg1());
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r")); case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r")); case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
case IO_LINES: return iolib._io_lines(args.arg1()); case IO_LINES: return iolib._io_lines(args.isvalue(1)? args.checkjstring(1): null);
case IO_READ: return iolib._io_read(args); case IO_READ: return iolib._io_read(args);
case IO_WRITE: return iolib._io_write(args); case IO_WRITE: return iolib._io_write(args);
@@ -310,8 +310,8 @@ public class IoLib extends OneArgFunction {
} }
// io.lines(filename) -> iterator // io.lines(filename) -> iterator
public Varargs _io_lines(LuaValue filename) { public Varargs _io_lines(String filename) {
infile = filename.isnil()? input(): ioopenfile(filename.checkjstring(),"r"); infile = filename==null? input(): ioopenfile(filename,"r");
checkopen(infile); checkopen(infile);
return lines(infile); return lines(infile);
} }
@@ -433,24 +433,29 @@ public class IoLib extends OneArgFunction {
private Varargs ioread(File f, Varargs args) throws IOException { private Varargs ioread(File f, Varargs args) throws IOException {
int i,n=args.narg(); int i,n=args.narg();
LuaValue[] v = new LuaValue[n]; LuaValue[] v = new LuaValue[n];
for ( i=0; i<n; i++ ) { LuaValue ai,vi;
if ( args.isnumber(i+1) ) { LuaString fmt;
v[i] = freadbytes(f,args.checkint(i+1)); for ( i=0; i<n; ) {
} else { item: switch ( (ai = args.arg(i+1)).type() ) {
String format = args.checkjstring(i+1); case LuaValue.TNUMBER:
if ( "*n".equals(format) ) vi = freadbytes(f,ai.toint());
v[i] = valueOf( freadnumber(f) ); break item;
else if ( "*a".equals(format) ) case LuaValue.TSTRING:
v[i] = freadall(f); fmt = ai.checkstring();
else if ( "*l".equals(format) ) if ( fmt.m_length == 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
v[i] = freadline(f); switch ( fmt.m_bytes[fmt.m_offset+1] ) {
else case 'n': vi = freadnumber(f); break item;
argerror( i+1, "(invalid format)" ); case 'l': vi = freadline(f); break item;
case 'a': vi = freadall(f); break item;
}
}
default:
return argerror( i+1, "(invalid format)" );
} }
if ( v[i].isnil() ) if ( (v[i++] = vi).isnil() )
return i==0? NIL: varargsOf(v,0,i); break;
} }
return varargsOf(v); return i==0? NIL: varargsOf(v, 0, i);
} }
private static File checkfile(LuaValue val) { private static File checkfile(LuaValue val) {
@@ -529,7 +534,7 @@ public class IoLib extends OneArgFunction {
return freaduntil(f,false); return freaduntil(f,false);
} }
} }
public static double freadnumber(File f) throws IOException { public static LuaValue freadnumber(File f) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
freadchars(f," \t\r\n",null); freadchars(f," \t\r\n",null);
freadchars(f,"-+",baos); freadchars(f,"-+",baos);
@@ -542,7 +547,7 @@ public class IoLib extends OneArgFunction {
// freadchars(f,"+-",baos); // freadchars(f,"+-",baos);
//freadchars(f,"0123456789",baos); //freadchars(f,"0123456789",baos);
String s = baos.toString(); String s = baos.toString();
return s.length()>0? Double.parseDouble(s): 0; return s.length()>0? valueOf( Double.parseDouble(s) ): NIL;
} }
private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException { private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException {
int c; int c;

View File

@@ -159,8 +159,9 @@ public class JseIoLib extends IoLib {
is.reset(); is.reset();
return c; return c;
} else if ( file != null ) { } else if ( file != null ) {
long fp = file.getFilePointer();
int c = file.read(); int c = file.read();
file.seek(file.getFilePointer()-1); file.seek(fp);
return c; return c;
} }
notimplemented(); notimplemented();

View File

@@ -11,38 +11,44 @@ checkallpass('io.close',{{f}})
checkallerrors('io.close',{notanil},'bad argument') checkallerrors('io.close',{notanil},'bad argument')
-- io.input ([file]) -- io.input ([file])
banner('io.input')
f = io.open("abc.txt","r") f = io.open("abc.txt","r")
checkallpass('io.input',{{nil,f,"abc.txt",n=3}}) checkallpass('io.input',{{nil,f,"abc.txt",n=3}})
checkallerrors('io.input',{nonstring},'bad argument') checkallerrors('io.input',{nonstring},'bad argument')
-- io.lines ([filename]) -- io.lines ([filename])
banner('io.lines')
io.input("abc.txt") io.input("abc.txt")
checkallpass('io.lines',{{nil,"abc.txt",n=2}}) checkallpass('io.lines',{{"abc.txt"}})
checkallerrors('io.lines',{{f}},'bad argument') checkallerrors('io.lines',{{f}},'bad argument')
checkallerrors('io.lines',{nonstring},'bad argument') checkallerrors('io.lines',{notastring},'bad argument')
-- io.open (filename [, mode]) -- io.open (filename [, mode])
banner('io.open')
checkallpass('io.open',{{"abc.txt"},{nil,"r","w","a","r+","w+","a+"}}) checkallpass('io.open',{{"abc.txt"},{nil,"r","w","a","r+","w+","a+"}})
checkallerrors('io.open',{notastring},'bad argument') checkallerrors('io.open',{notastring},'bad argument')
checkallerrors('io.open',{{"abc.txt"},{nonstring}},'bad argument') checkallerrors('io.open',{{"abc.txt"},{nonstring}},'bad argument')
-- io.output ([file]) -- io.output ([file])
banner('io.output')
checkallpass('io.output',{{nil,f,"abc.txt",n=3}}) checkallpass('io.output',{{nil,f,"abc.txt",n=3}})
checkallerrors('io.output',{nonstring},'bad argument') checkallerrors('io.output',{nonstring},'bad argument')
-- io.popen (prog [, mode]) -- io.popen (prog [, mode])
checkallpass('io.popen',{{"hostname"},{nil,"w",n=2}}) banner('io.popen')
--checkallpass('io.popen',{{"hostname"},{nil,"w",n=2}})
checkallerrors('io.popen',{notastring},'bad argument') checkallerrors('io.popen',{notastring},'bad argument')
checkallerrors('io.popen',{{"hostname"},{nonstring}},'bad argument') checkallerrors('io.popen',{{"hostname"},{nonstring}},'bad argument')
-- io.read (···) -- io.read (<EFBFBD><EFBFBD><EFBFBD>)
local areadfmt = {2,"*n","*a","*l","3"} banner('io.read')
checkallpass('io.read',{}) checkallpass('io.read',{})
checkallpass('io.read',{areadfmt}) checkallpass('io.read',{{2,"*n","*a","*l"}})
checkallpass('io.read',{areadfmt,areadfmt}) checkallpass('io.read',{{2,"*n","*a","*l"},{2,"*a","*l"}})
checkallerrors('io.read',{{aboolean,afunction,atable}},'bad argument') checkallerrors('io.read',{{aboolean,afunction,atable,"3"}},'bad argument')
-- io.read (···) -- io.write (<28><><EFBFBD>)
banner('io.write')
checkallpass('io.write',{}) checkallpass('io.write',{})
checkallpass('io.write',{somestring}) checkallpass('io.write',{somestring})
checkallpass('io.write',{somestring,somestring}) checkallpass('io.write',{somestring,somestring})
@@ -50,6 +56,7 @@ checkallerrors('io.write',{nonstring},'bad argument')
checkallerrors('io.write',{somestring,nonstring},'bad argument') checkallerrors('io.write',{somestring,nonstring},'bad argument')
-- file:write () -- file:write ()
banner('file:write')
file = io.open("seektest.txt","w") file = io.open("seektest.txt","w")
checkallpass('file.write',{{file},somestring}) checkallpass('file.write',{{file},somestring})
checkallpass('file.write',{{file},somestring,somestring}) checkallpass('file.write',{{file},somestring,somestring})
@@ -59,6 +66,7 @@ checkallerrors('file.write',{{file},somestring,nonstring},'bad argument')
pcall( file.close, file ) pcall( file.close, file )
-- file:seek ([whence] [, offset]) -- file:seek ([whence] [, offset])
banner('file:seek')
file = io.open("seektest.txt","r") file = io.open("seektest.txt","r")
checkallpass('file.seek',{{file}}) checkallpass('file.seek',{{file}})
checkallpass('file.seek',{{file},{"set","cur","end"}}) checkallpass('file.seek',{{file},{"set","cur","end"}})
@@ -68,6 +76,7 @@ checkallerrors('file.seek',{{file},nonstring},'bad argument')
checkallerrors('file.seek',{{file},{"set","cur","end"},nonnumber},'bad argument') checkallerrors('file.seek',{{file},{"set","cur","end"},nonnumber},'bad argument')
-- file:setvbuf (mode [, size]) -- file:setvbuf (mode [, size])
banner('file:setvbuf')
checkallpass('file.setvbuf',{{file},{"no","full","line"}}) checkallpass('file.setvbuf',{{file},{"no","full","line"}})
checkallpass('file.setvbuf',{{file},{"full"},{1024,"512"}}) checkallpass('file.setvbuf',{{file},{"full"},{1024,"512"}})
checkallerrors('file.setvbuf',{},'bad argument') checkallerrors('file.setvbuf',{},'bad argument')