1
votes

I have two questions basically. I am using JACL interpreter to run TCL script in JAVA.

My questions are:

  1. How to get the data from standard output after running tcl file?

  2. How to pass arguments for tcl script when executing using jatcl?

E.G:
sample.tcl:

`puts "Hi this is from tcl"  `

When ran using java as follows:

`Interp i = new Interp();
 i.eval("source sample.tcl");`

then the output will be written to stdout console of JAVA. I want to read that output to some variable like x[] = i.eval("sample.tcl") then x should contain Hi this is from tcl.

  1. How to pass some parameter to sample.tcl
1

1 Answers

1
votes

Getting standard out is a bit difficult — you have to do a lot of work creating your own instance of a tcl.lang.channel.Channel and then plugging that in with TclIO.registerChannel(), which isn't really for someone just starting out — yet you often don't need to do that if you are just wanting to communicate with a Tcl program. The result of the script (which is not the standard output, but rather the result of the last command in the script) will be available via the Interp's getResult() method after the eval finishes.

Interp interp = new Interp();
interp.eval("source sample.tcl");
String result = interp.getResult().toString();

More likely, once you've sourced the script, you'll then invoke commands in the same interpreter and inspect their results. That works much better.

Interp interp = new Interp();
interp.eval("source sample.tcl");
String arg = "abc";
interp.eval("sampleCommand " + arg);
String result = interp.getResult().toString();

If you want to pass something more complex, the simplest way is to store the value you want to pass in a Tcl variable prior to invoking the script, which can then pull the value out of the variable when it needs it.

interp.setVar("theVar", "the value, which may have spaces in it", 0);
interp.eval("sampleCommand $theVar");

If you're insisting on reading script stdout, you can try this:

Interp interp = new Interp();
TclByteArrayChannel tbac = new TclByteArrayChannel(interp);

// WARNING untested, but I think you have to unregister the old stdout first
TclIO.unregisterChannel(interp, TclIO.getStdChannel(StdChannel.STDOUT));
TclIO.registerChannel(interp, tbac);

interp.eval("source sample.tcl");

// The channel will have had *bytes* written to it, so that's what we ought to get
byte[] bytes = TclByteArray.getBytes(interp, tbac.getTclByteArray());

I truly do not recommend this. I also wouldn't recommend it if you were interacting with Tcl from any other language either (e.g., C or C++). Tcl is designed to integrate at the interpreter-result level that I described earlier; you'll find it much easier to make work for anything complex.