X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMicrosoft.Build.Engine%2FMicrosoft.Build.BuildEngine%2FDirectoryScanner.cs;h=69c721c9df9cca3c0c778187da4850ec089c68d4;hb=c0a8ef12af1f473bfc837325581fe738f1b3178c;hp=5f93ca38825e4afb3a7f34908164c92e729be739;hpb=07ec1253c277856bdbb74213e2defc8ed23cf8e3;p=mono.git diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs index 5f93ca38825..69c721c9df9 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs @@ -31,14 +31,24 @@ using System; 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 () { } @@ -46,56 +56,77 @@ namespace Microsoft.Build.BuildEngine { public void Scan () { Dictionary excludedItems; - List includedItems; - string[] splitInclude, splitExclude; + List includedItems; if (includes == null) throw new ArgumentNullException ("Includes"); - if (excludes == null) - throw new ArgumentNullException ("Excludes"); if (baseDirectory == null) throw new ArgumentNullException ("BaseDirectory"); excludedItems = new Dictionary (); - includedItems = new List (); - - splitInclude = includes.Split (';'); - splitExclude = excludes.Split (';'); + includedItems = new List (); - if (excludes != String.Empty) { - foreach (string si in splitExclude) { - ProcessExclude (si, excludedItems); - } - } - if (includes != String.Empty) { - foreach (string si in splitInclude) { - ProcessInclude (si, excludedItems, includedItems); - } - } + if (excludes != null) + foreach (ITaskItem excl in excludes) + ProcessExclude (excl.ItemSpec, excludedItems); + + foreach (ITaskItem include_item in includes) + ProcessInclude (include_item, excludedItems, includedItems); - matchedFilenames = includedItems.ToArray (); + matchedItems = includedItems.ToArray (); } - private void ProcessInclude (string name, Dictionary excludedItems, List includedItems) + private void ProcessInclude (ITaskItem include_item, Dictionary excludedItems, + List includedItems) { string[] separatedPath; FileInfo[] fileInfo; - if (name.IndexOf ('?') == -1 && name.IndexOf ('*') == -1) { + string name = include_item.ItemSpec; + if (!HasWildcard (name)) { if (!excludedItems.ContainsKey (Path.GetFullPath(name))) - includedItems.Add (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.ContainsKey (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) { + string itemName = fi.FullName; + if (!Path.IsPathRooted (name) && itemName.Length > baseDirectory.FullName.Length && itemName.StartsWith (baseDirectory.FullName)) + itemName = itemName.Substring (baseDirectory.FullName.Length + 1); + + if (!excludedItems.ContainsKey (itemName) && !excludedItems.ContainsKey (Path.GetFullPath (itemName))) { + TaskItem item = new TaskItem (include_item); + item.ItemSpec = itemName; + + 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); + } + } } } @@ -109,13 +140,24 @@ namespace Microsoft.Build.BuildEngine { 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.ContainsKey (fi.FullName)) excludedItems.Add (fi.FullName, true); @@ -124,35 +166,66 @@ namespace Microsoft.Build.BuildEngine { private FileInfo[] ParseIncludeExclude (string[] input, int ptr, DirectoryInfo directory) { + return ParseIncludeExclude (input, ptr, directory, false); + } + + private FileInfo[] ParseIncludeExclude (string[] input, int ptr, DirectoryInfo directory, bool recursive) + { + DirectoryInfo[] di; + List fileInfos = new List (); + if (input.Length > 1 && ptr == 0 && input [0] == String.Empty) ptr++; - if (input.Length == ptr + 1) { - FileInfo[] fi; - fi = directory.GetFiles (input [ptr]); - return fi; - } else { - DirectoryInfo[] di; - FileInfo[] fi; - List fileInfos = new List (); - if (input [ptr] == ".") { - di = new DirectoryInfo [1]; - di [0] = directory; - } else if (input [ptr] == "..") { - di = new DirectoryInfo [1]; - di [0] = directory.Parent; - } else - di = directory.GetDirectories (input [ptr]); - foreach (DirectoryInfo info in di) { - fi = ParseIncludeExclude (input, ptr + 1, info); - foreach (FileInfo file in fi) - fileInfos.Add (file); - } - fi = new FileInfo [fileInfos.Count]; - int i = 0; - foreach (FileInfo file in fileInfos) - fi [i++] = file; - return fi; + + string cur = input.Length > ptr ? input[ptr] : input[input.Length-1]; + bool dot = cur == "."; + recursive = recursive || cur == "**"; + bool parent = cur == ".."; + + if (input.Length <= ptr + 1) { + if (parent) + directory = directory.Parent; + if ((input.Length == ptr + 1 && !recursive) || input.Length <= ptr) + return directory.GetFiles (cur); } + + if (dot) { + di = new DirectoryInfo [1]; + di [0] = directory; + } else if (parent) { + di = new DirectoryInfo [1]; + di [0] = directory.Parent; + } else if (recursive) + { + // Read this directory and all subdirectories recursive + Stack currentDirectories = new Stack(); + currentDirectories.Push(directory); + List allDirectories = new List(); + + 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 (cur); + + foreach (DirectoryInfo info in di) + fileInfos.AddRange (ParseIncludeExclude (input, ptr + 1, info, recursive)); + + return fileInfos.ToArray (); + } + + public static bool HasWildcard (string expression) + { + return expression.IndexOf ('?') >= 0 || expression.IndexOf ('*') >= 0; } public DirectoryInfo BaseDirectory { @@ -160,20 +233,23 @@ namespace Microsoft.Build.BuildEngine { 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; } + } } }