aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-10 19:44:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-10 19:44:20 +0000
commit04e11c9209f88b878d6bef0b56a4d8345c89c217 (patch)
treedc67a11b65d3d7e4a03b955dd2f5d1b3c7721b2f
parent9304d6ea92f7fc1529669800b75456d549cf1bfc (diff)
downloadbusybox-w32-04e11c9209f88b878d6bef0b56a4d8345c89c217.tar.gz
busybox-w32-04e11c9209f88b878d6bef0b56a4d8345c89c217.tar.bz2
busybox-w32-04e11c9209f88b878d6bef0b56a4d8345c89c217.zip
getpot: add support for "a+" specifier for nonnegative int parameters.
By Vladimir Dronnikov <dronnikov at gmail.com>. fdisk and top are converted as an example. function old new delta getopt32 1340 1370 +30 top_main 1137 1120 -17 fdisk_main 3033 2949 -84 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 30/-101) Total: -71 bytes
-rw-r--r--libbb/getopt32.c61
-rw-r--r--procps/top.c9
-rw-r--r--util-linux/fdisk.c29
3 files changed, 55 insertions, 44 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 80d5d2822..46807a3b6 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -220,6 +220,14 @@ Special characters:
220 "x--x" Variation of the above, it means that -x option should occur 220 "x--x" Variation of the above, it means that -x option should occur
221 at most once. 221 at most once.
222 222
223 "a+:" A plus after a char in opt_complementary means that the parameter
224 for this option is a nonnegative integer. It will be processed
225 with xatoi_u() - allowed range is 0..INT_MAX.
226
227 int param; // "unsigned param;" will also work
228 opt_complementary = "p+";
229 getopt32(argv, "p:", &param);
230
223 "a::" A double colon after a char in opt_complementary means that the 231 "a::" A double colon after a char in opt_complementary means that the
224 option can occur multiple times. Each occurrence will be saved as 232 option can occur multiple times. Each occurrence will be saved as
225 a llist_t element instead of char*. 233 a llist_t element instead of char*.
@@ -275,14 +283,20 @@ Special characters:
275 283
276const char *opt_complementary; 284const char *opt_complementary;
277 285
286enum {
287 PARAM_STRING,
288 PARAM_LIST,
289 PARAM_INT,
290};
291
278typedef struct { 292typedef struct {
279 int opt; 293 unsigned char opt_char;
280 int list_flg; 294 smallint param_type;
281 unsigned switch_on; 295 unsigned switch_on;
282 unsigned switch_off; 296 unsigned switch_off;
283 unsigned incongruously; 297 unsigned incongruously;
284 unsigned requires; 298 unsigned requires;
285 void **optarg; /* char **optarg or llist_t **optarg */ 299 void **optarg; /* char**, llist_t** or int *. */
286 int *counter; 300 int *counter;
287} t_complementary; 301} t_complementary;
288 302
@@ -337,12 +351,14 @@ getopt32(char **argv, const char *applet_opts, ...)
337 if (*s == '+' || *s == '-') 351 if (*s == '+' || *s == '-')
338 s++; 352 s++;
339 while (*s) { 353 while (*s) {
340 if (c >= 32) break; 354 if (c >= 32)
341 on_off->opt = *s; 355 break;
356 on_off->opt_char = *s;
342 on_off->switch_on = (1 << c); 357 on_off->switch_on = (1 << c);
343 if (*++s == ':') { 358 if (*++s == ':') {
344 on_off->optarg = va_arg(p, void **); 359 on_off->optarg = va_arg(p, void **);
345 while (*++s == ':') /* skip */; 360 while (*++s == ':')
361 continue;
346 } 362 }
347 on_off++; 363 on_off++;
348 c++; 364 c++;
@@ -375,11 +391,12 @@ getopt32(char **argv, const char *applet_opts, ...)
375 for (l_o = long_options; l_o->name; l_o++) { 391 for (l_o = long_options; l_o->name; l_o++) {
376 if (l_o->flag) 392 if (l_o->flag)
377 continue; 393 continue;
378 for (on_off = complementary; on_off->opt != 0; on_off++) 394 for (on_off = complementary; on_off->opt_char; on_off++)
379 if (on_off->opt == l_o->val) 395 if (on_off->opt_char == l_o->val)
380 goto next_long; 396 goto next_long;
381 if (c >= 32) break; 397 if (c >= 32)
382 on_off->opt = l_o->val; 398 break;
399 on_off->opt_char = l_o->val;
383 on_off->switch_on = (1 << c); 400 on_off->switch_on = (1 << c);
384 if (l_o->has_arg != no_argument) 401 if (l_o->has_arg != no_argument)
385 on_off->optarg = va_arg(p, void **); 402 on_off->optarg = va_arg(p, void **);
@@ -422,11 +439,15 @@ getopt32(char **argv, const char *applet_opts, ...)
422 s++; 439 s++;
423 continue; 440 continue;
424 } 441 }
425 for (on_off = complementary; on_off->opt; on_off++) 442 for (on_off = complementary; on_off->opt_char; on_off++)
426 if (on_off->opt == *s) 443 if (on_off->opt_char == *s)
427 break; 444 break;
428 if (c == ':' && s[2] == ':') { 445 if (c == ':' && s[2] == ':') {
429 on_off->list_flg++; 446 on_off->param_type = PARAM_LIST;
447 continue;
448 }
449 if (c == '+' && (s[2] == ':' || s[2] == '\0')) {
450 on_off->param_type = PARAM_INT;
430 continue; 451 continue;
431 } 452 }
432 if (c == ':' || c == '\0') { 453 if (c == ':' || c == '\0') {
@@ -454,8 +475,8 @@ getopt32(char **argv, const char *applet_opts, ...)
454 else 475 else
455 pair_switch = &(pair->switch_off); 476 pair_switch = &(pair->switch_off);
456 } else { 477 } else {
457 for (on_off = complementary; on_off->opt; on_off++) 478 for (on_off = complementary; on_off->opt_char; on_off++)
458 if (on_off->opt == *s) { 479 if (on_off->opt_char == *s) {
459 *pair_switch |= on_off->switch_on; 480 *pair_switch |= on_off->switch_on;
460 break; 481 break;
461 } 482 }
@@ -508,9 +529,9 @@ getopt32(char **argv, const char *applet_opts, ...)
508#endif 529#endif
509 c &= 0xff; /* fight libc's sign extension */ 530 c &= 0xff; /* fight libc's sign extension */
510 loop_arg_is_opt: 531 loop_arg_is_opt:
511 for (on_off = complementary; on_off->opt != c; on_off++) { 532 for (on_off = complementary; on_off->opt_char != c; on_off++) {
512 /* c==0 if long opt have non NULL flag */ 533 /* c==0 if long opt have non NULL flag */
513 if (on_off->opt == 0 && c != 0) 534 if (on_off->opt_char == '\0' && c != '\0')
514 bb_show_usage(); 535 bb_show_usage();
515 } 536 }
516 if (flags & on_off->incongruously) 537 if (flags & on_off->incongruously)
@@ -521,8 +542,10 @@ getopt32(char **argv, const char *applet_opts, ...)
521 flags ^= trigger; 542 flags ^= trigger;
522 if (on_off->counter) 543 if (on_off->counter)
523 (*(on_off->counter))++; 544 (*(on_off->counter))++;
524 if (on_off->list_flg) { 545 if (on_off->param_type == PARAM_LIST) {
525 llist_add_to_end((llist_t **)(on_off->optarg), optarg); 546 llist_add_to_end((llist_t **)(on_off->optarg), optarg);
547 } else if (on_off->param_type == PARAM_INT) {
548 *(unsigned*)(on_off->optarg) = xatoi_u(optarg);
526 } else if (on_off->optarg) { 549 } else if (on_off->optarg) {
527 *(char **)(on_off->optarg) = optarg; 550 *(char **)(on_off->optarg) = optarg;
528 } 551 }
@@ -550,7 +573,7 @@ getopt32(char **argv, const char *applet_opts, ...)
550 free(argv[1]); 573 free(argv[1]);
551#endif 574#endif
552 /* check depending requires for given options */ 575 /* check depending requires for given options */
553 for (on_off = complementary; on_off->opt; on_off++) { 576 for (on_off = complementary; on_off->opt_char; on_off++) {
554 if (on_off->requires && (flags & on_off->switch_on) && 577 if (on_off->requires && (flags & on_off->switch_on) &&
555 (flags & on_off->requires) == 0) 578 (flags & on_off->requires) == 0)
556 bb_show_usage(); 579 bb_show_usage();
diff --git a/procps/top.c b/procps/top.c
index 4df58f227..37b6a0cdb 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -740,7 +740,7 @@ int top_main(int argc, char **argv)
740 int count, lines, col; 740 int count, lines, col;
741 unsigned interval; 741 unsigned interval;
742 int iterations; 742 int iterations;
743 char *sinterval, *siterations; 743 char *sinterval;
744 SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK; 744 SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK;
745#if ENABLE_FEATURE_USE_TERMIOS 745#if ENABLE_FEATURE_USE_TERMIOS
746 struct termios new_settings; 746 struct termios new_settings;
@@ -757,15 +757,12 @@ int top_main(int argc, char **argv)
757 iterations = 0; /* infinite */ 757 iterations = 0; /* infinite */
758 758
759 /* do normal option parsing */ 759 /* do normal option parsing */
760 opt_complementary = "-"; 760 opt_complementary = "-:n+";
761 getopt32(argv, "d:n:b", &sinterval, &siterations); 761 getopt32(argv, "d:n:b", &sinterval, &iterations);
762 if (option_mask32 & 0x1) { 762 if (option_mask32 & 0x1) {
763 /* Need to limit it to not overflow poll timeout */ 763 /* Need to limit it to not overflow poll timeout */
764 interval = xatou16(sinterval); // -d 764 interval = xatou16(sinterval); // -d
765 } 765 }
766 if (option_mask32 & 0x2)
767 iterations = xatoi_u(siterations); // -n
768 //if (option_mask32 & 0x4) // -b
769 766
770 /* change to /proc */ 767 /* change to /proc */
771 xchdir("/proc"); 768 xchdir("/proc");
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index cd053b876..c98a74fc0 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -2754,7 +2754,6 @@ unknown_command(int c)
2754int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2754int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
2755int fdisk_main(int argc, char **argv) 2755int fdisk_main(int argc, char **argv)
2756{ 2756{
2757 char *str_b, *str_C, *str_H, *str_S;
2758 unsigned opt; 2757 unsigned opt;
2759 /* 2758 /*
2760 * fdisk -v 2759 * fdisk -v
@@ -2776,8 +2775,9 @@ int fdisk_main(int argc, char **argv)
2776 2775
2777 INIT_G(); 2776 INIT_G();
2778 2777
2778 opt_complementary = "b+:C+:H+:S+"; /* numeric params */
2779 opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), 2779 opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
2780 &str_b, &str_C, &str_H, &str_S); 2780 &sector_size, &user_cylinders, &user_heads, &user_sectors);
2781 argc -= optind; 2781 argc -= optind;
2782 argv += optind; 2782 argv += optind;
2783 if (opt & OPT_b) { // -b 2783 if (opt & OPT_b) { // -b
@@ -2785,27 +2785,18 @@ int fdisk_main(int argc, char **argv)
2785 so cannot be combined with multiple disks, 2785 so cannot be combined with multiple disks,
2786 and the same goes for the C/H/S options. 2786 and the same goes for the C/H/S options.
2787 */ 2787 */
2788 sector_size = xatoi_u(str_b); 2788 if (sector_size != 512 && sector_size != 1024
2789 if (sector_size != 512 && sector_size != 1024 && 2789 && sector_size != 2048)
2790 sector_size != 2048)
2791 bb_show_usage(); 2790 bb_show_usage();
2792 sector_offset = 2; 2791 sector_offset = 2;
2793 user_set_sector_size = 1; 2792 user_set_sector_size = 1;
2794 } 2793 }
2795 if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C 2794 if (user_heads <= 0 || user_heads >= 256)
2796 if (opt & OPT_H) { // -H 2795 user_heads = 0;
2797 user_heads = xatoi_u(str_H); 2796 if (user_sectors <= 0 || user_sectors >= 64)
2798 if (user_heads <= 0 || user_heads >= 256) 2797 user_sectors = 0;
2799 user_heads = 0; 2798 if (opt & OPT_u)
2800 } 2799 display_in_cyl_units = 0; // -u
2801 //if (opt & OPT_l) // -l
2802 if (opt & OPT_S) { // -S
2803 user_sectors = xatoi_u(str_S);
2804 if (user_sectors <= 0 || user_sectors >= 64)
2805 user_sectors = 0;
2806 }
2807 if (opt & OPT_u) display_in_cyl_units = 0; // -u
2808 //if (opt & OPT_s) // -s
2809 2800
2810 if (user_set_sector_size && argc != 1) 2801 if (user_set_sector_size && argc != 1)
2811 printf("Warning: the -b (set sector size) option should" 2802 printf("Warning: the -b (set sector size) option should"