summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2013-01-21 15:37:37 +0000
committerPádraig Brady <P@draigBrady.com>2013-01-26 02:31:53 +0000
commit51ce0bf8440e18de34586003b1a5d7f568fbf636 (patch)
tree03bb7348eb727280dbc428072434d32dfcc96908 /src
parenta46d8d02f2b0e49d851a45e63420744b10a10ed4 (diff)
downloadcoreutils-51ce0bf8440e18de34586003b1a5d7f568fbf636.tar.xz
cut: with -f, process each line independently
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
Diffstat (limited to 'src')
-rw-r--r--src/cut.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/src/cut.c b/src/cut.c
index 4059ecc54..416591ced 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -601,6 +601,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.'
@@ -631,6 +632,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. */
@@ -646,6 +649,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;
}
@@ -658,38 +662,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;
}
}
@@ -699,7 +693,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;