2 // DirectoryScanner.cs: Class used by BuildItem.
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
7 // (C) 2005 Marek Sieradzki
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections;
32 namespace Microsoft.Build.BuildEngine {
33 internal class DirectoryScanner {
35 DirectoryInfo baseDirectory;
38 string[] matchedFilenames;
40 public DirectoryScanner ()
46 Hashtable temporaryItems;
47 string[] splittedInclude, splittedExclude;
50 throw new ArgumentNullException ("Includes");
52 throw new ArgumentNullException ("Excludes");
53 if (baseDirectory == null)
54 throw new ArgumentNullException ("BaseDirectory");
56 temporaryItems = new Hashtable ();
58 splittedInclude = includes.Split (';');
59 splittedExclude = excludes.Split (';');
61 foreach (string si in splittedInclude) {
62 ProcessInclude (si, temporaryItems);
64 if (excludes != String.Empty) {
65 foreach (string si in splittedExclude) {
66 ProcessExclude (si, temporaryItems);
70 matchedFilenames = new string [temporaryItems.Count];
72 foreach (DictionaryEntry de in temporaryItems)
73 matchedFilenames [i++] = (string) de.Value;
76 private void ProcessInclude (string name, Hashtable temporaryItems)
78 string[] separatedPath;
81 if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1)
82 temporaryItems.Add (Path.GetFullPath (name), name);
84 if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
85 separatedPath = name.Split (Path.DirectorySeparatorChar);
87 separatedPath = name.Split (Path.AltDirectorySeparatorChar);
89 if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
91 fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
92 foreach (FileInfo fi in fileInfo)
93 temporaryItems.Add (fi.FullName, fi.FullName);
97 private void ProcessExclude (string name, Hashtable temporaryItems)
99 string[] separatedPath;
102 if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) {
103 if (temporaryItems.Contains (Path.GetFullPath (name)))
104 temporaryItems.Remove (Path.GetFullPath (name));
106 if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
107 separatedPath = name.Split (Path.DirectorySeparatorChar);
109 separatedPath = name.Split (Path.AltDirectorySeparatorChar);
111 if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
113 fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
114 foreach (FileInfo fi in fileInfo)
115 if (temporaryItems.Contains (fi.FullName))
116 temporaryItems.Remove (fi.FullName);
120 private FileInfo[] ParseIncludeExclude (string[] input, int ptr, DirectoryInfo directory)
122 if (input.Length > 1 && ptr == 0 && input [0] == String.Empty)
124 if (input.Length == ptr + 1) {
126 fi = directory.GetFiles (input [ptr]);
131 ArrayList fileInfos = new ArrayList ();
132 if (input [ptr] == ".") {
133 di = new DirectoryInfo [1];
135 } else if (input [ptr] == "..") {
136 di = new DirectoryInfo [1];
137 di [0] = directory.Parent;
139 di = directory.GetDirectories (input [ptr]);
140 foreach (DirectoryInfo info in di) {
141 fi = ParseIncludeExclude (input, ptr + 1, info);
142 foreach (FileInfo file in fi)
143 fileInfos.Add (file);
145 fi = new FileInfo [fileInfos.Count];
147 foreach (FileInfo file in fileInfos)
153 public DirectoryInfo BaseDirectory {
154 get { return baseDirectory; }
155 set { baseDirectory = value; }
158 public string Includes {
159 get { return includes; }
160 set { includes = value; }
163 public string Excludes {
164 get { return excludes; }
165 set { excludes = value; }
168 public string[] MatchedFilenames {
169 get { return matchedFilenames; }