I am using Amira 3.1, a visualization software interfaced with tcl.
Inside the Amira console, I would like to use tcl command such as
"puts hello" or "gets stdin". I get the following error message:
error writing "stdout": bad file number
would you have any idea and any hints to solve that problem?
thanks
Eric
The Amira console is not a console understood to be those channels. I'd contact
the company that wrote it and ask them to improve their interface.
It is easily possible at the creation of an interpreter to redirect Tcl's std
channels from/to whatever widget they have.
--
"I don't know which is worse, ...that everyone has his price, or that the
price is always so low." -Calvin
# Choose a name convenient for you.
set my_special_log /tmp/tcl.experiment
set ::stdout [open $my_special_log w]
somewhere. If that proves successful, it might even be possible for
*him* to write pure-Tcl to reconnect stdout to the Amira console, with
no help from the vendor.
and secondly, even if that somehow magically worked, the output would
be going to your log file, not the console.
Bruce
If your console is a tk console, you could "source /path/to/tkcon.tcl"
to get a more fully-featured console.
--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry
Thing is, if you do a [close stdout] immediately before, the value will
actually be "stdout" and not file1. It will have captured the real
stdout (yes, even stuff from C-level printf() calls!) Once you can do
the capture, you can make any scriptable console work...
Donal.
Cool, I've done that in C to deal with ugly programs in the past, but
didn;t know definitetively that Tcl did that as well. On the other hand
the OP was working with a case where stdout didn't exist in the first place.
Bruce
clear
Clears console window.
echo args
Prints its arguments to the amira console. Use this rather than the native Tcl command puts which prints to stdout.
Bruce
> echo args
> Prints its arguments to the amira console. Use this rather than the
> native Tcl command puts which prints to stdout.
Ohh, I had a program that used [echo]. I made an extension to fix it, so [puts]
went to the console by creating a new channel type and invoking [echo] upon each
call to the DriverOutputProc.
source is:
http://tomasoft.cvs.sf.net/tomasoft/XiRC_Hack/XiRCStdOutChan.hpp?revision=1.9&view=markup
http://tomasoft.cvs.sf.net/tomasoft/XiRC_Hack/XiRCStdOutChan.cpp?revision=1.11&view=markup
--
Hobbes: What would you call the creation of the universe?
Calvin: The Horrendous Space Kablooie!
Bruce
I doubt the ability to do it completely from script exists as:
1) if stdout doesn't first exist, you can't close it to reopen the next file as stdout
2) the first call to puts, in any new interp, will always try to grab stdout from
the OS unless it was prefilled by Tcl_SetStdChannel() explicitly.
--
If we don't all watch the same TV, what will keep our culture homogeneous?
-- Calvin
I am talking about a puts wrapper, and in the case where the channel isn't specified,
or the channel is stdout (and stderr probably) then call echo, else call the original puts.
something like (untested)
rename puts real_puts
proc puts {args} {
switch [llength $args] {
1 {
echo $args
}
2 {
set opt [lindex $args 0]
set str [lindex $args 1]
if {($opt eq "stdout") || ($opt eq "stderr") || ($opt eq "-nonewline")} {
echo $str
} else {
real_puts $opt $str
}
}
3 {
set opt [lindex $args 0]
set chan [lindex $args 1]
set str [lindex $args 2]
if {($chan eq "stdout") || ($chan eq "stderr")} {
echo $str
} else {
real_puts $opt $chan $str
}
}
}
}
Oh, you mean that in unix, the fd's are reused (smallest hole reused
first). The behavior is thus not a consequence of magic in the Tcl
core, but of the simple fact that [puts] and print() converge on fd 1
(through two parallel, distinct buffering machines).
True, but I'd be surprised if this worked in Windows since handles
don't follow this simple, ordered-small-ints, rule (there are fd's in
the pseudo-posix "emulation" library of the MSVC runtime, but Tcl
doesn't use them, right ?)
-Alex
> I am talking about a puts wrapper, and in the case where the channel
> isn't specified,
> or the channel is stdout (and stderr probably) then call echo, else call
> the original puts.
Ok, that's simpler than what I was doing. You do miss any compiled libraries that
call something like:
Tcl_Write(Tcl_GetStdChannel(interp, TCL_STDOUT), msg);
Expect I know does that and a few of mine regarding special error messages not
passable through the normal path (The great POSIX mis-translation thing).
--
Calvin : I think we have got enough information now, don't you?
Hobbes : All we have is one "fact" that you made up.
Calvin : That's plenty. By the time we add an introduction, a few
illustrations and a conclusion, it'll look like a graduate thesis.
> True, but I'd be surprised if this worked in Windows since handles
> don't follow this simple, ordered-small-ints, rule (there are fd's in
> the pseudo-posix "emulation" library of the MSVC runtime, but Tcl
> doesn't use them, right ?)
Correct.. closing the actual console HANDLE that represents stdout on win from a
console app ends the application... and any other apps in the process tree. But I
think there is some magic in Tcl for that situation..
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\WINDOWS\system32>tclsh
% close stdout
open foo.txt w
parray tcl_platform
exit
C:\WINDOWS\system32>
foo.txt contains:
file9e9910
% tcl_platform(byteOrder) = littleEndian
tcl_platform(machine) = intel
tcl_platform(os) = Windows NT
tcl_platform(osVersion) = 5.1
tcl_platform(platform) = windows
tcl_platform(threaded) = 1
tcl_platform(tip,268) = 1
tcl_platform(tip,280) = 1
tcl_platform(user) = davygrvy
tcl_platform(wordSize) = 4
%
So it does indeed behave unixy. I highly doubt any calls to printf() would follow
to the file.
--
This one's tricky. You have to use imaginary numbers, like eleventeen ...
-- Hobbes