[tcljava-dev] PATCH: stdout flushing, mods for Swank
Brought to you by:
mdejong
From: Tom P. <tpo...@ny...> - 2002-07-01 05:00:26
|
Here's a patch that is similar in function to Shawn Boyce's recent patch, but works by only causing a flush on stdout when it is attached to a tty. Shawn's patch causes a flush for every puts on every file, which seems a little heavy handed. I modified 'jaclsh' to run the 'tty' program (on most Unix systems), which sets a property. The property is checked in the Interp() constructor. The StdChannel driver adds a flush if writing to stdout and the tty flag is set. Also, in Interp.eventuallyDispose(), all open file channels are flushed. My patch also includes the two minor fixes that are needed to run Swank in the stock Jacl interpreter, making TCL.OK and Interp.allowExceptions() public. And my jaclsh adds JACL_PROPS on the java command line to allow passing extra -Dxxxx=yyyy property values. -- Tom Poindexter tpo...@ny... http://www.nyx.net/~tpoindex/ diff -c -r tcljava.cvs/jaclsh.in tcljava.tp/jaclsh.in *** tcljava.cvs/jaclsh.in Sun Jun 30 22:24:16 2002 --- tcljava.tp/jaclsh.in Sun Jun 30 22:27:55 2002 *************** *** 30,35 **** --- 30,39 ---- # The arguments to the JAVA command JAVA_FLAGS="@JAVA_FLAGS@" + # Set jacl.tty property to 'tty' exit code, affects stdout flush behavior + tty -s >/dev/null 2>&1 + JACL_TTY="-Djacl.tty=$?" + # Run java with the args passed in from the calling environment # We must set the CLASSPATH env var instead of using the -classpath # argument because jacl might want to exec a program that also *************** *** 38,41 **** CLASSPATH=${JACL_CLASSPATH}:${CLASSPATH} export CLASSPATH ! exec ${JAVA} ${JAVA_FLAGS} tcl.lang.Shell ${1+"$@"} --- 42,45 ---- CLASSPATH=${JACL_CLASSPATH}:${CLASSPATH} export CLASSPATH ! exec ${JAVA} ${JAVA_FLAGS} ${JACL_TTY} ${JACL_PROPS} tcl.lang.Shell ${1+"$@"} diff -c -r tcljava.cvs/src/jacl/tcl/lang/Interp.java tcljava.tp/src/jacl/tcl/lang/Interp.java *** tcljava.cvs/src/jacl/tcl/lang/Interp.java Fri Apr 12 15:00:26 2002 --- tcljava.tp/src/jacl/tcl/lang/Interp.java Sun Jun 30 22:29:15 2002 *************** *** 162,167 **** --- 162,171 ---- boolean isSafe; + // Is the standard output a tty? Set via system property + + boolean isTty; + // Offset of character just after last one compiled or executed // by Parser.eval2(). *************** *** 327,332 **** --- 331,337 ---- scriptFile = null; flags = 0; isSafe = false; + isTty = false; assocData = null; *************** *** 404,409 **** --- 409,425 ---- TCL.GLOBAL_ONLY); } + // Check system property if running on a tty, so that we know to flush + // stdout output on each write. A "jacl.tty" property set to + // "0" means running stdin is a tty. + // This allows the exit code from the Unix 'tty' program to be used. + // Windows or MacOS < 10 will need to manually set the property. + String jaclTtyProp = Util.tryGetSystemProperty("jacl.tty", "1"); + if (jaclTtyProp.equals("0")) { + isTty = true; + } + + // Create the env array an populated it with proper // values. *************** *** 541,546 **** --- 557,573 ---- } } + // Flush all channels + for (Enumeration e = interpChanTable.keys(); e.hasMoreElements();) { + Object key = e.nextElement(); + Channel chan = (Channel) interpChanTable.get(key); + try { + chan.flush(this); + } catch (Exception ex) { + // Ignore flush error + } + } + // Finish deleting the global namespace. // FIXME : check impl of Tcl_DeleteNamespace *************** *** 3724,3730 **** *---------------------------------------------------------------------- */ ! void allowExceptions() { evalFlags |= Parser.TCL_ALLOW_EXCEPTIONS; --- 3751,3757 ---- *---------------------------------------------------------------------- */ ! public void allowExceptions() { evalFlags |= Parser.TCL_ALLOW_EXCEPTIONS; diff -c -r tcljava.cvs/src/jacl/tcl/lang/StdChannel.java tcljava.tp/src/jacl/tcl/lang/StdChannel.java *** tcljava.cvs/src/jacl/tcl/lang/StdChannel.java Wed Jan 23 02:53:49 2002 --- tcljava.tp/src/jacl/tcl/lang/StdChannel.java Sun Jun 30 22:29:22 2002 *************** *** 138,144 **** // The OutputStreamWriter class will buffer even if you don't // wrap it in a BufferedWriter. The stderr file object must // not require an explicit flush so we just hack a flush in. ! if (stdType == STDERR) flush(interp); } --- 138,145 ---- // The OutputStreamWriter class will buffer even if you don't // wrap it in a BufferedWriter. The stderr file object must // not require an explicit flush so we just hack a flush in. ! // Also flush if stdout and interp is connected to a tty ! if (stdType == STDERR || (stdType == STDOUT && interp.isTty)) flush(interp); } diff -c -r tcljava.cvs/src/tcljava/tcl/lang/TCL.java tcljava.tp/src/tcljava/tcl/lang/TCL.java *** tcljava.cvs/src/tcljava/tcl/lang/TCL.java Sun May 14 17:10:20 2000 --- tcljava.tp/src/tcljava/tcl/lang/TCL.java Sun Jun 30 22:30:02 2002 *************** *** 59,65 **** // the completion code TCL.OK. If the desired completion code is TCL.OK, no // exception should be thrown. ! static final int OK = 0; // The following value is used by the Interp::commandComplete(). It's used // to report that a script is not complete. --- 59,65 ---- // the completion code TCL.OK. If the desired completion code is TCL.OK, no // exception should be thrown. ! public static final int OK = 0; // The following value is used by the Interp::commandComplete(). It's used // to report that a script is not complete. |