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

View File

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

View File

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