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>
This commit is contained in:
parent
7f9d62d7f5
commit
727948e585
@ -1183,7 +1183,9 @@ extern const char *opt_complementary;
|
|||||||
extern const char *applet_long_options;
|
extern const char *applet_long_options;
|
||||||
#endif
|
#endif
|
||||||
extern uint32_t option_mask32;
|
extern uint32_t option_mask32;
|
||||||
extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
|
uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC;
|
||||||
|
/* For top, ps. Some argv[i] are replaced by malloced "-opt" strings */
|
||||||
|
void make_all_argv_opts(char **argv) FAST_FUNC;
|
||||||
/* BSD-derived getopt() functions require that optind be set to 1 in
|
/* BSD-derived getopt() functions require that optind be set to 1 in
|
||||||
* order to reset getopt() state. This used to be generally accepted
|
* order to reset getopt() state. This used to be generally accepted
|
||||||
* way of resetting getopt(). However, glibc's getopt()
|
* way of resetting getopt(). However, glibc's getopt()
|
||||||
|
@ -40,7 +40,6 @@ lib-y += full_write.o
|
|||||||
lib-y += get_console.o
|
lib-y += get_console.o
|
||||||
lib-y += get_last_path_component.o
|
lib-y += get_last_path_component.o
|
||||||
lib-y += get_line_from_file.o
|
lib-y += get_line_from_file.o
|
||||||
lib-y += getopt32.o
|
|
||||||
lib-y += getpty.o
|
lib-y += getpty.o
|
||||||
lib-y += get_volsize.o
|
lib-y += get_volsize.o
|
||||||
lib-y += herror_msg.o
|
lib-y += herror_msg.o
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
*
|
*
|
||||||
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
|
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
|
//kbuild:lib-y += getopt32.o
|
||||||
|
|
||||||
/* Documentation
|
/* Documentation
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
@ -170,21 +171,6 @@ const char *opt_complementary
|
|||||||
|
|
||||||
Special characters:
|
Special characters:
|
||||||
|
|
||||||
"-" A group consisting of just a dash forces all arguments
|
|
||||||
to be treated as options, even if they have no leading dashes.
|
|
||||||
Next char in this case can't be a digit (0-9), use ':' or end of line.
|
|
||||||
Example:
|
|
||||||
|
|
||||||
opt_complementary = "-:w-x:x-w"; // "-w-x:x-w" would also work,
|
|
||||||
getopt32(argv, "wx"); // but is less readable
|
|
||||||
|
|
||||||
This makes it possible to use options without a dash (./program w x)
|
|
||||||
as well as with a dash (./program -x).
|
|
||||||
|
|
||||||
NB: getopt32() will leak a small amount of memory if you use
|
|
||||||
this option! Do not use it if there is a possibility of recursive
|
|
||||||
getopt32() calls.
|
|
||||||
|
|
||||||
"--" A double dash at the beginning of opt_complementary means the
|
"--" A double dash at the beginning of opt_complementary means the
|
||||||
argv[1] string should always be treated as options, even if it isn't
|
argv[1] string should always be treated as options, even if it isn't
|
||||||
prefixed with a "-". This is useful for special syntax in applets
|
prefixed with a "-". This is useful for special syntax in applets
|
||||||
@ -373,8 +359,7 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
int max_arg = -1;
|
int max_arg = -1;
|
||||||
|
|
||||||
#define SHOW_USAGE_IF_ERROR 1
|
#define SHOW_USAGE_IF_ERROR 1
|
||||||
#define ALL_ARGV_IS_OPTS 2
|
#define FIRST_ARGV_IS_OPT 2
|
||||||
#define FIRST_ARGV_IS_OPT 4
|
|
||||||
|
|
||||||
int spec_flgs = 0;
|
int spec_flgs = 0;
|
||||||
|
|
||||||
@ -486,8 +471,7 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
spec_flgs |= FIRST_ARGV_IS_OPT;
|
spec_flgs |= FIRST_ARGV_IS_OPT;
|
||||||
s++;
|
s++;
|
||||||
} else
|
}
|
||||||
spec_flgs |= ALL_ARGV_IS_OPTS;
|
|
||||||
} else {
|
} else {
|
||||||
min_arg = c - '0';
|
min_arg = c - '0';
|
||||||
s++;
|
s++;
|
||||||
@ -551,9 +535,9 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
opt_complementary = NULL;
|
opt_complementary = NULL;
|
||||||
va_end(p);
|
va_end(p);
|
||||||
|
|
||||||
if (spec_flgs & (FIRST_ARGV_IS_OPT | ALL_ARGV_IS_OPTS)) {
|
if (spec_flgs & FIRST_ARGV_IS_OPT) {
|
||||||
pargv = argv + 1;
|
pargv = argv + 1;
|
||||||
while (*pargv) {
|
if (*pargv) {
|
||||||
if (pargv[0][0] != '-' && pargv[0][0] != '\0') {
|
if (pargv[0][0] != '-' && pargv[0][0] != '\0') {
|
||||||
/* Can't use alloca: opts with params will
|
/* Can't use alloca: opts with params will
|
||||||
* return pointers to stack!
|
* return pointers to stack!
|
||||||
@ -563,9 +547,6 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
strcpy(pp + 1, *pargv);
|
strcpy(pp + 1, *pargv);
|
||||||
*pargv = pp;
|
*pargv = pp;
|
||||||
}
|
}
|
||||||
if (!(spec_flgs & ALL_ARGV_IS_OPTS))
|
|
||||||
break;
|
|
||||||
pargv++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
libbb/getopt_allopts.c
Normal file
27
libbb/getopt_allopts.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Denys Vlasenko
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||||
|
*/
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
//kbuild:lib-y += getopt_allopts.o
|
||||||
|
|
||||||
|
void FAST_FUNC make_all_argv_opts(char **argv)
|
||||||
|
{
|
||||||
|
/* Note: we skip argv[0] */
|
||||||
|
while (*++argv) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (argv[0][0] == '-')
|
||||||
|
continue;
|
||||||
|
/* Neither top nor ps care if "" arg turns into "-" */
|
||||||
|
/*if (argv[0][0] == '\0')
|
||||||
|
continue;*/
|
||||||
|
p = xmalloc(strlen(*argv) + 2);
|
||||||
|
*p = '-';
|
||||||
|
strcpy(p + 1, *argv);
|
||||||
|
*argv = p;
|
||||||
|
}
|
||||||
|
}
|
@ -715,7 +715,8 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
# if ENABLE_FEATURE_PS_WIDE
|
# if ENABLE_FEATURE_PS_WIDE
|
||||||
/* -w is a bit complicated */
|
/* -w is a bit complicated */
|
||||||
int w_count = 0;
|
int w_count = 0;
|
||||||
opt_complementary = "-:ww";
|
make_all_argv_opts(argv);
|
||||||
|
opt_complementary = "ww";
|
||||||
opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")
|
opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")
|
||||||
"w", &w_count);
|
"w", &w_count);
|
||||||
/* if w is given once, GNU ps sets the width to 132,
|
/* 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)
|
|||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
/* -w is not supported, only -Z and/or -T */
|
/* -w is not supported, only -Z and/or -T */
|
||||||
opt_complementary = "-";
|
make_all_argv_opts(argv);
|
||||||
opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l"));
|
opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l"));
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@ -1110,15 +1110,14 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* all args are options; -n NUM */
|
/* all args are options; -n NUM */
|
||||||
opt_complementary = "-"; /* options can be specified w/o dash */
|
make_all_argv_opts(argv); /* options can be specified w/o dash */
|
||||||
col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations);
|
col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations);
|
||||||
#if ENABLE_FEATURE_TOPMEM
|
#if ENABLE_FEATURE_TOPMEM
|
||||||
if (col & OPT_m) /* -m (busybox specific) */
|
if (col & OPT_m) /* -m (busybox specific) */
|
||||||
scan_mask = TOPMEM_MASK;
|
scan_mask = TOPMEM_MASK;
|
||||||
#endif
|
#endif
|
||||||
if (col & OPT_d) {
|
if (col & OPT_d) {
|
||||||
/* work around for "-d 1" -> "-d -1" done by getopt32
|
/* work around for "-d 1" -> "-d -1" done by make_all_argv_opts() */
|
||||||
* (opt_complementary == "-" does this) */
|
|
||||||
if (str_interval[0] == '-')
|
if (str_interval[0] == '-')
|
||||||
str_interval++;
|
str_interval++;
|
||||||
/* Need to limit it to not overflow poll timeout */
|
/* Need to limit it to not overflow poll timeout */
|
||||||
|
Loading…
Reference in New Issue
Block a user