Return-Path: Mailing-List: contact dev-help@ant.apache.org; run by ezmlm Delivered-To: mailing list dev@ant.apache.org Received: (qmail 41170 invoked by uid 500); 9 May 2003 13:32:08 -0000 Received: (qmail 41159 invoked from network); 9 May 2003 13:32:08 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 9 May 2003 13:32:08 -0000 Received: (qmail 21108 invoked by uid 1146); 9 May 2003 13:32:07 -0000 Date: 9 May 2003 13:32:07 -0000 Message-ID: <20030509133207.21107.qmail@icarus.apache.org> From: bodewig@apache.org To: ant-cvs@apache.org Subject: cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs ConcatTest.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N bodewig 2003/05/09 06:32:07 Modified: . WHATSNEW docs/manual/CoreTasks concat.html src/etc/testcases/taskdefs concat.xml src/main/org/apache/tools/ant/taskdefs Concat.java src/testcases/org/apache/tools/ant/taskdefs ConcatTest.java Log: outputencoding and fixlastline attributes for PR: 12511 Submitted by: Peter Reilly Revision Changes Path 1.412 +4 -0 ant/WHATSNEW Index: WHATSNEW =================================================================== RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.411 retrieving revision 1.412 diff -u -r1.411 -r1.412 --- WHATSNEW 9 May 2003 13:01:00 -0000 1.411 +++ WHATSNEW 9 May 2003 13:32:06 -0000 1.412 @@ -308,6 +308,10 @@ * There is a new data type that can be used to collect properties. +* can now control the encoding of the output as well and optionally + add new-line characters at the end files that get concatenated but + don't end in newlines. Bugzilla Report 12511. + Changes from Ant 1.5.2 to Ant 1.5.3 =================================== 1.8 +48 -1 ant/docs/manual/CoreTasks/concat.html Index: concat.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/concat.html,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- concat.html 28 Mar 2003 12:41:01 -0000 1.7 +++ concat.html 9 May 2003 13:32:07 -0000 1.8 @@ -76,6 +76,53 @@ No + + outputencoding + + The encoding to use when writing the output file + since Ant 1.6. + Defaults to the value of the encoding attribute + if given or the default JVM encoding otherwise. + + No + + + fixlastline + + Specifies whether or not to check if + each file concatenated is terminated by + a new line. If this attribute is "yes" + a new line will be appended to the stream if + the file did not end in a new line. + since Ant 1.6. + Defaults to "no". + This attribute does not apply to embedded text. + + No + + + eol + + Specifies what the end of line character are + for use by the fixlastline attribute. + since Ant 1.6 + Valid values for this property are: +
    +
  • cr: a single CR
  • +
  • lf: a single LF
  • +
  • crlf: the pair CRLF
  • +
  • mac: a single CR
  • +
  • unix: a single LF
  • +
  • dos: the pair CRLF
  • +
+ The default is "platform". + For Unix platforms, the default is "lf". + For DOS based systems (including Windows), + the default is "crlf". + For Mac OS, the default is "cr". + + No + @@ -86,7 +133,7 @@

This is a Path. This is used to select file files to be concatenated. Note that - if a file can only appear once in a path. If this is + a file can only appear once in a path. If this is an issue consider using multiple paths.

1.7 +33 -1 ant/src/etc/testcases/taskdefs/concat.xml Index: concat.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/concat.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- concat.xml 28 Mar 2003 12:41:01 -0000 1.6 +++ concat.xml 9 May 2003 13:32:07 -0000 1.7 @@ -11,7 +11,11 @@ - + + + + + @@ -153,4 +157,32 @@ + + + This has no end of line + + + + + + + + + + + + + + + + + + + + + + + + 1.20 +190 -34 ant/src/main/org/apache/tools/ant/taskdefs/Concat.java Index: Concat.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Concat.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- Concat.java 18 Apr 2003 23:40:22 -0000 1.19 +++ Concat.java 9 May 2003 13:32:07 -0000 1.20 @@ -122,6 +122,9 @@ */ private String encoding = null; + /** Stores the output file encoding. */ + private String outputEncoding = null; + // Child elements. /** @@ -143,6 +146,14 @@ private TextElement footer; /** String to place at the end of the concatented stream */ private TextElement header; + /** add missing line.separator to files **/ + private boolean fixLastLine = false; + /** endofline for fixlast line */ + private String eolString = System.getProperty("line.separator"); + /** outputwriter */ + private Writer outputWriter = null; + + /** internal variable - used to collect the source files from sources */ private Vector sourceFiles = new Vector(); /** 1.1 utilities and copy utilities */ @@ -179,6 +190,17 @@ */ public void setEncoding(String encoding) { this.encoding = encoding; + if (outputEncoding == null) { + outputEncoding = encoding; + } + } + + /** + * Sets the character encoding for outputting + * @since Ant 1.6 + */ + public void setOutputEncoding(String outputEncoding) { + this.outputEncoding = outputEncoding; } /** @@ -220,8 +242,9 @@ * @since Ant 1.6 */ public void addFilterChain(FilterChain filterChain) { - if (filterChains == null) + if (filterChains == null) { filterChains = new Vector(); + } filterChains.addElement(filterChain); } @@ -244,19 +267,52 @@ * Add a header to the concatenated output * @since Ant 1.6 */ - public void addHeader(TextElement el) { - this.header = el; + public void addHeader(TextElement header) { + this.header = header; } /** * Add a footer to the concatenated output * @since Ant 1.6 */ - public void addFooter(TextElement el) { - this.footer = el; + public void addFooter(TextElement footer) { + this.footer = footer; + } + + /** + * Append line.separator to files that do not end + * with a line.separator, default false. + * @since Ant 1.6 + */ + public void setFixLastLine(boolean fixLastLine) { + this.fixLastLine = fixLastLine; + } + + /** + * Specify the end of line to find and to add if + * not present at end of each input file. + */ + public void setEol(FixCRLF.CrLf enum) { + String s = enum.getValue(); + if (s.equals("cr") || s.equals("mac")) { + eolString = "\r"; + } else if (s.equals("lf") || s.equals("unix")) { + eolString = "\n"; + } else if (s.equals("crlf") || s.equals("dos")) { + eolString = "\r\n"; + } } /** + * set the output writer, this is to allow + * concat to be used as a nested element + * @since Ant 1.6 + */ + public void setWriter(Writer outputWriter) { + this.outputWriter = outputWriter; + } + + /** * This method performs the concatenation. */ public void execute() @@ -265,6 +321,11 @@ // treat empty nested text as no text sanitizeText(); + if (destinationFile != null && outputWriter != null) { + throw new BuildException( + "Cannot specify both a destination file and an output writer"); + } + // Sanity check our inputs. if (sources.size() == 0 && textBuffer == null) { // Nothing to concatenate! @@ -339,6 +400,8 @@ forceOverwrite = true; destinationFile = null; encoding = null; + outputEncoding = null; + fixLastLine = false; sources.removeAllElements(); sourceFiles.removeAllElements(); filterChains = null; @@ -371,32 +434,36 @@ try { - if (destinationFile == null) { - // Log using WARN so it displays in 'quiet' mode. - os = new LogOutputStream(this, Project.MSG_WARN); + PrintWriter writer = null; + + if (outputWriter != null) { + writer = new PrintWriter(outputWriter); } else { - // ensure that the parent dir of dest file exists - File parent = fileUtils.getParentFile(destinationFile); - if (!parent.exists()) { - parent.mkdirs(); - } + if (destinationFile == null) { + // Log using WARN so it displays in 'quiet' mode. + os = new LogOutputStream(this, Project.MSG_WARN); + } else { + // ensure that the parent dir of dest file exists + File parent = fileUtils.getParentFile(destinationFile); + if (!parent.exists()) { + parent.mkdirs(); + } - os = new FileOutputStream(destinationFile.getAbsolutePath(), - append); - } + os = new FileOutputStream(destinationFile.getAbsolutePath(), + append); + } - PrintWriter writer = null; - if (encoding == null) { - writer = new PrintWriter( - new BufferedWriter( - new OutputStreamWriter(os))); - } else { - writer = new PrintWriter( - new BufferedWriter( - new OutputStreamWriter(os, encoding))); + if (outputEncoding == null) { + writer = new PrintWriter( + new BufferedWriter( + new OutputStreamWriter(os))); + } else { + writer = new PrintWriter( + new BufferedWriter( + new OutputStreamWriter(os, outputEncoding))); + } } - if (header != null) { if (header.getFiltering()) { concatenate( @@ -425,7 +492,9 @@ } writer.flush(); - os.flush(); + if (os != null) { + os.flush(); + } } catch (IOException ioex) { throw new BuildException("Error while concatenating: " @@ -486,6 +555,7 @@ private boolean trimLeading = false; private boolean trim = false; private boolean filtering = true; + private String encoding = null; /** * whether to filter the text in this element @@ -502,6 +572,10 @@ private boolean getFiltering() { return filtering; } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } /** * set the text using a file @@ -517,7 +591,13 @@ BufferedReader reader = null; try { - reader = new BufferedReader(new FileReader(file)); + if (this.encoding == null) { + reader = new BufferedReader(new FileReader(file)); + } else { + reader = new BufferedReader( + new InputStreamReader(new FileInputStream(file), + this.encoding)); + } value = fileUtils.readFully(reader); } catch (IOException ex) { throw new BuildException(ex); @@ -596,9 +676,12 @@ * a single stream. */ private class MultiReader extends Reader { - private int pos = 0; + private int pos = 0; private Reader reader = null; - + private int lastPos = 0; + private char[] lastChars = new char[eolString.length()]; + private boolean needAddSeparator = false; + private Reader getReader() throws IOException { if (reader == null) { if (encoding == null) { @@ -611,7 +694,10 @@ new FileInputStream( (File) sourceFiles.elementAt(pos)), encoding)); - } + } + for (int i = 0; i < lastChars.length; ++i) { + lastChars[i] = 0; + } } return reader; } @@ -624,12 +710,26 @@ * object. */ public int read() throws IOException { + if (needAddSeparator) { + int ret = eolString.charAt(lastPos++); + if (lastPos >= eolString.length()) { + lastPos = 0; + needAddSeparator = false; + } + return ret; + } + while (pos < sourceFiles.size()) { int ch = getReader().read(); if (ch == -1) { reader.close(); reader = null; + if (fixLastLine && isMissingEndOfLine()) { + needAddSeparator = true; + lastPos = 0; + } } else { + addLastChar((char) ch); return ch; } pos++; @@ -647,15 +747,45 @@ */ public int read(char cbuf[], int off, int len) throws IOException { + int amountRead = 0; int iOff = off; - while (pos < sourceFiles.size()) { + while (pos < sourceFiles.size() || (needAddSeparator)) { + if (needAddSeparator) { + cbuf[off] = eolString.charAt(lastPos++); + if (lastPos >= eolString.length()) { + lastPos = 0; + needAddSeparator = false; + pos++; + } + len--; + off++; + amountRead++; + if (len == 0) + return amountRead; + continue; + } + int nRead = getReader().read(cbuf, off, len); if (nRead == -1 || nRead == 0) { reader.close(); reader = null; - pos++; + if (fixLastLine && isMissingEndOfLine()) { + needAddSeparator = true; + lastPos = 0; + } else { + pos++; + } } else { + if (fixLastLine) { + for (int i = nRead; i > (nRead-lastChars.length); + --i) { + if (i < 0) { + break; + } + addLastChar(cbuf[off+i]); + } + } len -= nRead; off += nRead; amountRead += nRead; @@ -671,11 +801,37 @@ } } + /** + * Close the current reader + */ public void close() throws IOException { if (reader != null) { reader.close(); } } + /** + * if checking for end of line at end of file + * add a character to the lastchars buffer + */ + private void addLastChar(char ch) { + for (int i = lastChars.length-2; i >= 0; --i) { + lastChars[i] = lastChars[i+1]; + } + lastChars[lastChars.length-1] = ch; + } + + /** + * return true if the lastchars buffer does + * not contain the lineseparator + */ + private boolean isMissingEndOfLine() { + for (int i = 0; i < lastChars.length; ++i) { + if (lastChars[i] != eolString.charAt(i)) + return true; + } + return false; + } } - } + +} 1.7 +69 -0 ant/src/testcases/org/apache/tools/ant/taskdefs/ConcatTest.java Index: ConcatTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/ConcatTest.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ConcatTest.java 28 Mar 2003 12:41:01 -0000 1.6 +++ ConcatTest.java 9 May 2003 13:32:07 -0000 1.7 @@ -55,8 +55,12 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.util.FileUtils; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; /** * A test class for the 'concat' task, used to concatenate a series of @@ -241,5 +245,70 @@ assertTrue(getLog().indexOf("Bye") > -1); assertTrue(getLog().indexOf("Hello") == -1); } + /** + * Check if fixlastline works + */ + public void testfixlastline() + throws IOException + { + expectFileContains( + "testfixlastline", "concat.line4", + "end of line" + System.getProperty("line.separator") + + "This has"); + } + + /** + * Check if fixlastline works with eol + */ + public void testfixlastlineeol() + throws IOException + { + expectFileContains( + "testfixlastlineeol", "concat.linecr", + "end of line\rThis has"); + } + + // ------------------------------------------------------ + // Helper methods - should be in BuildFileTest + // ----------------------------------------------------- + + private String getFileString(String filename) + throws IOException + { + Reader r = null; + try { + r = new FileReader(getProject().resolveFile(filename)); + return FileUtils.newFileUtils().readFully(r); + } + finally { + try {r.close();} catch (Throwable ignore) {} + } + } + + private String getFileString(String target, String filename) + throws IOException + { + executeTarget(target); + return getFileString(filename); + } + + private void expectFileContains( + String target, String filename, String contains) + throws IOException + { + String content = getFileString(target, filename); + assertTrue( + "expecting file " + filename + " to contain " + + contains + + " but got " + content, content.indexOf(contains) > -1); + } + + public void testTranscoding() throws IOException { + executeTarget("testTranscoding"); + FileUtils fileUtils = FileUtils.newFileUtils(); + File f1 = getProject().resolveFile("copy/expected/utf-8"); + File f2 = getProject().resolveFile("concat.utf8"); + assertTrue(fileUtils.contentEquals(f1, f2)); + } }