Browse Source

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.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267602 13f79535-47bb-0310-9956-ffa450edef68
master
Sam Ruby 25 years ago
parent
commit
e75231b54c
4 changed files with 486 additions and 1 deletions
  1. +2
    -0
      build.xml
  2. +119
    -1
      docs/index.html
  3. +364
    -0
      src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
  4. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties

+ 2
- 0
build.xml View File

@@ -69,6 +69,8 @@
<copydir src="${src.bin.dir}" dest="${bin.dir}"/> <copydir src="${src.bin.dir}" dest="${bin.dir}"/>
<chmod perm="+x" src="${bin.dir}/ant"/> <chmod perm="+x" src="${bin.dir}/ant"/>
<chmod perm="+x" src="${bin.dir}/antRun"/> <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> </target>


<!-- =================================================================== --> <!-- =================================================================== -->


+ 119
- 1
docs/index.html View File

@@ -14,8 +14,9 @@
<li>James Duncan Davison (<a href="mailto:(duncan@x180.com">duncan@x180.com</a>)</li> <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>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>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> </ul>
<p>Version 1.0.4 - 2000/02/10</p> <p>Version 1.0.5 - 2000/02/12</p>
<hr> <hr>
<h2>Table of Contents</h2> <h2>Table of Contents</h2>
<ul> <ul>
@@ -430,6 +431,7 @@ but excludes all &quot;*.gif&quot; files from the copy.</p>
<li><a href="#expand">Expand</a></li> <li><a href="#expand">Expand</a></li>
<li><a href="#get">Get</a></li> <li><a href="#get">Get</a></li>
<li><a href="#gzip">GZip</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="#jar">Jar</a></li>
<li><a href="#java">Java</a></li> <li><a href="#java">Java</a></li>
<li><a href="#javac">Javac</a></li> <li><a href="#javac">Javac</a></li>
@@ -901,6 +903,122 @@ archive with http/ftp.</p>
/&gt;</code></p> /&gt;</code></p>
</blockquote> </blockquote>
<hr> <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> <h2><a name="jar">Jar</a></h2>
<h3>Description</h3> <h3>Description</h3>
<p>Jars a set of files.</p> <p>Jars a set of files.</p>


+ 364
- 0
src/main/org/apache/tools/ant/taskdefs/FixCRLF.java View File

@@ -0,0 +1,364 @@
/*
* 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); }
}
}

+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -25,6 +25,7 @@ ant=org.apache.tools.ant.taskdefs.Ant
exec=org.apache.tools.ant.taskdefs.Exec exec=org.apache.tools.ant.taskdefs.Exec
tar=org.apache.tools.ant.taskdefs.Tar tar=org.apache.tools.ant.taskdefs.Tar
available=org.apache.tools.ant.taskdefs.Available available=org.apache.tools.ant.taskdefs.Available
fixcrlf=org.apache.tools.ant.taskdefs.FixCRLF


# deprecated ant tasks (kept for back compatibility) # deprecated ant tasks (kept for back compatibility)
javadoc2=org.apache.tools.ant.taskdefs.Javadoc javadoc2=org.apache.tools.ant.taskdefs.Javadoc

||||||
x
 
000:0
Loading…
Cancel
Save