[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] cut: with -f, process each line independently
From: |
Pádraig Brady |
Subject: |
[PATCH 1/2] cut: with -f, process each line independently |
Date: |
Tue, 22 Jan 2013 01:47:50 +0000 |
Previously line N+1 was inspected before line N was fully output,
which causes output ordering issues at the terminal or delays
from intermittent sources like tail -f.
* src/cut.c (cut_fields): Adjust so that we record the
previous output character so we can use that info to
determine wether to output a '\n' or not.
* tests/misc/cut.pl: Add tests to ensure existing
functionality isn't broken.
* NEWS: Mention the fix.
Fixes bug http://bugs.gnu.org/13498
---
NEWS | 4 ++++
src/cut.c | 47 ++++++++++++++++++++++-------------------------
tests/misc/cut.pl | 15 +++++++++++++++
3 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/NEWS b/NEWS
index 46d1aba..782918c 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,10 @@ GNU coreutils NEWS -*-
outline -*-
another range. Before, "echo 123|cut --output-delim=: -b2-,3" would print
"2:3". Now it prints "23". [bug introduced in 5.3.0]
+ cut -f no longer inspects input line N+1 before fully outputting line N,
+ which causes delayed output from intermittent inputs.
+ [bug introduced in TEXTUTILS-1_8b]
+
factor no longer loops infinitely on 32 bit powerpc or sparc systems.
[bug introduced in coreutils-8.20]
diff --git a/src/cut.c b/src/cut.c
index 7e877cb..88a2f1b 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -602,6 +602,7 @@ cut_fields (FILE *stream)
return;
ungetc (c, stream);
+ c = 0;
/* To support the semantics of the -s flag, we may have to buffer
all of the first field to determine whether it is 'delimited.'
@@ -632,6 +633,8 @@ cut_fields (FILE *stream)
n_bytes = len;
assert (n_bytes != 0);
+ c = 0;
+
/* If the first field extends to the end of line (it is not
delimited) and we are printing all non-delimited lines,
print this one. */
@@ -647,6 +650,7 @@ cut_fields (FILE *stream)
/* Make sure the output line is newline terminated. */
if (field_1_buffer[n_bytes - 1] != '\n')
putchar ('\n');
+ c = '\n';
}
continue;
}
@@ -659,38 +663,28 @@ cut_fields (FILE *stream)
++field_idx;
}
- if (c != EOF)
+ int prev_c = c;
+
+ if (print_kth (field_idx, NULL))
{
- if (print_kth (field_idx, NULL))
+ if (found_any_selected_field)
{
- if (found_any_selected_field)
- {
- fwrite (output_delimiter_string, sizeof (char),
- output_delimiter_length, stdout);
- }
- found_any_selected_field = true;
-
- while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
- {
- putchar (c);
- }
+ fwrite (output_delimiter_string, sizeof (char),
+ output_delimiter_length, stdout);
}
- else
+ found_any_selected_field = true;
+
+ while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
- while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
- {
- /* Empty. */
- }
+ putchar (c);
+ prev_c = c;
}
}
-
- if (c == '\n')
+ else
{
- c = getc (stream);
- if (c != EOF)
+ while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
- ungetc (c, stream);
- c = '\n';
+ prev_c = c;
}
}
@@ -700,7 +694,10 @@ cut_fields (FILE *stream)
{
if (found_any_selected_field
|| !(suppress_non_delimited && field_idx == 1))
- putchar ('\n');
+ {
+ if (c == '\n' || prev_c != '\n')
+ putchar ('\n');
+ }
if (c == EOF)
break;
field_idx = 1;
diff --git a/tests/misc/cut.pl b/tests/misc/cut.pl
index c9cff1a..3ce09bb 100755
--- a/tests/misc/cut.pl
+++ b/tests/misc/cut.pl
@@ -129,6 +129,21 @@ my @Tests =
['8bit-delim', '-d', "\255", '--out=_', '-f2,3', {IN=>"a\255b\255c\n"},
{OUT=>"b_c\n"}],
+ # newline processing for fields
+ ['newline-1', '-f1-', {IN=>"a\nb"}, {OUT=>"a\nb\n"}],
+ ['newline-2', '-f1-', {IN=>""}, {OUT=>""}],
+ ['newline-3', '-d:', '-f1', {IN=>"a:1\nb:2\n"}, {OUT=>"a\nb\n"}],
+ ['newline-4', '-d:', '-f1', {IN=>"a:1\nb:2"}, {OUT=>"a\nb\n"}],
+ ['newline-5', '-d:', '-f2', {IN=>"a:1\nb:2\n"}, {OUT=>"1\n2\n"}],
+ ['newline-6', '-d:', '-f2', {IN=>"a:1\nb:2"}, {OUT=>"1\n2\n"}],
+ ['newline-7', '-s', '-d:', '-f1', {IN=>"a:1\nb:2"}, {OUT=>"a\nb\n"}],
+ ['newline-8', '-s', '-d:', '-f1', {IN=>"a:1\nb:2\n"}, {OUT=>"a\nb\n"}],
+ ['newline-9', '-s', '-d:', '-f1', {IN=>"a1\nb2"}, {OUT=>""}],
+ ['newline-10', '-s', '-d:', '-f1,2', {IN=>"a:1\nb:2"}, {OUT=>"a:1\nb:2\n"}],
+ ['newline-11', '-s', '-d:', '-f1,2', {IN=>"a:1\nb:2\n"},
{OUT=>"a:1\nb:2\n"}],
+ ['newline-12', '-s', '-d:', '-f1', {IN=>"a:1\nb:"}, {OUT=>"a\nb\n"}],
+ ['newline-13', '-d:', '-f1-', {IN=>"a1:\n:"}, {OUT=>"a1:\n:\n"}],
+
# New functionality:
['out-delim1', '-c1-3,5-', '--output-d=:', {IN=>"abcdefg\n"},
{OUT=>"abc:efg\n"}],
--
1.7.6.4
- [PATCH 1/2] cut: with -f, process each line independently,
Pádraig Brady <=