When source a Tcl script in Tcl shell, how can I let Tcl print every Tcl command inside the script to the shell?

谁说胖子不能爱 提交于 2021-01-29 14:21:49

问题


Running our software will start a Tcl shell in Terminal, then we can execute a series of tcl commands in this Tcl shell by souce a tcl script file. But the tcl commands inside the tcl script file will not be printed on the Tcl shell, so, we cannot see what commands have been executed by source the tcl script.

So my question is, is there any configuration of Tcl can print out the commands in the script when the script been source.

Following is an sample tcl script

# sample.tcl, composed of 3 tcl commands:
read designfile
analyze
write output

If we interactively execute the 3 tcl commands in the Tcl shell, the result will be look as:

Tcl> read designfile
Info: reading designfile
Info: size: 128k
...
...
Tcl> analyze
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
Tcl> write output
Info: analyzed data been written into file "output"

If we source this tcl sript in Tcl shell, the result will be:

Tcl> source sample.tcl
Info: reading designfile
Info: size: 128k
...
...
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
Info: analyzed data been written into file "output"

We expect the the result will be as below when we source the script.

Tcl> source sample.tcl
> read designfile
Info: reading designfile
Info: size: 128k
...
...
> analyze
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
> write output
Info: analyzed data been written into file "output"

回答1:


That's a job for an execution trace. These can be applied to all sorts of Tcl commands, not just procedures.

trace add execution source enterstep {apply {{cmd op} {
    # Trim multiline commands down a bit; I find this helps me at least!
    regsub {\n.*} $cmd ... cmd
    # Print what's being run
    puts "EXECUTE: $cmd"
}}}
source thefile.tcl

Note that this may print a lot more than you expect! Here's a more sophisticated version that prints only the outermost level of execution.

# Called before [source] starts running
trace add execution source enter {apply {args {
    global SOURCE_LEVEL
    if {![info exists SOURCE_LEVEL]} {
        set SOURCE_LEVEL [info level]
    }
}}}
# Called after [source] finishes running
trace add execution source leave {apply {args {
    global SOURCE_LEVEL
    if {$SOURCE_LEVEL == [info level]} {
        unset SOURCE_LEVEL
    }
}}}
# Called for every command called while [source] is running
trace add execution source enterstep {apply {{cmd op} {
    global SOURCE_LEVEL
    if {$SOURCE_LEVEL == [info level]} {
        regsub {\n.*} $cmd "..." cmd
        puts "EXECUTE: $cmd"
    }
}}}



回答2:


Thanks Donal very much! Based on his suggestion, finally I got the trace command as below to satisfy my requirment.

proc print {args} {
    set cmd [lindex $args 0]
    puts stdout "$> $cmd"
}

trace add execution source enterstep print


来源:https://stackoverflow.com/questions/63832193/when-source-a-tcl-script-in-tcl-shell-how-can-i-let-tcl-print-every-tcl-command

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!