diff --git a/examples/jse/ScriptEngineSample.java b/examples/jse/ScriptEngineSample.java index ec9b638b..5dc75e63 100644 --- a/examples/jse/ScriptEngineSample.java +++ b/examples/jse/ScriptEngineSample.java @@ -97,7 +97,7 @@ public class ScriptEngineSample { "print(\"string written using 'print'\")\n" + "io.write(\"string written using 'io.write()'\\n\")\n" + "io.stdout:write(\"string written using 'io.stdout:write()'\\n\")\n" + - "io.stderr:write(\"string written using 'io.stderr:write()'\\n\")\n" + + "io.stderr:write(\"string written using 'io.stderr:write(), hit return to continue...'\\n\")\n" + "io.write([[string read using 'io.stdin:read(\"*l\")':]]..io.stdin:read(\"*l\")..\"\\n\")\n"; System.out.println("Evaluating script with redirection set."); @@ -114,7 +114,7 @@ public class ScriptEngineSample { e.getContext().setReader(null); e.getContext().setWriter(null); e.getContext().setErrorWriter(null); - e.eval(script); + e.eval(script); // Will wait for a line from the user at this step! System.out.println("output::>"+output+"<::output"); System.out.println("errors::>"+errors+"<::errors"); diff --git a/src/core/org/luaj/vm2/lib/IoLib.java b/src/core/org/luaj/vm2/lib/IoLib.java index 9da029f9..d510ebc2 100644 --- a/src/core/org/luaj/vm2/lib/IoLib.java +++ b/src/core/org/luaj/vm2/lib/IoLib.java @@ -111,6 +111,14 @@ public class IoLib extends OneArgFunction { } } + /** Enumerated value representing stdin */ + protected static final int FTYPE_STDIN = 0; + /** Enumerated value representing stdout */ + protected static final int FTYPE_STDOUT = 1; + /** Enumerated value representing stderr */ + protected static final int FTYPE_STDERR = 2; + /** Enumerated value representing a file type for a named file */ + protected static final int FTYPE_NAMED = 3; /** * Wrap the standard input. @@ -126,6 +134,13 @@ public class IoLib extends OneArgFunction { */ abstract protected File wrapStdout() throws IOException; + /** + * Wrap the standard error output. + * @return File + * @throws IOException + */ + abstract protected File wrapStderr() throws IOException; + /** * Open a file in a particular mode. * @param filename @@ -295,7 +310,7 @@ public class IoLib extends OneArgFunction { } private File input() { - return infile!=null? infile: (infile=ioopenfile("-","r")); + return infile!=null? infile: (infile=ioopenfile(FTYPE_STDIN, "-","r")); } // io.flush() -> bool @@ -320,7 +335,7 @@ public class IoLib extends OneArgFunction { // io.input([file]) -> file public Varargs _io_input(LuaValue file) { infile = file.isnil()? input(): - file.isstring()? ioopenfile(file.checkjstring(),"r"): + file.isstring()? ioopenfile(FTYPE_NAMED, file.checkjstring(),"r"): checkfile(file); return infile; } @@ -328,7 +343,7 @@ public class IoLib extends OneArgFunction { // io.output(filename) -> file public Varargs _io_output(LuaValue filename) { outfile = filename.isnil()? output(): - filename.isstring()? ioopenfile(filename.checkjstring(),"w"): + filename.isstring()? ioopenfile(FTYPE_NAMED, filename.checkjstring(),"w"): checkfile(filename); return outfile; } @@ -348,12 +363,12 @@ public class IoLib extends OneArgFunction { // io.open(filename, [mode]) -> file | nil,err public Varargs _io_open(String filename, String mode) throws IOException { - return rawopenfile(filename, mode); + return rawopenfile(FTYPE_NAMED, filename, mode); } // io.lines(filename) -> iterator public Varargs _io_lines(String filename) { - infile = filename==null? input(): ioopenfile(filename,"r"); + infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r"); checkopen(infile); return lines(infile); } @@ -420,16 +435,16 @@ public class IoLib extends OneArgFunction { } private File output() { - return outfile!=null? outfile: (outfile=ioopenfile("-","w")); + return outfile!=null? outfile: (outfile=ioopenfile(FTYPE_STDOUT,"-","w")); } private File errput() { - return errfile!=null? errfile: (errfile=ioopenfile("-","w")); + return errfile!=null? errfile: (errfile=ioopenfile(FTYPE_STDERR,"-","w")); } - private File ioopenfile(String filename, String mode) { + private File ioopenfile(int filetype, String filename, String mode) { try { - return rawopenfile(filename, mode); + return rawopenfile(filetype, filename, mode); } catch ( Exception e ) { error("io error: "+e.getMessage()); return null; @@ -517,15 +532,14 @@ public class IoLib extends OneArgFunction { error("attempt to use a closed file"); return file; } - - private File rawopenfile(String filename, String mode) throws IOException { - boolean isstdfile = "-".equals(filename); - boolean isreadmode = mode.startsWith("r"); - if ( isstdfile ) { - return isreadmode? - wrapStdin(): - wrapStdout(); + + private File rawopenfile(int filetype, String filename, String mode) throws IOException { + switch (filetype) { + case FTYPE_STDIN: return wrapStdin(); + case FTYPE_STDOUT: return wrapStdout(); + case FTYPE_STDERR: return wrapStderr(); } + boolean isreadmode = mode.startsWith("r"); boolean isappend = mode.startsWith("a"); boolean isupdate = mode.indexOf("+") > 0; boolean isbinary = mode.endsWith("b"); diff --git a/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java b/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java index f1f2e20a..676a110d 100644 --- a/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java +++ b/src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java @@ -75,6 +75,10 @@ public class JmeIoLib extends IoLib { return new FileImpl(globals.STDOUT); } + protected File wrapStderr() throws IOException { + return new FileImpl(globals.STDERR); + } + protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { String url = "file:///" + filename; int mode = readMode? Connector.READ: Connector.READ_WRITE; diff --git a/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java b/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java index 2416cd37..54b3fcfd 100644 --- a/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java +++ b/src/jse/org/luaj/vm2/lib/jse/JseIoLib.java @@ -23,9 +23,11 @@ package org.luaj.vm2.lib.jse; import java.io.BufferedInputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PrintStream; import java.io.RandomAccessFile; import org.luaj.vm2.LuaError; @@ -68,11 +70,15 @@ import org.luaj.vm2.lib.LibFunction; public class JseIoLib extends IoLib { protected File wrapStdin() throws IOException { - return new FileImpl(globals.STDIN); + return new StdinFile(); } protected File wrapStdout() throws IOException { - return new FileImpl(globals.STDOUT); + return new StdoutFile(FTYPE_STDOUT); + } + + protected File wrapStderr() throws IOException { + return new StdoutFile(FTYPE_STDERR); } protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { @@ -103,6 +109,7 @@ public class JseIoLib extends IoLib { throw new LuaError("not implemented"); } + private final class FileImpl extends File { private final RandomAccessFile file; private final InputStream is; @@ -215,4 +222,120 @@ public class JseIoLib extends IoLib { return length; } } + + private final class StdoutFile extends File { + private final int file_type; + + private StdoutFile(int file_type) { + this.file_type = file_type; + } + + public String tojstring() { + return "file ("+this.hashCode()+")"; + } + + private final PrintStream getPrintStream() { + return file_type == FTYPE_STDERR? + globals.STDERR: + globals.STDOUT; + } + + public void write(LuaString string) throws IOException { + getPrintStream().write(string.m_bytes, string.m_offset, string.m_length); + } + + public void flush() throws IOException { + getPrintStream().flush(); + } + + public boolean isstdfile() { + return true; + } + + public void close() throws IOException { + // do not close std files. + } + + public boolean isclosed() { + return false; + } + + public int seek(String option, int bytecount) throws IOException { + return 0; + } + + public void setvbuf(String mode, int size) { + } + + public int remaining() throws IOException { + return 0; + } + + public int peek() throws IOException, EOFException { + return 0; + } + + public int read() throws IOException, EOFException { + return 0; + } + + public int read(byte[] bytes, int offset, int length) + throws IOException { + return 0; + } + } + + private final class StdinFile extends File { + private StdinFile() { + } + + public String tojstring() { + return "file ("+this.hashCode()+")"; + } + + public void write(LuaString string) throws IOException { + } + + public void flush() throws IOException { + } + + public boolean isstdfile() { + return true; + } + + public void close() throws IOException { + // do not close std files. + } + + public boolean isclosed() { + return false; + } + + public int seek(String option, int bytecount) throws IOException { + return 0; + } + + public void setvbuf(String mode, int size) { + } + + public int remaining() throws IOException { + return 0; + } + + public int peek() throws IOException, EOFException { + globals.STDIN.mark(1); + int c = globals.STDIN.read(); + globals.STDIN.reset(); + return c; + } + + public int read() throws IOException, EOFException { + return globals.STDIN.read(); + } + + public int read(byte[] bytes, int offset, int length) + throws IOException { + return globals.STDIN.read(bytes, offset, length); + } + } }