getopt32: move support for "always treat first arg as option" to users (tar/ar)
Now getopt() never leaks (and never performs) any xmalloc's. function old new delta ar_main 522 556 +34 tar_main 986 1014 +28 getopt32 1458 1350 -108 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 62/-108) Total: -46 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
727948e585
commit
dd5a40246b
@ -240,10 +240,12 @@ int ar_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
archive_handle = init_handle();
|
archive_handle = init_handle();
|
||||||
|
|
||||||
/* --: prepend '-' to the first argument if required */
|
/* prepend '-' to the first argument if required */
|
||||||
|
if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0')
|
||||||
|
argv[1] = xasprintf("-%s", argv[1]);
|
||||||
/* -1: at least one param is reqd */
|
/* -1: at least one param is reqd */
|
||||||
/* one of p,t,x[,r] is required */
|
/* one of p,t,x[,r] is required */
|
||||||
opt_complementary = "--:-1:p:t:x"IF_FEATURE_AR_CREATE(":r");
|
opt_complementary = "-1:p:t:x"IF_FEATURE_AR_CREATE(":r");
|
||||||
opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r"));
|
opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r"));
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
@ -966,7 +966,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM;
|
tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM;
|
||||||
|
|
||||||
/* Prepend '-' to the first argument if required */
|
/* Prepend '-' to the first argument if required */
|
||||||
opt_complementary = "--:" // first arg is options
|
if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0')
|
||||||
|
argv[1] = xasprintf("-%s", argv[1]);
|
||||||
|
opt_complementary =
|
||||||
"tt:vv:" // count -t,-v
|
"tt:vv:" // count -t,-v
|
||||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
|
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
|
||||||
"\xff::" // --exclude=PATTERN is a list
|
"\xff::" // --exclude=PATTERN is a list
|
||||||
|
@ -171,16 +171,6 @@ const char *opt_complementary
|
|||||||
|
|
||||||
Special characters:
|
Special characters:
|
||||||
|
|
||||||
"--" 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
|
|
||||||
prefixed with a "-". This is useful for special syntax in applets
|
|
||||||
such as "ar" and "tar":
|
|
||||||
tar xvf foo.tar
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
"-N" A dash as the first char in a opt_complementary group followed
|
"-N" A dash as the first char in a opt_complementary group followed
|
||||||
by a single digit (0-9) means that at least N non-option
|
by a single digit (0-9) means that at least N non-option
|
||||||
arguments must be present on the command line
|
arguments must be present on the command line
|
||||||
@ -337,6 +327,8 @@ const char *applet_long_options;
|
|||||||
|
|
||||||
uint32_t option_mask32;
|
uint32_t option_mask32;
|
||||||
|
|
||||||
|
/* Please keep getopt32 free from xmalloc */
|
||||||
|
|
||||||
uint32_t FAST_FUNC
|
uint32_t FAST_FUNC
|
||||||
getopt32(char **argv, const char *applet_opts, ...)
|
getopt32(char **argv, const char *applet_opts, ...)
|
||||||
{
|
{
|
||||||
@ -354,12 +346,10 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
struct option *long_options = (struct option *) &bb_null_long_options;
|
struct option *long_options = (struct option *) &bb_null_long_options;
|
||||||
#endif
|
#endif
|
||||||
unsigned trigger;
|
unsigned trigger;
|
||||||
char **pargv;
|
|
||||||
int min_arg = 0;
|
int min_arg = 0;
|
||||||
int max_arg = -1;
|
int max_arg = -1;
|
||||||
|
|
||||||
#define SHOW_USAGE_IF_ERROR 1
|
#define SHOW_USAGE_IF_ERROR 1
|
||||||
#define FIRST_ARGV_IS_OPT 2
|
|
||||||
|
|
||||||
int spec_flgs = 0;
|
int spec_flgs = 0;
|
||||||
|
|
||||||
@ -467,12 +457,7 @@ getopt32(char **argv, const char *applet_opts, ...)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*s == '-') {
|
if (*s == '-') {
|
||||||
if (c < '0' || c > '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
if (c == '-') {
|
|
||||||
spec_flgs |= FIRST_ARGV_IS_OPT;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
min_arg = c - '0';
|
min_arg = c - '0';
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
@ -535,21 +520,6 @@ 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) {
|
|
||||||
pargv = argv + 1;
|
|
||||||
if (*pargv) {
|
|
||||||
if (pargv[0][0] != '-' && pargv[0][0] != '\0') {
|
|
||||||
/* Can't use alloca: opts with params will
|
|
||||||
* return pointers to stack!
|
|
||||||
* NB: we leak these allocations... */
|
|
||||||
char *pp = xmalloc(strlen(*pargv) + 2);
|
|
||||||
*pp = '-';
|
|
||||||
strcpy(pp + 1, *pargv);
|
|
||||||
*pargv = pp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In case getopt32 was already called:
|
/* In case getopt32 was already called:
|
||||||
* reset the libc getopt() function, which keeps internal state.
|
* reset the libc getopt() function, which keeps internal state.
|
||||||
* run_nofork_applet() does this, but we might end up here
|
* run_nofork_applet() does this, but we might end up here
|
||||||
|
Loading…
Reference in New Issue
Block a user