Fix too many ]s in try
[tcl-tlc-base.git] / scripts / stackdump.tcl
bloba36ef55f4fc0b2fce07d0f4a50d04653ee53abbb
1 # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4
3 proc tlc::stackdump {} { #<<<
4 return "Disfunctional at the moment"
5 set build ""
6 set stackframes [tlc::build_stackdump 2]
8 foreach frameinfo $stackframes {
9 if {[dict get $frameinfo type] eq "precompiled"} {
10 append build "compiled - no info" \n
11 continue
14 if {[dict get $frameinfo type] eq "eval"} {
15 continue
18 set line {}
20 if {[dict exists $frameinfo file]} {
21 lappend line "([dict get $frameinfo file]:[dict get $frameinfo line])"
22 } elseif {[dict exists $frameinfo proc]} {
23 lappend line "(proc [dict get $frameinfo proc]:[dict get $frameinfo line])"
26 if {[dict exists $frameinfo desc]} {
27 lappend line [dict get $frameinfo desc]
28 } else {
29 # TODO: defend against very long values of cmd
30 lappend line [dict get $frameinfo cmd]
33 append build [join $line " "] "\n"
36 return $build
39 #>>>
40 proc tlc::build_stackdump {{trim 2}} { #<<<
41 set stackframes {}
43 set thislevel [expr {[info frame] - $trim}]
44 for {set i $thislevel} {$i > 0} {incr i -1} {
45 set frameinfo [info frame $i]
46 if {[dict exists $frameinfo level]} {
47 set level [dict get $frameinfo level]
48 if {![catch {
49 dict set frameinfo levelinf [info level [expr {0 - $level}]]
50 }]} {
51 set stackname [lindex [dict get $frameinfo levelinf] 0]
52 set passed_args [lrange [dict get $frameinfo levelinf] 1 end]
54 if {$stackname ne "" && $stackname ne "namespace"} {
55 if {[catch {
56 set fqname \
57 [uplevel $level [list namespace origin $stackname]]
58 } errmsg]} {
59 set fqname "??$stackname"
61 if {[catch {
62 set caller_args_def \
63 [uplevel $level [list info args $stackname]]
64 } errmsg]} {
65 set caller_args_def "Bad uplevel depth: ($level)"
67 } else {
68 set fqname "<unknown>"
69 set caller_args_def {}
70 for {set j 1} {$j < [llength $passed_args]} {incr j} {
71 lappend caller_args_def "<unknown$j>"
74 set idx -1
75 set substmap [list "\n" "\\n" "\t" "\\t"]
76 set argdesc {}
77 foreach arg $caller_args_def {
78 incr idx
79 if {$arg eq "args"} {
80 set this_passed_arg [lrange $passed_args $idx end]
81 } else {
82 set this_passed_arg [lindex $passed_args $idx]
85 set alen [string length $this_passed_arg]
87 if {$this_passed_arg eq ""} {
88 set this_passed_arg "{}"
89 } elseif {![string is print $this_passed_arg]} {
90 set this_passed_arg "#<nonprint($alen)>"
91 } elseif {$alen > 23} {
92 set this_passed_arg [string range $this_passed_arg 0 21]
93 set this_passed_arg [string map $substmap $this_passed_arg]
94 set this_passed_arg "$this_passed_arg/$alen"
95 } else {
96 set this_passed_arg [string map $substmap $this_passed_arg]
99 lappend argdesc "$arg<$this_passed_arg>"
101 set desc "${fqname}([join $argdesc])"
102 dict set frameinfo desc $desc
105 lappend stackframes $frameinfo
109 return $stackframes
112 #>>>