You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@locus.apache.org on 2000/11/09 17:18:52 UTC

cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet CSharp.java Ilasm.java NetCommand.java

bodewig     00/11/09 08:18:51

  Modified:    .        WHATSNEW
               docs     index.html
               src/main/org/apache/tools/ant/taskdefs defaults.properties
  Added:       docs     dotnet.html
               src/main/org/apache/tools/ant/taskdefs/optional/dotnet
                        CSharp.java Ilasm.java NetCommand.java
  Log:
  New tasks csc and ilasm for Microsoft's .NET SDK.
  
  Submitted by:	Steve Loughran <st...@iseran.com>
  
  Revision  Changes    Path
  1.47      +1 -1      jakarta-ant/WHATSNEW
  
  Index: WHATSNEW
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/WHATSNEW,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- WHATSNEW	2000/11/08 17:13:56	1.46
  +++ WHATSNEW	2000/11/09 16:18:45	1.47
  @@ -6,7 +6,7 @@
   
   * A GUI Frontend: Antidote
   
  -* New tasks: propertyfile, depend, antlr, telnet
  +* New tasks: propertyfile, depend, antlr, telnet, csc, ilasm
   
   * Added output attribute to <java>.
   
  
  
  
  1.148     +2 -1      jakarta-ant/docs/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/index.html,v
  retrieving revision 1.147
  retrieving revision 1.148
  diff -u -r1.147 -r1.148
  --- index.html	2000/11/08 17:14:17	1.147
  +++ index.html	2000/11/09 16:18:46	1.148
  @@ -26,7 +26,7 @@
     <li>Dave Walend (<a href="mailto:dwalend@cs.tufts.edu">dwalend@cs.tufts.edu</a>)</li>
   </ul>
   
  -<p>Version 1.3 - 2000/11/02</p>
  +<p>Version 1.3 - 2000/11/10</p>
   
   <hr>
   <h2>Table of Contents</h2>
  @@ -4535,6 +4535,7 @@
   <hr>
   <h2><a name="optionaltasks">Optional tasks</a></h2>
   <ul>
  +  <li><a href="dotnet.html">.NET tasks</a></li>
     <li><a href="#cab">Cab</a></li>
     <li><a href="#ftp">FTP</a></li>
     <li><a href="javacc.html">JavaCC</a></li>
  
  
  
  1.1                  jakarta-ant/docs/dotnet.html
  
  Index: dotnet.html
  ===================================================================
  <html>
  <head>
  <title> .Net classes for Ant
  </title>
  <body>
  <h1>.Net classes for Ant</h1>
  
  
  Vision: make ant the definative build tool for .net projects, just
  as it is becoming for java projects
  <p>
  
  <h2>Detail. </h2>
  
  The emergent policy in big java projects is 'IDE for code and debug';
  Ant for builds, test and deployment. While IDEs are great for an 
  individual development task, Ant not only rebuilds everything insanely
  fast, it has great support for modern deployment tasks -ftp upload, 
  EJB servers, SQL commands, all can be done from a relatively simple
  XML declaration of what you want done. Also in a large project 
  (especially open source) there is no means of dictating which IDE to use.
  Ant gives IDE independence, cross platform portability and ease of 
  extensibility. 
   
  <p>
  
  Projects using .net should be able to use the same tool. This will 
  avoid everyone being dependent on Visual Studio.net (if they have it) 
  supplemented with makefiles and batch files. Anyone doing mixed java/dotnet
  development will be particulary grateful, as they can have a unified build 
  process. 
  
  <p>
  
  If at sometime in the future bits of .net do appear on different platforms 
  then ant based build files will migrate -once the ant tasks have been 
  migrated and any hard codings of DOS-descendant file system conventions 
  removed from the build.xml files
  
  <h2>Key .net Tasks</h2>
  
  <ol>
  <li>csc - csharp compiler - *.csc -&gt; output
  <li>ilasm - IL assembler - *.il -&gt;.exe or .dll
  <li>ResX - ResXToResources.exe .resx -&gt; .resources
  <li>al - assembly linker (.dll) -&gt;
  <li>Signcode - .exe + keys -&gt; .exe'
  <li>Resgen - .properties -&gt; .resources
  <li>Type Library Exporter (TlbExp.exe- .dll -&gt; .tlb
  <li>TlbImp.exe Type Library Importer 
  <li>RegAsm.exe Assembly Registration Tool .dll -&gt; .reg | registration
  <li>WebServiceUtil -SOAP proxy import, SDL generation tool
  </ol>
  
  <h2>Ant Wrapper for net tasks</h2>
  
  Rarely used .net command line tools can be invoked manually. The key tasks
  to address are the common steps in a build process and those which benefit
  from the file pattern matching function. 
  
  <p>
  
  The esoteric tasks can then supported on demand by those who need them. 
  The initial .net tasks should provide a foundation for that demand creation 
  to be simple. 
  
  <h2>Plan</h2>
  
  <ol>
  
  <li>code up C sharp task and distribute for feedback & identify possible
  aid
  <li>Add the next task I need (whatever that is)
  <li>Refactor to produce a base class for .net tasks
  <li>Leave it other people write all the other tasks
  </ol>
  
  <h2>Risks</h2>
  <ul>
  <li>
  The .net SDK is unstable; the next builds will change the commands, arguments 
  and behaviours. Probability: 100%. Impact: 2 days.
  <li>Portable tasks turn out to be harder than envisaged 
   (=reworking if/when non Win32 .net build tools appear)
  
  </ul>
  
  <hr>
  <h2>Using Ant in .net projects</h2>
  
  <h3>
  Setup</h3>
  
  To use the net tasks one needs
  <ul>
  
  <li> A win2K box (or any other platform which supports the .net build tools)
  
  <li> JavaVM - Java1.1 or later
  
  <li> Ant downloaded and the environment and path variables set up so 
  that typing 'ant' invokes ant via a batch file.
  
  <li> An XML parser for ant. The usual distributions include an appropriate 
  version parser.jar and jaxp.jar.
  
  <li> the .net tasks archive (dotnettasks.jar) included in the
   ant\lib directory
  
  <li> The .net sdk installed with the binaries on the path. (Test: type CSC)
  
  <li> A build.xml file to describe the build process
  </ul>
  
  An example build.xml file is included in the test directory.
  
  <h2>Task: CSC</h2>
  
  This task compiles CSharp source into executables or modules.
  Consult the javadoc file for parameter details.
  <h2> Task: ilasm <h2>
  Task to assemble .il files. 
  Consult the javadoc file for parameter details.
  
  </body>
  </html>
  
  
  1.52      +2 -0      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -r1.51 -r1.52
  --- defaults.properties	2000/11/08 17:00:25	1.51
  +++ defaults.properties	2000/11/09 16:18:49	1.52
  @@ -71,6 +71,8 @@
   vajexport=org.apache.tools.ant.taskdefs.optional.ide.VAJExport
   vajimport=org.apache.tools.ant.taskdefs.optional.ide.VAJImport
   telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask
  +csc=org.apache.tools.ant.taskdefs.optional.dotnet.CSharp
  +ilasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm
   
   # deprecated ant tasks (kept for back compatibility)
   javadoc2=org.apache.tools.ant.taskdefs.Javadoc
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java
  
  Index: CSharp.java
  ===================================================================
  /* -*-Java-*-
  *******************************************************************
  *
  * File:         Csharp.java
  * RCS:          $Header: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java,v 1.1 2000/11/09 16:18:50 bodewig Exp $
  * Author:       Steve Loughran
  * Created:      July 21,  2000
  * Modified:     $Modtime: 00-11-01 12:57 $
  * Language:     Java
  * Status:       Experimental 
  *
  *********************************************************************/
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /* build notes
  
  -The reference CD to listen to while editing this file is 
  nap: Underworld  - Everything, Everything
  -variable naming policy from Fowler's refactoring book.
  -tested against the PDC pre-beta of csc.exe; future versions will 
  inevitably change things
  */
  
  // ====================================================================
  // place in the optional ant tasks package
  // but in its own dotnet group
  // ====================================================================
  
  package org.apache.tools.ant.taskdefs.optional.dotnet;
  
  // ====================================================================
  // imports
  // ====================================================================
  
  import org.apache.tools.ant.*;
  import org.apache.tools.ant.taskdefs.*;
  import org.apache.tools.ant.types.*;
  import java.io.*;
  import java.util.*;
  import java.text.*;
  
  
  // ====================================================================
  /**
  This task compiles CSharp source into executables or modules.
  The task will only work on win2K until other platforms support csc.exe or 
  an equivalent. CSC.exe must be on the execute path too.
  
  <p>
  All parameters are optional: &lt;csc/&gt; should suffice to produce a debug
  build of all *.cs files. References to external files do require explicit 
  enumeration, so are one of the first attributes to consider adding. 
  
  <p>
  
  The task is a directory based task, so attributes like <b>includes="*.cs"</b> and 
  <b>excludes="broken.cs"</b> can be used to control the files pulled in. By default, 
  all *.cs files from the project folder down are included in the command. 
  When this happens the output file -if not specified-
  is taken as the first file in the list, which may be somewhat hard to control.
  Specifying the output file with <b>'outfile'</b> seems prudent. 
  
  <p>
  
  <table border="1" cellpadding="2" cellspacing="0">
    <tr>
      <td valign="top"><b>Attribute</b></td>
      <td valign="top"><b>Description</b></td>
      <td align="center" valign="top"><b>Example</b></td>
    </tr>
  
  
  <tr>
      <td valign="top">additionalModules
      <td valign="top">Semicolon separated list of modules to refer to
      </tr>
    <tr>
      <td valign="top">defaultexcludes</td>
      <td valign="top">indicates whether default excludes should be used or not
        (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
    </tr>
  <tr>
      <td valign="top">definitions
      <td valign="top">defined constants
      <td valign="top"> "RELEASE;BETA1"
      </tr>
  <tr>
      <td valign="top">debug
      <td valign="top">include debug information
      <td valign="top">"true" or "false"
      </tr>
  
  <tr>
      <td valign="top">docFile
      <td valign="top">name of file for documentation
      <td valign="top">"doc.xml"
      </tr>
    <tr>
      <td valign="top">excludes</td>
      <td valign="top">comma separated list of patterns of files that must be
        excluded. No files (except default excludes) are excluded when omitted.</td>
    </tr>
    <tr>
      <td valign="top">excludesfile</td>
      <td valign="top">the name of a file. Each line of this file is
        taken to be an exclude pattern</td>
    </tr>
  <tr>
      <td valign="top">failOnError
      <td valign="top">Should a failed compile halt the build?
      <td valign="top">"true" or "false"
      </tr>
    <tr>
      <td valign="top">includes</td>
      <td valign="top">comma separated list of patterns of files that must be
        included. All files are included when omitted.</td>
    </tr>
    <tr>
      <td valign="top">includesfile</td>
      <td valign="top">the name of a file. Each line of this file is
        taken to be an include pattern</td>
    </tr>
  <tr>
      <td valign="top">incremental
      <td valign="top">Incremental build flag. Off by default
      <td valign="top">"false"
      </tr>
  <tr>
      <td valign="top">mainClass
      <td valign="top">name of main class for executables
      <td valign="top">com.example.project.entrypoint
      </tr>
  <tr>
      <td valign="top">optimize
      <td valign="top">optimisation flag
      <td valign="top">"true" or "false"
      </tr>
  <tr>
      <td valign="top">outputFile
      <td valign="top">filename of output
      <td valign="top">"example.exe"
      </tr>
  <tr>
      <td valign="top">references
      <td valign="top">Semicolon separated list of dlls to refer to
      </tr>
  <tr>
      <td valign="top">srcDir
      <td valign="top">source directory (default = project directory)
      <td valign="top">
      </tr>
  <tr>
      <td valign="top">targetType
      <td valign="top">Type of target
      <td valign="top">"exe","module","winexe","library"
      </tr>
  <tr>
      <td valign="top">unsafe
      <td valign="top">enable unsafe code
      <td valign="top">"true" or "false"
      </tr>
  <tr>
      <td valign="top">warnLevel
      <td valign="top">level of warning
      <td valign="top">1-4
      </tr>
  <tr>
      <td valign="top">win32Icon
      <td valign="top">filename of icon to include
      <td valign="top">
      </tr>
  
  </table>
  
  
  
  <p>
  The first pass is just a proof of concept; enough to test. 
  <p>
  TODO
  <ol>
  	<li>get PATH incorporated into reference/module lookup
  	<li>is Win32Icon broken?
  	<li>all the missing options
  </ol>
  <p>
  History
  	<Table>
  	<tr><td>0.2</td>
  		<td> Slightly different</td>
  		<td> Split command execution to a separate class; 
  	</tr>
  	<tr><td>0.1</td>
  		<td> "I can't believe it's so rudimentary"</td>
  		<td>  First pass; minimal builds only support; 
  	</tr>
  
  	</table>
  @version 0.2
  @author Steve Loughran steve_l@iseran.com
  
   */
  // ====================================================================
  
  public class CSharp 
      extends org.apache.tools.ant.taskdefs.MatchingTask {
  
      //=============================================================================	
      /** constructor inits everything and set up the search pattern
       */
  
      public CSharp () {
          Clear();
          setIncludes(csc_file_pattern);
      }
  
  
      //-----------------------------------------------------------------------------
      /** name of the executable. the .exe suffix is deliberately not included 
       * in anticipation of the unix version
       */
      protected static final String csc_exe_name="csc";
  
      /** what is the file extension we search on?
       */
      protected static final String csc_file_ext="cs";
  
      /** and now derive the search pattern from the extension 
       */
      protected static final String csc_file_pattern="*."+csc_file_ext;
  
  
      //=============================================================================	
      /** list of reference classes. (pretty much a classpath equivalent)
       */
  
      protected  String _references;
  
      /**
       * Set the reference list to be used for this compilation.
       */
  
      public void setReferences(String s) {
          _references=s;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getReferencesParameter() {
          //bail on no references
          if (_references==null ||_references.length()==0)
              return null;
          else
              return "/reference:"+_references;
      }
              
  
      /* using the path approach didnt work as it could not handle the implicit
         execution path. Perhaps that could be extracted from the runtime and then
         the path approach would be viable
  
  
         protected  Path _references;
  
         public void setReferences(Path s) {
         //demand create pathlist
         if(_references==null)
         _references=new Path(this.project);
         _references.append(s);
         }
  
         protected String getReferencesParameter()
         {
         //bail on no references
         if (_references==null)
         return null;
         //iterate through the ref list & generate an entry for each
         //or just rely on the fact that the toString operator does this, but
         //noting that the separator is ';' on windows, ':' on unix
         String refpath=_references.toString();
  
         //bail on no references listed
         if (refpath.length()==0)
         return null;
  	
         StringBuffer s=new StringBuffer("/reference:");
         s.append(refpath);
         return new String(s);
         }	
      */
  
      //=============================================================================	
      /* optimise flag
       */
   
      protected boolean _optimize;
  
      /** set the optimise flag on or off
          @param on/off flag
      */
      public void setOptimize(boolean f) {
          _optimize=f;
      }
  
      /** query the optimise flag
          @return true if optimise is turned on
      */
      public boolean getOptimize() {
          return _optimize;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getOptimizeParameter() {
          return "/optimize"+(_optimize?"+":"-");
      }	
  	
      //=============================================================================	
      /** incremental build flag */
      protected boolean _incremental;
  
      /** set the incremental compilation flag on or off
       *@param on/off flag
       */
      public void setIncremental(boolean f){
          _incremental=f;
      }
  
      /** query the incrementalflag
       * @return true iff incremental compilation is turned on
       */
      public boolean getIncremental() {
          return _incremental;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getIncrementalParameter() {
          return "/incremental"+(_incremental?"+":"-");
      }	
  
      //=============================================================================	
      /** debug flag. Controls generation of debug information. 
       */
   
      protected boolean _debug;
  
      /** set the debug flag on or off
       * @param on/off flag
       */
   
      public void setDebug(boolean f)
      {_debug=f;}
  	
      /** query the debug flag
       * @return true if debug is turned on
       */
   
      public boolean getDebug() {
          return _debug;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getDebugParameter() {
          return "/debug"+(_debug?"+":"-");
      }	
  
  
      //=============================================================================	
      /** output XML documentation flag
       */	
  	
      protected File _docFile;
  	
      /** file for generated XML documentation
       * @param output file
       */
   
      public void setDocFile(String f) {
          _docFile=project.resolveFile(f);
      }
  
  
  
      /** get the argument or null for no argument needed
       */
      protected String getDocFileParameter() {
          if (_docFile!=null)
              return "/doc:"+_docFile.toString();
          else
              return null;
      }	
  	
      //=============================================================================	
      /** warning level: 0-4, with 4 being most verbose
       */
      private int _warnLevel;
  
      /** set warn level (no range checking)
       * @param warn level -see .net docs for valid range (probably 0-4)
       */
      public void setWarnLevel(int warnLevel)
      {this._warnLevel=warnLevel;}
  
      /** query warn level
       * @return current value
       */
      public int getWarnLevel()
      {return _warnLevel;}
  
      /** get the argument or null for no argument needed
       */
      protected String getWarnLevelParameter() {
          return "/warn:"+_warnLevel;
      }	
  
      //=============================================================================	
      /** enable unsafe code flag. Clearly set to false by default
       */
  
      protected boolean _unsafe;
  
      public void setUnsafe(boolean unsafe)
      {this._unsafe=unsafe;}
  
      public boolean getUnsafe()
      {return this._unsafe;}
  
      /** get the argument or null for no argument needed
       */
      protected String getUnsafeParameter(){
          return _unsafe?"/unsafe":null;
      }	
  	
      //=============================================================================	
      /** main class (or null for automatic choice)
       */
      protected String _mainClass;
  
      public void setMainClass(String mainClass)
      {this._mainClass=mainClass;}
  
      public String getMainClass()
      {return this._mainClass;}
  
      /** get the argument or null for no argument needed
       */
      protected String getMainClassParameter(){
          if (_mainClass!=null && _mainClass.length()!=0)
              return "/main:"+_mainClass;
          else
              return null;
      }	
  
      //=============================================================================	
      /** source directory upon which the search pattern is applied
       */
      private File _srcDir;
  
      /**
       * Set the source dir to find the files to be compiled
       */
      public void setSrcDir(String srcDirName){
          _srcDir = project.resolveFile(srcDirName);
      }
  
      //=============================================================================	
      /** destination directory (null means use the source directory)
       */
      private File _destDir;
  
      /**
       * Set the source dir to find the files to be compiled
       */
      public void setDestDir(String dirName) {
          _destDir = project.resolveFile(dirName);
      }
  	
  
      //=============================================================================	
      /** type of target. Should be one of exe|library|module|winexe|(null)
          default is exe; the actual value (if not null) is fed to the command line.
          <br>See /target
      */
      protected String _targetType;
  
      /** define the target
       * param target. 
       * @throws BuildException if target is not one of exe|library|module|winexe 
       */
  
      public void setTargetType(String targetType)
          throws  BuildException {
          targetType=targetType.toLowerCase();
          if(targetType.equals("exe") || targetType.equals("library") ||
             targetType.equals("module") ||targetType.equals("winexe") ) {
              _targetType=targetType;	
          }
          else 
              throw new BuildException("targetType " +targetType+" is not a valid type");
      }
  
      public String getTargetType() { 
          return _targetType;
      } 	
  
      /** get the argument or null for no argument needed
       */
      protected String getTargetTypeParameter() {
          if (_targetType!=null)
              return "/target:"+_targetType;
          else
              return null;
      }	
  
  
      //=============================================================================	
      /* icon for incorporation into apps
       */
   
      protected File _win32icon;	
  
      /**
       * Set the win32 icon 
       * @param path to the file. Can be relative, absolute, whatever.
       */
      public void setWin32Icon(String fileName) {
          _win32icon = project.resolveFile(fileName);
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getWin32IconParameter() {
          if (_win32icon!=null)
              return "/win32icon:"+_win32icon.toString();
          else
              return null;
      }
  
      //=============================================================================	
      /** defines list 'RELEASE;WIN32;NO_SANITY_CHECKS;;SOMETHING_ELSE'
       *
       */
  
      String _definitions;
  
      /**
       * Set the definitions
       * @param list of definitions split by ; or , or even :
       */
      public void setDefinitions(String params) {
          _definitions=params;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getDefinitionsParameter() {
          if (_definitions==null || _definitions.length()==0)
              return null;
          else return "/DEFINE:"+_definitions;
      }
  
      //=============================================================================	
      /** list of extra modules to refer to 
       *
       */
  
      String _additionalModules;
  
      /**
       * Set the definitions
       * @param list of definitions split by ; or , or even :
       */
      public void setAdditionalModules(String params) {
          _additionalModules=params;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getAdditionalModulesParameter() {
          if (_additionalModules==null || _additionalModules.length()==0)
              return null;
          else return "/addmodule:"+_additionalModules;
      }
  
      //=============================================================================	
      /** output file. If not supplied this is derived from the
       *  source file
       */
  
      protected String _outputFile;
  
      /**
       * Set the definitions
       * @param list of definitions split by ; or , or even :
       */
      public void setOutputFile(String params) {
          _outputFile=params;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getOutputFileParameter() {
          if (_outputFile==null || _outputFile.length()==0)
              return null;
          File f=project.resolveFile(_outputFile);
          return "/out:"+f.toString();
      }
  
      //=============================================================================	
      /** flag to control action on execution trouble
       */
  
      protected boolean _failOnError;
  
      /**set fail on error flag
       */
      public void setFailOnError(boolean b){
          _failOnError=b;
      }
  
      /** query fail on error flag
       */
      public boolean getFailFailOnError() {
          return _failOnError;
      }
  
      //=============================================================================	
      /** reset all contents. 
       */
      public void Clear() {
          _targetType=null;
          _win32icon=null;
          _srcDir=null;
          _destDir=null;
          _mainClass=null;
          _unsafe=false;
          _warnLevel=3;
          _docFile = null;
          _incremental=false;
          _optimize=false;
          _debug=true;
          _references=null;
          _failOnError=true;
          _definitions=null;
          _additionalModules=null;
      }
  
  
      //=============================================================================	
      /** do the work by building the command line and then calling it
       */
  
      public void execute() 
          throws BuildException {
          if (_srcDir == null)
              _srcDir=project.resolveFile(".");
  
          NetCommand command=new NetCommand(this,"CSC",csc_exe_name);
          command.setFailOnError(getFailFailOnError());
          //DEBUG helper
          command.setTraceCommandLine(true);
          //fill in args
          command.addArgument("/nologo");
          command.addArgument(getAdditionalModulesParameter());
          command.addArgument(getDefinitionsParameter());
          command.addArgument(getDebugParameter());
          command.addArgument(getDocFileParameter());
          command.addArgument(getIncrementalParameter());
          command.addArgument(getMainClassParameter());
          command.addArgument(getOptimizeParameter());
          command.addArgument(getReferencesParameter());
          command.addArgument(getTargetTypeParameter());
          command.addArgument(getUnsafeParameter());
          command.addArgument(getWarnLevelParameter());
          command.addArgument(getWin32IconParameter());
          command.addArgument(getOutputFileParameter());   
          /* space for more argumentativeness
             command.addArgument();
             command.addArgument();
          */
  
  
          //get dependencies list. 
          DirectoryScanner scanner = super.getDirectoryScanner(_srcDir);
          String[] dependencies = scanner.getIncludedFiles();
          log("compiling "+dependencies.length+" file"+((dependencies.length==1)?"":"s"));
          String baseDir=scanner.getBasedir().toString();
          //add to the command
          for (int i = 0; i < dependencies.length; i++) {
              String targetFile=dependencies[i];
              targetFile=baseDir+File.separator+targetFile;
              command.addArgument(targetFile);
          }
      
          //now run the command of exe + settings + files
          command.runCommand();
      } // end execute
  
  
  
  } //end class
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java
  
  Index: Ilasm.java
  ===================================================================
  /* -*-Java-*-
  *******************************************************************
  *
  * File:         Csharp.java
  * RCS:          $Header: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java,v 1.1 2000/11/09 16:18:50 bodewig Exp $
  * Author:       Steve Loughran
  * Created:      July 21,  2000
  * Modified:		$Modtime: 00-11-01 10:25 $
  * Language:     Java
  * Status:       Experimental 
  *
  *********************************************************************/
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /* build notes
  
  -The reference CD to listen to while editing this file is 
  nap: Underworld  - Everything, Everything
  -variable naming policy from Fowler's refactoring book.
  -tested against the PDC pre-beta of csc.exe; future versions will 
  inevitably change things
  */
  
  // ====================================================================
  // place in the optional ant tasks package
  // but in its own dotnet group
  // ====================================================================
  
  package org.apache.tools.ant.taskdefs.optional.dotnet;
  
  // ====================================================================
  // imports
  // ====================================================================
  
  import org.apache.tools.ant.*;
  import org.apache.tools.ant.taskdefs.*;
  import org.apache.tools.ant.types.*;
  import java.io.*;
  import java.util.*;
  import java.text.*;
  
  /**
     Task to assemble .net 'Intermediate Language' files.
     The task will only work on win2K until other platforms support csc.exe or 
     an equivalent. ilasm.exe must be on the execute path too.
     <p>
  
     <p>
     All parameters are optional: &lt;il/&gt; should suffice to produce a debug
     build of all *.il files.
     The option set is roughly compatible with the CSharp class;
     even though the command line options are only vaguely
     equivalent. [The low level commands take things like /OUT=file,
     csc wants /out:file ... /verbose is used some places; /quiet here in
     ildasm... etc.] It would be nice if someone made all the command line
     tools consistent (and not as brittle as the java cmdline tools) 
  
  
     <p>
  
     The task is a directory based task, so attributes like <b>includes="*.il"</b> and 
     <b>excludes="broken.il"</b> can be used to control the files pulled in. 
     Each file is built on its own, producing an appropriately named output file unless
     manually specified with <b>outfile</b>
  
     <p>
  
     <table border="1" cellpadding="2" cellspacing="0">
     <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Example</b></td>
     </tr>
  
  
     <tr>
     <tr>
     <td valign="top">defaultexcludes</td>
     <td valign="top">indicates whether default excludes should be used or not
     (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
     </tr>
  
     <tr>
     <td valign="top">debug
     <td valign="top">include debug information
     <td valign="top">true (default)
     </tr>
     <tr>
     <tr>
     <td valign="top">excludes</td>
     <td valign="top">comma separated list of patterns of files that must be
     excluded. No files (except default excludes) are excluded when omitted.</td>
     </tr>
     <tr>
     <td valign="top">excludesfile</td>
     <td valign="top">the name of a file. Each line of this file is
     taken to be an exclude pattern</td>
     </tr>
     <tr>
     <td valign="top">failOnError
     <td valign="top">Should a failed compile halt the build?
     <td valign="top">true(default)
     </tr>
     <tr>
     <td valign="top">includes</td>
     <td valign="top">comma separated list of patterns of files that must be
     included. All files are included when omitted.</td>
     </tr>
     <tr>
     <td valign="top">includesfile</td>
     <td valign="top">the name of a file. Each line of this file is
     taken to be an include pattern</td>
     </tr>
     <tr>
     <td valign="top">listing
     <td valign="top">Produce a listing (off by default)
     <td valign="top">off (default)
     </tr>
     <tr>
     <td valign="top">outputFile
     <td valign="top">filename of output
     <td valign="top">"example.exe"
     </tr>
     <tr>
     <td valign="top">owner
     <td valign="top">restrict disassembly by setting the 'owner' string
     <td valign="top">"secret"
     </tr>
     <tr>
     <td valign="top">resourceFile
     <td valign="top">name of resource file to include
     <td valign="top">"resources.res"
     </tr>
     <tr>
     <td valign="top">srcDir
     <td valign="top">source directory (default = project directory)
     <td valign="top">
     </tr>
     <tr>
     <td valign="top">targetType
     <td valign="top">Type of target. library means DLL is output. 
     <td valign="top">"exe","library"
     </tr>
     <tr>
     <td valign="top">verbose
     <td valign="top">output progress messages
     <td valign="top">off (default)
     </tr>
  
     </table>
  
  
  
  
     @author Steve Loughran steve_l@iseran.com
     @version 0.1
  */
  // ====================================================================
  
  public class Ilasm
      extends org.apache.tools.ant.taskdefs.MatchingTask {
  
      //=============================================================================	
      /** constructor inits everything and set up the search pattern
       */
  
      public Ilasm () {
          Clear();
          setIncludes(file_pattern);
      }
  
  
      //-----------------------------------------------------------------------------
      /** name of the executable. the .exe suffix is deliberately not included 
       * in anticipation of the unix version
       */
      protected static final String exe_name="ilasm";
  
      /** what is the file extension we search on?
       */
      protected static final String file_ext="il";
  
      /** and now derive the search pattern from the extension 
       */
      protected static final String file_pattern="*."+file_ext;
  
      /** title of task for external presentation
       */
      protected static final String exe_title="ilasm";
  
      //=============================================================================	
      /** reset all contents. 
       */
      public void Clear() {
          _targetType=null;
          _srcDir=null;
          _listing = false;
          _verbose=false;
          _debug=true;
          _owner=null;
          _outputFile=null;
          _failOnError=true;
          _resourceFile=null;
          _owner=null;
      }
  
      //=============================================================================	
      /** source directory upon which the search pattern is applied
       */
      private File _srcDir;
  
      /**
       * Set the source dir to find the files to be compiled
       */
      public void setSrcDir(String srcDirName){
          _srcDir = project.resolveFile(srcDirName);
      }
  
  
      //=============================================================================	
      /** type of target. Should be one of exe|library|module|winexe|(null)
          default is exe; the actual value (if not null) is fed to the command line.
          <br>See /target
      */
      protected String _targetType;
  
      /** define the target
       * param target. 
       * @throws BuildException if target is not one of exe|library|module|winexe 
       */
  
      public void setTargetType(String targetType)
          throws  BuildException {
          targetType=targetType.toLowerCase();
          if(targetType.equals("exe") || targetType.equals("library")) {
              _targetType=targetType;	
          }
          else 
              throw new BuildException("targetType " +targetType+" is not a valid type");
      }
  
      public String getTargetType() { 
          return _targetType;
      } 	
  
      /** get the argument or null for no argument needed
       */
  
      protected String getTargetTypeParameter() {
          if(!notEmpty(_targetType))
              return null;
          if (_targetType.equals("exe"))
              return "/exe";
          else 
              if (_targetType.equals("library"))
                  return "/dll";
              else
                  return null;
      }	
  	
      //=============================================================================	
      /** owner string is a slightly trivial barrier to disassembly
       */
  
      protected String _owner;
  
      public void setOwner(String s) {
          _owner=s;
      }
      
      protected String getOwnerParameter() {
          if(notEmpty(_owner))
              return "/owner="+_owner;
          else 
              return null;
      }
  
      //=============================================================================	
      /** test for a string containing something useful
       * @param string to test
       * @returns true if the argument is not null or empty
       */
      protected boolean notEmpty(String s)
      {return s!=null && s.length()!=0;}
  
      //=============================================================================	
      /** verbose flag
       */
       
      protected boolean _verbose;
  
      public void setVerbose(boolean b) {
          _verbose=b;
      }
  
      protected String getVerboseParameter() {
          return _verbose?null:"/quiet";
      }   
  
      //=============================================================================	
      /** listing flag
       */
       
      protected boolean _listing;
  
      public void setListing(boolean b) {
          _listing=b;
      }
  
      protected String getListingParameter() {
          return _listing?"/listing":"/nolisting";
      }
     
      //=============================================================================	
      /** output file. If not supplied this is derived from the
       *  source file
       */
   
      protected String _outputFile;
  
      /**
       * Set the definitions
       * @param list of definitions split by ; or , or even :
       */
      public void setOutputFile(String params) {
          _outputFile=params;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getOutputFileParameter() {
          if (_outputFile==null || _outputFile.length()==0)
              return null;
          File f=project.resolveFile(_outputFile);
          return "/output="+f.toString();
      }
  
      //=============================================================================	
      /** resource file (.res format) to include in the app. 
       */
   
      protected String _resourceFile;
  
      public void setResourceFile(String s) {
          _resourceFile=s;
      }
      
      protected String getResourceFileParameter() {
          if(notEmpty(_resourceFile)) {
              return "/resource="+_resourceFile;
          }
          else 
              return null;
      }
     
      //=============================================================================	
      /** flag to control action on execution trouble
       */
  
      protected boolean _failOnError;
  
      /**set fail on error flag
       */
      public void setFailOnError(boolean b){
          _failOnError=b;
      }
  
      /** query fail on error flag
       */
      public boolean getFailFailOnError() {
          return _failOnError;
      }
  
      //=============================================================================	
      /** debug flag. Controls generation of debug information. 
       */
   
      protected boolean _debug;
  
      /** set the debug flag on or off
       * @param on/off flag
       */
   
      public void setDebug(boolean f)
      {_debug=f;}
  	
      /** query the debug flag
       * @return true if debug is turned on
       */
   
      public boolean getDebug() {
          return _debug;
      }
  
      /** get the argument or null for no argument needed
       */
      protected String getDebugParameter() {
          return _debug?"/debug":null;
      }	
     
      //=============================================================================	
      /** This is the execution entry point. Build a list of files and
       *  call ilasm on each of them.
       */
  
      public void execute() 
          throws BuildException {
          if (_srcDir == null)
              _srcDir=project.resolveFile(".");
  
          //get dependencies list. 
          DirectoryScanner scanner = super.getDirectoryScanner(_srcDir);
          String[] dependencies = scanner.getIncludedFiles();
          log("assembling "+dependencies.length+" file"+((dependencies.length==1)?"":"s"));
          String baseDir=scanner.getBasedir().toString();
          //add to the command
          for (int i = 0; i < dependencies.length; i++) {
              String targetFile=dependencies[i];
              targetFile=baseDir+File.separator+targetFile;
              executeOneFile(targetFile);
          }
      
      } // end execute
  
      //=============================================================================	
      /** do the work by building the command line and then calling it
       */
  
      public void executeOneFile(String targetFile) 
          throws BuildException {
          NetCommand command=new NetCommand(this,exe_title,exe_name);
          command.setFailOnError(getFailFailOnError());
          //DEBUG helper
          command.setTraceCommandLine(true);
          //fill in args
          command.addArgument(getDebugParameter());
          command.addArgument(getTargetTypeParameter());
          command.addArgument(getListingParameter());
          command.addArgument(getOutputFileParameter());   
          command.addArgument(getOwnerParameter());
          command.addArgument(getResourceFileParameter());
          command.addArgument(getVerboseParameter());
  
   
          /* space for more argumentativeness
             command.addArgument();
             command.addArgument();
          */
      
          command.addArgument(targetFile);
          //now run the command of exe + settings + file
          command.runCommand();
      } // end executeOneFile
  
  
  
  } //class
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java
  
  Index: NetCommand.java
  ===================================================================
  /* -*-Java-*-
   *******************************************************************
   *
   * File:         CSharp.java
   * RCS:          $Header: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java,v 1.1 2000/11/09 16:18:50 bodewig Exp $
   * Author:       Steve Loughran
   * Created:      July 21,  2000
   * Modified:     $Modtime: 00-11-01 10:09 $
   * Language:     Java
   * Status:       Experimental
   *
   *********************************************************************/
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /* build notes
  
  The reference CD to listen to while editing this file is
  Underworld Everything, Everything
  variable naming policy from Fowler's refactoring book.
  */
  
  // place below the optional ant tasks package
  
  package org.apache.tools.ant.taskdefs.optional.dotnet;
  
  // imports
  
  import org.apache.tools.ant.*;
  import org.apache.tools.ant.taskdefs.*;
  import org.apache.tools.ant.types.*;
  import java.io.*;
  import java.util.*;
  import java.text.*;
  
  
  
  /**
  This is a helper class to spawn net commands out. 
  In its initial form it contains no .net specifics, just contains
  all the command line/exe construction stuff. However, it may be handy in future
  to have a means of setting the path to point to the dotnet bin directory; in which
  case the shared code should go in here.
  @author Steve Loughran steve_l@iseran.com
  
   */
  
  
  public class NetCommand {
  
      /** constructor
          @param owning task
          @param title (for logging/errors)
          @param executable. Leave off the '.exe. for future portability
      */
  
      public NetCommand(Task owner, String title, String program)
          throws BuildException {
          _owner=owner;
          _title=title;
          _program=program;
          _commandLine=new Commandline();
          _commandLine.setExecutable(_program);
          prepareExecutor();
      }
  
      /** owner project
       */
      protected Task _owner;
  
      /** executabe
       */
      protected Execute _exe;
  
      /** what is the command line
       */
      protected Commandline _commandLine;
  
      /** title of the command
       */
      protected String _title;
  
      /** actual program to invoke
       */
      protected String _program;
  
      /** trace flag
       */
      protected boolean _traceCommandLine=false;
  
      public void setTraceCommandLine(boolean b){
          _traceCommandLine=b;
      }
  
      /** flag to control action on execution trouble
       */
  
      protected boolean _failOnError;
  
      /**set fail on error flag
       */
      public void setFailOnError(boolean b){
          _failOnError=b;
      }
  
      /** query fail on error flag
       */
      public boolean getFailFailOnError() {
          return _failOnError;
      }
  
  
          
      /** verbose text log
       * @param string to add to log iff verbose is defined for the build
       */
      protected void logVerbose(String msg){
          _owner.getProject().log(msg,Project.MSG_VERBOSE);
      }
  
  
      /** error text log
       * @param string to add to the error log
       */
      protected void logError(String msg) {
          _owner.getProject().log(msg,Project.MSG_ERR);
      }
  
      /*
       * add an argument to a command line; do nothing if the arg is null or empty string
       * @param commandline to extend
       * @param next arg
       */
      public void addArgument(String argument){
          if(argument!=null && argument.length()!=0) {
              _commandLine.createArgument().setValue(argument);
          }
      }
  
      /**
       * set up the command sequence..
       */
      protected void prepareExecutor() throws BuildException {
          // default directory to the project's base directory
          File dir = _owner.getProject().getBaseDir();
          ExecuteStreamHandler handler=new LogStreamHandler(_owner,
                                                            Project.MSG_INFO, Project.MSG_WARN);
          _exe = new Execute(handler, null);
          _exe.setAntRun(_owner.getProject());
          _exe.setWorkingDirectory(dir);
          /* do nothing with env variables. REVISIT: SDK command line?
             String[] environment = env.getVariables();
             exe.setEnvironment(environment);
          */
      }
  
      /**
       * Run the command using the given Execute instance.
       * @throws an exception of something goes wrong and the failOnError flag is true
       */
      public void runCommand()
          throws BuildException {
          int err = -1; // assume the worst
          try {
              if(_traceCommandLine) {
                  _owner.log(_commandLine.toString());
              }
              else
                  logVerbose(_commandLine.toString());
              _exe.setCommandline(_commandLine.getCommandline());
              err = _exe.execute();
              if (err != 0) {
                  if (_failOnError) {
                      throw new BuildException(_title+" returned: "+err, _owner.getLocation());
                  } else {
                      _owner.log(_title+"  Result: " + err, Project.MSG_ERR);
                  }
              }
          } catch (IOException e) {
              throw new BuildException(_title+" failed: " + e, e, _owner.getLocation());
          }
      }
  
  
  } //class