aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-04 16:23:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-04 16:33:23 +0200
commit727948e585cb133c32c8d42570e5524c58190307 (patch)
treef2beb48ded47f9d8ebef707516e7bbb00335b1a8
parent7f9d62d7f5b67b6b1cc7e0b94826ba2a6e193586 (diff)
downloadbusybox-w32-727948e585cb133c32c8d42570e5524c58190307.tar.gz
busybox-w32-727948e585cb133c32c8d42570e5524c58190307.tar.bz2
busybox-w32-727948e585cb133c32c8d42570e5524c58190307.zip
getopt32: factor out code to treat all args as options
Working towards making getopt32() xmalloc-free function old new delta make_all_argv_opts - 58 +58 top_main 914 912 -2 getopt32 1517 1458 -59 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/2 up/down: 58/-61) Total: -3 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/Kbuild.src1
-rw-r--r--libbb/getopt32.c31
-rw-r--r--libbb/getopt_allopts.c27
-rw-r--r--procps/ps.c5
-rw-r--r--procps/top.c5
6 files changed, 41 insertions, 32 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 46180c5aa..bb27c59a1 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1183,7 +1183,9 @@ extern const char *opt_complementary;
1183extern const char *applet_long_options; 1183extern const char *applet_long_options;
1184#endif 1184#endif
1185extern uint32_t option_mask32; 1185extern uint32_t option_mask32;
1186extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; 1186uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
1187/* For top, ps. Some argv[i] are replaced by malloced "-opt" strings */
1188void make_all_argv_opts(char **argv) FAST_FUNC;
1187/* BSD-derived getopt() functions require that optind be set to 1 in 1189/* BSD-derived getopt() functions require that optind be set to 1 in
1188 * order to reset getopt() state. This used to be generally accepted 1190 * order to reset getopt() state. This used to be generally accepted
1189 * way of resetting getopt(). However, glibc's getopt() 1191 * way of resetting getopt(). However, glibc's getopt()
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 458973f17..73201a6bd 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -40,7 +40,6 @@ lib-y += full_write.o
40lib-y += get_console.o 40lib-y += get_console.o
41lib-y += get_last_path_component.o 41lib-y += get_last_path_component.o
42lib-y += get_line_from_file.o 42lib-y += get_line_from_file.o
43lib-y += getopt32.o
44lib-y += getpty.o 43lib-y += getpty.o
45lib-y += get_volsize.o 44lib-y += get_volsize.o
46lib-y += herror_msg.o 45lib-y += herror_msg.o
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 80f4cc060..129840cea 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -6,12 +6,13 @@
6 * 6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */ 8 */
9
10#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG 9#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
11# include <getopt.h> 10# include <getopt.h>
12#endif 11#endif
13#include "libbb.h" 12#include "libbb.h"
14 13
14//kbuild:lib-y += getopt32.o
15
15/* Documentation 16/* Documentation
16 17
17uint32_t 18uint32_t
@@ -170,21 +171,6 @@ const char *opt_complementary
170 171
171Special characters: 172Special characters:
172 173
173 "-" A group consisting of just a dash forces all arguments
174 to be treated as options, even if they have no leading dashes.
175 Next char in this case can't be a digit (0-9), use ':' or end of line.
176 Example:
177
178 opt_complementary = "-:w-x:x-w"; // "-w-x:x-w" would also work,
179 getopt32(argv, "wx"); // but is less readable
180
181 This makes it possible to use options without a dash (./program w x)
182 as well as with a dash (./program -x).
183
184 NB: getopt32() will leak a small amount of memory if you use
185 this option! Do not use it if there is a possibility of recursive
186 getopt32() calls.
187
188 "--" A double dash at the beginning of opt_complementary means the 174 "--" A double dash at the beginning of opt_complementary means the
189 argv[1] string should always be treated as options, even if it isn't 175 argv[1] string should always be treated as options, even if it isn't
190 prefixed with a "-". This is useful for special syntax in applets 176 prefixed with a "-". This is useful for special syntax in applets
@@ -373,8 +359,7 @@ getopt32(char **argv, const char *applet_opts, ...)
373 int max_arg = -1; 359 int max_arg = -1;
374 360
375#define SHOW_USAGE_IF_ERROR 1 361#define SHOW_USAGE_IF_ERROR 1
376#define ALL_ARGV_IS_OPTS 2 362#define FIRST_ARGV_IS_OPT 2
377#define FIRST_ARGV_IS_OPT 4
378 363
379 int spec_flgs = 0; 364 int spec_flgs = 0;
380 365
@@ -486,8 +471,7 @@ getopt32(char **argv, const char *applet_opts, ...)
486 if (c == '-') { 471 if (c == '-') {
487 spec_flgs |= FIRST_ARGV_IS_OPT; 472 spec_flgs |= FIRST_ARGV_IS_OPT;
488 s++; 473 s++;
489 } else 474 }
490 spec_flgs |= ALL_ARGV_IS_OPTS;
491 } else { 475 } else {
492 min_arg = c - '0'; 476 min_arg = c - '0';
493 s++; 477 s++;
@@ -551,9 +535,9 @@ getopt32(char **argv, const char *applet_opts, ...)
551 opt_complementary = NULL; 535 opt_complementary = NULL;
552 va_end(p); 536 va_end(p);
553 537
554 if (spec_flgs & (FIRST_ARGV_IS_OPT | ALL_ARGV_IS_OPTS)) { 538 if (spec_flgs & FIRST_ARGV_IS_OPT) {
555 pargv = argv + 1; 539 pargv = argv + 1;
556 while (*pargv) { 540 if (*pargv) {
557 if (pargv[0][0] != '-' && pargv[0][0] != '\0') { 541 if (pargv[0][0] != '-' && pargv[0][0] != '\0') {
558 /* Can't use alloca: opts with params will 542 /* Can't use alloca: opts with params will
559 * return pointers to stack! 543 * return pointers to stack!
@@ -563,9 +547,6 @@ getopt32(char **argv, const char *applet_opts, ...)
563 strcpy(pp + 1, *pargv); 547 strcpy(pp + 1, *pargv);
564 *pargv = pp; 548 *pargv = pp;
565 } 549 }
566 if (!(spec_flgs & ALL_ARGV_IS_OPTS))
567 break;
568 pargv++;
569 } 550 }
570 } 551 }
571 552
diff --git a/libbb/getopt_allopts.c b/libbb/getopt_allopts.c
new file mode 100644
index 000000000..a67d2b70e
--- /dev/null
+++ b/libbb/getopt_allopts.c
@@ -0,0 +1,27 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2017 Denys Vlasenko
4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
6 */
7#include "libbb.h"
8
9//kbuild:lib-y += getopt_allopts.o
10
11void FAST_FUNC make_all_argv_opts(char **argv)
12{
13 /* Note: we skip argv[0] */
14 while (*++argv) {
15 char *p;
16
17 if (argv[0][0] == '-')
18 continue;
19 /* Neither top nor ps care if "" arg turns into "-" */
20 /*if (argv[0][0] == '\0')
21 continue;*/
22 p = xmalloc(strlen(*argv) + 2);
23 *p = '-';
24 strcpy(p + 1, *argv);
25 *argv = p;
26 }
27}
diff --git a/procps/ps.c b/procps/ps.c
index eb1946d27..081479b33 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -715,7 +715,8 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
715# if ENABLE_FEATURE_PS_WIDE 715# if ENABLE_FEATURE_PS_WIDE
716 /* -w is a bit complicated */ 716 /* -w is a bit complicated */
717 int w_count = 0; 717 int w_count = 0;
718 opt_complementary = "-:ww"; 718 make_all_argv_opts(argv);
719 opt_complementary = "ww";
719 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") 720 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")
720 "w", &w_count); 721 "w", &w_count);
721 /* if w is given once, GNU ps sets the width to 132, 722 /* if w is given once, GNU ps sets the width to 132,
@@ -731,7 +732,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
731 } 732 }
732# else 733# else
733 /* -w is not supported, only -Z and/or -T */ 734 /* -w is not supported, only -Z and/or -T */
734 opt_complementary = "-"; 735 make_all_argv_opts(argv);
735 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); 736 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l"));
736# endif 737# endif
737 738
diff --git a/procps/top.c b/procps/top.c
index 015d1ab74..1bc432fc9 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -1110,15 +1110,14 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1110#endif 1110#endif
1111 1111
1112 /* all args are options; -n NUM */ 1112 /* all args are options; -n NUM */
1113 opt_complementary = "-"; /* options can be specified w/o dash */ 1113 make_all_argv_opts(argv); /* options can be specified w/o dash */
1114 col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); 1114 col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations);
1115#if ENABLE_FEATURE_TOPMEM 1115#if ENABLE_FEATURE_TOPMEM
1116 if (col & OPT_m) /* -m (busybox specific) */ 1116 if (col & OPT_m) /* -m (busybox specific) */
1117 scan_mask = TOPMEM_MASK; 1117 scan_mask = TOPMEM_MASK;
1118#endif 1118#endif
1119 if (col & OPT_d) { 1119 if (col & OPT_d) {
1120 /* work around for "-d 1" -> "-d -1" done by getopt32 1120 /* work around for "-d 1" -> "-d -1" done by make_all_argv_opts() */
1121 * (opt_complementary == "-" does this) */
1122 if (str_interval[0] == '-') 1121 if (str_interval[0] == '-')
1123 str_interval++; 1122 str_interval++;
1124 /* Need to limit it to not overflow poll timeout */ 1123 /* Need to limit it to not overflow poll timeout */