Version 5 of Matthias Hoffmann - Tcl-Code-Snippets

Updated 2004-02-09 08:59:43

globx: Extended globbing, non-recursively walking through directory-trees

 proc globx {startDir {search *} {cb ""}} {
      set dirStack [list [file normalize $startDir]]
      set files {}
      set fc    0
      while {[llength $dirStack]} {
            set newStack {}
            foreach dir $dirStack {
                    set fn [glob -noc -typ f          -dir $dir -- $search]
                    set fh [glob -noc -typ {f hidden} -dir $dir -- $search]
                    if {[string equal $cb ""]} {
                       eval lappend files $fn $fh
                    } else {
                       foreach f [concat $fn $fh] {
                               incr fc
                               uplevel [list $cb $f]
                       }
                    }
                    set dn [glob -noc -typ d          -dir $dir *]
                    set dh [glob -noc -typ {d hidden} -dir $dir *]
                    eval lappend newStack $dn $dh
            }
            set dirStack $newStack
            update
      }
      if {[string equal $cb ""]} {
         return [lsort $files]
      } else {
         return $fc
      }
 }

Examples:

Without a callback, directly returning the filenames as a list:

 puts [globx c:/winnt]
 puts [globx c:/winnt *.dll]

Returning the filenames unsorted name-by-name via callback:

 proc callback file {
     puts $file
 }

 puts [globx c:/winnt * callback]; # will return the number of files read

readprof: Reading profiles with custom commands via a slave interpreter

 package provide readprof 1.0
 namespace eval readprof {}

 #----------------------------------------------------------------------------------
 # prof - filename of the profile
 # cmds - allowed 'commands' in the profile as a list where each element is {cmdName defVal}
 # returns: cmdName Value cmdName Value [...] _errorMsg <rc> (<rc> empty if ok)
 #
 proc readprof::readprof1 {prof cmds} {
      catch {
         set id [interp create -safe]
         # maximum security in the slave: deleting all availabe commands!
         interp eval $id {
                foreach cmd [info commands] {
                        if {$cmd != {rename} && $cmd != {if} && $cmd != {info}} {
                           rename $cmd {}
                        }
                }
                rename if {}; rename info {}; rename rename {}
         }
         array set temp $cmds
         proc set$id {key args} {
              upvar 1 temp myArr; set myArr($key) [join $args]
         }
         # defining aliases in the slave for each available profile-'command'
         # and mapping of each command to the set$id procedure
         foreach {cmd default} $cmds {
                 interp alias $id $cmd {} readprof::set$id $cmd; # arg [...]
         }
         # 'invoking/executing' the profile
         $id invokehidden source $prof
         # clean-up
         interp delete $id
         rename set$id {}
      } rc
      set temp(_errorMsg) $rc
      return [array get temp]
 }

Examples: