diff options
author | Pádraig Brady <P@draigBrady.com> | 2013-01-21 15:37:37 +0000 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2013-01-26 02:31:53 +0000 |
commit | 51ce0bf8440e18de34586003b1a5d7f568fbf636 (patch) | |
tree | 03bb7348eb727280dbc428072434d32dfcc96908 /src | |
parent | a46d8d02f2b0e49d851a45e63420744b10a10ed4 (diff) | |
download | coreutils-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.c | 47 |
1 files changed, 22 insertions, 25 deletions
@@ -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; |