[git commit] cut: implement --output-delimiter

Denys Vlasenko vda.linux at googlemail.com
Tue Dec 10 17:49:10 UTC 2024


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

function                                             old     new   delta
cut_main                                            1204    1261     +57
static.cut_longopts                                    -      20     +20
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 77/0)               Total: 77 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/cut.c     | 27 +++++++++++++++++++++++++--
 testsuite/cut.tests | 32 ++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/coreutils/cut.c b/coreutils/cut.c
index f4d930db0..9f5b649d8 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -107,6 +107,7 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
 		/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
 		if (option_mask32 & (OPT_CHAR | OPT_BYTE)) {
 			char *printed = xzalloc(linelen + 1);
+			int need_odelim = 0;
 
 			/* print the chars specified in each cut list */
 			for (; cl_pos < nlists; cl_pos++) {
@@ -114,9 +115,14 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
 				for (spos = cut_list[cl_pos].startpos; spos < linelen;) {
 					if (!printed[spos]) {
 						printed[spos] = 'X';
+						if (need_odelim && spos != 0 && !printed[spos-1]) {
+							need_odelim = 0;
+							fputs_stdout(odelim);
+						}
 						putchar(line[spos]);
 					}
 					if (++spos > cut_list[cl_pos].endpos) {
+						need_odelim = (odelim && odelim[0]); /* will print OSEP (if not empty) */
 						break;
 					}
 				}
@@ -165,6 +171,9 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
 					goto next_line;
 			}
 
+			if (!odelim)
+				odelim = "\t";
+
 			/* Loop through bytes, finding next delimiter */
 			for (;;) {
 				/* End of current range? */
@@ -257,17 +266,31 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
 #if ENABLE_FEATURE_CUT_REGEX
 	regex_t reg;
 #endif
+#if ENABLE_LONG_OPTS
+        static const char cut_longopts[] ALIGN1 =
+                "output-delimiter\0" Required_argument "O"
+                ;
+#endif
 
 #define ARG "bcf"IF_FEATURE_CUT_REGEX("F")
+#if !ENABLE_LONG_OPTS
 	opt = getopt32(argv, "^"
 			OPT_STR  // = "b:c:f:d:O:sD"IF_FEATURE_CUT_REGEX("F:")"n"
 			"\0" "b--"ARG":c--"ARG":f--"ARG IF_FEATURE_CUT_REGEX("F--"ARG),
 			&sopt, &sopt, &sopt, &delim, &odelim IF_FEATURE_CUT_REGEX(, &sopt)
 	);
-	if (!delim || !*delim)
-		delim = (opt & OPT_REGEX) ? "[[:space:]]+" : "\t";
+#else
+	opt = getopt32long(argv, "^"
+			OPT_STR  // = "b:c:f:d:O:sD"IF_FEATURE_CUT_REGEX("F:")"n"
+			"\0" "b--"ARG":c--"ARG":f--"ARG IF_FEATURE_CUT_REGEX("F--"ARG),
+			cut_longopts,
+			&sopt, &sopt, &sopt, &delim, &odelim IF_FEATURE_CUT_REGEX(, &sopt)
+	);
+#endif
 	if (!odelim)
 		odelim = (opt & OPT_REGEX) ? " " : delim;
+	if (!delim || !*delim)
+		delim = (opt & OPT_REGEX) ? "[[:space:]]+" : "\t";
 
 //	argc -= optind;
 	argv += optind;
diff --git a/testsuite/cut.tests b/testsuite/cut.tests
index 46ef545d7..ba5f88d60 100755
--- a/testsuite/cut.tests
+++ b/testsuite/cut.tests
@@ -23,14 +23,30 @@ the quick brown fox jumps over the lazy dog
 
 testing "cut -b a,a,a" "cut -b 3,3,3 input" "e\np\ne\n" "$abc" ""
 
-testing "cut -b overlaps" "cut -b 1-3,2-5,7-9,9-10 input" \
-  "one:to:th\nalphabeta\nthe qick \n" "$abc" ""
-testing "-b encapsulated" "cut -b 3-8,4-6 input" "e:two:\npha:be\ne quic\n" \
-  "$abc" ""
-# --output-delimiter not implemnted (yet?)
-#testing "cut -bO overlaps" \
-#  "cut --output-delimiter ' ' -b 1-3,2-5,7-9,9-10 input" \
-#  "one:t o:th\nalpha beta\nthe q ick \n" "$abc" ""
+testing "cut -b overlaps" \
+	"cut -b 1-3,2-5,7-9,9-10 input" \
+	"\
+one:to:th
+alphabeta
+the qick \n" \
+	"$abc" ""
+testing "-b encapsulated" \
+	"cut -b 3-8,4-6 input" \
+	"\
+e:two:
+pha:be
+e quic\n" \
+	"$abc" ""
+optional LONG_OPTS
+testing "cut -b --output-delimiter overlaps" \
+	"cut --output-delimiter='^' -b 1-3,2-5,7-9,9-10 input" \
+	"\
+one:t^o:th
+alpha^beta
+the q^ick \n" \
+	"$abc" ""
+SKIP=
+
 testing "cut high-low error" "cut -b 8-3 input 2>/dev/null || echo err" "err\n" \
   "$abc" ""
 


More information about the busybox-cvs mailing list