// 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 } }