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
57              objects.  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
95              invoked  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.
114              Errors thrown by the error callback itself are  not  caught  and
115              ignored, 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
124              hierarchies  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
129              under  Linux  where  some  hundred  devices  exist  under   both
130              "/sys/devices"  and  "/sys/class"  with  the two sub-hierarchies
131              linking to the other, generating millions of legal paths to enu‐
132              merate.   The structure, reduced to three devices, roughly looks
133              like
134
135
136                /sys/class/tty/tty0 --> ../../dev/tty0
137                /sys/class/tty/tty1 --> ../../dev/tty1
138                /sys/class/tty/tty2 --> ../../dev/tty1
139
140                /sys/dev/tty0/bus
141                /sys/dev/tty0/subsystem --> ../../class/tty
142                /sys/dev/tty1/bus
143                /sys/dev/tty1/subsystem --> ../../class/tty
144                /sys/dev/tty2/bus
145                /sys/dev/tty2/subsystem --> ../../class/tty
146
147
148       When having to handle such a pathological hierarchy it  is  recommended
149       to  use  the  -prefilter option to prevent the traverser from following
150       symbolic links, like so:
151
152
153                  package require fileutil::traverse
154
155                  proc NoLinks {fileName} {
156                      if {[string equal [file type $fileName] link]} {
157                          return 0
158                      }
159                      return 1
160                  }
161
162                  fileutil::traverse T /sys/devices -prefilter NoLinks
163                  T foreach p {
164                      puts $p
165                  }
166                  T destroy
167
168

BUGS, IDEAS, FEEDBACK

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

KEYWORDS

185       directory traversal, traversal
186

CATEGORY

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