1fileutil_traverse(n)            file utilities            fileutil_traverse(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       fileutil_traverse - Iterative directory traversal
9

SYNOPSIS

11       package require Tcl  8.3
12
13       package require fileutil::traverse  ?0.6?
14
15       package require fileutil
16
17       package require control
18
19       ::fileutil::traverse ?objectName? path ?option value...?
20
21       $traverser command ?arg arg ...?
22
23       $traverser files
24
25       $traverser foreach filevar script
26
27       $traverser next filevar
28
29______________________________________________________________________________
30

DESCRIPTION

32       This  package provides objects for the programmable traversal of direc‐
33       tory hierarchies.  The main command exported by the package is:
34
35       ::fileutil::traverse ?objectName? path ?option value...?
36              The command creates a new traversal object  with  an  associated
37              global Tcl command whose name is objectName. This command may be
38              used to invoke various operations  on  the  traverser.   If  the
39              string  %AUTO% is used as the objectName then a unique name will
40              be generated by the package itself.
41
42              Regarding the recognized options see section OPTIONS. Note  that
43              all  these  options  can  be set only during the creation of the
44              traversal object. Changing them later is not possible and causes
45              errors to be thrown if attempted.
46
47              The object command has the following general form:
48
49              $traverser command ?arg arg ...?
50                     Command and its arguments determine the exact behavior of
51                     the object.
52
53       The following commands are possible for traversal objects:
54
55       $traverser files
56              This method is the most highlevel one provided by traversal  ob‐
57              jects.  When  invoked  it returns a list containing the names of
58              all files and directories matching the current configuration  of
59              the traverser.
60
61       $traverser foreach filevar script
62              The  highlevel  files  method  (see above) is based on this mid-
63              level method. When invoked it finds all  files  and  directories
64              matching  per  the current configuration and executes the script
65              for each path. The current path under consideration is stored in
66              the  variable  named by filevar. Both variable and script live /
67              are executed in the context of the caller of the method. In  the
68              method  files  the  script simply saves the found paths into the
69              list to return.
70
71       $traverser next filevar
72              This is the lowest possible interface to the traverser, the core
73              all higher methods are built on. When invoked it returns a bool‐
74              ean value indicating whether it found a path matching  the  cur‐
75              rent  configuration  (True), or not (False). If a path was found
76              it is stored into the variable named by filevar, in the  context
77              of the caller.
78
79              The  foreach  method simply calls this method in a loop until it
80              returned False. This method is exposed so that we are also  able
81              to  incrementally  traverse  a  directory hierarchy in an event-
82              based manner.
83
84              Note that the traverser does follow symbolic links, except  when
85              doing  so  would cause it to enter a link-cycle. In other words,
86              the command takes care to not lose itself in infinite loops upon
87              encountering  circular  link  structures.  Note  that even links
88              which are not followed will still appear in the result.
89

OPTIONS

91       -prefilter command_prefix
92              This callback is executed for directories. Its result determines
93              if the traverser recurses into the directory or not. The default
94              is to always recurse into all directories. The callback  is  in‐
95              voked  with  a  single argument, the absolute path of the direc‐
96              tory, and has to return a boolean value, True when the directory
97              passes the filter, and False if not.
98
99       -filter command_prefix
100              This  callback  is executed for all paths. Its result determines
101              if the current path is a valid result, and returned by next. The
102              default is to accept all paths as valid. The callback is invoked
103              with a single argument, the absolute path to check, and  has  to
104              return  a  boolean  value, True when the path passes the filter,
105              and False if not.
106
107       -errorcmd command_prefix
108              This callback is executed for all paths the traverser has  trou‐
109              ble  with. Like being unable to change into them, get their sta‐
110              tus, etc. The default is to ignore any such problems. The  call‐
111              back  is  invoked  with  a  two arguments, the absolute path for
112              which the error occured, and the error message. Errors thrown by
113              the  filter callbacks are handled through this callback too. Er‐
114              rors thrown by the error callback itself are not caught and  ig‐
115              nored,  but  allowed to pass to the caller, i.e. however invoked
116              the next. Any other results from the callback are ignored.
117

WARNINGS AND INCOMPATIBILITIES

119       0.4.4  In this version the traverser's broken system for handling  sym‐
120              links  was replaced with one working correctly and properly enu‐
121              merating all the legal non-cyclic paths under a base directory.
122
123              While correct this means that certain pathological directory hi‐
124              erarchies  with  cross-linked  sym-links  will  now  take  about
125              O(n**2) time to enumerate whereas the original broken code  man‐
126              aged O(n) due to its brokenness.
127
128              A  concrete example and extreme case is the "/sys" hierarchy un‐
129              der Linux where some hundred devices exist under both  "/sys/de‐
130              vices"  and "/sys/class" with the two sub-hierarchies linking to
131              the other, generating millions of legal paths to enumerate.  The
132              structure, reduced to three devices, roughly looks like
133
134
135                /sys/class/tty/tty0 --> ../../dev/tty0
136                /sys/class/tty/tty1 --> ../../dev/tty1
137                /sys/class/tty/tty2 --> ../../dev/tty1
138
139                /sys/dev/tty0/bus
140                /sys/dev/tty0/subsystem --> ../../class/tty
141                /sys/dev/tty1/bus
142                /sys/dev/tty1/subsystem --> ../../class/tty
143                /sys/dev/tty2/bus
144                /sys/dev/tty2/subsystem --> ../../class/tty
145
146
147       When  having  to handle such a pathological hierarchy it is recommended
148       to use the -prefilter option to prevent the  traverser  from  following
149       symbolic links, like so:
150
151
152                  package require fileutil::traverse
153
154                  proc NoLinks {fileName} {
155                      if {[string equal [file type $fileName] link]} {
156                          return 0
157                      }
158                      return 1
159                  }
160
161                  fileutil::traverse T /sys/devices -prefilter NoLinks
162                  T foreach p {
163                      puts $p
164                  }
165                  T destroy
166
167

BUGS, IDEAS, FEEDBACK

169       This  document,  and the package it describes, will undoubtedly contain
170       bugs and other problems.  Please report such in the  category  fileutil
171       of  the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].  Please
172       also report any ideas for enhancements you may have for either  package
173       and/or documentation.
174
175       When proposing code changes, please provide unified diffs, i.e the out‐
176       put of diff -u.
177
178       Note further that  attachments  are  strongly  preferred  over  inlined
179       patches.  Attachments  can  be  made  by  going to the Edit form of the
180       ticket immediately after its creation, and  then  using  the  left-most
181       button in the secondary navigation bar.
182

KEYWORDS

184       directory traversal, traversal
185

CATEGORY

187       Programming tools
188
189
190
191tcllib                                0.6                 fileutil_traverse(n)
Impressum