0

I am using tee from https://wiki.tcl-lang.org/page/Tee to redirect file output from my procedures. I need to redirect both stdout and stderr to the file.

Using the input from Redirecting output of tcl proc to file and output (like tee) I arrived at doing the following:

    set LogFile  [open ${LogFileName} w]
    tee channel stderr $LogFile
    tee channel stdout $LogFile
    set BuildErrorCode [catch {LocalBuild $BuildName $Path_Or_File} BuildErrMsg]
    set BuildErrorInfo $::errorInfo
    
    # Restore stdout and stderr 
    chan pop stdout
    chan pop stderr

   # Handle errors from Build ...

I am testing this on three different EDA tools and I have three different issues.

  1. When I run from tclsh (on MSYS2 running on Windows 10) and run either the open source simulator GHDL, ModelSim, or QuestaSim, all the even characters are the NUL character.
  2. If I run ModelSim or QuestaSim from the GUI, I miss the output of each command. Shouldn't that be going to either stdout or stderr?
  3. In Riviera-PRO, I am getting extraneous characters that were previously printed. They are generally the second half of a word.

Am I doing something wrong? I tested out the above code using:

set LogFile  [open test_tee.log w]
tee channel stderr $LogFile
tee channel stdout $LogFile

puts "Hello, World!"
puts stderr "Error Channel"
puts stdout "Output Channel"

chan pop stdout
chan pop stderr

And this works well.

I am hoping to find something that works in the general case for all tools rather than having to write a different handler for each tool.

============ Update =============
For #1 above, with @Shawn's suggestion, I tried the following and it did not work.

    set LogFile  [open ${LogFileName} w]
    chan configure $LogFile -encoding ascii
    . . .

I also tried the following and it did not work.

    set LogFile  [open ${LogFileName} w]
    fconfigure $LogFile -encoding ascii
    . . .

Then I tried updating the write in tee to the following and it did not work:

proc tee::write {fd handle buffer} {
    puts -nonewline $fd [encoding convertto ascii $buffer]
    return $buffer
}

Any other hints solutions appreciated

============ Update2 =============
I have successfully removed the nul characters by doing the following, except now I have an extra newline. Still not a solution.

proc tee::write {fd handle buffer} {
    puts -nonewline $fd [regsub -all \x00 $buffer ""]
    return $buffer
}
Jim Lewis
  • 3,601
  • 10
  • 20
  • The first one sounds like the files are being written to using UTF-16. Try changing to UTF-8 or even ASCII with `chan configure`. – Shawn May 25 '22 at 04:41
  • Do not change the encoding of the console on Windows. That *will* make things be weird! The console channel implementation uses a Windows API that only ever expects that one encoding. – Donal Fellows May 26 '22 at 07:38

1 Answers1

1

The extra NUL bytes are probably because the stdout ahd steer channels are being written in UTF-16 (the main use for that encoding is the console on Windows). The tee interceptors you are using come after the data being written is encoded. There's a few ways to fix it, but the easiest is to open the file with the right encoding when reading it.

The output of the commands is not necessarily written to those channels. Code written in C or C++ is entirely free to write directly, and Tcl code cannot see that; it's all happening behind our back. Command results can be intercepted using execution traces, but that cannot see anything that the commands internally print that aren't routed via the Tcl library somehow. (There are a few more options on Unix due to the different ways that the OS handles I/O.)

Don't know what's happening with the extra characters. I can tell you that you are getting what goes through the channel, but there are too many tricks (especially in interactive use!) for a useful guess on that front.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • You are correct in that it is going to a MSYS2 console running on top of windows. The writers are EDA tools. Plural is correct as I have used TCL to create an abstraction layer on top of them so I can use the same command interface in each tool. Now it is just taming them enough so the output can be correctly put into a file. – Jim Lewis May 27 '22 at 16:31
  • After I removed the `NUL` character I found `cr cr lf` rather than just `cr lf` and I had to search on that and remove the extra `cr`. Unfortunate. – Jim Lewis May 27 '22 at 16:36
  • And I have to handle the tool output appropriately whether the tool is running interactively in the tool GUI or in batch. – Jim Lewis May 27 '22 at 18:05
  • When the tool is writing directly from C to the console, if I call the tool from exec can I redirect the output to stdout that way? – Jim Lewis May 27 '22 at 18:07