#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;
+ ITaskItem[] includes;
string excludes;
- string[] matchedFilenames;
+ 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;
+ string[] splitInclude, splitExclude;
if (includes == null)
throw new ArgumentNullException ("Includes");
if (baseDirectory == null)
throw new ArgumentNullException ("BaseDirectory");
- excludedItems = new Hashtable ();
- includedItems = new ArrayList ();
+ excludedItems = new Dictionary <string, bool> ();
+ includedItems = new List <ITaskItem> ();
- splittedInclude = includes.Split (';');
- splittedExclude = excludes.Split (';');
+ splitExclude = excludes.Split (new char[] {';'}, StringSplitOptions.RemoveEmptyEntries);
if (excludes != String.Empty) {
- foreach (string si in splittedExclude) {
+ foreach (string si in splitExclude) {
ProcessExclude (si, excludedItems);
}
}
- if (includes != String.Empty) {
- foreach (string si in splittedInclude) {
- ProcessInclude (si, excludedItems, includedItems);
- }
- }
- 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;
+ string name = include_item.ItemSpec;
if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) {
- if (!excludedItems.Contains (Path.GetFullPath(name)))
- includedItems.Add (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)) {
+ if (!IsRunningOnWindows) {
+ baseDirectory = new DirectoryInfo ("/");
+ } else {
+ baseDirectory = new DirectoryInfo (separatedPath [0]);
+ offset = 1;
+ }
+ }
+
+ fileInfo = ParseIncludeExclude (separatedPath, offset, baseDirectory);
+
+ foreach (FileInfo fi in fileInfo) {
+ if (!excludedItems.ContainsKey (fi.FullName)) {
+ TaskItem item = new TaskItem (include_item);
+ item.ItemSpec = fi.FullName;
+ 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)) {
+ if (IsRunningOnWindows) {
+ // set base dir to drive:, and skip that
+ baseDirectory = new DirectoryInfo (separatedPath [0]);
+ offset = 1;
+ } else {
+ baseDirectory = new DirectoryInfo ("/");
+ }
+ }
+
+ 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)
set { baseDirectory = value; }
}
- public string Includes {
+ public ITaskItem[] Includes {
get { return includes; }
set { includes = value; }
}
set { excludes = value; }
}
- public string[] MatchedFilenames {
- get { return matchedFilenames; }
+ public ITaskItem[] MatchedItems {
+ get { return matchedItems; }
}
+ static bool IsRunningOnWindows {
+ get { return _runningOnWindows; }
+ }
}
}