#if NET_2_0
using System;
-using System.Collections;
+using System.Collections.Generic;
using System.IO;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
namespace Microsoft.Build.BuildEngine {
internal class DirectoryScanner {
DirectoryInfo baseDirectory;
- string includes;
- string excludes;
- string[] matchedFilenames;
+ ITaskItem[] includes, excludes;
+ ITaskItem[] matchedItems;
+
+ static bool _runningOnWindows;
+ static DirectoryScanner ()
+ {
+ PlatformID pid = Environment.OSVersion.Platform;
+ _runningOnWindows =((int) pid != 128 && (int) pid != 4 && (int) pid != 6);
+ }
+
public DirectoryScanner ()
{
}
public void Scan ()
{
- Hashtable excludedItems;
- ArrayList includedItems;
- string[] splittedInclude, splittedExclude;
+ Dictionary <string, bool> excludedItems;
+ List <ITaskItem> includedItems;
if (includes == null)
throw new ArgumentNullException ("Includes");
- if (excludes == null)
- throw new ArgumentNullException ("Excludes");
if (baseDirectory == null)
throw new ArgumentNullException ("BaseDirectory");
- excludedItems = new Hashtable ();
- includedItems = new ArrayList ();
-
- splittedInclude = includes.Split (';');
- splittedExclude = excludes.Split (';');
+ excludedItems = new Dictionary <string, bool> ();
+ includedItems = new List <ITaskItem> ();
- if (excludes != String.Empty) {
- foreach (string si in splittedExclude) {
- ProcessExclude (si, excludedItems);
- }
- }
- if (includes != String.Empty) {
- foreach (string si in splittedInclude) {
- ProcessInclude (si, excludedItems, includedItems);
- }
- }
+ if (excludes != null)
+ foreach (ITaskItem excl in excludes)
+ ProcessExclude (excl.ItemSpec, excludedItems);
- matchedFilenames = (string[])includedItems.ToArray (typeof (string));
+ foreach (ITaskItem include_item in includes)
+ ProcessInclude (include_item, excludedItems, includedItems);
+
+ matchedItems = includedItems.ToArray ();
}
- private void ProcessInclude (string name, Hashtable excludedItems, ArrayList includedItems)
+ private void ProcessInclude (ITaskItem include_item, Dictionary <string, bool> excludedItems,
+ List <ITaskItem> includedItems)
{
string[] separatedPath;
FileInfo[] fileInfo;
- if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) {
- if (!excludedItems.Contains (Path.GetFullPath(name)))
- includedItems.Add (name);
+ string name = include_item.ItemSpec;
+ if (!HasWildcard (name)) {
+ if (!excludedItems.ContainsKey (Path.GetFullPath(name)))
+ includedItems.Add (include_item);
} else {
if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
- separatedPath = name.Split (Path.DirectorySeparatorChar);
+ separatedPath = name.Split (new char [] {Path.DirectorySeparatorChar},
+ StringSplitOptions.RemoveEmptyEntries);
} else {
- separatedPath = name.Split (Path.AltDirectorySeparatorChar);
+ separatedPath = name.Split (new char [] {Path.AltDirectorySeparatorChar},
+ StringSplitOptions.RemoveEmptyEntries);
}
if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
return;
- fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
- foreach (FileInfo fi in fileInfo)
- if (!excludedItems.Contains (fi.FullName))
- includedItems.Add (fi.FullName);
+
+ int offset = 0;
+ if (Path.IsPathRooted (name)) {
+ baseDirectory = new DirectoryInfo (Path.GetPathRoot (name));
+ if (IsRunningOnWindows)
+ // skip the "drive:"
+ offset = 1;
+ }
+
+ string full_path = Path.GetFullPath (Path.Combine (Environment.CurrentDirectory, include_item.ItemSpec));
+ fileInfo = ParseIncludeExclude (separatedPath, offset, baseDirectory);
+
+ int wildcard_offset = full_path.IndexOf ("**");
+ foreach (FileInfo fi in fileInfo) {
+ if (!excludedItems.ContainsKey (fi.FullName)) {
+ TaskItem item = new TaskItem (include_item);
+ item.ItemSpec = fi.FullName;
+ if (wildcard_offset >= 0) {
+ string rec_dir = Path.GetDirectoryName (fi.FullName.Substring (wildcard_offset));
+ if (rec_dir.Length > 0)
+ rec_dir += Path.DirectorySeparatorChar;
+ item.SetMetadata ("RecursiveDir", rec_dir);
+ }
+ includedItems.Add (item);
+ }
+ }
}
}
- private void ProcessExclude (string name, Hashtable excludedItems)
+ private void ProcessExclude (string name, Dictionary <string, bool> excludedItems)
{
string[] separatedPath;
FileInfo[] fileInfo;
if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) {
- if (!excludedItems.Contains (Path.GetFullPath (name)))
- excludedItems.Add (Path.GetFullPath (name), null);
+ if (!excludedItems.ContainsKey (Path.GetFullPath (name)))
+ excludedItems.Add (Path.GetFullPath (name), true);
} else {
if (name.Split (Path.DirectorySeparatorChar).Length > name.Split (Path.AltDirectorySeparatorChar).Length) {
- separatedPath = name.Split (Path.DirectorySeparatorChar);
+ separatedPath = name.Split (new char [] {Path.DirectorySeparatorChar},
+ StringSplitOptions.RemoveEmptyEntries);
} else {
- separatedPath = name.Split (Path.AltDirectorySeparatorChar);
+ separatedPath = name.Split (new char [] {Path.AltDirectorySeparatorChar},
+ StringSplitOptions.RemoveEmptyEntries);
}
if (separatedPath.Length == 1 && separatedPath [0] == String.Empty)
return;
- fileInfo = ParseIncludeExclude (separatedPath, 0, baseDirectory);
+
+ int offset = 0;
+ if (Path.IsPathRooted (name)) {
+ baseDirectory = new DirectoryInfo (Path.GetPathRoot (name));
+ if (IsRunningOnWindows)
+ // skip the "drive:"
+ offset = 1;
+ }
+ fileInfo = ParseIncludeExclude (separatedPath, offset, baseDirectory);
foreach (FileInfo fi in fileInfo)
- if (!excludedItems.Contains (fi.FullName))
- excludedItems.Add (fi.FullName, null);
+ if (!excludedItems.ContainsKey (fi.FullName))
+ excludedItems.Add (fi.FullName, true);
}
}
} else {
DirectoryInfo[] di;
FileInfo[] fi;
- ArrayList fileInfos = new ArrayList ();
+ List <FileInfo> fileInfos = new List <FileInfo> ();
if (input [ptr] == ".") {
di = new DirectoryInfo [1];
di [0] = directory;
} else if (input [ptr] == "..") {
di = new DirectoryInfo [1];
di [0] = directory.Parent;
- } else
+ } else if (input[ptr] == "**")
+ {
+ // Read this directory and all subdirectories recursive
+ Stack<DirectoryInfo> currentDirectories = new Stack<DirectoryInfo>();
+ currentDirectories.Push(directory);
+ List<DirectoryInfo> allDirectories = new List<DirectoryInfo>();
+
+ while (currentDirectories.Count > 0)
+ {
+ DirectoryInfo current = currentDirectories.Pop();
+ allDirectories.Insert (0, current);
+ foreach (DirectoryInfo dir in current.GetDirectories())
+ {
+ currentDirectories.Push(dir);
+ }
+ }
+
+ // No further directories shall be read
+ di = allDirectories.ToArray();
+ } else {
di = directory.GetDirectories (input [ptr]);
+ }
foreach (DirectoryInfo info in di) {
fi = ParseIncludeExclude (input, ptr + 1, info);
foreach (FileInfo file in fi)
return fi;
}
}
+
+ public static bool HasWildcard (string expression)
+ {
+ return expression.IndexOf ('?') >= 0 || expression.IndexOf ('*') >= 0;
+ }
public DirectoryInfo BaseDirectory {
get { return baseDirectory; }
set { baseDirectory = value; }
}
- public string Includes {
+ public ITaskItem[] Includes {
get { return includes; }
set { includes = value; }
}
- public string Excludes {
+ public ITaskItem[] Excludes {
get { return excludes; }
set { excludes = value; }
}
- public string[] MatchedFilenames {
- get { return matchedFilenames; }
+ public ITaskItem[] MatchedItems {
+ get { return matchedItems; }
}
+ static bool IsRunningOnWindows {
+ get { return _runningOnWindows; }
+ }
}
}