// 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
//
// Gert Driesen (gert.driesen@ardatis.com)
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using NAnt.Core;
using NAnt.Core.Util;
using NAnt.VSNet.Tasks;
namespace NAnt.VSNet {
public abstract class ConfigurationBase {
#region Protected Instance Constructors
///
/// Initializes a new instance of the
/// class with the given .
///
/// The project of the configuration.
protected ConfigurationBase(ProjectBase project) {
if (project == null) {
throw new ArgumentNullException("project");
}
_project = project;
_extraOutputFiles = CollectionsUtil.CreateCaseInsensitiveHashtable();
}
#endregion Protected Instance Constructors
#region Public Instance Properties
///
/// Gets the project.
///
public ProjectBase Project {
get { return _project;}
}
///
/// Gets the name of the configuration.
///
public abstract string Name {
get;
}
///
/// Get the directory in which intermediate build output will be stored
/// for this configuration.
///
///
///
/// This is a directory relative to the project directory named
/// obj\<configuration name>.
///
///
/// .resx and .licx files will only be recompiled if the
/// compiled resource files in the are not
/// uptodate.
///
///
public virtual DirectoryInfo ObjectDir {
get {
return new DirectoryInfo(FileUtils.CombinePaths(Project.ObjectDir.FullName,
Name));
}
}
///
/// Gets the output directory.
///
public abstract DirectoryInfo OutputDir {
get;
}
///
/// Gets the path for the output file.
///
public abstract string OutputPath {
get;
}
///
/// Gets the path in which the output file will be created before its
/// copied to the actual output path.
///
public abstract string BuildPath {
get;
}
///
/// Get the path of the output directory relative to the project
/// directory.
///
public abstract string RelativeOutputDir {
get;
}
///
/// Gets the platform that the configuration targets.
///
///
/// The platform targeted by the configuration.
///
public abstract string PlatformName {
get;
}
///
/// Gets the set of output files that is specific to the project
/// configuration.
///
///
/// The set of output files that is specific to the project
/// configuration.
///
///
/// The key of the case-insensitive is the
/// full path of the output file and the value is the path relative to
/// the output directory.
///
public Hashtable ExtraOutputFiles {
get { return _extraOutputFiles; }
}
#endregion Public Instance Properties
#region Protected Instance Properties
protected SolutionTask SolutionTask {
get { return Project.SolutionTask; }
}
#endregion Protected Instance Properties
#region Public Instance Methods
public string ExpandMacros(string s) {
if (s == null) {
return s;
}
return _rxMacro.Replace(s, new MatchEvaluator(EvaluateMacro));
}
#endregion Public Instance Methods
#region Protected Instance Methods
///
/// Expands the given macro.
///
/// The macro to expand.
///
/// The expanded macro.
///
///
/// The macro is not supported.
/// -or-
/// The macro is not implemented.
/// -or-
/// The macro cannot be expanded.
///
///
/// Expansion of a given macro is not yet implemented.
///
protected internal virtual string ExpandMacro(string macro) {
// perform case-insensitive expansion of macros
switch (macro.ToLower(CultureInfo.InvariantCulture)) {
case "outdir": // E.g. bin\Debug\
return RelativeOutputDir;
case "configurationname": // E.g. Debug
return Name;
case "targetname": // E.g. WindowsApplication1
return Path.GetFileNameWithoutExtension(Path.GetFileName(
OutputPath));
case "targetpath": // E.g. C:\Doc...\Visual Studio Projects\WindowsApplications1\bin\Debug\WindowsApplications1.exe
return OutputPath;
case "targetext": // E.g. .exe
return Path.GetExtension(OutputPath);
case "targetfilename": // E.g. WindowsApplications1.exe
return Path.GetFileName(OutputPath);
case "targetdir": // Absolute path to OutDir
return OutputDir.FullName + (OutputDir.FullName.EndsWith(
Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture))
? "" : Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture));
case "platformname": // .NET, does this value ever change?
return PlatformName;
}
// expand using solution level macro's
string expandedMacro = Project.SolutionTask.ExpandMacro(macro);
if (expandedMacro != null) {
return expandedMacro;
}
// expand using project level macro's
expandedMacro = Project.ExpandMacro(macro);
if (expandedMacro != null) {
return expandedMacro;
}
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Macro \"{0}\" is not supported.", macro), Location.UnknownLocation);
}
#endregion Protected Instance Methods
#region Private Instance Methods
///
/// Is called each time a regular expression match is found during a
/// operation.
///
/// The resulting from a single regular expression match during a .
///
/// The expanded .
///
private string EvaluateMacro(Match m) {
return ExpandMacro(m.Groups[1].Value);
}
#endregion Private Instance Methods
#region Private Instance Fields
private readonly ProjectBase _project;
private readonly Regex _rxMacro = new Regex(@"\$\((\w+)\)");
private Hashtable _extraOutputFiles;
#endregion Private Instance Fields
}
}