diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-06-20 09:01:58 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-06-20 09:01:58 +0000 |
commit | 8876fb2f59a0b515b3121d5894933eef88ce566a (patch) | |
tree | f67de9320202043aca8ded20fb80d668c3b0c2d8 /coreutils/cut.c | |
parent | dfce3536ace2bcd38bdd3731841998ce344d786e (diff) | |
download | busybox-w32-8876fb2f59a0b515b3121d5894933eef88ce566a.tar.gz busybox-w32-8876fb2f59a0b515b3121d5894933eef88ce566a.tar.bz2 busybox-w32-8876fb2f59a0b515b3121d5894933eef88ce566a.zip |
last_patch89 from vodz:
Manuel,
I rewrite bb_getopt_ulflags() function for more universal usage.
My version support now:
- options with arguments (optional arg as GNU extension also)
- complementaly and/or incomplementaly and/or incongruously and/or list
options
- long_opt (all applets may have long option, add supporting is trivial)
This realisation full compatibile from your version.
Code size grow 480 bytes, but only coreutils/* over compensate this size
after using new function. Last patch reduced over 800 bytes and not full
applied to all. "mkdir" and "mv" applets have long_opt now for demonstrate
trivial addition support long_opt with usage new bb_getopt_ulflags().
Complementaly and/or incomplementaly and/or incongruously and/or list options
logic is not trivial, but new "cut" and "grep" applets using this logic
for examples with full demostrating. New "grep" applet reduced over 300
bytes.
Mark,
Also. I removed bug from "grep" applet.
$ echo a b | busybox grep -e a b
a b
a b
But right is printing one only.
--w
vodz
Diffstat (limited to 'coreutils/cut.c')
-rw-r--r-- | coreutils/cut.c | 68 |
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 */ | ||
32 | extern int optind; | ||
33 | extern char *optarg; | ||
34 | |||
35 | |||
36 | /* option vars */ | 32 | /* option vars */ |
37 | static char part = 0; /* (b)yte, (c)har, (f)ields */ | 33 | static const char optstring[] = "b:c:f:d:sn"; |
38 | static 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 | ||
39 | static char part; /* (b)yte, (c)har, (f)ields */ | ||
40 | static unsigned int supress_non_delimited_lines; | ||
39 | static char delim = '\t'; /* delimiter, default is tab */ | 41 | static char delim = '\t'; /* delimiter, default is tab */ |
40 | 42 | ||
41 | struct cut_list { | 43 | struct 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 | ||
290 | extern int cut_main(int argc, char **argv) | 292 | extern 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 | } |