traverse(3)



fileutil_traverse(3tcl)         file utilities         fileutil_traverse(3tcl)

______________________________________________________________________________

NAME
       fileutil_traverse - Iterative directory traversal

SYNOPSIS
       package require Tcl  8.3

       package require fileutil::traverse  ?0.6?

       package require fileutil

       package require control

       ::fileutil::traverse ?objectName? path ?option value...?

       $traverser command ?arg arg ...?

       $traverser files

       $traverser foreach filevar script

       $traverser next filevar

______________________________________________________________________________

DESCRIPTION
       This  package provides objects for the programmable traversal of direc-
       tory hierarchies.  The main command exported by the package is:

       ::fileutil::traverse ?objectName? path ?option value...?
              The command creates a new traversal object  with  an  associated
              global Tcl command whose name is objectName. This command may be
              used to invoke various operations  on  the  traverser.   If  the
              string  %AUTO% is used as the objectName then a unique name will
              be generated by the package itself.

              Regarding the recognized options see section OPTIONS. Note  that
              all  these  options  can  be set only during the creation of the
              traversal object. Changing them later is not possible and causes
              errors to be thrown if attempted.

              The object command has the following general form:

              $traverser command ?arg arg ...?
                     Command and its arguments determine the exact behavior of
                     the object.

       The following commands are possible for traversal objects:

       $traverser files
              This method is the most highlevel one provided by traversal  ob-
              jects.  When  invoked  it returns a list containing the names of
              all files and directories matching the current configuration  of
              the traverser.

       $traverser foreach filevar script
              The  highlevel  files  method  (see above) is based on this mid-
              level method. When invoked it finds all  files  and  directories
              matching  per  the current configuration and executes the script
              for each path. The current path under consideration is stored in
              the  variable  named by filevar. Both variable and script live /
              are executed in the context of the caller of the method. In  the
              method  files  the  script simply saves the found paths into the
              list to return.

       $traverser next filevar
              This is the lowest possible interface to the traverser, the core
              all higher methods are built on. When invoked it returns a bool-
              ean value indicating whether it found a path matching  the  cur-
              rent  configuration  (True), or not (False). If a path was found
              it is stored into the variable named by filevar, in the  context
              of the caller.

              The  foreach  method simply calls this method in a loop until it
              returned False. This method is exposed so that we are also  able
              to  incrementally  traverse  a  directory hierarchy in an event-
              based manner.

              Note that the traverser does follow symbolic links, except  when
              doing  so  would cause it to enter a link-cycle. In other words,
              the command takes care to not lose itself in infinite loops upon
              encountering  circular  link  structures.  Note  that even links
              which are not followed will still appear in the result.

OPTIONS
       -prefilter command_prefix
              This callback is executed for directories. Its result determines
              if the traverser recurses into the directory or not. The default
              is to always recurse into all directories. The callback  is  in-
              voked  with  a  single argument, the absolute path of the direc-
              tory, and has to return a boolean value, True when the directory
              passes the filter, and False if not.

       -filter command_prefix
              This  callback  is executed for all paths. Its result determines
              if the current path is a valid result, and returned by next. The
              default is to accept all paths as valid. The callback is invoked
              with a single argument, the absolute path to check, and  has  to
              return  a  boolean  value, True when the path passes the filter,
              and False if not.

       -errorcmd command_prefix
              This callback is executed for all paths the traverser has  trou-
              ble  with. Like being unable to change into them, get their sta-
              tus, etc. The default is to ignore any such problems. The  call-
              back  is  invoked  with  a  two arguments, the absolute path for
              which the error occured, and the error message. Errors thrown by
              the  filter callbacks are handled through this callback too. Er-
              rors thrown by the error callback itself are not caught and  ig-
              nored,  but  allowed to pass to the caller, i.e. however invoked
              the next. Any other results from the callback are ignored.

WARNINGS AND INCOMPATIBILITIES
       0.4.4  In this version the traverser's broken system for handling  sym-
              links  was replaced with one working correctly and properly enu-
              merating all the legal non-cyclic paths under a base directory.

              While correct this means that certain pathological directory hi-
              erarchies  with  cross-linked  sym-links  will  now  take  about
              O(n**2) time to enumerate whereas the original broken code  man-
              aged O(3tcl) due to its brokenness.

              A  concrete example and extreme case is the "/sys" hierarchy un-
              der Linux where some hundred devices exist under both  "/sys/de-
              vices"  and "/sys/class" with the two sub-hierarchies linking to
              the other, generating millions of legal paths to enumerate.  The
              structure, reduced to three devices, roughly looks like

                /sys/class/tty/tty0 --> ../../dev/tty0
                /sys/class/tty/tty1 --> ../../dev/tty1
                /sys/class/tty/tty2 --> ../../dev/tty1

                /sys/dev/tty0/bus
                /sys/dev/tty0/subsystem --> ../../class/tty
                /sys/dev/tty1/bus
                /sys/dev/tty1/subsystem --> ../../class/tty
                /sys/dev/tty2/bus
                /sys/dev/tty2/subsystem --> ../../class/tty

       When  having  to handle such a pathological hierarchy it is recommended
       to use the -prefilter option to prevent the  traverser  from  following
       symbolic links, like so:

                  package require fileutil::traverse

                  proc NoLinks {fileName} {
                      if {[string equal [file type $fileName] link]} {
                          return 0
                      }
                      return 1
                  }

                  fileutil::traverse T /sys/devices -prefilter NoLinks
                  T foreach p {
                      puts $p
                  }
                  T destroy

BUGS, IDEAS, FEEDBACK
       This  document,  and the package it describes, will undoubtedly contain
       bugs and other problems.  Please report such in the  category  fileutil
       of  the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].  Please
       also report any ideas for enhancements you may have for either  package
       and/or documentation.

       When proposing code changes, please provide unified diffs, i.e the out-
       put of diff -u.

       Note further that  attachments  are  strongly  preferred  over  inlined
       patches.  Attachments  can  be  made  by  going to the Edit form of the
       ticket immediately after its creation, and  then  using  the  left-most
       button in the secondary navigation bar.

KEYWORDS
       directory traversal, traversal

CATEGORY
       Programming tools

tcllib                                0.6              fileutil_traverse(3tcl)

Man(1) output converted with man2html
list of all man pages