- File names with paths are maltreated
- Just puts the line is not very ingenious, you could write an interactive procedure for it instead, using something like A minimal debugger, as shown in Steppin' out.
# trace_script.tcl --
# Trace a script that is being executed
# Usage:
# tclsh trace_script.tcl script-to-run args
#
# namespace Trace --
# Private namespace
#
namespace eval ::Trace {
variable traceOut stdout
}
# prepareLine --
# Prepare the line of code for output
#
# Arguments:
# line Line of code
# Result:
# Line of code with [ and ] escaped
#
proc ::Trace::prepareLine {line} {
string map {[ \\\[ ] \\\] \" \\\" \{ \\\{ \} \\\} } $line
}
# source --
# Redefine the source command to manipulate the source
# of the script
#
# Arguments:
# filename Name of the file to be sourced
# Result:
# Whatever the source file does
# Side effects:
# The manipulated source file is loaded
#
if {[info commands ::tcl::source] == {}} then {
rename source ::tcl::source
}
proc source {filename} {
set infile [open $filename "r"]
set outfile [open TMP_$filename "w"]
while { [gets $infile line] >=0 } {
puts $outfile "puts \$::Trace::traceOut \"[::Trace::prepareLine $line]\""
puts $outfile $line
}
close $infile
close $outfile
::tcl::source TMP_$filename
file delete -force TMP_$filename
}
# main --
# Prepare argv and source the code
#
namespace import
catch {
console show
}
set filename [lindex $argv 0]
set argv [lrange $argv 1 end]
source $filenameMSW says, nice :) I've taken the freedom to change the target of the rename to ::tcl::source and remove the temporary file later.RS: Writing a temporary file isn't necessary - just collect the "instrumented" code in a string variable and eval that. But I see a bigger danger: not every line contains a single command - sometimes it's less, or more. Consider
example with a long line that we want to continue \
on the next line
set data {
red
green
blue
}The putses will be inserted both inside the 'example' command, and in the 'data' block, probably both leading to unexpected behavior. Better use trace execution, it's built in - see Steppin' out
