diff --git a/WHATSNEW b/WHATSNEW
index 079dba9bf..617f88dfc 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -32,6 +32,9 @@ Changes that could break older environments:
Fixed bugs:
-----------
+* A new attribute named skip is added to the TailFilter and
+ HeadFilter filter readers.
+
* Expand tasks did not behave as expected with PatternSets.
*
+ +See the testcases for more examples (src\etc\testcases\filters\head-tail.xml in the +source distribution). ++<loadfile srcfile="${src.file}" property="${src.file.head}"> + <filterchain> + <headfilter lines="15" skip="2"/> + </filterchain> +</loadfile> +
+ +
Content | ++ | + | + | Filter | +||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Line 1 | ++ | + | + |
+
|
+||||||||||
Line 2 | +||||||||||||||
Line 3 | ++ | |||||||||||||
Line 4 | +||||||||||||||
Line 5 | ++ | |||||||||||||
Lines ... | +||||||||||||||
Line 95 | +||||||||||||||
Line 96 | ++ | |||||||||||||
Line 97 | +||||||||||||||
Line 98 | ++ | |||||||||||||
Line 99 | +
++<loadfile srcfile="${src.file}" property="${src.file.head}"> + <filterchain> + <tailfilter lines="10" skip="2"/> + </filterchain> +</loadfile> +
Copyright © 2002-2003 Apache Software Foundation. All rights
diff --git a/src/etc/testcases/filters/expected/head-tail.head.test b/src/etc/testcases/filters/expected/head-tail.head.test
new file mode 100644
index 000000000..43d44e572
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.head.test
@@ -0,0 +1,10 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
diff --git a/src/etc/testcases/filters/expected/head-tail.headAllSkip.test b/src/etc/testcases/filters/expected/head-tail.headAllSkip.test
new file mode 100644
index 000000000..eeffaa304
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.headAllSkip.test
@@ -0,0 +1,58 @@
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
diff --git a/src/etc/testcases/filters/expected/head-tail.headLines.test b/src/etc/testcases/filters/expected/head-tail.headLines.test
new file mode 100644
index 000000000..98fa9e8ef
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.headLines.test
@@ -0,0 +1,2 @@
+Line 1
+Line 2
diff --git a/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test b/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test
new file mode 100644
index 000000000..13cb234bb
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test
@@ -0,0 +1,2 @@
+Line 3
+Line 4
diff --git a/src/etc/testcases/filters/expected/head-tail.headSkip.test b/src/etc/testcases/filters/expected/head-tail.headSkip.test
new file mode 100644
index 000000000..57f17d53a
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.headSkip.test
@@ -0,0 +1,10 @@
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
diff --git a/src/etc/testcases/filters/expected/head-tail.headtail.test b/src/etc/testcases/filters/expected/head-tail.headtail.test
new file mode 100644
index 000000000..239d56bc8
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.headtail.test
@@ -0,0 +1 @@
+Line 4
diff --git a/src/etc/testcases/filters/expected/head-tail.tail.test b/src/etc/testcases/filters/expected/head-tail.tail.test
new file mode 100644
index 000000000..5793dc414
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.tail.test
@@ -0,0 +1,10 @@
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
diff --git a/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test b/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test
new file mode 100644
index 000000000..532cf014f
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test
@@ -0,0 +1,58 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
diff --git a/src/etc/testcases/filters/expected/head-tail.tailLines.test b/src/etc/testcases/filters/expected/head-tail.tailLines.test
new file mode 100644
index 000000000..665067388
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.tailLines.test
@@ -0,0 +1,2 @@
+Line 59
+Line 60
diff --git a/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test b/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test
new file mode 100644
index 000000000..42746d1ed
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test
@@ -0,0 +1,2 @@
+Line 57
+Line 58
diff --git a/src/etc/testcases/filters/expected/head-tail.tailSkip.test b/src/etc/testcases/filters/expected/head-tail.tailSkip.test
new file mode 100644
index 000000000..070eeee0e
--- /dev/null
+++ b/src/etc/testcases/filters/expected/head-tail.tailSkip.test
@@ -0,0 +1,10 @@
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
diff --git a/src/etc/testcases/filters/head-tail.xml b/src/etc/testcases/filters/head-tail.xml
new file mode 100644
index 000000000..fbba1f274
--- /dev/null
+++ b/src/etc/testcases/filters/head-tail.xml
@@ -0,0 +1,107 @@
+
+null
.
- *
+ *
* @return a new filter based on this configuration, but filtering
* the specified reader
*/
public final Reader chain(final Reader rdr) {
HeadFilter newFilter = new HeadFilter(rdr);
newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
newFilter.setInitialized(true);
return newFilter;
}
@@ -180,6 +211,10 @@ public final class HeadFilter
lines = new Long(params[i].getValue()).longValue();
break;
}
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = new Long(params[i].getValue()).longValue();
+ break;
+ }
}
}
}
diff --git a/src/main/org/apache/tools/ant/filters/TailFilter.java b/src/main/org/apache/tools/ant/filters/TailFilter.java
index 21dd14925..72a335b0c 100644
--- a/src/main/org/apache/tools/ant/filters/TailFilter.java
+++ b/src/main/org/apache/tools/ant/filters/TailFilter.java
@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -78,12 +78,18 @@ public final class TailFilter
/** Parameter name for the number of lines to be returned. */
private static final String LINES_KEY = "lines";
+ /** Parameter name for the number of lines to be skipped. */
+ private static final String SKIP_KEY = "skip";
+
/** Number of lines currently read in. */
private long linesRead = 0;
/** Number of lines to be returned in the filtered stream. */
private long lines = 10;
+ /** Number of lines to be skipped. */
+ private long skip = 0;
+
/** Buffer to hold in characters read ahead. */
private char[] buffer = new char[4096];
@@ -98,7 +104,7 @@ public final class TailFilter
/**
* Constructor for "dummy" instances.
- *
+ *
* @see BaseFilterReader#BaseFilterReader()
*/
public TailFilter() {
@@ -121,12 +127,12 @@ public final class TailFilter
* Otherwise, the stream is read to the end and buffered (with the buffer
* growing as necessary), then the appropriate position in the buffer is
* set to read from.
- *
+ *
* @return the next character in the resulting stream, or -1
* if the end of the resulting stream has been reached
- *
+ *
* @exception IOException if the underlying stream throws an IOException
- * during reading
+ * during reading
*/
public final int read() throws IOException {
if (!getInitialized()) {
@@ -152,16 +158,18 @@ public final class TailFilter
}
}
- if (ch == '\n' || ch == -1) {
- ++linesRead;
+ if (lines > 0) {
+ if (ch == '\n' || ch == -1) {
+ ++linesRead;
- if (linesRead == lines) {
- int i = 0;
- for (i = returnedCharPos + 1;
- buffer[i] != 0 && buffer[i] != '\n'; i++) {
+ if ((linesRead == lines + skip)) {
+ int i = 0;
+ for (i = returnedCharPos + 1;
+ buffer[i] != 0 && buffer[i] != '\n'; i++) {
+ }
+ returnedCharPos = i;
+ --linesRead;
}
- returnedCharPos = i;
- --linesRead;
}
}
if (ch == -1) {
@@ -174,6 +182,26 @@ public final class TailFilter
completedReadAhead = true;
}
+ // Because the complete stream is read into the buffer I can delete
+ // the "skip lines" from back to the beginning.
+ if (skip > 0) {
+ // searching...
+ int i;
+ for (i = buffer.length - 1; skip > 0; i--) {
+ if (buffer[i]=='\n') {
+ skip--;
+ }
+ }
+
+ // cut the buffer to the new length
+ char[] newBuffer = new char[i];
+ System.arraycopy(buffer, 0, newBuffer, 0, i);
+ buffer = newBuffer;
+
+ // don´t forget to set the "lastposition" new
+ bufferPos = i;
+ }
+
++returnedCharPos;
if (returnedCharPos >= bufferPos) {
return -1;
@@ -184,7 +212,7 @@ public final class TailFilter
/**
* Sets the number of lines to be returned in the filtered stream.
- *
+ *
* @param lines the number of lines to be returned in the filtered stream
*/
public final void setLines(final long lines) {
@@ -193,26 +221,45 @@ public final class TailFilter
/**
* Returns the number of lines to be returned in the filtered stream.
- *
+ *
* @return the number of lines to be returned in the filtered stream
*/
private final long getLines() {
return lines;
}
+ /**
+ * Sets the number of lines to be skipped in the filtered stream.
+ *
+ * @param lines the number of lines to be skipped in the filtered stream
+ */
+ public final void setSkip(final long skip) {
+ this.skip = skip;
+ }
+
+ /**
+ * Returns the number of lines to be skipped in the filtered stream.
+ *
+ * @return the number of lines to be skipped in the filtered stream
+ */
+ private final long getSkip() {
+ return skip;
+ }
+
/**
* Creates a new TailFilter using the passed in
* Reader for instantiation.
- *
+ *
* @param rdr A Reader object providing the underlying stream.
* Must not be null
.
- *
+ *
* @return a new filter based on this configuration, but filtering
* the specified reader
*/
public final Reader chain(final Reader rdr) {
TailFilter newFilter = new TailFilter(rdr);
newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
newFilter.setInitialized(true);
return newFilter;
}
@@ -229,6 +276,10 @@ public final class TailFilter
setLines(new Long(params[i].getValue()).longValue());
break;
}
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = new Long(params[i].getValue()).longValue();
+ break;
+ }
}
}
}
diff --git a/src/testcases/org/apache/tools/ant/filters/HeadTailTest.java b/src/testcases/org/apache/tools/ant/filters/HeadTailTest.java
new file mode 100644
index 000000000..442887cb7
--- /dev/null
+++ b/src/testcases/org/apache/tools/ant/filters/HeadTailTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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
+ *