[git commit] cut: fix "echo 1.2 | cut -d. -f1, 3" (print "1", not "1.")

Denys Vlasenko vda.linux at googlemail.com
Tue Dec 10 16:21:30 UTC 2024


commit: https://git.busybox.net/busybox/commit/?id=103139d0e6e97c188a647adeb5c71eb39c308c26
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
cut_main                                            1228    1201     -27

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 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


More information about the busybox-cvs mailing list