1# Copyright (C) 1999-2000 Jean-Claude Wippler <jcw@equi4.com> 2# 3# MetaKit file show utility 4 5proc dumpView {db view {prop ""}} { 6 array set fields {} 7 set desc {} 8 set work {} 9 10 # a property list of the form "-file" causes reading from file 11 if {[regexp {^-(.*)} $prop - file]} { 12 if {$file == ""} { set fd stdin } else { set fd [open $file] } 13 set prop {} 14 while {[gets $fd line] >= 0} { 15 lappend prop $line 16 } 17 if {$file != ""} { close $fd } 18 } 19 20 # set up datatypes, build property list if none given 21 foreach name [mk::view info $db.$view] { 22 if {![regexp {^(.*):(.)} $name - name type]} { 23 set type S 24 } 25 switch $type { 26 M { set format {fn:(%db)} } 27 V { set format {s:[#%d]} } 28 default { set format f } 29 } 30 set fields($name) $format 31 lappend desc $name 32 } 33 34 # expand all fields if there is an empty entry 35 set n [lsearch -exact $prop ""] 36 if {$prop == "" || $n >= 0} { 37 set prop [eval lreplace [list $prop] $n $n $desc] 38 } 39 40 # split off commands and formatting details into a work list 41 foreach name $prop { 42 if {![regexp {^([^/]*)/(.*)} $name - name actions]} { 43 set actions "" 44 } 45 if {$actions == "" && [info exists fields($name)]} { 46 set actions $fields($name) 47 } 48 if {![regexp {^([^:]*):(.*)} $actions - actions format]} { 49 set format "" 50 } 51 lappend work $name [split $actions ""] $format 52 } 53 54 # go through each row in the view 55 mk::loop c $db.$view { 56 set r {} 57 foreach {s a f} $work { 58 set gmt 0 59 foreach x $a { 60 switch -- $x { 61 62 f { set s [mk::get $c $s] } 63 n { set s [string length $s] } 64 s { set s [mk::view size $c.$s] } 65 66 g { set gmt [expr {1-$gmt}] } 67 d { set s [clock format $s -format {%Y/%m/%d} -gmt $gmt] } 68 t { set s [clock format $s -format {%H:%M:%S} -gmt $gmt] } 69 70 k { set s [expr {($s+1023)/1024}] } 71 x { binary scan $s H* s } 72 h { set s [join [hexDump $s] \n] } 73 74 z { package require Trf; set s [zip -mode d $s] } 75 b { package require Trf; set s [bz2 -mode d $s] } 76 77 l { puts $r; set r {} } 78 79 i { set s [mk::cursor pos c] } 80 p { set s $desc } 81 v { set s $view } 82 } 83 } 84 if {$f != ""} { 85 set s [format $f $s] 86 } 87 lappend r $s 88 } 89 if {[llength $r] > 0} { 90 puts [join $r " "] 91 } 92 } 93} 94 95proc hexDump {s} { 96 set r {} 97 set n [string length $s] 98 for {set i 0} {$i < $n} {incr i 16} { 99 set t [string range $s $i [expr {$i + 15}]] 100 regsub -all {[^ -~]} $t {.} u 101 binary scan $t H* t 102 lappend r [format {%8d: %-32s %-16s} $i $t $u] 103 } 104 return $r 105} 106 107set USAGE " Usage: mkshow file view ?prop ...? 108 109 file is the name of the MetaKit datafile 110 view is a view or subview description (e.g. 'view/123.subview') 111 prop lists of properties (all if omitted, from file if '-file') 112 113 The properties may not contain a ':X' type specifier, but they may 114 contain a list of action specifiers (i.e. 'prop/abc...'). Each is 115 applied to the result so far. An optional ':...' introduces a format. 116 An empty argument is expanded to the list of all fields in the view. 117 118 Examples: 119 mkshow file view -- one line per row, all properties 120 mkshow file view /i:%5d: \"\" -- prefix each line with the row # 121 mkshow file view :blah \"\" /l -- dump each row as a Tcl command 122 mkshow file view name:%-12s -- just the name, left, fixed width 123 mkshow file view name/fz:%.100s -- unzip, then show first 100 chars 124 mkshow file view date/fd date/ft -- show field as date and as time 125 126 For a description of all actions specifiers, type 'mkshow -actions'. 127" 128 129set ACTIONS " Action codes available in mkshow: 130 131 f fetch the property value (this is usually the first action) 132 n returns size of the property value (default for :B and :M) 133 s returns the number of rows in the subview 134 135 g set gmt mode for following 'd' and 't' actions 136 d converts int seconds to a YYYY/MM/DD value 137 t converts int seconds to a HH:MM:SS value 138 139 k convert int value to 'kilo' (i.e. '(N+1023)/1024') 140 x convert string value to hexadecimal form 141 h convert string value to a pretty-printed hex dump 142 143 z uncompress string value using Trf's zip 144 b uncompress string value using Trf's bz2 145 146 i returns the row number (used without property, i.e. '/i:%5d:') 147 p returns list of all properties (used without property: '/p') 148 v returns the input view path (used without property: '/v') 149 150 l generate output in Tcl list format (must be last arg: '/l') 151 : the remainder of this argument specifies a format string 152" 153 154if {[llength $argv] < 2} { 155 switch -glob -- [lindex $argv 0] { 156 -a* { puts stderr $ACTIONS } 157 default { puts stderr $USAGE } 158 } 159 exit 1 160} 161 162set file [lindex $argv 0] 163set view [lindex $argv 1] 164set prop [lrange $argv 2 end] 165 166mk::file open db $file -readonly 167 168dumpView db $view $prop 169