// NAnt - A .NET build tool
// Copyright (C) 2001-2003 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Brad Wilson (http://www.quality.nu/contact.aspx)
using System;
using System.Collections.Specialized;
using System.IO;
using NAnt.Core.Util;
namespace NAnt.Core {
///
/// Used to search for files on the PATH.
///
///
///
/// The local directory is not searched (since this would already be covered
/// by normal use of the includes element).
///
///
/// Also, advanced pattern matching isn't supported: you need to know the
/// exact name of the file.
///
///
[Serializable()]
public sealed class PathScanner : ICloneable {
#region Private Instance Fields
private StringCollection _unscannedNames = new StringCollection();
#endregion Private Instance Fields
#region Implementation of ICloneable
///
/// Creates a shallow copy of the .
///
///
/// A shallow copy of the .
///
object ICloneable.Clone() {
return Clone();
}
///
/// Creates a shallow copy of the .
///
///
/// A shallow copy of the .
///
public PathScanner Clone() {
PathScanner clone = new PathScanner();
clone._unscannedNames = Clone(_unscannedNames);
return clone;
}
#endregion Implementation of ICloneable
#region Public Instance Methods
///
/// Adds a file to the list of files to be scanned for.
///
/// The filename or search pattern to add to the list.
public void Add(string fileName) {
_unscannedNames.Add(fileName);
}
public void Clear() {
_unscannedNames.Clear();
}
///
/// Scans all direcetories in the PATH environment variable for files.
///
///
/// List of matching files found in the PATH.
///
public StringCollection Scan() {
return Scan("PATH");
}
///
/// Scans all directories in the given environment variable for files.
///
/// The environment variable of which the directories should be scanned.
///
/// List of matching files found in the directory of the given
/// environment variable.
///
public StringCollection Scan(string name) {
StringCollection scannedNames = new StringCollection();
string envValue = Environment.GetEnvironmentVariable(name);
if (envValue == null) {
return scannedNames;
}
// break apart the PATH
string[] paths = envValue.Split(Path.PathSeparator);
// walk the names list
foreach (string unscannedName in _unscannedNames) {
// check if file is rooted
if (Path.IsPathRooted(unscannedName)) {
if (File.Exists(unscannedName)) {
scannedNames.Add(unscannedName);
} else {
// no need to scan paths in environment variable for
// this file as it does not exist
continue;
}
}
string fileName = Path.GetFileName(unscannedName);
string directoryName = Path.GetDirectoryName(unscannedName);
// walk the paths, and see if the given file is on the path
foreach (string path in paths) {
//do not scan inaccessible directories.
if (!Directory.Exists(path)) {
continue;
}
// search pattern might include directory part (eg. foo\bar.txt)
string scanPath = path;
if (!StringUtils.IsNullOrEmpty(directoryName)) {
scanPath = FileUtils.CombinePaths(path, directoryName);
//do not scan inaccessible directories.
if (!Directory.Exists(scanPath)) {
continue;
}
}
string[] found = Directory.GetFiles(scanPath, fileName);
if (found.Length > 0) {
scannedNames.Add(found[0]);
break;
}
}
}
// return an enumerator to the scanned (& found) files
return scannedNames;
}
#endregion Public Instance Methods
#region Private Static Methods
///
/// Creates a shallow copy of the specified .
///
/// The that should be copied.
///
/// A shallow copy of the specified .
///
private static StringCollection Clone(StringCollection stringCollection) {
string[] strings = new string[stringCollection.Count];
stringCollection.CopyTo(strings, 0);
StringCollection clone = new StringCollection();
clone.AddRange(strings);
return clone;
}
#endregion Private Static Methods
}
}