[git commit] cut: fix up -D/-s behavior with -F

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 20 21:12:33 UTC 2024


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

function                                             old     new   delta
cut_main                                            1388    1402     +14
packed_usage                                       34934   34933      -1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 14/-1)              Total: 13 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/cut.c     |  6 +++---
 testsuite/cut.tests | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/coreutils/cut.c b/coreutils/cut.c
index a766db40f..65e0e5c30 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -43,7 +43,7 @@
 //usage:     "\n	-F LIST	Print only these fields (-d is regex)"
 //usage:     )
 //usage:     "\n	-s	Drop lines with no delimiter (else print them in full)"
-//usage:     "\n	-D	Don't sort/collate sections or match -f"IF_FEATURE_CUT_REGEX("F")" lines without delimeter"
+//usage:     "\n	-D	Don't sort ranges; line without delimiters has one field"
 //usage:     IF_LONG_OPTS(
 //usage:     "\n	--output-delimiter SEP	Output field delimeter"
 //usage:     ) IF_NOT_LONG_OPTS(
@@ -202,8 +202,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
 				/* 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 we've seen no delimiters, and no -D, check -s */
+					if (!(option_mask32 & OPT_NOSORT) && cl_pos == 0 && dcount == 0) {
 						if (option_mask32 & OPT_SUPPRESS)
 							goto next_line;
 						/* else: will print entire line */
diff --git a/testsuite/cut.tests b/testsuite/cut.tests
index e57b028ac..21cfea809 100755
--- a/testsuite/cut.tests
+++ b/testsuite/cut.tests
@@ -95,8 +95,16 @@ testing "cut with -d -s omits blank lines" "cut -d' ' -f2 -s input" "bar\nbong\n
 
 # substitute for awk
 optional FEATURE_CUT_REGEX
-testing "cut -DF" "cut -DF 2,7,5" \
-  "said and your\nare\nis demand. supply\nforecast :\nyou you better,\n\nEm: Took hate\n" "" \
+testing "cut -DF unordered" "cut -DF 2,7,5" \
+	"\
+said and your
+are
+is demand. supply
+forecast :
+you you better,
+
+Em: Took hate
+" "" \
 "Bother, said Pooh. It's your husband, and he has a gun.
 Cheerios are donut seeds.
 Talk is cheap because supply exceeds demand.
@@ -105,6 +113,29 @@ Apple: you can buy better, but you can't pay more.
 Subcalifragilisticexpialidocious.
 Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy."
 
+# No delimiter found: print entire line regardless of -F RANGES
+testing "cut -F1" "cut -d: -F1" \
+	"the_only_field\n" "" \
+	"the_only_field\n"
+testing "cut -F2" "cut -d: -F2" \
+	"the_only_field\n" "" \
+	"the_only_field\n"
+# No delimiter found and -s: skip entire line
+testing "cut -sF1" "cut -d: -sF1" \
+	"" "" \
+	"the_only_field\n"
+#^^^ the above is probably mishandled by toybox, it prints the line
+testing "cut -sF2" "cut -d: -sF2" \
+	"" "" \
+	"the_only_field\n"
+# -D disables special handling of lines with no delimiters, the line is treated as the 1st field
+testing "cut -DF1" "cut -d: -DF1" \
+	"the_only_field\n" "" \
+	"the_only_field\n"
+testing "cut -DF2" "cut -d: -DF2" \
+	"\n" "" \
+	"the_only_field\n"
+
 optional FEATURE_CUT_REGEX LONG_OPTS
 testing "cut -F preserves intermediate delimiters" \
 	"cut --output-delimiter=: -F2,4-6,7" \


More information about the busybox-cvs mailing list