diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-08 21:55:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-08 21:55:02 +0200 |
commit | 22542eca18e5807b72ddc78999f5101e33f17a53 (patch) | |
tree | 1271842a37c6215c998674a44bf7f561a0deff52 /libbb/getopt32.c | |
parent | 036585a911a5fe6c2cd77b808dd9150500f37272 (diff) | |
download | busybox-w32-22542eca18e5807b72ddc78999f5101e33f17a53.tar.gz busybox-w32-22542eca18e5807b72ddc78999f5101e33f17a53.tar.bz2 busybox-w32-22542eca18e5807b72ddc78999f5101e33f17a53.zip |
getopt32: remove opt_complementary
function old new delta
vgetopt32 1318 1392 +74
runsvdir_main 703 713 +10
bb_make_directory 423 425 +2
collect_cpu 546 545 -1
opt_chars 3 - -3
opt_complementary 4 - -4
tftpd_main 567 562 -5
ntp_init 476 471 -5
zcip_main 1266 1256 -10
xxd_main 428 418 -10
whois_main 140 130 -10
who_main 463 453 -10
which_main 212 202 -10
wget_main 2535 2525 -10
watchdog_main 291 281 -10
watch_main 222 212 -10
vlock_main 399 389 -10
uuencode_main 332 322 -10
uudecode_main 316 306 -10
unlink_main 45 35 -10
udhcpd_main 1482 1472 -10
udhcpc_main 2762 2752 -10
tune2fs_main 290 280 -10
tunctl_main 366 356 -10
truncate_main 218 208 -10
tr_main 518 508 -10
time_main 1134 1124 -10
tftp_main 286 276 -10
telnetd_main 1873 1863 -10
tcpudpsvd_main 1785 1775 -10
taskset_main 521 511 -10
tar_main 1009 999 -10
tail_main 1644 1634 -10
syslogd_main 1967 1957 -10
switch_root_main 368 358 -10
svlogd_main 1454 1444 -10
sv 1296 1286 -10
stat_main 104 94 -10
start_stop_daemon_main 1028 1018 -10
split_main 542 532 -10
sort_main 796 786 -10
slattach_main 624 614 -10
shuf_main 504 494 -10
setsid_main 96 86 -10
setserial_main 1132 1122 -10
setfont_main 388 378 -10
setconsole_main 78 68 -10
sendmail_main 1209 1199 -10
sed_main 677 667 -10
script_main 1077 1067 -10
run_parts_main 325 315 -10
rtcwake_main 454 444 -10
rm_main 175 165 -10
reformime_main 119 109 -10
readlink_main 123 113 -10
rdate_main 246 236 -10
pwdx_main 189 179 -10
pstree_main 317 307 -10
pscan_main 663 653 -10
popmaildir_main 818 808 -10
pmap_main 80 70 -10
nc_main 1042 1032 -10
mv_main 558 548 -10
mountpoint_main 477 467 -10
mount_main 1264 1254 -10
modprobe_main 768 758 -10
modinfo_main 333 323 -10
mktemp_main 200 190 -10
mkswap_main 324 314 -10
mkfs_vfat_main 1489 1479 -10
microcom_main 715 705 -10
md5_sha1_sum_main 521 511 -10
man_main 867 857 -10
makedevs_main 1052 1042 -10
ls_main 563 553 -10
losetup_main 432 422 -10
loadfont_main 89 79 -10
ln_main 524 514 -10
link_main 75 65 -10
ipcalc_main 544 534 -10
iostat_main 2397 2387 -10
install_main 768 758 -10
id_main 480 470 -10
i2cset_main 1239 1229 -10
i2cget_main 380 370 -10
i2cdump_main 1482 1472 -10
i2cdetect_main 682 672 -10
hwclock_main 406 396 -10
httpd_main 741 731 -10
grep_main 837 827 -10
getty_main 1559 1549 -10
fuser_main 297 287 -10
ftpgetput_main 345 335 -10
ftpd_main 2232 2222 -10
fstrim_main 251 241 -10
fsfreeze_main 77 67 -10
fsck_minix_main 2921 2911 -10
flock_main 314 304 -10
flashcp_main 740 730 -10
flash_eraseall_main 833 823 -10
fdformat_main 532 522 -10
expand_main 680 670 -10
eject_main 335 325 -10
dumpleases_main 630 620 -10
du_main 314 304 -10
dos2unix_main 441 431 -10
diff_main 1350 1340 -10
df_main 1064 1054 -10
date_main 1095 1085 -10
cut_main 961 951 -10
cryptpw_main 228 218 -10
crontab_main 575 565 -10
crond_main 1149 1139 -10
cp_main 370 360 -10
common_traceroute_main 3834 3824 -10
common_ping_main 1767 1757 -10
comm_main 239 229 -10
cmp_main 655 645 -10
chrt_main 379 369 -10
chpst_main 704 694 -10
chpasswd_main 308 298 -10
chown_main 171 161 -10
chmod_main 158 148 -10
cat_main 428 418 -10
bzip2_main 120 110 -10
blkdiscard_main 264 254 -10
base64_main 221 211 -10
arping_main 1665 1655 -10
ar_main 556 546 -10
adjtimex_main 406 396 -10
adduser_main 882 872 -10
addgroup_main 411 401 -10
acpid_main 1198 1188 -10
optstring 11 - -11
opt_string 18 - -18
OPT_STR 25 - -25
ubi_tools_main 1288 1258 -30
ls_options 31 - -31
------------------------------------------------------------------------------
(add/remove: 0/6 grow/shrink: 3/129 up/down: 86/-1383) Total: -1297 bytes
text data bss dec hex filename
915428 485 6876 922789 e14a5 busybox_old
914629 485 6872 921986 e1182 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/getopt32.c')
-rw-r--r-- | libbb/getopt32.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index b2b4de8cb..f778c6e89 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -96,9 +96,11 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
96 | env -i ls -d / | 96 | env -i ls -d / |
97 | Here we want env to process just the '-i', not the '-d'. | 97 | Here we want env to process just the '-i', not the '-d'. |
98 | 98 | ||
99 | "!" Report bad option, missing required options, | 99 | "!" Report bad options, missing required options, |
100 | inconsistent options with all-ones return value (instead of abort). | 100 | inconsistent options with all-ones return value (instead of abort). |
101 | 101 | ||
102 | "^" options string is "^optchars""\0""opt_complementary". | ||
103 | |||
102 | uint32_t | 104 | uint32_t |
103 | getopt32long(char **argv, const char *applet_opts, const char *logopts...) | 105 | getopt32long(char **argv, const char *applet_opts, const char *logopts...) |
104 | 106 | ||
@@ -121,7 +123,7 @@ getopt32long(char **argv, const char *applet_opts, const char *logopts...) | |||
121 | config process and not a required feature. The current standard | 123 | config process and not a required feature. The current standard |
122 | is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. | 124 | is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. |
123 | 125 | ||
124 | const char *opt_complementary | 126 | opt_complementary - option modifiers. |
125 | 127 | ||
126 | ":" The colon (":") is used to separate groups of two or more chars | 128 | ":" The colon (":") is used to separate groups of two or more chars |
127 | and/or groups of chars and special characters (stating some | 129 | and/or groups of chars and special characters (stating some |
@@ -132,8 +134,7 @@ const char *opt_complementary | |||
132 | Their flags will be turned on if the main option is found even | 134 | Their flags will be turned on if the main option is found even |
133 | if they are not specified on the command line. For example: | 135 | if they are not specified on the command line. For example: |
134 | 136 | ||
135 | opt_complementary = "abc"; | 137 | flags = getopt32(argv, "^abcd""\0""abc") |
136 | flags = getopt32(argv, "abcd") | ||
137 | 138 | ||
138 | If getopt() finds "-a" on the command line, then | 139 | If getopt() finds "-a" on the command line, then |
139 | getopt32's return value will be as if "-a -b -c" were | 140 | getopt32's return value will be as if "-a -b -c" were |
@@ -146,8 +147,7 @@ const char *opt_complementary | |||
146 | if w is given more than once, it is "unlimited" | 147 | if w is given more than once, it is "unlimited" |
147 | 148 | ||
148 | int w_counter = 0; // must be initialized! | 149 | int w_counter = 0; // must be initialized! |
149 | opt_complementary = "ww"; | 150 | getopt32(argv, "^w""\0""ww", &w_counter); |
150 | getopt32(argv, "w", &w_counter); | ||
151 | if (w_counter) | 151 | if (w_counter) |
152 | width = (w_counter == 1) ? 132 : INT_MAX; | 152 | width = (w_counter == 1) ? 132 : INT_MAX; |
153 | else | 153 | else |
@@ -162,8 +162,9 @@ const char *opt_complementary | |||
162 | 162 | ||
163 | llist_t *my_b = NULL; | 163 | llist_t *my_b = NULL; |
164 | int verbose_level = 0; | 164 | int verbose_level = 0; |
165 | opt_complementary = "vv:b-c:c-b"; | 165 | f = getopt32(argv, "^vb:*c" |
166 | f = getopt32(argv, "vb:*c", &my_b, &verbose_level); | 166 | "\0""vv:b-c:c-b" |
167 | , &my_b, &verbose_level); | ||
167 | if (f & 2) // -c after -b unsets -b flag | 168 | if (f & 2) // -c after -b unsets -b flag |
168 | while (my_b) dosomething_with(llist_pop(&my_b)); | 169 | while (my_b) dosomething_with(llist_pop(&my_b)); |
169 | if (my_b) // but llist is stored if -b is specified | 170 | if (my_b) // but llist is stored if -b is specified |
@@ -199,7 +200,7 @@ Special characters: | |||
199 | getopt32 finds -s, then -d is unset or if it finds -d | 200 | getopt32 finds -s, then -d is unset or if it finds -d |
200 | then -s is unset. (Note: busybox implements the GNU | 201 | then -s is unset. (Note: busybox implements the GNU |
201 | "--max-depth" option as "-d".) To obtain this behavior, you | 202 | "--max-depth" option as "-d".) To obtain this behavior, you |
202 | set opt_complementary = "s-d:d-s". Only one flag value is | 203 | set opt_complementary to "s-d:d-s". Only one flag value is |
203 | added to getopt32's return value depending on the | 204 | added to getopt32's return value depending on the |
204 | position of the options on the command line. If one of the | 205 | position of the options on the command line. If one of the |
205 | two options requires an argument pointer (":" in applet_opts | 206 | two options requires an argument pointer (":" in applet_opts |
@@ -207,8 +208,7 @@ Special characters: | |||
207 | 208 | ||
208 | char *smax_print_depth; | 209 | char *smax_print_depth; |
209 | 210 | ||
210 | opt_complementary = "s-d:d-s:x-x"; | 211 | opt = getopt32(argv, "^sd:x""\0""s-d:d-s:x-x", &smax_print_depth); |
211 | opt = getopt32(argv, "sd:x", &smax_print_depth); | ||
212 | 212 | ||
213 | if (opt & 2) | 213 | if (opt & 2) |
214 | max_print_depth = atoi(smax_print_depth); | 214 | max_print_depth = atoi(smax_print_depth); |
@@ -224,7 +224,7 @@ Special characters: | |||
224 | The cut applet must have only one type of list specified, so | 224 | The cut applet must have only one type of list specified, so |
225 | -b, -c and -f are mutually exclusive and should raise an error | 225 | -b, -c and -f are mutually exclusive and should raise an error |
226 | if specified together. In this case you must set | 226 | if specified together. In this case you must set |
227 | opt_complementary = "b--cf:c--bf:f--bc". If two of the | 227 | opt_complementary to "b--cf:c--bf:f--bc". If two of the |
228 | mutually exclusive options are found, getopt32 will call | 228 | mutually exclusive options are found, getopt32 will call |
229 | bb_show_usage() and die. | 229 | bb_show_usage() and die. |
230 | 230 | ||
@@ -236,8 +236,7 @@ Special characters: | |||
236 | with xatoi_positive() - allowed range is 0..INT_MAX. | 236 | with xatoi_positive() - allowed range is 0..INT_MAX. |
237 | 237 | ||
238 | int param; // "unsigned param;" will also work | 238 | int param; // "unsigned param;" will also work |
239 | opt_complementary = "p+"; | 239 | getopt32(argv, "^p:""\0""p+", ¶m); |
240 | getopt32(argv, "p:", ¶m); | ||
241 | 240 | ||
242 | "o::" A double colon after a char in opt_complementary means that the | 241 | "o::" A double colon after a char in opt_complementary means that the |
243 | option can occur multiple times. Each occurrence will be saved as | 242 | option can occur multiple times. Each occurrence will be saved as |
@@ -252,8 +251,7 @@ Special characters: | |||
252 | (this pointer must be initializated to NULL if the list is empty | 251 | (this pointer must be initializated to NULL if the list is empty |
253 | as required by llist_add_to_end(llist_t **old_head, char *new_item).) | 252 | as required by llist_add_to_end(llist_t **old_head, char *new_item).) |
254 | 253 | ||
255 | opt_complementary = "e::"; | 254 | getopt32(argv, "^e:""\0""e::", &patterns); |
256 | getopt32(argv, "e:", &patterns); | ||
257 | 255 | ||
258 | $ grep -e user -e root /etc/passwd | 256 | $ grep -e user -e root /etc/passwd |
259 | root:x:0:0:root:/root:/bin/bash | 257 | root:x:0:0:root:/root:/bin/bash |
@@ -271,8 +269,7 @@ Special characters: | |||
271 | For example from "id" applet: | 269 | For example from "id" applet: |
272 | 270 | ||
273 | // Don't allow -n -r -rn -ug -rug -nug -rnug | 271 | // Don't allow -n -r -rn -ug -rug -nug -rnug |
274 | opt_complementary = "r?ug:n?ug:u--g:g--u"; | 272 | flags = getopt32(argv, "^rnug""\0""r?ug:n?ug:u--g:g--u"); |
275 | flags = getopt32(argv, "rnug"); | ||
276 | 273 | ||
277 | This example allowed only: | 274 | This example allowed only: |
278 | $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng | 275 | $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng |
@@ -283,8 +280,7 @@ Special characters: | |||
283 | For example from "start-stop-daemon" applet: | 280 | For example from "start-stop-daemon" applet: |
284 | 281 | ||
285 | // Don't allow -KS -SK, but -S or -K is required | 282 | // Don't allow -KS -SK, but -S or -K is required |
286 | opt_complementary = "K:S:K--S:S--K"; | 283 | flags = getopt32(argv, "^KS...""\0""K:S:K--S:S--K"); |
287 | flags = getopt32(argv, "KS...); | ||
288 | 284 | ||
289 | 285 | ||
290 | Don't forget to use ':'. For example, "?322-22-23X-x-a" | 286 | Don't forget to use ':'. For example, "?322-22-23X-x-a" |
@@ -299,8 +295,6 @@ Special characters: | |||
299 | 295 | ||
300 | const char *const bb_argv_dash[] = { "-", NULL }; | 296 | const char *const bb_argv_dash[] = { "-", NULL }; |
301 | 297 | ||
302 | const char *opt_complementary; | ||
303 | |||
304 | enum { | 298 | enum { |
305 | PARAM_STRING, | 299 | PARAM_STRING, |
306 | PARAM_LIST, | 300 | PARAM_LIST, |
@@ -337,10 +331,12 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
337 | int argc; | 331 | int argc; |
338 | unsigned flags = 0; | 332 | unsigned flags = 0; |
339 | unsigned requires = 0; | 333 | unsigned requires = 0; |
334 | unsigned len; | ||
340 | t_complementary complementary[33]; /* last stays zero-filled */ | 335 | t_complementary complementary[33]; /* last stays zero-filled */ |
341 | char first_char; | 336 | char dont_die_flag; |
342 | int c; | 337 | int c; |
343 | const unsigned char *s; | 338 | const unsigned char *s; |
339 | const char *opt_complementary; | ||
344 | t_complementary *on_off; | 340 | t_complementary *on_off; |
345 | #if ENABLE_LONG_OPTS | 341 | #if ENABLE_LONG_OPTS |
346 | const struct option *l_o; | 342 | const struct option *l_o; |
@@ -349,23 +345,29 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
349 | unsigned trigger; | 345 | unsigned trigger; |
350 | int min_arg = 0; | 346 | int min_arg = 0; |
351 | int max_arg = -1; | 347 | int max_arg = -1; |
352 | |||
353 | #define SHOW_USAGE_IF_ERROR 1 | ||
354 | |||
355 | int spec_flgs = 0; | 348 | int spec_flgs = 0; |
356 | 349 | ||
357 | /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ | 350 | #define SHOW_USAGE_IF_ERROR 1 |
358 | argc = 1 + string_array_len(argv + 1); | ||
359 | 351 | ||
360 | on_off = complementary; | 352 | on_off = complementary; |
361 | memset(on_off, 0, sizeof(complementary)); | 353 | memset(on_off, 0, sizeof(complementary)); |
362 | 354 | ||
363 | applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts); | 355 | len = strlen(applet_opts); |
364 | 356 | ||
365 | /* skip bbox extension */ | 357 | /* skip bbox extension */ |
366 | first_char = applet_opts[0]; | 358 | opt_complementary = NULL; |
367 | if (first_char == '!') | 359 | if (applet_opts[0] == '^') { |
368 | applet_opts++; | 360 | applet_opts++; |
361 | /* point it past terminating NUL */ | ||
362 | opt_complementary = applet_opts + len; | ||
363 | } | ||
364 | |||
365 | /* skip another bbox extension */ | ||
366 | dont_die_flag = applet_opts[0]; | ||
367 | if (dont_die_flag == '!') | ||
368 | applet_opts++; | ||
369 | |||
370 | applet_opts = strcpy(alloca(len + 1), applet_opts); | ||
369 | 371 | ||
370 | /* skip GNU extension */ | 372 | /* skip GNU extension */ |
371 | s = (const unsigned char *)applet_opts; | 373 | s = (const unsigned char *)applet_opts; |
@@ -435,7 +437,8 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
435 | } | 437 | } |
436 | #endif /* ENABLE_LONG_OPTS */ | 438 | #endif /* ENABLE_LONG_OPTS */ |
437 | 439 | ||
438 | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { | 440 | s = (const unsigned char *)opt_complementary; |
441 | if (s) for (; *s; s++) { | ||
439 | t_complementary *pair; | 442 | t_complementary *pair; |
440 | unsigned *pair_switch; | 443 | unsigned *pair_switch; |
441 | 444 | ||
@@ -513,8 +516,6 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
513 | s--; | 516 | s--; |
514 | } | 517 | } |
515 | 518 | ||
516 | /* Make it unnecessary to clear it by hand after each getopt32 call */ | ||
517 | opt_complementary = NULL; | ||
518 | /* In case getopt32 was already called: | 519 | /* In case getopt32 was already called: |
519 | * reset the libc getopt() function, which keeps internal state. | 520 | * reset the libc getopt() function, which keeps internal state. |
520 | * run_nofork_applet() does this, but we might end up here | 521 | * run_nofork_applet() does this, but we might end up here |
@@ -522,6 +523,9 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
522 | */ | 523 | */ |
523 | GETOPT_RESET(); | 524 | GETOPT_RESET(); |
524 | 525 | ||
526 | /* skip 0: some applets cheat: they do not actually HAVE argv[0] */ | ||
527 | argc = 1 + string_array_len(argv + 1); | ||
528 | |||
525 | /* Note: just "getopt() <= 0" will not work well for | 529 | /* Note: just "getopt() <= 0" will not work well for |
526 | * "fake" short options, like this one: | 530 | * "fake" short options, like this one: |
527 | * wget $'-\203' "Test: test" http://kernel.org/ | 531 | * wget $'-\203' "Test: test" http://kernel.org/ |
@@ -583,7 +587,7 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
583 | return flags; | 587 | return flags; |
584 | 588 | ||
585 | error: | 589 | error: |
586 | if (first_char != '!') | 590 | if (dont_die_flag != '!') |
587 | bb_show_usage(); | 591 | bb_show_usage(); |
588 | return (int32_t)-1; | 592 | return (int32_t)-1; |
589 | } | 593 | } |