Thread: [tcljava-user] help - how to execute a tcl from java
Brought to you by:
mdejong
From: rohit <roh...@ya...> - 2007-10-01 08:00:21
|
good morning, am trying to execute a simple tcl script from a java stub. below is the java stub and the tcl script. i am able to execute the script. however, i need to get the results of the tcl script execution into a output stream / buffer in the calling java stub. i am not able to figure how this is done. please help ! any pointers/suggestions will be highly appreciated java stub : Interp interp = new Interp(); try { interp.evalFile("test.tcl"); System.out.println("running tcl done."); } catch (TclException ex) { // some exception handling } } finally { interp.dispose(); } test.tcl contents : set a 3 set b 4 set message "c = sqrt($a*$a+$b*$b) = [expr sqrt($a*$a+$b*$b)]" puts $message going, going, ... gone. --------------------------------- Luggage? GPS? Comic books? Check out fitting gifts for grads at Yahoo! Search. |
From: Horace A. 'K. V. <ha...@ha...> - 2007-10-01 19:37:33
|
to get the retultsd of the puts in the tcl, maybe something like ... interp.getResult().toString(); ...following the eval call? > java stub : > Interp interp = new Interp(); > > try { > interp.evalFile("test.tcl"); System.out.print(interp.getResult().toString()); > System.out.println("running tcl done."); > } > catch (TclException ex) { > // some exception handling > } > } > finally { > interp.dispose(); > } > > test.tcl contents : > set a 3 > set b 4 > set message "c = sqrt($a*$a+$b*$b) = [expr sqrt($a*$a+$b*$b)]" > puts $message > -- Horace ...once known as "Kicker" :-) ================================================================ ...drop by and chat if I'm online http://www.hav.com/chat/ ...or chuckle at a little left hand fingertip torture http://www.hav.com/junk/ After silence, that which comes nearest to expressing the inexpressible is music - Aldous Huxley, "Music at Night", 1931 ... and that which comes nearest to explaining the inexplicable is my insistence on trying to play it - hav '06 :-)) ================================================================ Horace Vallas hav.Software http://www.hav.com/ 4660 Francisco Rd. ha...@ha... Pensacola, Fl. 32504 USA 850-207-7009 Thawte Web Of Trust Notary in Pensacola, Fl. http://www.hav.com/?content=/thawteWOTnotary.htm |
From: Mo D. <mo...@mo...> - 2007-10-01 21:57:37
Attachments:
guishell.patch
|
rohit wrote: > good morning, > > am trying to execute a simple tcl script from a java stub. below is > the java stub and the tcl script. > > i am able to execute the script. however, i need to get the results of > the tcl script execution into a output stream / buffer in the calling > java stub. i am not able to figure how this is done. please help ! > > any pointers/suggestions will be highly appreciated > > java stub : > Interp interp = new Interp(); > > try { > interp.evalFile("test.tcl"); > System.out.println("running tcl done."); > } > catch (TclException ex) { > // some exception handling > } > } > finally { > interp.dispose(); > } > > test.tcl contents : > set a 3 > set b 4 > set message "c = sqrt($a*$a+$b*$b) = [expr sqrt($a*$a+$b*$b)]" > puts $message > Hello Rohit Folks keep asking for this sort of functionality in Jacl, so I went ahead and created a patch to make this much easier. What I did was make the tcl.lang.StdChannel class public and add the methods setIn, setOut, and setErr. These work like the same methods in the Java System class except that the streams will store only data written to stdout or stderr from Tcl. I also updated the extras/GuiShell/GuiShell.java example so that it works with swing under JDK 1.4 and makes use of the new methods in the StdChannel class to implement the kind of redirection you want to do. I think a working example shows exactly what is needed. You can apply this patch to the CVS or just grab the CVS tree fresh. Another approach you could use, which is a lot more simple would be to overload the puts command and then save the results in a variable. Your script could then set the interp result at the end to be the value of this variable. you could also just set the interp result directly, instead of worrying about using puts, but it depends on what you are wanting to do. I hope that thelps Mo DeJong |
From: rohit <roh...@ya...> - 2007-10-03 07:37:42
|
thanks, all for your responses i got what i was looking for after looking into GUIShell.java and google-ing a bit lines below were added to my java stub before "interp.evalFile("test.tcl");" to get the output of the execution to a text file stdout = System.out; stderr = System.err; FileOutputStream iosFile = new FileOutputStream("output.txt"); PrintStream ps = new PrintStream(iosFile); System.setOut(ps); System.setErr(ps); thanks ! going, going, ... gone. Mo DeJong <mo...@mo...> wrote: rohit wrote: > good morning, > > am trying to execute a simple tcl script from a java stub. below is > the java stub and the tcl script. > > i am able to execute the script. however, i need to get the results of > the tcl script execution into a output stream / buffer in the calling > java stub. i am not able to figure how this is done. please help ! > > any pointers/suggestions will be highly appreciated > > java stub : > Interp interp = new Interp(); > > try { > interp.evalFile("test.tcl"); > System.out.println("running tcl done."); > } > catch (TclException ex) { > // some exception handling > } > } > finally { > interp.dispose(); > } > > test.tcl contents : > set a 3 > set b 4 > set message "c = sqrt($a*$a+$b*$b) = [expr sqrt($a*$a+$b*$b)]" > puts $message > Hello Rohit Folks keep asking for this sort of functionality in Jacl, so I went ahead and created a patch to make this much easier. What I did was make the tcl.lang.StdChannel class public and add the methods setIn, setOut, and setErr. These work like the same methods in the Java System class except that the streams will store only data written to stdout or stderr from Tcl. I also updated the extras/GuiShell/GuiShell.java example so that it works with swing under JDK 1.4 and makes use of the new methods in the StdChannel class to implement the kind of redirection you want to do. I think a working example shows exactly what is needed. You can apply this patch to the CVS or just grab the CVS tree fresh. Another approach you could use, which is a lot more simple would be to overload the puts command and then save the results in a variable. Your script could then set the interp result at the end to be the value of this variable. you could also just set the interp result directly, instead of worrying about using puts, but it depends on what you are wanting to do. I hope that thelps Mo DeJong 2007-10-01 Mo DeJong * extras/GuiShell/GuiShell.java: Reimplement GuiShell example so that it uses standard swing package names and makes use of new StdChannel.setOut() and StdChannel.setErr() APIs to redirect output. The GuiShell example now exists in the global package instead of having to live in the tcl.lang package. * extras/GuiShell/README: * extras/GuiShell/swingempty.jar: Removed. * src/jacl/tcl/lang/StdChannel.java (setIn, setOut, setErr): Add new methods used to set the stdin, stdout, and stderr streams used by Jacl. This is more precise than just resetting the streams used by Java since it provides a way for an application to read just the results of Tcl's puts command. Index: extras/GuiShell/GuiShell.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/extras/GuiShell/GuiShell.java,v retrieving revision 1.2 diff -u -r1.2 GuiShell.java --- extras/GuiShell/GuiShell.java 13 Mar 2003 22:28:10 -0000 1.2 +++ extras/GuiShell/GuiShell.java 1 Oct 2007 21:41:29 -0000 @@ -1,40 +1,17 @@ -package tcl.lang; +import tcl.lang.*; -// We can not compile outside of the tcl.lang package -// the perms inside jacl need to be fixed before this will work -//import tcl.lang.*; +import java.io.*; import java.awt.*; import java.awt.event.*; -import java.io.*; - -// we need to incluse swingempty.jar in CLASSPATH so we -// can compile with swing 1.0 and 1.1 - -import com.sun.java.swing.*; -import com.sun.java.swing.text.*; -import com.sun.java.swing.event.*; - import javax.swing.*; import javax.swing.text.*; import javax.swing.event.*; - public class GuiShell { - private static String pre_swing; - - static { - Class c = UIManager.class; - String c_name = c.getName(); - - pre_swing = "com.sun.java.swing"; - if (c_name.startsWith(pre_swing)) { - pre_swing = "javax.swing"; - } - - } + private static String pre_swing = "javax.swing"; public GuiShell() { @@ -54,7 +31,7 @@ - frame = new JFrame("Main"); + frame = new JFrame("GuiShell"); frame.setSize(500,350); frame.setLocation(100,100); frame.addWindowListener(closer); @@ -69,7 +46,6 @@ append("% "); - JScrollPane scroller = new JScrollPane(edit,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); @@ -85,29 +61,23 @@ public void setupInterp() { try { - interp.setVar("argv0", "tcl.lang.Shell", TCL.GLOBAL_ONLY); - interp.setVar("tcl_interactive", "1", TCL.GLOBAL_ONLY); + interp.setVar("argv0", TclString.newInstance("tcl.lang.Shell"), TCL.GLOBAL_ONLY); + interp.setVar("tcl_interactive", TclString.newInstance("1"), TCL.GLOBAL_ONLY); interp.setVar("argv", TclList.newInstance(), TCL.GLOBAL_ONLY); - interp.setVar("argc", "0", TCL.GLOBAL_ONLY); + interp.setVar("argc", TclString.newInstance("0"), TCL.GLOBAL_ONLY); } catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e); } - ThreadedTclEventLoop tsr = new ThreadedTclEventLoop(); - Thread t = new Thread(tsr); + Thread t = new Thread(tsr); t.setPriority(Thread.MIN_PRIORITY); t.setDaemon(true); t.start(); - - } - - - public class ThreadedTclEventLoop implements Runnable { public void run() { @@ -121,53 +91,72 @@ } + public void setupStreamReaders() { + try { + // Save original stdout and stderr + _stdout = System.out; + _stderr = System.err; + pout = new PipedOutputStream(); + ps = new PrintStream(pout); + // Connect the PipedInputStream to the PipedOutputStream, + // so that a read on the pin instance will read data + // from the pout instance. - public void setupStreamReaders() { - - try { - stdout = System.out; - stderr = System.err; pin = new PipedInputStream(); - pout = new PipedOutputStream(pin); - ps = new PrintStream(pout); - System.setOut(ps); - System.setErr(ps); + pin.connect(pout); + + // Use Jacl's IO redirection API to send stdout and stderr + // to the PipedOutputStream. + + StdChannel.setOut(ps); + StdChannel.setErr(ps); + } catch (java.io.IOException e) { - e.printStackTrace(stderr); + e.printStackTrace(_stderr); } - ThreadedStreamReader tsr = new ThreadedStreamReader(); - Thread t = new Thread(tsr); + Thread t = new Thread(tsr); //t.setPriority(Thread.MIN_PRIORITY); t.setDaemon(true); t.start(); - } - - + + // This class reads from a PipedInputStream, it is connected + // to a PipedOutputStream that has been set as the output + // channel for both stdout and stderr in the Jacl interpreter. + // The result is that a command like "puts HELLO" will result + // in the string "HELLO" being read by this method. public class ThreadedStreamReader implements Runnable { - + public void run() { + final boolean debug = false; + + if (debug) { + _stderr.println("Entered ThreadedStreamReader.run()"); + } + BufferedReader br = new BufferedReader(new InputStreamReader(pin)); - + String nextline = null; - + while (true) { try { - nextline = br.readLine() + "\n"; - doc.insertString(doc.getLength(), nextline, null); - edit.setCaretPosition(doc.getLength()); - + nextline = br.readLine() + "\n"; + if (debug) { + _stderr.println("readLine() -> \"" + nextline + "\""); + } + doc.insertString(doc.getLength(), nextline, null); + edit.setCaretPosition(doc.getLength()); } catch (IOException e) { - e.printStackTrace(stderr); + e.printStackTrace(_stderr); } catch (BadLocationException e) { - e.printStackTrace(stderr); + e.printStackTrace(_stderr); } } @@ -203,9 +192,11 @@ public void processCommand() { + final boolean debug = false; - //System.out.println("now to process event"); - + if (debug) { + System.out.println("now to process event"); + } if (cmd_buff.length() == 0) { return; @@ -240,15 +231,10 @@ append("command returned bad code: " + code + "\n"); } } - - - //System.out.println("done processing event"); - - //try to read any data still floating around in stdout or stderr - - System.out.flush(); - System.err.flush(); + if (debug) { + System.out.println("done processing event"); + } Thread.yield(); Thread.yield(); @@ -282,47 +268,47 @@ - //append this string into the text widget + // append this string into the text widget + public void append(String str) { try { doc.insertString(doc.getLength(),str,null); + edit.setCaretPosition(doc.getLength()); } catch (BadLocationException e) { throw new RuntimeException(e.toString()); } } - - //delete char from the end of the widget public void removeLastChar() { try { doc.remove(doc.getLength()-1,1); + edit.setCaretPosition(doc.getLength()); } catch (BadLocationException e) { throw new RuntimeException(e.toString()); } } - - - public class Editor extends JEditorPane { - - private final boolean debug = false; + + private static final boolean debug = false; protected void processComponentKeyEvent(KeyEvent e) { - if (debug) { - //System.out.println("processing " + e); + if (false && debug) { + System.out.println("processComponentKeyEvent " + e); } - if (e.getKeyCode() != 0) { - return; //only process key typed commands + // Ignore KEY_PRESSED and KEY_RELEASED, only process KEY_TYPED + // events in this method. + + return; } char c = e.getKeyChar(); @@ -332,7 +318,7 @@ } - //if they pressed Return + // if they pressed Return if (c == KeyEvent.VK_ENTER) { @@ -341,14 +327,14 @@ } cmd_buff.append("\n"); - append("\n"); + //append("\n"); if (isCommandComplete()) { processCommand(); cmd_buff.setLength(0); - + append("% "); } else { @@ -366,18 +352,17 @@ else if (c == KeyEvent.VK_BACK_SPACE || c == KeyEvent.VK_DELETE) { - //letter deleted + // letter deleted if (debug) { System.out.println("letter deleted"); } - //stop deleting at front of this line + // stop deleting at front of this line if (cur_line_chars != 0) { cmd_buff.setLength(cmd_buff.length() - 1); cur_line_chars--; - removeLastChar(); } else { if (debug) { System.out.println("begin of cur_line"); @@ -387,28 +372,18 @@ } else { - //for any other letter - cmd_buff.append(c); cur_line_chars++; - append(String.valueOf(c)); - } - - - /* if (debug) { System.out.println("after event process"); System.out.println("cmd_buff is \"" + cmd_buff + "\""); System.out.println("cmd_buff len is " + cmd_buff.length()); System.out.println("cur_line_chars is " + cur_line_chars); } - */ - edit.setCaretPosition(doc.getLength()); - } } @@ -433,8 +408,8 @@ private transient PipedOutputStream pout = null; private transient PrintStream ps = null; - private transient PrintStream stdout = null; - private transient PrintStream stderr = null; + private transient PrintStream _stdout = null; + private transient PrintStream _stderr = null; private transient Thread messageThread = null; private transient StringBuffer cmd_buff = new StringBuffer(200); Index: extras/GuiShell/README =================================================================== RCS file: /cvsroot/tcljava/tcljava/extras/GuiShell/README,v retrieving revision 1.1 diff -u -r1.1 README --- extras/GuiShell/README 8 May 1999 05:19:00 -0000 1.1 +++ extras/GuiShell/README 1 Oct 2007 21:41:29 -0000 @@ -3,20 +3,11 @@ of the tcl.lang.Shell class that ships with jacl. It is not included in the regular classes because it requires the Swing toolkit to work. -To compile the GuiShell program you will need to make sure the -swingempty.jar file is included on your CLASSPATH. You can then -compile GuiShell.java with swing 1.0 or swing 1.1. You will need -to include the created .class files on your CLASSPATH. Watch out -becasue the GuiShell classes are in the tcl.lang package so -you need to set up the directory structure correctly. The best way -to do this is to use the -d argument to javac. +To compile the GuiShell program, make sure the CLASSPATH is setup +properly and includes the Jacl jar files. Then invoke javac like so: -(build it, also make sure swingall.jar is in your CLASSPATH!) +javac GuiShell.java -setenv CLASSPATH ${CLASSPATH}:swingempty.jar:build -mkdir build -javac -d build GuiShell.java +(and to run it) -(run it) - -java tcl.lang.GuiShell +java GuiShell Index: src/jacl/tcl/lang/StdChannel.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/src/jacl/tcl/lang/StdChannel.java,v retrieving revision 1.19 diff -u -r1.19 StdChannel.java --- src/jacl/tcl/lang/StdChannel.java 8 Mar 2003 03:42:44 -0000 1.19 +++ src/jacl/tcl/lang/StdChannel.java 1 Oct 2007 21:41:30 -0000 @@ -20,8 +20,8 @@ * methods to perform read, write, open, close, etc on system stdio channels. */ -class StdChannel extends Channel { - +public class StdChannel extends Channel { + /** * stdType store which type, of the three below, this StdChannel is. */ @@ -37,6 +37,39 @@ static final int STDERR = 2; /** + * These static variables contain references to the actual + * in, out, and err streams that are read from or written + * to when the "stdin", "stdout", or "stderr" streams + * are read from or written to in Jacl. The user should + * invoke the setIn(), setOut(), and setErr() methods + * in this class to reassign to a specific Java stream. + */ + + static InputStream _in = System.in; + static PrintStream _out = System.out; + static PrintStream _err = System.err; + + /** + * Reassign the static variables that reference the + * in, out, and err streams used by Jacl. The user + * should note that these methods will change the + * underlying Java stream in use for all Jacl + * interpreters in the current process. + */ + + public static void setIn(InputStream in) { + _in = in; + } + + public static void setOut(PrintStream out) { + _out = out; + } + + public static void setErr(PrintStream err) { + _err = err; + } + + /** * Constructor that does nothing. Open() must be called before * any of the subsequent read, write, etc calls can be made. */ @@ -124,13 +157,13 @@ checkWrite(interp); if (stdType == STDERR) { - System.err.print(outData.toString()); + _err.print(outData.toString()); } else { String s = outData.toString(); - System.out.print(s); + _out.print(s); if (buffering == TclIO.BUFF_NONE || (buffering == TclIO.BUFF_LINE && s.endsWith("\n"))) { - System.out.flush(); + _out.flush(); } } } @@ -144,7 +177,7 @@ super.close(); if (stdType == STDOUT) - System.out.flush(); + _out.flush(); } String getChanType() { @@ -152,7 +185,7 @@ } protected InputStream getInputStream() throws IOException { - return System.in; + return _in; } protected OutputStream getOutputStream() throws IOException { ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/_______________________________________________ tcljava-user mailing list tcl...@li... https://lists.sourceforge.net/lists/listinfo/tcljava-user --------------------------------- Pinpoint customers who are looking for what you sell. |