Fragment of Tcl Script
puts "Line <LINE_NO or something> : ABC" # Line 123
Output File :
Line 123 : ABC
How can we do it?
Thanks in advance
===========================
Alex Vinokur
mailto:ale...@bigfoot.com
mailto:ale...@yahoo.com
http://up.to/alexvn
http://go.to/alexv_math
===========================
Alex Vinokur wrote:
> I would like to print line number of Tcl Script in puts,
> for instance,
>
> Fragment of Tcl Script
> puts "Line <LINE_NO or something> : ABC" # Line 123
>
> Output File :
> Line 123 : ABC
>
> How can we do it?
>
According to http://tcl.activestate.com/man/tcl8.4/TclCmd/info.htm :
we can print script name --> info script,
however I didn't find --> info line.
--
This information is not available. See also the thread later on "Access
to call-stack information...".
I have wondered about how file name and line numbers could be
implemented in the Tcl core. I know that Tcl is dynamic, and it
wouldn't always apply. But a lot of the code (that I execute) is
sourced from files.
Would an approach like this be reasonable?
1. Modify [source] to be aware of line numbers. On reading a little
code it appears that you would have to pass filename information all the
way down to Tcl_EvalEx() in tclParse.c, where you could count newlines.
2. Modify the [proc] command to determine if it is being called from
[source], and if it is, save the file name and line number of the [proc]
invocation in some array in the ::tcl namespace.
3. Modify [info] and friends (maybe ProcessProcResultCode()?) to look
for the filename and line number, add in the offset into the proc, and
add file/line to the message.
Or would it be better implemented in the byte-code engine? (Where all
really good procs end up anyway.)
Bob
--
Bob Techentin techenti...@mayo.edu
Mayo Foundation (507) 538-5495
200 First St. SW FAX (507) 284-9171
Rochester MN, 55901 USA http://www.mayo.edu/sppdg/
And what about when the proc is redefined? Do you make sure to do
all the backtrack cleanup of what might have been defined? Doing
all this dynamically will just slow the entire eval engine down.
> 3. Modify [info] and friends (maybe ProcessProcResultCode()?) to look
> for the filename and line number, add in the offset into the proc, and
> add file/line to the message.
I think just getting the proc line offset might be feasible for an
[info line], but not much more without noticeable tradeoffs.
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions
I'm not sure about Tcl's guts, and what would slow things down. I was
envisioning extra work only during proc definition and error message
construction. In Tcl, something like:
rename proc _proc
proc ::proc { name args body } {
if { [info exists ::tcl::sourcingFile] } {
# proc is defined in a file that we are sourcing
set ::tcl::savedSourceInfo($name) \
[list $::tcl::sourcingFile(fileName)
$::tcl::sourcingFile(lineNum)]
} else {
catch {unset ::tcl::savedSourceInfo($name)}
proc IncrLinesEvaled {procName} {
incr ::linesEvaled($procName)
}
rename proc _proc
_proc ::proc { name args body } {
set ::linesEvaled($name) 0
regsub -all "\n" $body ";IncrLinesEvaled $name \n" body
eval [list _proc $name $args $body ]
}
One use is to put a "idebug break 123" anywhere in a procedure and
print the line number - "set ::linesEvaled([lindex [info level 0] 0])"
This code is still not completed, as it might ruin procedures return
value.
Eyal.
Bruce
> This is a somewhat dangerous design - if there is a continuation of a
> command across a newline boundary you will get nasty results. Inside
> a switch body these will NOT be commands but pattern action statements
> (which since they are an even number of words it won't break the switch,
> but you line counts will be wrong). If there is code that relies on the last command
> becoming the default return instead of an explicit return statement you will
> break it as well.
I agree this code has many existing and potential problems. It is
considered as an incomplete "hack". I also agree that messing around
with basic tcl commands like [proc] or [eval] requires great attention
and understanding.
Even if the code was fixed to handle all problems, note that it would
not correctly return the current line number, but the number of lines
that were evaluated (think of loops).
Another problem is the existance of comments.
Seems like when a proc is created, some amount of info is saved regarding
that proc in some sort of structure. Having a line number and source file
stored within that structure (or a pointer to another structure with that
info) '''seems''' simple enough. Renaming a proc has no relevance to
the file name and line number info for the original proc, so it stays the
same and the new proc being created gets its out unique file name and line
number.
--
"I know of vanishingly few people ... who choose to use ksh." "I'm a minority!"
<URL: mailto:lvi...@cas.org> <URL: http://www.purl.org/NET/lvirden/>
Even if explicitly stated to the contrary, nothing in this posting
should be construed as representing my employer's opinions.
> According to Jeffrey Hobbs <Je...@ActiveState.com>:
> :And what about when the proc is redefined? Do you make sure to do
> :all the backtrack cleanup of what might have been defined? Doing
> :all this dynamically will just slow the entire eval engine down.
> Seems like when a proc is created, some amount of info is saved regarding
> that proc in some sort of structure. Having a line number and source file
> stored within that structure (or a pointer to another structure with that
> info) '''seems''' simple enough. Renaming a proc has no relevance to
> the file name and line number info for the original proc, so it stays the
> same and the new proc being created gets its out unique file name and line
> number.
Now this I would find extremely useful, even if it worked only for
well behaved (no redefined procs) programs. For a simple debugger I wrote,
I can currently "break" at any proc call via the wonderful Tcl_CreateTrace.
However, there is no way to easily find the source to display for the proc.
Instramentation is just no substitute (too slow). In fact,
I would even go so far as to say a simple cmd line debugger
should be bundled with Tcl (ala perl).
--
Peter MacDonald BrowseX Systems Inc
Email: pe...@BrowseX.com http://BrowseX.com
Phone: (250) 595-5998
info file PROC
info line PROC
that return respectively the file name and line number for the PROC.
No proc name to "info file" returns all known sourced file names.
It seems to work for the simple cases I've tried and for a random
sampling of procs in a big Tcl system (BrowseX).
There should be little overhead, as it creates a global hash table
with one entry for each sourced file.
The patch is 430 lines and is against tcl8.4a3. It is available here:
http://dev.browsex.com/tclline.diff.gz
One use I can forsee for this would be a bgerror handler in Tk
taking you directly to the file and line number of the offending
statement.
Feedback is appreciated.
Peter
> http://dev.browsex.com/tclline.diff.gz
One more small addition to this patch. Now, upon
an error in a proc, the filename and absolute line number
are printed out (if available), even from after or callback
invocations. This should be machine parsable so that an
you could be brought into an editor at the offending line,
automatically
Haven't tested this, but it looks generally good. The one obvious
problem that I see now is that it leaks memory with the caching
of filenames. Also, I don't think it's as efficient as it could
be. Instead of dup'ing the obj, it could just incr the ref count,
but you have to remember to decr it (upon interp finalization or
exit).
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions