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
This commit is contained in:
parent
9304d6ea92
commit
04e11c9209
@ -220,6 +220,14 @@ Special characters:
|
|||||||
"x--x" Variation of the above, it means that -x option should occur
|
"x--x" Variation of the above, it means that -x option should occur
|
||||||
at most once.
|
at most once.
|
||||||
|
|
||||||
|
"a+:" A plus after a char in opt_complementary means that the parameter
|
||||||
|
for this option is a nonnegative integer. It will be processed
|
||||||
|
with xatoi_u() - allowed range is 0..INT_MAX.
|
||||||
|
|
||||||
|
int param; // "unsigned param;" will also work
|
||||||
|
opt_complementary = "p+";
|
||||||
|
getopt32(argv, "p:", ¶m);
|
||||||
|
|
||||||
"a::" A double colon after a char in opt_complementary means that the
|
"a::" A double colon after a char in opt_complementary means that the
|
||||||
option can occur multiple times. Each occurrence will be saved as
|
option can occur multiple times. Each occurrence will be saved as
|
||||||
a llist_t element instead of char*.
|
a llist_t element instead of char*.
|
||||||
@ -275,14 +283,20 @@ Special characters:
|
|||||||
|
|
||||||
const char *opt_complementary;
|
const char *opt_complementary;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PARAM_STRING,
|
||||||
|
PARAM_LIST,
|
||||||
|
PARAM_INT,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int opt;
|
unsigned char opt_char;
|
||||||
int list_flg;
|
smallint param_type;
|
||||||
unsigned switch_on;
|
unsigned switch_on;
|
||||||
unsigned switch_off;
|
unsigned switch_off;
|
||||||
unsigned incongruously;
|
unsigned incongruously;
|
||||||
unsigned requires;
|
unsigned requires;
|
||||||
void **optarg; /* char **optarg or llist_t **optarg */
|
void **optarg; /* char**, llist_t** or int *. */
|
||||||
int *counter;
|
int *counter;
|
||||||
} t_complementary;
|
} t_complementary;
|
||||||
|
|
||||||
@ -337,12 +351,14 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
if (*s == '+' || *s == '-')
|
if (*s == '+' || *s == '-')
|
||||||
s++;
|
s++;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
if (c >= 32) break;
|
if (c >= 32)
|
||||||
on_off->opt = *s;
|
break;
|
||||||
|
on_off->opt_char = *s;
|
||||||
on_off->switch_on = (1 << c);
|
on_off->switch_on = (1 << c);
|
||||||
if (*++s == ':') {
|
if (*++s == ':') {
|
||||||
on_off->optarg = va_arg(p, void **);
|
on_off->optarg = va_arg(p, void **);
|
||||||
while (*++s == ':') /* skip */;
|
while (*++s == ':')
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
on_off++;
|
on_off++;
|
||||||
c++;
|
c++;
|
||||||
@ -375,11 +391,12 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
for (l_o = long_options; l_o->name; l_o++) {
|
for (l_o = long_options; l_o->name; l_o++) {
|
||||||
if (l_o->flag)
|
if (l_o->flag)
|
||||||
continue;
|
continue;
|
||||||
for (on_off = complementary; on_off->opt != 0; on_off++)
|
for (on_off = complementary; on_off->opt_char; on_off++)
|
||||||
if (on_off->opt == l_o->val)
|
if (on_off->opt_char == l_o->val)
|
||||||
goto next_long;
|
goto next_long;
|
||||||
if (c >= 32) break;
|
if (c >= 32)
|
||||||
on_off->opt = l_o->val;
|
break;
|
||||||
|
on_off->opt_char = l_o->val;
|
||||||
on_off->switch_on = (1 << c);
|
on_off->switch_on = (1 << c);
|
||||||
if (l_o->has_arg != no_argument)
|
if (l_o->has_arg != no_argument)
|
||||||
on_off->optarg = va_arg(p, void **);
|
on_off->optarg = va_arg(p, void **);
|
||||||
@ -422,11 +439,15 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
s++;
|
s++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (on_off = complementary; on_off->opt; on_off++)
|
for (on_off = complementary; on_off->opt_char; on_off++)
|
||||||
if (on_off->opt == *s)
|
if (on_off->opt_char == *s)
|
||||||
break;
|
break;
|
||||||
if (c == ':' && s[2] == ':') {
|
if (c == ':' && s[2] == ':') {
|
||||||
on_off->list_flg++;
|
on_off->param_type = PARAM_LIST;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '+' && (s[2] == ':' || s[2] == '\0')) {
|
||||||
|
on_off->param_type = PARAM_INT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == ':' || c == '\0') {
|
if (c == ':' || c == '\0') {
|
||||||
@ -454,8 +475,8 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
else
|
else
|
||||||
pair_switch = &(pair->switch_off);
|
pair_switch = &(pair->switch_off);
|
||||||
} else {
|
} else {
|
||||||
for (on_off = complementary; on_off->opt; on_off++)
|
for (on_off = complementary; on_off->opt_char; on_off++)
|
||||||
if (on_off->opt == *s) {
|
if (on_off->opt_char == *s) {
|
||||||
*pair_switch |= on_off->switch_on;
|
*pair_switch |= on_off->switch_on;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -508,9 +529,9 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
#endif
|
#endif
|
||||||
c &= 0xff; /* fight libc's sign extension */
|
c &= 0xff; /* fight libc's sign extension */
|
||||||
loop_arg_is_opt:
|
loop_arg_is_opt:
|
||||||
for (on_off = complementary; on_off->opt != c; on_off++) {
|
for (on_off = complementary; on_off->opt_char != c; on_off++) {
|
||||||
/* c==0 if long opt have non NULL flag */
|
/* c==0 if long opt have non NULL flag */
|
||||||
if (on_off->opt == 0 && c != 0)
|
if (on_off->opt_char == '\0' && c != '\0')
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
if (flags & on_off->incongruously)
|
if (flags & on_off->incongruously)
|
||||||
@ -521,8 +542,10 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
flags ^= trigger;
|
flags ^= trigger;
|
||||||
if (on_off->counter)
|
if (on_off->counter)
|
||||||
(*(on_off->counter))++;
|
(*(on_off->counter))++;
|
||||||
if (on_off->list_flg) {
|
if (on_off->param_type == PARAM_LIST) {
|
||||||
llist_add_to_end((llist_t **)(on_off->optarg), optarg);
|
llist_add_to_end((llist_t **)(on_off->optarg), optarg);
|
||||||
|
} else if (on_off->param_type == PARAM_INT) {
|
||||||
|
*(unsigned*)(on_off->optarg) = xatoi_u(optarg);
|
||||||
} else if (on_off->optarg) {
|
} else if (on_off->optarg) {
|
||||||
*(char **)(on_off->optarg) = optarg;
|
*(char **)(on_off->optarg) = optarg;
|
||||||
}
|
}
|
||||||
@ -550,7 +573,7 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
free(argv[1]);
|
free(argv[1]);
|
||||||
#endif
|
#endif
|
||||||
/* check depending requires for given options */
|
/* check depending requires for given options */
|
||||||
for (on_off = complementary; on_off->opt; on_off++) {
|
for (on_off = complementary; on_off->opt_char; on_off++) {
|
||||||
if (on_off->requires && (flags & on_off->switch_on) &&
|
if (on_off->requires && (flags & on_off->switch_on) &&
|
||||||
(flags & on_off->requires) == 0)
|
(flags & on_off->requires) == 0)
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
|
@ -740,7 +740,7 @@ int top_main(int argc, char **argv)
|
|||||||
int count, lines, col;
|
int count, lines, col;
|
||||||
unsigned interval;
|
unsigned interval;
|
||||||
int iterations;
|
int iterations;
|
||||||
char *sinterval, *siterations;
|
char *sinterval;
|
||||||
SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK;
|
SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK;
|
||||||
#if ENABLE_FEATURE_USE_TERMIOS
|
#if ENABLE_FEATURE_USE_TERMIOS
|
||||||
struct termios new_settings;
|
struct termios new_settings;
|
||||||
@ -757,15 +757,12 @@ int top_main(int argc, char **argv)
|
|||||||
iterations = 0; /* infinite */
|
iterations = 0; /* infinite */
|
||||||
|
|
||||||
/* do normal option parsing */
|
/* do normal option parsing */
|
||||||
opt_complementary = "-";
|
opt_complementary = "-:n+";
|
||||||
getopt32(argv, "d:n:b", &sinterval, &siterations);
|
getopt32(argv, "d:n:b", &sinterval, &iterations);
|
||||||
if (option_mask32 & 0x1) {
|
if (option_mask32 & 0x1) {
|
||||||
/* Need to limit it to not overflow poll timeout */
|
/* Need to limit it to not overflow poll timeout */
|
||||||
interval = xatou16(sinterval); // -d
|
interval = xatou16(sinterval); // -d
|
||||||
}
|
}
|
||||||
if (option_mask32 & 0x2)
|
|
||||||
iterations = xatoi_u(siterations); // -n
|
|
||||||
//if (option_mask32 & 0x4) // -b
|
|
||||||
|
|
||||||
/* change to /proc */
|
/* change to /proc */
|
||||||
xchdir("/proc");
|
xchdir("/proc");
|
||||||
|
@ -2754,7 +2754,6 @@ unknown_command(int c)
|
|||||||
int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int fdisk_main(int argc, char **argv)
|
int fdisk_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *str_b, *str_C, *str_H, *str_S;
|
|
||||||
unsigned opt;
|
unsigned opt;
|
||||||
/*
|
/*
|
||||||
* fdisk -v
|
* fdisk -v
|
||||||
@ -2776,8 +2775,9 @@ int fdisk_main(int argc, char **argv)
|
|||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
|
opt_complementary = "b+:C+:H+:S+"; /* numeric params */
|
||||||
opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
|
opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
|
||||||
&str_b, &str_C, &str_H, &str_S);
|
§or_size, &user_cylinders, &user_heads, &user_sectors);
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
if (opt & OPT_b) { // -b
|
if (opt & OPT_b) { // -b
|
||||||
@ -2785,27 +2785,18 @@ int fdisk_main(int argc, char **argv)
|
|||||||
so cannot be combined with multiple disks,
|
so cannot be combined with multiple disks,
|
||||||
and the same goes for the C/H/S options.
|
and the same goes for the C/H/S options.
|
||||||
*/
|
*/
|
||||||
sector_size = xatoi_u(str_b);
|
if (sector_size != 512 && sector_size != 1024
|
||||||
if (sector_size != 512 && sector_size != 1024 &&
|
&& sector_size != 2048)
|
||||||
sector_size != 2048)
|
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
sector_offset = 2;
|
sector_offset = 2;
|
||||||
user_set_sector_size = 1;
|
user_set_sector_size = 1;
|
||||||
}
|
}
|
||||||
if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C
|
if (user_heads <= 0 || user_heads >= 256)
|
||||||
if (opt & OPT_H) { // -H
|
user_heads = 0;
|
||||||
user_heads = xatoi_u(str_H);
|
if (user_sectors <= 0 || user_sectors >= 64)
|
||||||
if (user_heads <= 0 || user_heads >= 256)
|
user_sectors = 0;
|
||||||
user_heads = 0;
|
if (opt & OPT_u)
|
||||||
}
|
display_in_cyl_units = 0; // -u
|
||||||
//if (opt & OPT_l) // -l
|
|
||||||
if (opt & OPT_S) { // -S
|
|
||||||
user_sectors = xatoi_u(str_S);
|
|
||||||
if (user_sectors <= 0 || user_sectors >= 64)
|
|
||||||
user_sectors = 0;
|
|
||||||
}
|
|
||||||
if (opt & OPT_u) display_in_cyl_units = 0; // -u
|
|
||||||
//if (opt & OPT_s) // -s
|
|
||||||
|
|
||||||
if (user_set_sector_size && argc != 1)
|
if (user_set_sector_size && argc != 1)
|
||||||
printf("Warning: the -b (set sector size) option should"
|
printf("Warning: the -b (set sector size) option should"
|
||||||
|
Loading…
Reference in New Issue
Block a user