You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by ru...@locus.apache.org on 2000/02/12 17:59:26 UTC

cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs FixCRLF.java defaults.properties

rubys       00/02/12 08:59:26

  Modified:    .        build.xml
               docs     index.html
               src/main/org/apache/tools/ant/taskdefs defaults.properties
  Added:       src/main/org/apache/tools/ant/taskdefs FixCRLF.java
  Log:
  Add a task to convert a text file to local OS conventions.  Can also
  be used to adjust tabs and spaces.  See documentation for details.
  
  Revision  Changes    Path
  1.10      +2 -0      jakarta-ant/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- build.xml	2000/02/11 01:33:31	1.9
  +++ build.xml	2000/02/12 16:59:25	1.10
  @@ -69,6 +69,8 @@
        <copydir src="${src.bin.dir}" dest="${bin.dir}"/>
        <chmod perm="+x" src="${bin.dir}/ant"/>
        <chmod perm="+x" src="${bin.dir}/antRun"/>
  +     <fixcrlf srcdir="${bin.dir}" includes="ant,antRun" cr="remove"/>
  +     <fixcrlf srcdir="${bin.dir}" includes="*.bat" cr="add"/>
     </target>
   
     <!-- =================================================================== -->
  
  
  
  1.8       +119 -1    jakarta-ant/docs/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/index.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- index.html	2000/02/11 01:33:22	1.7
  +++ index.html	2000/02/12 16:59:25	1.8
  @@ -14,8 +14,9 @@
     <li>James Duncan Davison (<a href="mailto:(duncan@x180.com">duncan@x180.com</a>)</li>
     <li>Arnout J. Kuiper (<a href="mailto:(ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>)</li>
     <li>Stefano Mazzocchi (<a href="mailto:(stefano@apache.org">stefano@apache.org</a>)</li>
  +  <li>Sam Ruby (<a href="mailto:(rubys@us.ibm.com">rubys@us.ibm.com</a>)</li>
   </ul>
  -<p>Version 1.0.4 - 2000/02/10</p>
  +<p>Version 1.0.5 - 2000/02/12</p>
   <hr>
   <h2>Table of Contents</h2>
   <ul>
  @@ -430,6 +431,7 @@
     <li><a href="#expand">Expand</a></li>
     <li><a href="#get">Get</a></li>
     <li><a href="#gzip">GZip</a></li>
  +  <li><a href="#fixcrlf">FixCRLF</a></li>
     <li><a href="#jar">Jar</a></li>
     <li><a href="#java">Java</a></li>
     <li><a href="#javac">Javac</a></li>
  @@ -900,6 +902,122 @@
     <p><code>&lt;gzip src=&quot;test.tar&quot; zipfile=&quot;test.tar.gz&quot;
     /&gt;</code></p>
   </blockquote>
  +<hr>
  +<h2><a name="fixcrlf">FixCRLF</a></h2>
  +<h3>Description</h3>
  +<p>Adjusts a text file to local.</p>
  +<p>The <i>basedir</i> attribute is the reference directory from where to jar.</p>
  +<h3>Parameters</h3>
  +<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>Required</b></td>
  +  </tr>
  +  <tr>
  +    <td valign="top">srcDir</td>
  +    <td valign="top">Where to find the files to be fixed up.</td>
  +    <td valign="top" align="center">Yes</td>
  +  </tr>
  +  <tr>
  +    <td valign="top">destDir</td>
  +    <td valign="top">Where to place the corrected files.  Defaults to
  +      srcDir (replacing the original file)</td>
  +    <td valign="top" align="center">No</td>
  +  </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>
  +    <td valign="top" align="center">No</td>
  +  </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>
  +    <td valign="top" align="center">No</td>
  +  </tr>
  +  <tr>
  +    <td valign="top">cr</td>
  +    <td valign="top">Specifies how carriage return (CR) characters are to
  +      be handled.  Valid values for this property are:
  +      <ul>
  +      <li>add: ensure that there is a CR before every LF
  +      <li>asis: leave CR characters alone
  +      <li>remove: remove all CR characters
  +      </ul>
  +      Default is based on the platform on which you are running this task.
  +      For Unix platforms, the default is remove.  For DOS based systems
  +      (including Windows), the default is add.
  +      <p>
  +      Note: Unless this property is specified as "asis", extra CR characters
  +      which do not preceed a LF will be removed.
  +      </td>
  +    <td valign="top" align="center">No</td>
  +  </tr>
  +  <tr>
  +    <td valign="top">tab</td>
  +    <td valign="top">Specifies how tab characters are to be handled.  Valid 
  +      values for this property are:
  +      <ul>
  +      <li>add: convert sequences of spaces which span a tab stop to tabs
  +      <li>asis: leave tab and space characters alone
  +      <li>remove: convert tabs to spaces
  +      </ul>
  +      Default for this parameter is "asis".
  +      <p>
  +      Note: Unless this property is specified as "asis", extra spaces and
  +      tabs after the last non-whitespace character on the line will be removed.
  +      </td>
  +    <td valign="top" align="center">No</td>
  +  </tr>
  +  <tr>
  +    <td valign="top">eof</td>
  +    <td valign="top">Specifies how DOS end of file (control-Z) characters are 
  +      to be handled.  Valid values for this property are:
  +      <ul>
  +      <li>add: ensure that there is an EOF character at the end of the file 
  +      <li>asis: leave EOF characters alone
  +      <li>remove: remove any EOF character found at the end
  +      </ul>
  +      Default is based on the platform on which you are running this task.
  +      For Unix platforms, the default is remove.  For DOS based systems
  +      (including Windows), the default is asis.
  +      </td>
  +    <td valign="top" align="center">No</td>
  +  </tr>
  +</table>
  +<h3>Examples</h3>
  +<pre>  &lt;fixcrlf srcdir=&quot;${src}&quot;
  +       cr="remove" eof="remove"
  +       includes=&quot;**/*.sh&quot;
  +  /&gt;</pre>
  +<p>Removes carriage return and eof characters from the shell scripts.  Tabs and
  +spaces are left as is. 
  +<pre>  &lt;fixcrlf srcdir=&quot;${src}&quot;
  +       cr="add"
  +       includes=&quot;**/*.bat&quot;
  +  /&gt;</pre>
  +<p>Ensures that there are carriage return characters prior to evey line feed.
  +Tabs and spaces are left as is.  
  +EOF characters are left alone if run on
  +DOS systems, and are removed if run on Unix systems.</p>
  +<pre>  &lt;fixcrlf srcdir=&quot;${src}&quot;
  +       tabs="add"
  +       includes=&quot;**/Makefile&quot;
  +  /&gt;</pre>
  +<p>Adds or removes CR characters to match local OS conventions, and
  +converts spaces to tabs when appropriate.  EOF characters are left alone if 
  +run on DOS systems, and are removed if run on Unix systems.
  +Many versions of make require tabs prior to commands.</p>
  +<pre>  &lt;fixcrlf srcdir=&quot;${src}&quot;
  +       tabs="remove"
  +       includes=&quot;**/README*&quot;
  +  /&gt;</pre>
  +<p>Adds or removes CR characters to match local OS conventions, and
  +converts all tabs to spaces.  EOF characters are left alone if run on
  +DOS systems, and are removed if run on Unix systems.
  +You never know what editor a user will use to browse README's.</p>
   <hr>
   <h2><a name="jar">Jar</a></h2>
   <h3>Description</h3>
  
  
  
  1.6       +1 -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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- defaults.properties	2000/02/11 01:31:24	1.5
  +++ defaults.properties	2000/02/12 16:59:26	1.6
  @@ -25,6 +25,7 @@
   exec=org.apache.tools.ant.taskdefs.Exec
   tar=org.apache.tools.ant.taskdefs.Tar
   available=org.apache.tools.ant.taskdefs.Available
  +fixcrlf=org.apache.tools.ant.taskdefs.FixCRLF
   
   # 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/FixCRLF.java
  
  Index: FixCRLF.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 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/>.
   */
  
  package org.apache.tools.ant.taskdefs;
  
  import org.apache.tools.ant.*;
  import java.io.*;
  import java.util.*;
  import java.text.*;
  
  /**
   * Task to convert text source files to local OS formatting conventions, as 
   * well as repair text files damaged by misconfigured or misguided editors or 
   * file transfer programs.
   * <p>
   * This task can take the following arguments:
   * <ul>
   * <li>srcdir
   * <li>destdir
   * <li>include
   * <li>exclude
   * <li>cr
   * <li>tab
   * <li>eof
   * </ul>
   * Of these arguments, only <b>sourcedir</b> is required.
   * <p>
   * When this task executes, it will scan the srcdir based on the include
   * and exclude properties.
   * <p>
   * <em>Warning:</em> do not run on binary or carefully formatted files.
   * this may sound obvious, but if you don't specify asis, presume that
   * your files are going to be modified.  If you want tabs to be fixed,
   * whitespace characters may be added or removed as necessary.  Similarly,
   * for CR's - in fact cr="add" can result in cr characters being removed.
   * (to handle cases where other programs have converted CRLF into CRCRLF).
   *
   * @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a>
   */
  
  public class FixCRLF extends MatchingTask {
  
      private int addcr;      // cr:  -1 => remove, 0 => asis, +1 => add
      private int addtab;     // tab: -1 => remove, 0 => asis, +1 => add
      private int ctrlz;      // eof: -1 => remove, 0 => asis, +1 => add
  
      private File srcDir;
      private File destDir = null;
  
      /**
       * Defaults the properties based on the system type.
       * <ul><li>Unix: cr="remove" tab="asis" eof="remove"
       *     <li>DOS: cr="add" tab="asis" eof="asis"</ul>
       */
      public FixCRLF() {
          if (System.getProperty("path.separator").equals(":")) {
              addcr = -1; // remove
              ctrlz = -1; // remove
          } else {
              addcr = +1; // add
              ctrlz = 0;  // asis
          }
      }
  
      /**
       * Set the source dir to find the source text files.
       *
       * @param srcDirName name of the source directory.
       */
      public void setSrcdir(String srcDirName) {
          srcDir = project.resolveFile(srcDirName);
      }
  
      /**
       * Set the destination where the fixed files should be placed.
       * Default is to replace the original file.
       *
       * @param destDirName name of the destination directory.
       */
      public void setDestdir(String destDirName) {
          destDir = project.resolveFile(destDirName);
      }
  
      /**
       * Specify how carriage return (CR) charaters are to be handled
       *
       * @param option valid values:
       * <ul>
       * <li>add: ensure that there is a CR before every LF
       * <li>asis: leave CR characters alone
       * <li>remove: remove all CR characters
       * </ul>
       */
      public void setCr(String option) {
          if (option.equals("remove")) {
              addcr = -1;
          } else if (option.equals("asis")) {
              addcr = 0;
          } else if (option.equals("add")) {
              addcr = +1;
          } else {
              throw new BuildException("Invalid option: " + option );
          }
      }
  
      /**
       * Specify how tab charaters are to be handled
       *
       * @param option valid values:
       * <ul>
       * <li>add: convert sequences of spaces which span a tab stop to tabs
       * <li>asis: leave tab and space characters alone
       * <li>remove: convert tabs to spaces
       * </ul>
       */
      public void setTab(String option) {
          if (option.equals("remove")) {
              addtab = -1;
          } else if (option.equals("asis")) {
              addtab = 0;
          } else if (option.equals("add")) {
              addtab = +1;
          } else {
              throw new BuildException("Invalid option: " + option );
          }
      }
  
      /**
       * Specify how DOS EOF (control-z) charaters are to be handled
       *
       * @param option valid values:
       * <ul>
       * <li>add: ensure that there is an eof at the end of the file
       * <li>asis: leave eof characters alone
       * <li>remove: remove any eof character found at the end
       * </ul>
       */
      public void setEof(String option) {
          if (option.equals("remove")) {
              ctrlz = -1;
          } else if (option.equals("asis")) {
              ctrlz = 0;
          } else if (option.equals("add")) {
              ctrlz = +1;
          } else {
              throw new BuildException("Invalid option: " + option );
          }
      }
  
      /**
       * Executes the task.
       */
      public void execute() throws BuildException {
          // first off, make sure that we've got a srcdir and destdir
  
          if (srcDir == null) {
              throw new BuildException("srcdir attribute must be set!");
          }
          if (!srcDir.exists()) {
              throw new BuildException("srcdir does not exist!");
          }
  	if (!srcDir.isDirectory()) {
              throw new BuildException("srcdir is not a directory!");
          }
          if (destDir != null) {
              if (!destDir.exists()) {
  		throw new BuildException("destdir does not exist!");
              }
  	    if (!destDir.isDirectory()) {
  		throw new BuildException("destdir is not a directory!");
  	    }
          }
  
          // log options used
          project.log("options:" +
              " cr=" + (addcr==-1 ? "add" : addcr==0 ? "asis" : "remove") +
              " tab=" + (addtab==-1 ? "add" : addtab==0 ? "asis" : "remove") +
              " eof=" + (ctrlz==-1 ? "add" : ctrlz==0 ? "asis" : "remove"),
              "fixcrlf", project.MSG_VERBOSE);
  
          DirectoryScanner ds = super.getDirectoryScanner(srcDir);
          String[] files = ds.getIncludedFiles();
  try {
  
          for (int i = 0; i < files.length; i++) {
              File srcFile = new File(srcDir, files[i]);
  
              // read the contents of the file
              int count = (int)srcFile.length();
              byte indata[] = new byte[count];
              try {
                  FileInputStream inStream = new FileInputStream(srcFile);
                  inStream.read(indata);
                  inStream.close();
              } catch (IOException e) {
                  throw new BuildException(e);
              }
  
              // count the number of cr, lf,  and tab characters
              int cr = 0;
              int lf = 0;
              int tab = 0;
  
              for (int k=0; k<count; k++) {
                  byte c = indata[k];
                  if (c == '\r') cr++;
                  if (c == '\n') lf++;
                  if (c == '\t') tab++;
              }
  
              // check for trailing eof
              boolean eof = ((count>0) && (indata[count-1] == 0x1A));
  
              // log stats (before fixes)
              project.log(srcFile + ": size=" + count + " cr=" + cr +
                          " lf=" + lf + " tab=" + tab + " eof=" + eof,
                          "fixcrlf", project.MSG_VERBOSE);
  
              // determine the output buffer size (slightly pessimisticly)
              int outsize = count;
              if (addcr  !=  0) outsize-=cr;
              if (addcr  == +1) outsize+=lf;
              if (addtab == -1) outsize+=tab*7;
              if (ctrlz  == +1) outsize+=1;
  
              // copy the data
              byte outdata[] = new byte[outsize];
              int o = 0;    // output offset
              int line = o; // beginning of line
              int col = 0;  // desired column
  
              for (int k=0; k<count; k++) {
                  switch (indata[k]) {
                      case ' ':
                          // advance column
                          if (addtab == 0) outdata[o++]=indata[k];
                          col++;
                          break;
  
                      case '\t':
                          if (addtab == 0) {
                              // treat like any other character
                              outdata[o++]=indata[k];
                              col++;
                          } else {
                              // advance column to next tab stop
                              col = (col|7)+1;
                          }
                          break;
  
                      case '\r':
                          if (addcr == 0) {
                              // treat like any other character
                              outdata[o++]=indata[k];
                              col++;
                          }
                          break;
  
                      case '\n':
                          // start a new line (optional CR followed by LF)
                          if (addcr == +1) outdata[o++]='\r';
                          outdata[o++]='\n';
                          line=o;
                          col=0;
                          break;
  
                      default:
                          // add tabs if two or more spaces are required
                          if (addtab>0 && o+1<line+col) {
                              // determine logical column
                              int diff=o-line;
  
                              // add tabs until this column would be passed
                              // note: the start of line is adjusted to match
                              while ((diff|7)<col) {
                                  outdata[o++]='\t';
                                  line-=7-(diff&7);
                                  diff=o-line;
                              };
                          };
  
                          // space out to desired column
                          while (o<line+col) outdata[o++]=' ';
  
                          // append desired character
                          outdata[o++]=indata[k];
                          col++;
                  }
              }
  
              // add or remove an eof character as required
              if (ctrlz == +1) {
                  if (outdata[o-1]!=0x1A) outdata[o++]=0x1A;
              } else if (ctrlz == -1) {
                  if (o>2 && outdata[o-1]==0x0A && outdata[o-2]==0x1A) o--;
                  if (o>1 && outdata[o-1]==0x1A) o--;
              }
  
              // output the data
              try {
                  File destFile = srcFile;
                  if (destDir != null) destFile = new File(destDir, files[i]);
                  FileOutputStream outStream = new FileOutputStream(destFile);
                  outStream.write(outdata,0,o);
                  outStream.close();
              } catch (IOException e) {
                  throw new BuildException(e);
              }
  
          } /* end for */
  } catch (Exception e) {e.printStackTrace(); throw new BuildException(e); }
      }
  }
  
  
  

discussion: build file format

Posted by jon seymour <jo...@zeta.org.au>.
Here are some points for offered for discussion and contemplation...I'd be interested in the
developers' thoughts.

I understand it, the following implicit rules govern the structure of the build file format.


   * if a target contains XML elements, then each element:

        o is an empty XML element
        o specifies a task
        o is executed in the order determined by its position within its parent target

Is this always going to be the case? For example: I think it would be neat to if dependencies
could be specified as child elements rather than attributes, as in:

      <target name="dist" depends="jar,javadocs">
         <mkdir dir="${dist.dir}"/>
         <mkdir dir="${dist.dir}/bin"/>
         <mkdir dir="${dist.dir}/lib"/>
        ...
    </target>

might be:

      <target name="dist">
         <depend target="jar"/>
         <depend target="jardocs"/>

         <mkdir dir="${dist.dir}"/>
         <mkdir dir="${dist.dir}/bin"/>
         <mkdir dir="${dist.dir}/lib"/>
    </target>

Why would you want to do that? For one, if you had a large number of dependencies, it would be far
easier to maintain the build file if each dependency was on a separate line. Of course, you could
write:
    <target name="something" depends="
x,
y,
z
">

but that looks a tad ugly.  Also, it would allow other attributes to be associated with a
dependency. For example:

      <target name="output">
         <depend name="input"/>
         <depend name="output.c" type="file"/>
         <depend name="someheader.h" type="file"/>
          <cc source="output.c" object="output.o"/>
    </target>

    <target name="input">
        ...

In this case, we have a dependency on another target but also on two external files.

Also, I must confess a bias here: I have a slight aversion to representing 1:n relationships in
XML attributes. Also, if I was going to do it, I'd use ' ' as the separator, not ',' since at
least then I get some API (or XSLT) support for parsing it [ the XML attribute value separator is
' ']

Similarly, if a task has a large number of inputs, it might be easier if they could be described
by multiple child elements of the task reference, for example:

      <target name="a.out">
         <depend name="input"/>
         <depend name="output"/>
          <link exe="a.out">
                <object name="input.o"/>
                <object name="output.o"/>
           </link>
    </target>

Regards,

jon.


CR handling

Posted by jon seymour <jo...@zeta.org.au>.
Just browsing the diffs for the FixCRLF task.

You may want to add support for the Mac. In that case you have to keep the CR's, discard/add the
LF's. Not actually being that familiar with Macs, I am not sure how necessary it is, but I do know
that by default the Apple MRJ generates byte streams containing only CRs.

Regards,

jon.