aboutsummaryrefslogtreecommitdiff
path: root/coreutils/cut.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/cut.c')
-rw-r--r--coreutils/cut.c68
1 files changed, 28 insertions, 40 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c
index c24cf6611..8ae762fb3 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -22,20 +22,22 @@
22 22
23#include <stdio.h> 23#include <stdio.h>
24#include <stdlib.h> 24#include <stdlib.h>
25#include <unistd.h> /* getopt */ 25#include <getopt.h>
26#include <unistd.h>
26#include <string.h> 27#include <string.h>
27#include <limits.h> 28#include <limits.h>
28#include "busybox.h" 29#include "busybox.h"
29 30
30 31
31/* globals from other files */
32extern int optind;
33extern char *optarg;
34
35
36/* option vars */ 32/* option vars */
37static char part = 0; /* (b)yte, (c)har, (f)ields */ 33static const char optstring[] = "b:c:f:d:sn";
38static unsigned int supress_non_delimited_lines = 0; 34#define OPT_BYTE_FLGS 1
35#define OPT_CHAR_FLGS 2
36#define OPT_FIELDS_FLGS 4
37#define OPT_DELIM_FLGS 8
38#define OPT_SUPRESS_FLGS 16
39static char part; /* (b)yte, (c)har, (f)ields */
40static unsigned int supress_non_delimited_lines;
39static char delim = '\t'; /* delimiter, default is tab */ 41static char delim = '\t'; /* delimiter, default is tab */
40 42
41struct cut_list { 43struct cut_list {
@@ -270,11 +272,11 @@ static void cut_file(FILE *file)
270 while ((line = bb_get_chomped_line_from_file(file)) != NULL) { 272 while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
271 273
272 /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ 274 /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
273 if (part == 'c' || part == 'b') 275 if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS)))
274 cut_line_by_chars(line); 276 cut_line_by_chars(line);
275 277
276 /* cut based on fields */ 278 /* cut based on fields */
277 else if (part == 'f') { 279 else {
278 if (delim == '\n') 280 if (delim == '\n')
279 cut_file_by_lines(line, linenum); 281 cut_file_by_lines(line, linenum);
280 else 282 else
@@ -289,46 +291,32 @@ static void cut_file(FILE *file)
289 291
290extern int cut_main(int argc, char **argv) 292extern int cut_main(int argc, char **argv)
291{ 293{
292 int opt; 294 unsigned long opt;
293 295 char *sopt, *sdopt;
294 while ((opt = getopt(argc, argv, "b:c:d:f:ns")) > 0) { 296
295 switch (opt) { 297 bb_opt_complementaly = "b~bcf:c~bcf:f~bcf";
296 case 'b': 298 opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt);
297 case 'c': 299 part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
298 case 'f': 300 if(part == 0)
299 /* make sure they didn't ask for two types of lists */ 301 bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
300 if (part != 0) { 302 if(opt & 0x80000000UL)
301 bb_error_msg_and_die("only one type of list may be specified"); 303 bb_error_msg_and_die("only one type of list may be specified");
302 } 304 parse_lists(sopt);
303 part = (char)opt; 305 if((opt & (OPT_DELIM_FLGS))) {
304 parse_lists(optarg); 306 if (strlen(sdopt) > 1) {
305 break;
306 case 'd':
307 if (strlen(optarg) > 1) {
308 bb_error_msg_and_die("the delimiter must be a single character"); 307 bb_error_msg_and_die("the delimiter must be a single character");
309 } 308 }
310 delim = optarg[0]; 309 delim = sdopt[0];
311 break;
312 case 'n':
313 /* no-op */
314 break;
315 case 's':
316 supress_non_delimited_lines++;
317 break;
318 }
319 }
320
321 if (part == 0) {
322 bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
323 } 310 }
311 supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS;
324 312
325 /* non-field (char or byte) cutting has some special handling */ 313 /* non-field (char or byte) cutting has some special handling */
326 if (part != 'f') { 314 if (part != OPT_FIELDS_FLGS) {
327 if (supress_non_delimited_lines) { 315 if (supress_non_delimited_lines) {
328 bb_error_msg_and_die("suppressing non-delimited lines makes sense" 316 bb_error_msg_and_die("suppressing non-delimited lines makes sense"
329 " only when operating on fields"); 317 " only when operating on fields");
330 } 318 }
331 if (delim != '\t' && part != 'f') { 319 if (delim != '\t') {
332 bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); 320 bb_error_msg_and_die("a delimiter may be specified only when operating on fields");
333 } 321 }
334 } 322 }