Mercurial > projects > ldc
comparison tango/tango/io/FileScan.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Jun 2004: Initial release | |
8 version: Dec 2006: Pacific release | |
9 | |
10 author: Kris | |
11 | |
12 *******************************************************************************/ | |
13 | |
14 module tango.io.FileScan; | |
15 | |
16 public import tango.io.FilePath; | |
17 | |
18 private import tango.core.Exception; | |
19 | |
20 /******************************************************************************* | |
21 | |
22 Recursively scan files and directories, adding filtered files to | |
23 an output structure as we go. This can be used to produce a list | |
24 of subdirectories and the files contained therein. The following | |
25 example lists all files with suffix ".d" located via the current | |
26 directory, along with the folders containing them: | |
27 --- | |
28 auto scan = new FileScan; | |
29 | |
30 scan (".", ".d"); | |
31 | |
32 Stdout.formatln ("{} Folders", scan.folders.length); | |
33 foreach (folder; scan.folders) | |
34 Stdout.formatln ("{}", folder); | |
35 | |
36 Stdout.formatln ("\n{} Files", scan.files.length); | |
37 foreach (file; scan.files) | |
38 Stdout.formatln ("{}", file); | |
39 --- | |
40 | |
41 This is unlikely the most efficient method to scan a vast number of | |
42 files, but operates in a convenient manner | |
43 | |
44 *******************************************************************************/ | |
45 | |
46 class FileScan | |
47 { | |
48 alias sweep opCall; | |
49 | |
50 FilePath[] fileSet; | |
51 char[][] errorSet; | |
52 FilePath[] folderSet; | |
53 | |
54 /*********************************************************************** | |
55 | |
56 Alias for Filter delegate. Accepts a FilePath & a bool as | |
57 arguments and returns a bool. | |
58 | |
59 The FilePath argument represents a file found by the scan, | |
60 and the bool whether the FilePath represents a folder. | |
61 | |
62 The filter should return true, if matched by the filter. Note | |
63 that returning false where the path is a folder will result | |
64 in all files contained being ignored. To always recurse folders, | |
65 do something like this: | |
66 --- | |
67 return (isDir || match (fp.name)); | |
68 --- | |
69 | |
70 ***********************************************************************/ | |
71 | |
72 alias FilePath.Filter Filter; | |
73 | |
74 /*********************************************************************** | |
75 | |
76 Return all the errors found in the last scan | |
77 | |
78 ***********************************************************************/ | |
79 | |
80 public char[][] errors () | |
81 { | |
82 return errorSet; | |
83 } | |
84 | |
85 /*********************************************************************** | |
86 | |
87 Return all the files found in the last scan | |
88 | |
89 ***********************************************************************/ | |
90 | |
91 public FilePath[] files () | |
92 { | |
93 return fileSet; | |
94 } | |
95 | |
96 /*********************************************************************** | |
97 | |
98 Return all directories found in the last scan | |
99 | |
100 ***********************************************************************/ | |
101 | |
102 public FilePath[] folders () | |
103 { | |
104 return folderSet; | |
105 } | |
106 | |
107 /*********************************************************************** | |
108 | |
109 Sweep a set of files and directories from the given parent | |
110 path, with no filtering applied | |
111 | |
112 ***********************************************************************/ | |
113 | |
114 FileScan sweep (char[] path, bool recurse=true) | |
115 { | |
116 return sweep (path, cast(Filter) null, recurse); | |
117 } | |
118 | |
119 /*********************************************************************** | |
120 | |
121 Sweep a set of files and directories from the given parent | |
122 path, where the files are filtered by the given suffix | |
123 | |
124 ***********************************************************************/ | |
125 | |
126 FileScan sweep (char[] path, char[] match, bool recurse=true) | |
127 { | |
128 return sweep (path, (FilePath fp, bool isDir) | |
129 {return isDir || fp.suffix == match;}, recurse); | |
130 } | |
131 | |
132 /*********************************************************************** | |
133 | |
134 Sweep a set of files and directories from the given parent | |
135 path, where the files are filtered by the provided delegate | |
136 | |
137 ***********************************************************************/ | |
138 | |
139 FileScan sweep (char[] path, Filter filter, bool recurse=true) | |
140 { | |
141 errorSet = null, fileSet = folderSet = null; | |
142 return scan (new FilePath(path), filter, recurse); | |
143 } | |
144 | |
145 /*********************************************************************** | |
146 | |
147 Internal routine to locate files and sub-directories. We | |
148 skip entries with names composed only of '.' characters. | |
149 | |
150 ***********************************************************************/ | |
151 | |
152 private FileScan scan (FilePath folder, Filter filter, bool recurse) | |
153 { | |
154 try { | |
155 auto paths = folder.toList (filter); | |
156 | |
157 auto count = fileSet.length; | |
158 foreach (path; paths) | |
159 if (! path.isFolder) | |
160 fileSet ~= path; | |
161 else | |
162 if (recurse) | |
163 scan (path, filter, recurse); | |
164 | |
165 // add packages only if there's something in them | |
166 if (fileSet.length > count) | |
167 folderSet ~= folder; | |
168 | |
169 } catch (IOException e) | |
170 errorSet ~= e.toString; | |
171 return this; | |
172 } | |
173 } | |
174 | |
175 | |
176 /******************************************************************************* | |
177 | |
178 *******************************************************************************/ | |
179 | |
180 debug (FileScan) | |
181 { | |
182 import tango.io.Stdout; | |
183 | |
184 void main() | |
185 { | |
186 auto scan = new FileScan; | |
187 | |
188 scan ("."); | |
189 | |
190 Stdout.formatln ("{} Folders", scan.folders.length); | |
191 foreach (folder; scan.folders) | |
192 Stdout (folder).newline; | |
193 | |
194 Stdout.formatln ("\n{} Files", scan.files.length); | |
195 foreach (file; scan.files) | |
196 Stdout (file).newline; | |
197 | |
198 Stdout.formatln ("\n{} Errors", scan.errors.length); | |
199 foreach (error; scan.errors) | |
200 Stdout (error).newline; | |
201 } | |
202 } |