From 103139d0e6e97c188a647adeb5c71eb39c308c26 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 10 Dec 2024 17:21:30 +0100 Subject: cut: fix "echo 1.2 | cut -d. -f1,3" (print "1", not "1.") function old new delta cut_main 1228 1201 -27 Signed-off-by: Denys Vlasenko --- coreutils/cut.c | 23 ++++++++++++++++++----- testsuite/cut.tests | 11 +++++++++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/coreutils/cut.c b/coreutils/cut.c index 1eb4968d9..2511befc8 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c @@ -114,7 +114,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, } } free(printed); - } else if (!opt_REGEX && *delim == '\n') { /* cut by lines */ + /* Cut by lines */ + } else if (!opt_REGEX && *delim == '\n') { int spos = cut_list[cl_pos].startpos; /* get out if we have no more lists to process or if the lines @@ -144,7 +145,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, * looking for, so print it */ puts(line); goto next_line; - } else { /* cut by fields */ + /* Cut by fields */ + } else { unsigned next = 0, start = 0, end = 0; int dcount = 0; /* Nth delimiter we saw (0 - didn't see any yet) */ int first_print = 1; @@ -159,22 +161,33 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, for (;;) { /* End of current range? */ if (end == linelen || dcount > cut_list[cl_pos].endpos) { + end_of_range: if (++cl_pos >= nlists) break; if (option_mask32 & OPT_NOSORT) start = dcount = next = 0; end = 0; /* (why?) */ + //bb_error_msg("End of current range"); } /* End of current line? */ if (next == linelen) { + end = linelen; /* print up to end */ /* If we've seen no delimiters, check -s */ if (cl_pos == 0 && dcount == 0 && !opt_REGEX) { if (option_mask32 & OPT_SUPPRESS) goto next_line; /* else: will print entire line */ - } else if (dcount < cut_list[cl_pos].startpos) - start = linelen; /* do not print */ - end = linelen; /* print up to end */ + } else if (dcount < cut_list[cl_pos].startpos) { + /* echo 1.2 | cut -d. -f1,3: prints "1", not "1." */ + //break; + /* ^^^ this fails a case with -D: + * echo 1 2 | cut -DF 1,3,2: + * do not end line processing when didn't find field#3 + */ + //if (option_mask32 & OPT_NOSORT) - no, just do it always + goto end_of_range; + } + //bb_error_msg("End of current line: s:%d e:%d", start, end); } else { /* Find next delimiter */ #if ENABLE_FEATURE_CUT_REGEX diff --git a/testsuite/cut.tests b/testsuite/cut.tests index c335f824b..46ef545d7 100755 --- a/testsuite/cut.tests +++ b/testsuite/cut.tests @@ -90,7 +90,14 @@ Subcalifragilisticexpialidocious. Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy." SKIP= -testing "cut empty field" "cut -d ':' -f 1-3" "a::b\n" "" "a::b\n" -testing "cut empty field 2" "cut -d ':' -f 3-5" "b::c\n" "" "a::b::c:d\n" +testing "cut empty field" "cut -d ':' -f 1-3" \ + "a::b\n" \ + "" "a::b\n" +testing "cut empty field 2" "cut -d ':' -f 3-5" \ + "b::c\n" \ + "" "a::b::c:d\n" +testing "cut non-existing field" "cut -d ':' -f1,3" \ + "1\n" \ + "" "1:\n" exit $FAILCOUNT -- cgit v1.2.3-55-g6feb