context: // 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
  //
  // Ian Maclean (imaclean@gmail.com)
  // Jaroslaw Kowalski (jkowalski@users.sourceforge.net)
  // Gert Driesen (driesen@users.sourceforge.net)
  
  using System;
  using System.Globalization;
  using System.IO;
  using System.Text;
  
  using NAnt.Core;
  using NAnt.Core.Attributes;
  using NAnt.Core.Util;
  
  namespace NAnt.Core.Functions {
      [FunctionSet("framework", "NAnt")]
      public class FrameworkFunctions : FunctionSetBase {
          #region Public Instance Constructors
  
          public FrameworkFunctions(Project project, PropertyDictionary properties) : base(project, properties) {
          }
  
          #endregion Public Instance Constructors
  
          #region Public Instance Methods
  
          /// <summary>
          /// Checks whether the specified framework exists, and is valid.
          /// </summary>
          /// <param name="framework">The framework to test.</param>
          /// <returns>
          /// <see langword="true" /> if the specified framework exists ; otherwise,
          /// <see langword="false" />.
          /// </returns>
          [Function("exists")]
          public bool Exists(string framework) {
              FrameworkInfo fi = Project.Frameworks [framework];
              return (fi != null && fi.IsValid);
          }
  
          /// <summary>
          /// Checks whether the SDK for the specified framework is installed.
          /// </summary>
          /// <param name="framework">The framework to test.</param>
          /// <returns>
          /// <see langword="true" /> if the SDK for specified framework is installed; 
          /// otherwise, <see langword="false" />.
          /// </returns>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("sdk-exists")]
          public bool SdkExists(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              return (fi.SdkDirectory != null);
          }
  
          /// <summary>
          /// Gets the identifier of the current target framework.
          /// </summary>
          /// <returns>
          /// The identifier of the current target framework.
          /// </returns>
          [Function("get-target-framework")]
          public string GetTargetFramework() {
              return Project.TargetFramework.Name;
          }
  
          /// <summary>
          /// Gets the identifier of the runtime framework.
          /// </summary>
          /// <returns>
          /// The identifier of the runtime framework.
          /// </returns>
          [Function("get-runtime-framework")]
          public string GetRuntimeFramework() {
              return Project.RuntimeFramework.Name;
          }
  
          /// <summary>
          /// Gets the family of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the family should be returned.</param>
          /// <returns>
          /// The family of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-family")]
          public string GetFamily(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return the family of the specified framework
              return fi.Family;
          }
  
          /// <summary>
          /// Gets the version of the current target framework.
          /// </summary>
          /// <returns>
          /// The version of the current target framework.
          /// </returns>
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-version")]
          public Version GetVersion() {
              return Project.TargetFramework.Version;
          }
  
          /// <summary>
          /// Gets the version of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the version should be returned.</param>
          /// <returns>
          /// The version of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-version")]
          public Version GetVersion(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return the version of the specified framework
              return fi.Version;
          }
  
          /// <summary>
          /// Gets the description of the current target framework.
          /// </summary>
          /// <returns>
          /// The description of the current target framework.
          /// </returns>
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-description")]
          public string GetDescription() {
              return Project.TargetFramework.Description;
          }
  
          /// <summary>
          /// Gets the description of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the description should be returned.</param>
          /// <returns>
          /// The description of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-description")]
          public string GetDescription(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return the description of the specified framework
              return fi.Description;
          }
  
          /// <summary>
          /// Gets the Common Language Runtime version of the current target
          /// framework.
          /// </summary>
          /// <returns>
          /// The Common Language Runtime version of the current target framework.
          /// </returns>
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-clr-version")]
          public Version GetClrVersion() {
              return Project.TargetFramework.ClrVersion;
          }
  
          /// <summary>
          /// Gets the Common Language Runtime version of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the Common Language Runtime version should be returned.</param>
          /// <returns>
          /// The Common Language Runtime version of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-clr-version")]
          public Version GetClrVersion(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return the family of the specified framework
              return fi.ClrVersion;
          }
  
          /// <summary>
          /// Gets the framework directory of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the framework directory should be returned.</param>
          /// <returns>
          /// The framework directory of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-framework-directory")]
          public string GetFrameworkDirectory(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return full path to the framework directory of the specified framework
              return fi.FrameworkDirectory.FullName;
          }
  
          /// <summary>
          /// Gets the assembly directory of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the assembly directory should be returned.</param>
          /// <returns>
          /// The assembly directory of the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-assembly-directory")]
          public string GetAssemblyDirectory(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // return full path to the assembly directory of the specified framework
              return fi.FrameworkAssemblyDirectory.FullName;
          }
  
          /// <summary>
          /// Gets the SDK directory of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the SDK directory should be returned.</param>
          /// <returns>
          /// The SDK directory of the specified framework, or an empty 
          /// <see cref="string" /> if the SDK of the specified framework is not 
          /// installed.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-sdk-directory")]
          public string GetSdkDirectory(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              // get the SDK directory of the specified framework
              DirectoryInfo sdkDirectory = fi.SdkDirectory;
              // return directory or empty string if SDK is not installed
              return (sdkDirectory != null) ? sdkDirectory.FullName : string.Empty;
          }
  
          /// <summary>
          /// Gets the absolute path of the specified tool for the current
          /// target framework.
          /// </summary>
          /// <param name="tool">The file name of the tool to search for.</param>
          /// <returns>
          /// The absolute path to <paramref name="tool" /> if found in one of the
          /// configured tool paths; otherwise, an error is reported.
          /// </returns>
          /// <exception cref="FileNotFoundException"><paramref name="tool" /> could not be found in the configured tool paths.</exception>
          /// <remarks>
          ///   <para>
          ///   The configured tool paths are scanned in the order in which they
          ///   are defined in the framework configuration.
          ///   </para>
          ///   <para>
          ///   The file name of the tool to search should include the extension.
          ///   </para>
          /// </remarks>
          /// <example>
          ///   <para>Use <b>gacutil</b> to install an assembly in the GAC.</para>
          ///   <code>
          ///     <![CDATA[
          /// <exec program="${framework::get-tool-path('gacutil.exe')}" managed="strict">
          ///     <arg value="/i" />
          ///     <arg file="Cegeka.HealthFramework.dll" />
          /// </exec>
          ///     ]]>
          ///   </code>
          /// </example>
          [Function("get-tool-path")]
          public string GetToolPath(string tool) {
              string toolPath = Project.TargetFramework.GetToolPath (tool);
              if (toolPath == null) {
                  throw new FileNotFoundException (string.Format (CultureInfo.InvariantCulture,
                      "\"{0}\" could not be found in any of the configured " +
                      "tool paths.", tool));
              }
              return toolPath;
          }
  
          /// <summary>
          /// Gets the runtime engine of the specified framework.
          /// </summary>
          /// <param name="framework">The framework of which the runtime engine should be returned.</param>
          /// <returns>
          /// The full path to the runtime engine of the specified framework, or
          /// an empty <see cref="string" /> if no runtime engine is defined
          /// for the specified framework.
          /// </returns>
          /// <exception cref="ArgumentException"><paramref name="framework" /> is not a valid framework identifier.</exception>
          /// <seealso cref="FrameworkFunctions.GetRuntimeFramework()" />
          /// <seealso cref="FrameworkFunctions.GetTargetFramework()" />
          [Function("get-runtime-engine")]
          public string GetRuntimeEngine(string framework) {
              // obtain framework and ensure it's valid
              FrameworkInfo fi = GetFramework(framework);
              return fi.RuntimeEngine;
          }
  
          /// <summary>
          /// Gets a comma-separated list of frameworks filtered by the specified
          /// <see cref="FrameworkTypes" />.
          /// </summary>
          /// <param name="types">A bitwise combination of <see cref="FrameworkTypes" /> values that filter the frameworks to retrieve.</param>
          /// <returns>
          /// A comma-separated list of frameworks filtered by the specified
          /// <see cref="FrameworkTypes" />, sorted on name.
          /// </returns>
          /// <example>
          ///   <para>
          ///   Define a <b>build-all</b> target that executes the <b>build</b>
          ///   target once for each installed framework targeting compact
          ///   devices.
          ///   </para>
          ///   <code>
          ///     <![CDATA[
          /// <target name="build-all">
          ///     <foreach item="String" in="${framework::get-frameworks('installed compact')}" delim="," property="framework">
          ///         <property name="nant.settings.currentframework" value="${framework}" />
          ///         <call target="build" />
          ///     </foreach>
          /// </target>
          /// 
          /// <target name="build">
          ///     ...
          /// </target>
          ///     ]]>
          ///   </code>
          /// </example>
          [Function("get-frameworks")]
          public string GetFrameworks(FrameworkTypes types) {
  
gt:             FrameworkInfo[] frameworks = Project.GetFrameworks(types);