diff options
-rw-r--r-- | coreutils/cut.c | 27 | ||||
-rwxr-xr-x | 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, | |||
107 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | 107 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ |
108 | if (option_mask32 & (OPT_CHAR | OPT_BYTE)) { | 108 | if (option_mask32 & (OPT_CHAR | OPT_BYTE)) { |
109 | char *printed = xzalloc(linelen + 1); | 109 | char *printed = xzalloc(linelen + 1); |
110 | int need_odelim = 0; | ||
110 | 111 | ||
111 | /* print the chars specified in each cut list */ | 112 | /* print the chars specified in each cut list */ |
112 | for (; cl_pos < nlists; cl_pos++) { | 113 | for (; cl_pos < nlists; cl_pos++) { |
@@ -114,9 +115,14 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
114 | for (spos = cut_list[cl_pos].startpos; spos < linelen;) { | 115 | for (spos = cut_list[cl_pos].startpos; spos < linelen;) { |
115 | if (!printed[spos]) { | 116 | if (!printed[spos]) { |
116 | printed[spos] = 'X'; | 117 | printed[spos] = 'X'; |
118 | if (need_odelim && spos != 0 && !printed[spos-1]) { | ||
119 | need_odelim = 0; | ||
120 | fputs_stdout(odelim); | ||
121 | } | ||
117 | putchar(line[spos]); | 122 | putchar(line[spos]); |
118 | } | 123 | } |
119 | if (++spos > cut_list[cl_pos].endpos) { | 124 | if (++spos > cut_list[cl_pos].endpos) { |
125 | need_odelim = (odelim && odelim[0]); /* will print OSEP (if not empty) */ | ||
120 | break; | 126 | break; |
121 | } | 127 | } |
122 | } | 128 | } |
@@ -165,6 +171,9 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
165 | goto next_line; | 171 | goto next_line; |
166 | } | 172 | } |
167 | 173 | ||
174 | if (!odelim) | ||
175 | odelim = "\t"; | ||
176 | |||
168 | /* Loop through bytes, finding next delimiter */ | 177 | /* Loop through bytes, finding next delimiter */ |
169 | for (;;) { | 178 | for (;;) { |
170 | /* End of current range? */ | 179 | /* End of current range? */ |
@@ -257,17 +266,31 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
257 | #if ENABLE_FEATURE_CUT_REGEX | 266 | #if ENABLE_FEATURE_CUT_REGEX |
258 | regex_t reg; | 267 | regex_t reg; |
259 | #endif | 268 | #endif |
269 | #if ENABLE_LONG_OPTS | ||
270 | static const char cut_longopts[] ALIGN1 = | ||
271 | "output-delimiter\0" Required_argument "O" | ||
272 | ; | ||
273 | #endif | ||
260 | 274 | ||
261 | #define ARG "bcf"IF_FEATURE_CUT_REGEX("F") | 275 | #define ARG "bcf"IF_FEATURE_CUT_REGEX("F") |
276 | #if !ENABLE_LONG_OPTS | ||
262 | opt = getopt32(argv, "^" | 277 | opt = getopt32(argv, "^" |
263 | OPT_STR // = "b:c:f:d:O:sD"IF_FEATURE_CUT_REGEX("F:")"n" | 278 | OPT_STR // = "b:c:f:d:O:sD"IF_FEATURE_CUT_REGEX("F:")"n" |
264 | "\0" "b--"ARG":c--"ARG":f--"ARG IF_FEATURE_CUT_REGEX("F--"ARG), | 279 | "\0" "b--"ARG":c--"ARG":f--"ARG IF_FEATURE_CUT_REGEX("F--"ARG), |
265 | &sopt, &sopt, &sopt, &delim, &odelim IF_FEATURE_CUT_REGEX(, &sopt) | 280 | &sopt, &sopt, &sopt, &delim, &odelim IF_FEATURE_CUT_REGEX(, &sopt) |
266 | ); | 281 | ); |
267 | if (!delim || !*delim) | 282 | #else |
268 | delim = (opt & OPT_REGEX) ? "[[:space:]]+" : "\t"; | 283 | opt = getopt32long(argv, "^" |
284 | OPT_STR // = "b:c:f:d:O:sD"IF_FEATURE_CUT_REGEX("F:")"n" | ||
285 | "\0" "b--"ARG":c--"ARG":f--"ARG IF_FEATURE_CUT_REGEX("F--"ARG), | ||
286 | cut_longopts, | ||
287 | &sopt, &sopt, &sopt, &delim, &odelim IF_FEATURE_CUT_REGEX(, &sopt) | ||
288 | ); | ||
289 | #endif | ||
269 | if (!odelim) | 290 | if (!odelim) |
270 | odelim = (opt & OPT_REGEX) ? " " : delim; | 291 | odelim = (opt & OPT_REGEX) ? " " : delim; |
292 | if (!delim || !*delim) | ||
293 | delim = (opt & OPT_REGEX) ? "[[:space:]]+" : "\t"; | ||
271 | 294 | ||
272 | // argc -= optind; | 295 | // argc -= optind; |
273 | argv += optind; | 296 | 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 | |||
23 | 23 | ||
24 | testing "cut -b a,a,a" "cut -b 3,3,3 input" "e\np\ne\n" "$abc" "" | 24 | testing "cut -b a,a,a" "cut -b 3,3,3 input" "e\np\ne\n" "$abc" "" |
25 | 25 | ||
26 | testing "cut -b overlaps" "cut -b 1-3,2-5,7-9,9-10 input" \ | 26 | testing "cut -b overlaps" \ |
27 | "one:to:th\nalphabeta\nthe qick \n" "$abc" "" | 27 | "cut -b 1-3,2-5,7-9,9-10 input" \ |
28 | testing "-b encapsulated" "cut -b 3-8,4-6 input" "e:two:\npha:be\ne quic\n" \ | 28 | "\ |
29 | "$abc" "" | 29 | one:to:th |
30 | # --output-delimiter not implemnted (yet?) | 30 | alphabeta |
31 | #testing "cut -bO overlaps" \ | 31 | the qick \n" \ |
32 | # "cut --output-delimiter ' ' -b 1-3,2-5,7-9,9-10 input" \ | 32 | "$abc" "" |
33 | # "one:t o:th\nalpha beta\nthe q ick \n" "$abc" "" | 33 | testing "-b encapsulated" \ |
34 | "cut -b 3-8,4-6 input" \ | ||
35 | "\ | ||
36 | e:two: | ||
37 | pha:be | ||
38 | e quic\n" \ | ||
39 | "$abc" "" | ||
40 | optional LONG_OPTS | ||
41 | testing "cut -b --output-delimiter overlaps" \ | ||
42 | "cut --output-delimiter='^' -b 1-3,2-5,7-9,9-10 input" \ | ||
43 | "\ | ||
44 | one:t^o:th | ||
45 | alpha^beta | ||
46 | the q^ick \n" \ | ||
47 | "$abc" "" | ||
48 | SKIP= | ||
49 | |||
34 | testing "cut high-low error" "cut -b 8-3 input 2>/dev/null || echo err" "err\n" \ | 50 | testing "cut high-low error" "cut -b 8-3 input 2>/dev/null || echo err" "err\n" \ |
35 | "$abc" "" | 51 | "$abc" "" |
36 | 52 | ||