From: Gert D. <dri...@us...> - 2007-08-23 09:21:34
|
Update of /cvsroot/nant/nant/src/NAnt.Core In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv2733 Modified Files: DirectoryScanner.cs Log Message: Added casesensitive attribute to <fileset>, which defaults to true on Unix and false on other platforms. Marked StringCollectionWithGoodToString and DirScannerStringCollection internal. Added unit tests for case-sensitive behaviour of FileSet and DirectoryScanner. Index: DirectoryScanner.cs =================================================================== RCS file: /cvsroot/nant/nant/src/NAnt.Core/DirectoryScanner.cs,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** DirectoryScanner.cs 22 Aug 2007 14:42:39 -0000 1.56 --- DirectoryScanner.cs 23 Aug 2007 09:21:35 -0000 1.57 *************** *** 104,120 **** // holds the nant patterns (absolute or relative paths) ! private StringCollectionWithGoodToString _includes = new StringCollectionWithGoodToString(); ! private StringCollectionWithGoodToString _excludes = new StringCollectionWithGoodToString(); // holds the nant patterns converted to regular expression patterns (absolute canonized paths) ! private ArrayList _includePatterns; ! private ArrayList _excludePatterns; // holds the nant patterns converted to non-regex names (absolute canonized paths) ! private StringCollectionWithGoodToString _includeNames; ! private StringCollectionWithGoodToString _excludeNames; // holds the result from a scan ! private StringCollectionWithGoodToString _fileNames; private DirScannerStringCollection _directoryNames; --- 104,120 ---- // holds the nant patterns (absolute or relative paths) ! private StringCollectionWithGoodToString _includes = new StringCollectionWithGoodToString(); ! private StringCollectionWithGoodToString _excludes = new StringCollectionWithGoodToString(); // holds the nant patterns converted to regular expression patterns (absolute canonized paths) ! private ArrayList _includePatterns; ! private ArrayList _excludePatterns; // holds the nant patterns converted to non-regex names (absolute canonized paths) ! private StringCollectionWithGoodToString _includeNames; ! private StringCollectionWithGoodToString _excludeNames; // holds the result from a scan ! private StringCollectionWithGoodToString _fileNames; private DirScannerStringCollection _directoryNames; *************** *** 123,126 **** --- 123,127 ---- private DirScannerStringCollection _scannedDirectories; private ArrayList _searchDirIsRecursive; + private bool _caseSensitive; #endregion Private Instance Fields *************** *** 134,137 **** --- 135,161 ---- #endregion Private Static Fields + #region Public Instance Constructor + + /// <summary> + /// Initializes a new instance of the <see cref="DirectoryScanner" />. + /// </summary> + /// <remarks> + /// On unix, patterns are matching case-sensitively; otherwise, they + /// are matched case-insensitively. + /// </remarks> + public DirectoryScanner () : this (PlatformHelper.IsUnix) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="DirectoryScanner" /> + /// specifying whether patterns are to be match case-sensitively. + /// </summary> + /// <param name="caseSensitive">Specifies whether patterns are to be matched case-sensititely.</param> + public DirectoryScanner (bool caseSensitive) { + _caseSensitive = caseSensitive; + } + + #endregion Public Instance Constructor + #region Implementation of ICloneable *************** *** 185,188 **** --- 209,213 ---- _searchDirIsRecursive.Clone(); } + clone._caseSensitive = _caseSensitive; return clone; } *************** *** 193,199 **** /// <summary> /// Gets the collection of include patterns. /// </summary> ! public StringCollectionWithGoodToString Includes { get { return _includes; } } --- 218,238 ---- /// <summary> + /// Gets or set a value indicating whether or not to use case-sensitive + /// pattern matching. + /// </summary> + public bool CaseSensitive { + get { return _caseSensitive; } + set { + if (value != _caseSensitive) { + _caseSensitive = value; + Reset (); + } + } + } + + /// <summary> /// Gets the collection of include patterns. /// </summary> ! public StringCollection Includes { get { return _includes; } } *************** *** 202,206 **** /// Gets the collection of exclude patterns. /// </summary> ! public StringCollectionWithGoodToString Excludes { get { return _excludes; } } --- 241,245 ---- /// Gets the collection of exclude patterns. /// </summary> ! public StringCollection Excludes { get { return _excludes; } } *************** *** 220,229 **** set { if (value != null) { ! // convert both slashes and backslashes to directory separator // char ! _baseDirectory = new DirectoryInfo(CleanPath( value.FullName).ToString()); ! } else { _baseDirectory = value; } } --- 259,271 ---- set { if (value != null) { ! // convert both slashes and backslashes to directory separator // char ! value = new DirectoryInfo(CleanPath( value.FullName).ToString()); ! } ! ! if (value != _baseDirectory) { _baseDirectory = value; + Reset (); } } *************** *** 233,237 **** /// Gets the list of files that match the given patterns. /// </summary> ! public StringCollectionWithGoodToString FileNames { get { if (_fileNames == null) { --- 275,279 ---- /// Gets the list of files that match the given patterns. /// </summary> ! public StringCollection FileNames { get { if (_fileNames == null) { *************** *** 245,249 **** /// Gets the list of directories that match the given patterns. /// </summary> ! public DirScannerStringCollection DirectoryNames { get { if (_directoryNames == null) { --- 287,291 ---- /// Gets the list of directories that match the given patterns. /// </summary> ! public StringCollection DirectoryNames { get { if (_directoryNames == null) { *************** *** 257,261 **** /// Gets the list of directories that were scanned for files. /// </summary> ! public DirScannerStringCollection ScannedDirectories { get { if (_scannedDirectories == null) { --- 299,303 ---- /// Gets the list of directories that were scanned for files. /// </summary> ! public StringCollection ScannedDirectories { get { if (_scannedDirectories == null) { *************** *** 280,287 **** _excludeNames = new StringCollectionWithGoodToString (); _fileNames = new StringCollectionWithGoodToString (); ! _directoryNames = new DirScannerStringCollection(); ! _searchDirectories = new DirScannerStringCollection(); _searchDirIsRecursive = new ArrayList(); ! _scannedDirectories = new DirScannerStringCollection(); #if DEBUG_REGEXES --- 322,330 ---- _excludeNames = new StringCollectionWithGoodToString (); _fileNames = new StringCollectionWithGoodToString (); ! _directoryNames = new DirScannerStringCollection(CaseSensitive); ! ! _searchDirectories = new DirScannerStringCollection(CaseSensitive); _searchDirIsRecursive = new ArrayList(); ! _scannedDirectories = new DirScannerStringCollection(CaseSensitive); #if DEBUG_REGEXES *************** *** 321,324 **** --- 364,379 ---- #region Private Instance Methods + private void Reset () { + _includePatterns = null; + _includeNames = null; + _excludePatterns = null; + _excludeNames = null; + _fileNames = null; + _directoryNames = null; + _searchDirectories = null; + _searchDirIsRecursive = null; + _scannedDirectories = null; + } + /// <summary> /// Parses specified NAnt search patterns for search directories and *************** *** 455,459 **** } ! //if the fs in case insensitive, make all the regex directories lowercase. regexPattern = ToRegexPattern(modifiedNAntPattern); --- 510,514 ---- } ! //if the fs in case-insensitive, make all the regex directories lowercase. regexPattern = ToRegexPattern(modifiedNAntPattern); *************** *** 465,473 **** } - private bool IsCaseSensitiveFileSystem(string path) { - string fullPath = Path.GetFullPath(path); - return PlatformHelper.IsVolumeCaseSensitive(fullPath); - } - /// <summary> /// Searches a directory recursively for files and directories matching --- 520,523 ---- *************** *** 493,503 **** DirectoryInfo currentDirectoryInfo = new DirectoryInfo(path); - // check whether directory is on case-sensitive volume - bool caseSensitive = IsCaseSensitiveFileSystem(path); - CompareOptions compareOptions = CompareOptions.None; CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; ! ! if (!caseSensitive) compareOptions |= CompareOptions.IgnoreCase; --- 543,550 ---- DirectoryInfo currentDirectoryInfo = new DirectoryInfo(path); CompareOptions compareOptions = CompareOptions.None; CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; ! ! if (!CaseSensitive) compareOptions |= CompareOptions.IgnoreCase; *************** *** 510,519 **** // check if the directory being searched is equal to the ! // basedirectory of the RegexEntry if (compare.Compare(path, baseDirectory, compareOptions) == 0) { includedPatterns.Add(entry); } else { // check if the directory being searched is subdirectory of ! // basedirectory of RegexEntry if (!entry.IsRecursive) { --- 557,566 ---- // check if the directory being searched is equal to the ! // base directory of the RegexEntry if (compare.Compare(path, baseDirectory, compareOptions) == 0) { includedPatterns.Add(entry); } else { // check if the directory being searched is subdirectory of ! // base directory of RegexEntry if (!entry.IsRecursive) { *************** *** 565,569 **** } else { // otherwise just test to see if the subdirectories are included ! if (IsPathIncluded(directoryInfo.FullName, caseSensitive, includedPatterns, excludedPatterns)) { _directoryNames.Add(directoryInfo.FullName); } --- 612,616 ---- } else { // otherwise just test to see if the subdirectories are included ! if (IsPathIncluded(directoryInfo.FullName, includedPatterns, excludedPatterns)) { _directoryNames.Add(directoryInfo.FullName); } *************** *** 574,578 **** foreach (FileInfo fileInfo in currentDirectoryInfo.GetFiles()) { string filename = Path.Combine(path, fileInfo.Name); ! if (IsPathIncluded(filename, caseSensitive, includedPatterns, excludedPatterns)) { _fileNames.Add(Path.Combine(path, fileInfo.Name)); } --- 621,625 ---- foreach (FileInfo fileInfo in currentDirectoryInfo.GetFiles()) { string filename = Path.Combine(path, fileInfo.Name); ! if (IsPathIncluded(filename, includedPatterns, excludedPatterns)) { _fileNames.Add(Path.Combine(path, fileInfo.Name)); } *************** *** 583,601 **** // but it is more like formalizing something in a way that makes // writing the delete task easier :) ! if (IsPathIncluded(path, caseSensitive, includedPatterns, excludedPatterns)) { _directoryNames.Add(path); } } ! private bool TestRegex(string path, RegexEntry entry, bool caseSensitive) { ! Hashtable regexCache = caseSensitive ? cachedCaseSensitiveRegexes : cachedCaseInsensitiveRegexes; Regex r = (Regex)regexCache[entry.Pattern]; if (r == null) { RegexOptions regexOptions = RegexOptions.Compiled; ! ! if (!caseSensitive) regexOptions |= RegexOptions.IgnoreCase; ! regexCache[entry.Pattern] = r = new Regex(entry.Pattern, regexOptions); } --- 630,648 ---- // but it is more like formalizing something in a way that makes // writing the delete task easier :) ! if (IsPathIncluded(path, includedPatterns, excludedPatterns)) { _directoryNames.Add(path); } } ! private bool TestRegex(string path, RegexEntry entry) { ! Hashtable regexCache = CaseSensitive ? cachedCaseSensitiveRegexes : cachedCaseInsensitiveRegexes; Regex r = (Regex)regexCache[entry.Pattern]; if (r == null) { RegexOptions regexOptions = RegexOptions.Compiled; ! ! if (!CaseSensitive) regexOptions |= RegexOptions.IgnoreCase; ! regexCache[entry.Pattern] = r = new Regex(entry.Pattern, regexOptions); } *************** *** 620,632 **** } ! private bool IsPathIncluded(string path, bool caseSensitive, ArrayList includedPatterns, ArrayList excludedPatterns) { bool included = false; ! CompareOptions compareOptions = CompareOptions.None; CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; ! ! if (!caseSensitive) compareOptions |= CompareOptions.IgnoreCase; ! #if DEBUG_REGEXES Console.WriteLine("Test: {0}", path); --- 667,679 ---- } ! private bool IsPathIncluded(string path, ArrayList includedPatterns, ArrayList excludedPatterns) { bool included = false; ! CompareOptions compareOptions = CompareOptions.None; CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; ! ! if (!CaseSensitive) compareOptions |= CompareOptions.IgnoreCase; ! #if DEBUG_REGEXES Console.WriteLine("Test: {0}", path); *************** *** 655,659 **** Console.Write("Test include pattern: "); #endif ! if (TestRegex(path, entry, caseSensitive)) { included = true; --- 702,706 ---- Console.Write("Test include pattern: "); #endif ! if (TestRegex(path, entry)) { included = true; *************** *** 689,694 **** Console.Write("Test exclude pattern: "); #endif ! if (TestRegex(path, entry, caseSensitive)) ! { included = false; #if DEBUG_REGEXES --- 736,740 ---- Console.Write("Test exclude pattern: "); #endif ! if (TestRegex(path, entry)) { included = false; #if DEBUG_REGEXES *************** *** 714,719 **** StringBuilder pathBuilder = new StringBuilder(nantPath); ! // NAnt patterns can use either / \ as a directory seperator. ! // We must replace both of these characters with Path.DirectorySeperatorChar pathBuilder.Replace('/', Path.DirectorySeparatorChar); pathBuilder.Replace('\\', Path.DirectorySeparatorChar); --- 760,765 ---- StringBuilder pathBuilder = new StringBuilder(nantPath); ! // NAnt patterns can use either / \ as a directory separator. ! // We must replace both of these characters with Path.DirectorySeparatorChar pathBuilder.Replace('/', Path.DirectorySeparatorChar); pathBuilder.Replace('\\', Path.DirectorySeparatorChar); *************** *** 804,808 **** patternText = patternText.Substring(3); if (patternText.EndsWith(".*$")) ! patternText = patternText.Substring(0, pattern.Length-3); return patternText.ToString(); --- 850,854 ---- patternText = patternText.Substring(3); if (patternText.EndsWith(".*$")) ! patternText = patternText.Substring(0, pattern.Length - 3); return patternText.ToString(); *************** *** 820,824 **** [Serializable()] ! public class StringCollectionWithGoodToString : StringCollection, ICloneable { #region Implementation of ICloneable --- 866,870 ---- [Serializable()] ! internal class StringCollectionWithGoodToString : StringCollection, ICloneable { #region Implementation of ICloneable *************** *** 861,865 **** [Serializable()] ! public class DirScannerStringCollection : StringCollectionWithGoodToString { #region Override implementation of ICloneable --- 907,939 ---- [Serializable()] ! internal class DirScannerStringCollection : StringCollectionWithGoodToString { ! #region Public Instance Constructors ! ! /// <summary> ! /// Initialize a new instance of the <see cref="DirScannerStringCollection" /> ! /// class specifying whether or not string comparison should be ! /// case-sensitive. ! /// </summary> ! /// <param name="caseSensitive">Specifies whether or not string comparison should be case-sensitive.</param> ! public DirScannerStringCollection (bool caseSensitive) { ! _caseSensitive = caseSensitive; ! } ! ! #endregion Public Instance Constructors ! ! #region Public Instance Properties ! ! /// <summary> ! /// Gets a value indicating whether string comparison is case-sensitive. ! /// </summary> ! /// <value> ! /// A value indicating whether string comparison is case-sensitive. ! /// </value> ! public bool CaseSensitive { ! get { return _caseSensitive; } ! } ! ! #endregion Public Instance Properties ! #region Override implementation of ICloneable *************** *** 873,877 **** string[] strings = new string[Count]; CopyTo(strings, 0); ! DirScannerStringCollection clone = new DirScannerStringCollection(); clone.AddRange(strings); return clone; --- 947,951 ---- string[] strings = new string[Count]; CopyTo(strings, 0); ! DirScannerStringCollection clone = new DirScannerStringCollection(CaseSensitive); clone.AddRange(strings); return clone; *************** *** 892,901 **** /// <remarks> /// String comparisons within the <see cref="DirScannerStringCollection" /> ! /// are only case-sensitive if the filesystem on which <paramref name="value" /> ! /// is located, is case-sensitive. /// </remarks> public new virtual bool Contains(string value) { return (IndexOf(value) > -1); - } --- 966,974 ---- /// <remarks> /// String comparisons within the <see cref="DirScannerStringCollection" /> ! /// are only case-sensitive if <see cref="CaseSensitive" /> is ! /// <see langword="true" /> /// </remarks> public new virtual bool Contains(string value) { return (IndexOf(value) > -1); } *************** *** 911,919 **** /// <remarks> /// String comparisons within the <see cref="DirScannerStringCollection" /> ! /// are only case-sensitive if the filesystem on which <paramref name="value" /> ! /// is located, is case-sensitive. /// </remarks> public new virtual int IndexOf(string value) { ! if (value == null || IsCaseSensitiveFileSystem(value)) { return base.IndexOf(value); } else { --- 984,992 ---- /// <remarks> /// String comparisons within the <see cref="DirScannerStringCollection" /> ! /// are only case-sensitive if <see cref="CaseSensitive" /> is ! /// <see langword="true" />. /// </remarks> public new virtual int IndexOf(string value) { ! if (value == null || CaseSensitive) { return base.IndexOf(value); } else { *************** *** 929,949 **** #endregion Override implementation of StringCollection ! #region Private Instance Methods ! /// <summary> ! /// Determines whether the filesystem on which the specified path is ! /// located is case-sensitive. ! /// </summary> ! /// <param name="path">The path of which should be determined whether its on a case-sensitive filesystem.</param> ! /// <returns> ! /// <see langword="true" /> if <paramref name="path" /> is located on a ! /// case-sensitive filesystem; otherwise, <see langword="false" />. ! /// </returns> ! private bool IsCaseSensitiveFileSystem(string path) { ! string fullPath = Path.GetFullPath(path); ! return PlatformHelper.IsVolumeCaseSensitive(fullPath); ! } ! #endregion Private Instance Methods } } --- 1002,1010 ---- #endregion Override implementation of StringCollection ! #region Private Instance Fields ! private readonly bool _caseSensitive; ! #endregion Private Instance Fields } } |