merge -r 58784:58785
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / DirectoryScanner.cs
1 //
2 // DirectoryScanner.cs: Class used by BuildItem.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2005 Marek Sieradzki
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
28 #if NET_2_0
29
30 using System;
31 using System.Collections;
32 using System.IO;
33
34 namespace Microsoft.Build.BuildEngine {
35         internal class DirectoryScanner {
36                 
37                 DirectoryInfo   baseDirectory;
38                 string          includes;
39                 string          excludes;
40                 string[]        matchedFilenames;
41                 
42                 public DirectoryScanner ()
43                 {
44                 }
45                 
46                 public void Scan ()
47                 {
48                         Hashtable temporaryItems;
49                         string[] splittedInclude, splittedExclude;
50                 
51                         if (includes == null)
52                                 throw new ArgumentNullException ("Includes");
53                         if (excludes == null)
54                                 throw new ArgumentNullException ("Excludes");
55                         if (baseDirectory == null)
56                                 throw new ArgumentNullException ("BaseDirectory");
57                         
58                         temporaryItems = new Hashtable ();
59                         
60                         splittedInclude = includes.Split (';');
61                         splittedExclude = excludes.Split (';');
62                         
63                         foreach (string si in splittedInclude) {
64                                 ProcessInclude (si, temporaryItems);
65                         }
66                         if (excludes != String.Empty) {
67                                 foreach (string si in splittedExclude) {
68                                         ProcessExclude (si, temporaryItems);
69                                 }
70                         }
71                         
72                         matchedFilenames = new string [temporaryItems.Count];
73                         int i = 0;
74                         foreach (DictionaryEntry de in temporaryItems)
75                                 matchedFilenames [i++] = (string) de.Value; 
76                 }
77                 
78                 private void ProcessInclude (string name, Hashtable temporaryItems)
79                 {
80                         string[] separatedPath;
81                         FileInfo[] fileInfo;
82                         
83                         if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1)
84                                 temporaryItems.Add (Path.GetFullPath (name), name);
85                         else {
86                                 if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
87                                         separatedPath = name.Split (Path.DirectorySeparatorChar);
88                                 } else {
89                                         separatedPath = name.Split (Path.AltDirectorySeparatorChar);
90                                 }
91                                 if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
92                                         return;
93                                 fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
94                                 foreach (FileInfo fi in fileInfo)
95                                         temporaryItems.Add (fi.FullName, fi.FullName);
96                         }
97                 }
98                 
99                 private void ProcessExclude (string name, Hashtable temporaryItems)
100                 {
101                         string[] separatedPath;
102                         FileInfo[] fileInfo;
103                         
104                         if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) {
105                                 if (temporaryItems.Contains (Path.GetFullPath (name)))
106                                         temporaryItems.Remove (Path.GetFullPath (name));
107                         } else {
108                                 if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
109                                         separatedPath = name.Split (Path.DirectorySeparatorChar);
110                                 } else {
111                                         separatedPath = name.Split (Path.AltDirectorySeparatorChar);
112                                 }
113                                 if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
114                                         return;
115                                 fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
116                                 foreach (FileInfo fi in fileInfo)
117                                         if (temporaryItems.Contains (fi.FullName))
118                                                 temporaryItems.Remove (fi.FullName);
119                         }
120                 }
121                 
122                 private FileInfo[] ParseIncludeExclude (string[] input, int ptr, DirectoryInfo directory)
123                 {
124                         if (input.Length > 1 && ptr == 0 && input [0] == String.Empty)
125                                 ptr++;
126                         if (input.Length == ptr + 1) {
127                                 FileInfo[] fi;
128                                 fi = directory.GetFiles (input [ptr]);
129                                 return fi;
130                         } else {
131                                 DirectoryInfo[] di;
132                                 FileInfo[] fi;
133                                 ArrayList fileInfos = new ArrayList ();
134                                 if (input [ptr] == ".") {
135                                         di = new DirectoryInfo [1];
136                                         di [0] = directory;
137                                 } else if (input [ptr] == "..") {
138                                         di = new DirectoryInfo [1];
139                                         di [0] = directory.Parent;
140                                 } else
141                                         di = directory.GetDirectories (input [ptr]);
142                                 foreach (DirectoryInfo info in di) {
143                                         fi = ParseIncludeExclude (input, ptr + 1, info);
144                                         foreach (FileInfo file in fi)
145                                                 fileInfos.Add (file);
146                                 }
147                                 fi = new FileInfo [fileInfos.Count];
148                                 int i = 0;
149                                 foreach (FileInfo file in fileInfos)
150                                         fi [i++] = file;
151                                 return fi;
152                         }
153                 }
154                 
155                 public DirectoryInfo BaseDirectory {
156                         get { return baseDirectory; }
157                         set { baseDirectory = value; }
158                 }
159                 
160                 public string Includes {
161                         get { return includes; }
162                         set { includes = value; }
163                 }
164                 
165                 public string Excludes {
166                         get { return excludes; }
167                         set { excludes = value; }
168                 }
169                 
170                 public string[] MatchedFilenames {
171                         get { return matchedFilenames; }
172                 }
173                 
174         }
175 }
176
177 #endif