# ACTIVESTATE TEAPOT-PKG BEGIN TM -*- tcl -*- # -- Tcl Module # @@ Meta Begin # Package menubar::debug 0.5 # Meta as::build::date 2015-05-26 # Meta as::origin http://sourceforge.net/projects/tcllib # Meta license BSD # Meta platform tcl # Meta require TclOO # Meta require menubar # @@ Meta End # ACTIVESTATE TEAPOT-PKG BEGIN DECLARE package provide menubar::debug 0.5 # ACTIVESTATE TEAPOT-PKG END DECLARE # ACTIVESTATE TEAPOT-PKG END TM # debug.tcl -- # # Package that add debugging procedures to the global namespace # and to the menubar::Tree class. # # Copyright (c) 2009 Tom Krehbiel # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: debug.tcl,v 1.5 2010/01/06 20:55:54 tomk Exp $ package require TclOO package require menubar package provide menubar::debug 0.5 # The ::oo namespace contains Tcloo commands that must be preceeded by 'my'. # as the default namespace for callback commands # -- # # Generic debugging method for TclOO object instance. # oo::define ::oo::object method debug {{pat *}} { set res [list class [info object class [self]]] foreach i [info object vars [self] $pat] { variable $i lappend res $i [set $i] } set res } # -- pdict # # A pretty printer for dict object, similar to parray. # # Usage: # # pdict [d [i [p [s]]]] # # Where: # d - dict to be printed # i - indent level # p - prefix string for one level of indent # s - seperator string between key and value # # Examples: # % set d [dict create a {1 i 2 j 3 k} b {x y z} c {i m j {q w e r} k o}] # % a {1 i 2 j 3 k} b {x y z} c {i m j {q w e r} k o} # % pdict $d # a -> # 1 -> 'i' # 2 -> 'j' # 3 -> 'k' # b -> 'x y z' # c -> # i -> 'm' # j -> # q -> 'w' # e -> 'r' # k -> 'o' # proc ::pdict { d {i 0} {p " "} {s " -> "} } { if { [catch {dict keys ${d}}] } { error "error: pdict - argument is not a dict" } set result "" set prefix [string repeat ${p} ${i}] set max 0 foreach key [dict keys ${d}] { if { [string length ${key}] > ${max} } { set max [string length ${key}] } } dict for {key val} ${d} { append result "${prefix}[format "%-${max}s" ${key}]${s}" if { [catch {dict keys ${val}}] } { append result "'${val}'\n" } else { append result "\n" append result "[pdict ${val} [expr ${i}+1] ${p} ${s}]\n" } } return ${result} } # ------------------------------------------------------------ # # Add debugging methods to ::menubar::tree class # # ------------------------------------------------------------ # -- ptree # debugging utility oo::define ::menubar::tree method ptree { {name ""} } { variable root if { ${name} eq "" } { my DumpSubtree ${root} } else { if { [my exists ${name}] ne "" } { error "node (${name}) - not found" } my DumpSubtree ${name} } } # -- pnodes # debugging utility oo::define ::menubar::tree method pnodes { } { variable nodes foreach name [lsort -dictionary [dict keys ${nodes}]] { set node [dict get ${nodes} ${name}] set pnode [${node} parent] set children [my children ${name}] puts [format "(%-12s) %-12s %s -> %s" ${pnode} ${node} ${name} [join ${children} {, }]] } } # -- pkeys # debugging utility oo::define ::menubar::tree method pkeys { args } { if { [llength ${args}] == 0 } { set args [my nodes] } else { set notfound [my exists {*}${args}] if { ${notfound} ne "" } { error "node (${notfound}) - not found" } } foreach name ${args} { set node [my Name2Node ${name}] puts "node(${name})" set width 0 foreach key [${node} attr.keys] { set len [string length ${key}] if { ${len} > ${width} } { set width ${len} } } foreach {key val} [${node} attrs.filter] { puts " [format "%-${width}s" ${key}]: '${val}'" } } } # -- pstream # debugging utility oo::define ::menubar::tree method pstream { stream } { lassign ${stream} name attrs children my Pstream ${name} ${attrs} ${children} 0 } # ------------------------------------------------------------ # # Add debugging methods to ::menubar class # # ------------------------------------------------------------ oo::define ::menubar method debug { {type tree} } { variable mtree variable installs variable notebookVals set result "" if { ${type} eq "tree" } { lappend result "##### tag tree #####" lappend result "menubar" lappend result {*}[my children menubar] } elseif { ${type} eq "nodes" } { lappend result "##### tag defs #####" foreach node [lsort -dictionary [${mtree} nodes]] { lappend result ${node} foreach {attr val} [${mtree} key.getall ${node} +*] { lappend result " ${attr}: ${val}" } foreach {opt val} [${mtree} key.getall ${node} -*] { lappend result " ${opt}: ${val}" } } } elseif { ${type} eq "installs" } { lappend result "##### installs #####" lappend result [pdict ${installs}] } elseif { ${type} eq "notebook" } { lappend result "##### notebookVals #####" lappend result [pdict ${notebookVals}] } return ${result} } oo::define ::menubar method children { node {indent 1} } { variable mtree set result "" foreach _node [${mtree} children ${node}] { lappend result [string repeat " " ${indent}]${_node} set more [my children ${_node} [expr ${indent}+1]] if { [string trim ${more}] ne "" } { lappend result {*}${more} } } return ${result} } oo::define ::menubar method debug_node { node } { variable mtree lappend result "==== node: ${node}" foreach {attr val} [${mtree} key.getall ${node} +*] { lappend result " ${attr}: ${val}" } foreach {opt val} [${mtree} key.getall ${node} -*] { lappend result " ${opt}: ${val}" } return ${result} } oo::define ::menubar method print { type } { variable mtree switch -exact ${type} { "tree" { ${mtree} ptree } "nodes" { ${mtree} pnodes } "keys" { ${mtree} pkeys } default { }} }