line number

"How do I calculate the line number of ...?" is a very frequently-asked question.

There's no satisfying answer, in general. While introspection is generally one of Tcl's strengths, no one has yet invested what's necessary to implement a line-number calculation satisfyingly.

[Explain difficulties (byte-coded vs. not, in script vs. proc body vs. eval)?]

[Various ways to instrument existing procedures ... ]

[Tom Tromey once wrote extension (?) to do this. Arjen Markus' Testcov does a nearly (?) identical instrumentation. (Arjen: not quite, it is available on the Neosoft archive now, but it rewrites the source code, interspersing calls to counting procedures and then when the program is run, the instrumented files are sourced. So things are not happening "on the fly"]

[tclguy's summary: "it is going to have to be somebody's science project"]

escargo 9 Nov 2006 - Perhaps somebody could explain how the information is available to the error handlers but not available to Tcl introspection.

Lars H: The error handlers know a bunch of stuff about how the scripts parse into commands, because this information was generated when evaluating/compiling the script. Everything in the errorInfo (except the location within the script of the command which throws the error) can be deduced from the text of the script being evaluated, so there is nothing magical about it, just a bunch of hard work.

One important point here is however that most people with requests in this area want line numbers of a file rather than line numbers of a script (e.g. procedure body), and that's not something Tcl knows enough to report at the moment. TIP#280 [L1 ] is the current spearhead in that direction, but last I heard it had a problem with continuation lines in procedure bodies. If you compare

 proc testA {} {
    set X\
       "some silly proc"
    error $X


 proc testB {} {
    set X "some silly proc"
    error $X

you'll see that the same line number is reported for the error in both cases. Technically that is because [info body testA] is equal to [info body testB], but those who want file-relative line numbers probably won't think of it that way.

steveb 22 Jun 2011. The approach Jim Tcl takes in tracking line numbers may be of interest here. Consider the script, errtest.tcl (numbered for convenience)

 1 proc a {&x} {
 2     set x \
 3         [expr blah]
 4 }
 6 proc b {} {
 7     set y 5
 8     a y
 9 }
11 proc c {} {
12     b
13 }
15 c

Now run this with Jim

$ ./jimsh errtest.tcl
Runtime Error: errtest.tcl:3: syntax error in expression: "blah"
in procedure 'c' called at file "errtest.tcl", line 15
in procedure 'b' called at file "errtest.tcl", line 12
in procedure 'a' called at file "errtest.tcl", line 8
at file "errtest.tcl", line 3

Note how the errors are line-accurate and include the source file. Internally, when Jim parses a script, it tracks the line number and original source file of each token (object). This information is kept as long as possible and lost only when the internal representation of an object needs to change.

It is also possible to access the source location of any object with 'info source'. For example:

. info source [info body throw]
tclcompat.tcl 266