ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject cvs commit: ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet Ildasm.java Ilasm.java NetCommand.java
Date Sat, 06 Sep 2003 07:09:59 GMT
stevel      2003/09/06 00:09:59

  Modified:    src/main/org/apache/tools/ant/taskdefs defaults.properties
               src/etc/testcases/taskdefs/optional dotnet.xml
               src/testcases/org/apache/tools/ant/taskdefs/optional
                        DotnetTest.java
               src/main/org/apache/tools/ant/taskdefs/optional/dotnet
                        Ilasm.java NetCommand.java
  Added:       src/main/org/apache/tools/ant/taskdefs/optional/dotnet
                        Ildasm.java
  Log:
  1. new ildasm command to disassemble .il files. So that you can disassemble the output of
tlbimport, patch it and recompile it. Yes, that is the official way to get C arrays marshalled
into .net
  
  2. patch to ilasm so that the default fileset is ignored when <src> elements are added
and srcDir attr is undefined
  
  3. tests!
  
  ildasm has duff resource handling. It autogenerates the resources in the dir it runs, you
cannot predict or control their names. So we CD to output dir, that is the dir of destFile
unless an explicit res dir is provided. Ugly, ugly ugly.
  
  And to think that they claim .net is better on account of the ease of development.
  
  Revision  Changes    Path
  1.153     +1 -0      ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
  retrieving revision 1.152
  retrieving revision 1.153
  diff -u -r1.152 -r1.153
  --- defaults.properties	14 Aug 2003 12:46:01 -0000	1.152
  +++ defaults.properties	6 Sep 2003 07:09:59 -0000	1.153
  @@ -196,6 +196,7 @@
   jsharpc=org.apache.tools.ant.taskdefs.optional.dotnet.JSharp
   rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask
   scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
  +ildasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ildasm
   
   # deprecated ant tasks (kept for back compatibility)
   starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
  
  
  
  1.9       +37 -4     ant/src/etc/testcases/taskdefs/optional/dotnet.xml
  
  Index: dotnet.xml
  ===================================================================
  RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/optional/dotnet.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- dotnet.xml	13 Aug 2003 14:06:38 -0000	1.8
  +++ dotnet.xml	6 Sep 2003 07:09:59 -0000	1.9
  @@ -6,7 +6,7 @@
     <property name="src.dir" location="dotnet"/>
     
     <property name="out.csc" location="${src.dir}/out.cs"/>
  -  <property name="out.app" location="${classes.dir}/out.exe"/>
  +  <property name="out.app" location="${build.dir}/out.exe"/>
     <property name="out.type" value="exe"/>  
     
     <target name="probe_for_apps" >
  @@ -48,6 +48,15 @@
       </condition>
      <echo> mono.ilasm.found=${mono.ilasm.found}</echo>
   
  +   <condition property="ildasm.found">
  +      <or>
  +        <available file="ildasm"     filepath="${env.PATH}" />
  +        <available file="ildasm.exe" filepath="${env.PATH}" />
  +        <available file="ildasm.exe" filepath="${env.Path}" />
  +      </or>
  +    </condition>
  +   <echo> ilasm.found=${ildasm.found}</echo>
  +   
      <condition property="dotnetapps.found">
         <or>
           <and>
  @@ -228,17 +237,17 @@
       </exec> 
     </target>
   
  -  <target name="testILASM"  depends="init">
  +  <target name="testILASM"  depends="init"  if="ilasm.found">
       <property name="testILASM.exe" 
         location="${build.dir}/ExampleIlasm.exe" />
       <ilasm 
         destFile="${testILASM.exe}"
         targetType="exe"
         >
  -      <src dir="${src.dir}" includes="**/*.il"/>
  +      <src dir="${src.dir}" includes="*.il"/>
       </ilasm>
       <available property="ilasm.created" file="${testILASM.exe}"/>
  -    <fail unless="ilasm.created">No app ${testCSC.exe} created</fail>
  +    <fail unless="ilasm.created">No app ${testILASM.exe} created</fail>
       <exec executable="${testILASM.exe}" failonerror="true" />
     </target>  
   
  @@ -258,5 +267,29 @@
       <property name="ilasm.string" refid="ilasm"/>
       <echo>${ilasm.string}</echo>
     </target>
  +  
  +  <target name="testILDASM"   depends="testILASM" if="ildasm.found">
  +    <property name="testILDASM.il" 
  +      location="${build.dir}/ExampleIldasm.il" />
  +    <ildasm 
  +      srcFile="${testILASM.exe}"
  +      destFile="${testILDASM.il}"
  +      metadata="true"
  +      header="true"
  +      linenumbers="true"
  +      encoding="ascii"
  +      />
  +    <available property="ildasm.created" file="${testILDASM.il}"/>
  +    <fail unless="ildasm.created">No file ${testILDASM.il} created</fail>
  +  </target>  
  +
  +  <!-- this is an error -->
  +  <target name="testILDASM_empty"   depends="init" >
  +    <ildasm/> 
  +  </target>  
  +  <target name="testILDASM_empty"   depends="init" >
  +    <ildasm/> 
  +  </target>  
  +  
   </project>
   
  
  
  
  1.4       +19 -2     ant/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java
  
  Index: DotnetTest.java
  ===================================================================
  RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DotnetTest.java	1 Aug 2003 05:55:16 -0000	1.3
  +++ DotnetTest.java	6 Sep 2003 07:09:59 -0000	1.4
  @@ -129,11 +129,28 @@
       }
   
       /**
  -     * A unit test for JUnit
  +     * test we can assemble
        */
       public void testILASM() throws Exception {
           executeTarget("testILASM");
  -    } 
  +    }
  +
  +    /**
  +     * test we can disassemble
  +     */
  +    public void testILDASM() throws Exception {
  +        executeTarget("testILDASM");
  +    }
  +
  +    /**
  +     * test we can disassemble
  +     */
  +    public void testILDASM_empty() throws Exception {
  +        expectBuildExceptionContaining("testILDASM_empty",
  +                "parameter validation",
  +                "invalid");
  +    }
  +
   
   }
   
  
  
  
  1.30      +1 -5      ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java
  
  Index: Ilasm.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- Ilasm.java	18 Jul 2003 14:21:23 -0000	1.29
  +++ Ilasm.java	6 Sep 2003 07:09:59 -0000	1.30
  @@ -304,7 +304,7 @@
   
       /**
        * Set the output file; identical to setDestFile
  -     * @see DotnetBaseMatchingTask.setDestFile
  +     * @see DotnetBaseMatchingTask#setDestFile
        *@param  params  The new outputFile value
        */
       public void setOutputFile(File params) {
  @@ -473,10 +473,6 @@
        */
       public void execute()
                throws BuildException {
  -        if (srcDir == null) {
  -            srcDir = getProject().resolveFile(".");
  -        }
  -
           NetCommand command = buildIlasmCommand();
   
           addFilesAndExecute(command, false);
  
  
  
  1.23      +24 -1     ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java
  
  Index: NetCommand.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- NetCommand.java	25 Jul 2003 12:14:43 -0000	1.22
  +++ NetCommand.java	6 Sep 2003 07:09:59 -0000	1.23
  @@ -124,6 +124,11 @@
        */
       protected boolean failOnError;
   
  +    /**
  +     * the directory to execute the command in. When null, the current
  +     * directory is used.
  +     */
  +    private File directory;
   
       /**
        *  constructor
  @@ -175,6 +180,14 @@
   
   
       /**
  +     * set the directory to run from, if the default is inadequate
  +     * @param directory
  +     */
  +    public void setDirectory(File directory) {
  +        this.directory = directory;
  +    }
  +
  +    /**
        *  verbose text log
        *
        *@param  msg  string to add to log iff verbose is defined for the build
  @@ -206,7 +219,13 @@
           }
       }
   
  -    public void addArgument(String argument1, String argument2) {
  +    /**
  +     *  concatenate two strings together and add them as a single argument,
  +     *  but only if argument2 is non-null and non-zero length
  +     *
  +     *@param  argument1  The first argument
  +     *@param  argument2  The second argument
  +     */   public void addArgument(String argument1, String argument2) {
           if (argument2 != null && argument2.length() != 0) {
               commandLine.createArgument().setValue(argument1 + argument2);
           }
  @@ -224,6 +243,10 @@
               throw new RuntimeException("Owner has no project");
           }
           File dir = owner.getProject().getBaseDir();
  +        if (directory != null) {
  +            dir=directory;
  +        }
  +
           ExecuteStreamHandler handler = new LogStreamHandler(owner,
                   Project.MSG_INFO, Project.MSG_WARN);
           executable = new Execute(handler, null);
  
  
  
  1.1                  ant/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ildasm.java
  
  Index: Ildasm.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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 "Ant" 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/>.
   */
  package org.apache.tools.ant.taskdefs.optional.dotnet;
  
  import org.apache.tools.ant.types.EnumeratedAttribute;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.util.FileUtils;
  
  import java.io.File;
  
  /**
   * Task to take a .NET or Mono -generated managed executable and turn it
   * into ILASM assembly code. Useful when converting imported typelibs into
   * assembler before patching and recompiling, as one has to do when doing
   * advanced typelib work.
   *
   * As well as generating the named output file, the ildasm program
   * will also generate resource files <code>Icons.resources</code>
   * <code>Message.resources</code> and a .res file whose filename stub is derived
   * from the source in ways to obscure to determine.
   * There is no way to control whether or not these files are created, or where they are
created
   * (they are created in the current directory; their names come from inside the
   * executable and may be those used by the original developer). This task
   * creates the resources in the directory specified by <code>resourceDir</code>
if
   * set, else in the same directory as the <code>destFile</code>.
   *
   *
   * This task requires the .NET SDK installed and ildasm on the path.
   * To disassemble using alternate CLR systems, set the executable attribute
   * to the name/path of the alternate implementation -one that must
   * support all the classic ildasm commands.
   *
   *
   * Dependency logic: the task executes the command if the output file is missing
   * or older than the source file. It does not take into account changes
   * in the options of the task, or timestamp differences in resource files.
   * When the underlying ildasm executable fails for some reason, it leaves the
   * .il file in place with some error message. To prevent this from confusing
   * the dependency logic, the file specified by the <code>dest</code>
   * attribute is <i>always</i> deleted after an unsuccessful build.
   */
  public class Ildasm extends Task {
  
      /**
       * source file (mandatory)
       */
      private File sourceFile;
  
      /**
       * dest file (mandatory)
       */
      private File destFile;
      /**
       * progress bar switch
       */
      private boolean progressBar=false;
  
      /**
       * what is our encoding
       */
      private String encoding;
  
      /**
       * /bytes flag for byte markup
       */
  
      private boolean bytes=false;
  
      /**
       * line numbers? /linenum
       */
      private boolean linenumbers=false;
  
      /**
       * /raweh flag for raw exception handling
       */
      private boolean rawExceptionHandling=false;
  
      /**
       * show the source; /source
       */
      private boolean showSource=false;
  
      /**
       * /quoteallnames to quote all names
       */
      private boolean quoteallnames=false;
  
      /**
       * /header for header information
       */
      private boolean header=false;
  
      /**
       * when false, sets the /noil attribute
       * to suppress assembly info
       */
      private boolean assembler=true;
  
      /**
       * include metadata
       * /tokens
       */
  
      private boolean metadata=false;
  
      /**
       * what visibility do we want.
       *
       */
      private String visibility;
  
      /**
       * specific item to disassemble
       */
  
      private String item;
  
      /**
       * override for the executable
       */
      private String executable="ildasm";
  
      /**
       *  name of the directory for resources to be created. We cannot control
       * their names, but we can say where they get created. If not set, the
       * directory of the dest file is used
       */
      private File resourceDir;
  
  
      /**
       * Set the name of the directory for resources to be created. We cannot control
       * their names, but we can say where they get created. If not set, the
       * directory of the dest file is used
       */
      public void setResourceDir(File resourceDir) {
          this.resourceDir = resourceDir;
      }
  
      /**
       * override the name of the executable (normally ildasm) or set
       * its full path. Do not set a relative path, as the ugly hacks
       * needed to create resource files in the dest directory
       * force us to change to this directory before running the application.
       * i.e use &lt;property location&gt to create an absolute path from a
       * relative one before setting this value.
       * @param executable
       */
      public void setExecutable(String executable) {
          this.executable = executable;
      }
  
      /**
       * Select the output encoding: ascii, utf8 or unicode
       * @param encoding
       */
      public void setEncoding(EncodingTypes encoding) {
          this.encoding = encoding.getValue();
      }
  
      /**
       * enable (default) or disable assembly language in the output
       * @param assembler
       */
      public void setAssembler(boolean assembler) {
          this.assembler = assembler;
      }
  
      /**
       * enable or disable (default) the orginal bytes as comments
       * @param bytes
       */
      public void setBytes(boolean bytes) {
          this.bytes = bytes;
      }
  
      /**
       * the output file (required)
       * @param destFile
       */
      public void setDestFile(File destFile) {
          this.destFile = destFile;
      }
  
      /**
       * include header information; default false.
       * @param header
       */
      public void setHeader(boolean header) {
          this.header = header;
      }
  
      /**
       * name a single item to decode; a class or a method
       * e.g item="Myclass::method" or item="namespace1::namespace2::Myclass:method(void(int32))
       * @param item
       */
      public void setItem(String item) {
          this.item = item;
      }
  
      /**
       * include line number information; default=false
       * @param linenumbers
       */
      public void setLinenumbers(boolean linenumbers) {
          this.linenumbers = linenumbers;
      }
  
      /**
       * include metadata information
       * @param metadata
       */
      public void setMetadata(boolean metadata) {
          this.metadata = metadata;
      }
  
      /**
       * show a graphical progress bar in a window during the process; off by default
       * @param progressBar
       */
      public void setProgressBar(boolean progressBar) {
          this.progressBar = progressBar;
      }
  
      /**
       * quote all names.
       * @param quoteallnames
       */
      public void setQuoteallnames(boolean quoteallnames) {
          this.quoteallnames = quoteallnames;
      }
  
      /**
       * enable raw exception handling (default = false)
       * @param rawExceptionHandling
       */
      public void setRawExceptionHandling(boolean rawExceptionHandling) {
          this.rawExceptionHandling = rawExceptionHandling;
      }
  
      /**
       * include the source as comments (default=false)
       */
      public void setShowSource(boolean showSource) {
          this.showSource = showSource;
      }
  
      /**
       * the file to disassemble -required
       * @param sourceFile
       */
      public void setSourceFile(File sourceFile) {
          this.sourceFile = sourceFile;
      }
  
      /**
       * alternate name for sourceFile
       * @param sourceFile
       */
      public void setSrcFile(File sourceFile) {
          setSourceFile(sourceFile);
      }
      /**
       * visibility options: one or more of the following, with + signs to
       * concatenate them:
       * <pre>
       * pub : Public
       * pri : Private
       * fam : Family
       * asm : Assembly
       * faa : Family and Assembly
       * foa : Family or Assembly
       * psc : Private Scope
       *</pre>
       * e.g. visibility="pub+pri".
       * Family means <code>protected</code> in C#;
       * @param visibility
       */
      public void setVisibility(String visibility) {
          this.visibility = visibility;
      }
  
      /**
       *  verify that source and dest are ok
       */
      private void validate() {
          if(sourceFile==null || !sourceFile.exists() || !sourceFile.isFile()) {
              throw new BuildException("invalid source");
          }
          if(destFile==null || destFile.isDirectory()) {
              throw new BuildException("invalid dest");
          }
          if(resourceDir!=null
                  && (!resourceDir.exists() || !resourceDir.isDirectory())) {
              throw new BuildException("invalid resource directory");
          }
      }
  
      /**
       *
       * @return
       */
      private boolean isDisassemblyNeeded() {
          if(!destFile.exists()) {
              return true;
          }
          long sourceTime=sourceFile.lastModified();
          long destTime=destFile.lastModified();
          return sourceTime>(destTime+ FileUtils.newFileUtils().getFileTimestampGranularity());
              
      }
      /**
       * do the work
       * @throws BuildException
       */
      public void execute() throws BuildException {
          validate();
          NetCommand command = new NetCommand(this, "ildasm", executable);
          command.setFailOnError(true);
          //fill in args
          command.addArgument("/text");
          command.addArgument("/out="+destFile.toString());
          if(!progressBar) {
              command.addArgument("/nobar");
          }
          if(linenumbers) {
              command.addArgument("/linenum");
          }
          if (showSource) {
              command.addArgument("/source");
          }
          if (quoteallnames) {
              command.addArgument("/quoteallnames");
          }
          if (header) {
              command.addArgument("/header");
          }
          if (!assembler) {
              command.addArgument("/noil");
          }
          if (metadata) {
              command.addArgument("/tokens");
          }
          command.addArgument("/item:",item);
          if (rawExceptionHandling) {
              command.addArgument("/raweh");
          }
          command.addArgument(EncodingTypes.getEncodingOption(encoding));
          if (bytes) {
              command.addArgument("/bytes");
          }
          command.addArgument("/vis:",visibility);
  
          //add the source file
          command.addArgument(sourceFile.getAbsolutePath());
  
          //determine directory: resourceDir if set,
          //the dir of the destFile if not
          File execDir=resourceDir;
          if(execDir==null) {
              execDir=destFile.getParentFile();
          }
          command.setDirectory(execDir);
  
          //now run
          try {
              command.runCommand();
          } catch (BuildException e) {
              //forcibly delete the output file in case of trouble
              if(destFile.exists()) {
                  destFile.delete();
              }
              //then rethrow the exception
              throw e;
          }
  
      }
  
      /**
       * encoding options; the default is ascii
       */
      public static class EncodingTypes extends EnumeratedAttribute {
          public final static String UNICODE= "unicode";
          public final static String UTF8 = "utf8";
          public final static String ASCII = "ascii";
          public String[] getValues() {
              return new String[]{
                  ASCII,
                  UTF8,
                  UNICODE,
              };
          }
  
          /**
           * map from an encoding enum to an encoding opion
           * @param enumValue
           * @return
           */
          public static String getEncodingOption(String enumValue) {
              if(UNICODE.equals(enumValue)) {
                  return "/unicode";
              }
              if (UTF8.equals(enumValue)) {
                  return "/utf8";
              }
              return null;
          }
      }
  
      /**
       * visibility options for decoding
       */
      public static class VisibilityOptions extends EnumeratedAttribute {
          public String[] getValues() {
              return new String[]{
                  "pub", //Public
                  "pri", //Private
                  "fam", //Family
                  "asm", //Assembly
                  "faa", //Family and Assembly
                  "foa", //Family or Assembly
                  "psc", //Private Scope
              };
          }
  
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message