getopt: code shrink

function                                             old     new   delta
.rodata                                            99277   99290     +13
normalize                                            177     142     -35
getopt_main                                          675     622     -53
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 13/-88)            Total: -75 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2021-09-12 12:26:03 +01:00 committed by Denys Vlasenko
parent 704c596563
commit 83e20cb81c

View File

@ -156,53 +156,39 @@ enum {
static const char *normalize(const char *arg) static const char *normalize(const char *arg)
{ {
char *bufptr; char *bufptr;
#if ENABLE_FEATURE_CLEAN_UP
static char *BUFFER = NULL;
free(BUFFER);
#else
char *BUFFER; char *BUFFER;
#endif
if (!quote) { /* Just copy arg */ if (!quote) { /* Just return arg */
BUFFER = xstrdup(arg); return arg;
return BUFFER;
} }
/* Each character in arg may take up to four characters in the result: /* Each character in arg may take up to four characters in the result:
For a quote we need a closing quote, a backslash, a quote and an For a quote we need a closing quote, a backslash, a quote and an
opening quote! We need also the global opening and closing quote, opening quote! We need also the global opening and closing quote,
and one extra character for '\0'. */ and one extra character for '\0'. */
BUFFER = xmalloc(strlen(arg)*4 + 3); BUFFER = auto_string(xmalloc(strlen(arg)*4 + 3));
bufptr = BUFFER; bufptr = BUFFER;
*bufptr ++= '\''; *bufptr ++= '\'';
while (*arg) { while (*arg) {
if (*arg == '\'') { if (shell_TCSH && *arg == '\n') {
/* Quote: replace it with: '\'' */
*bufptr ++= '\'';
*bufptr ++= '\\';
*bufptr ++= '\'';
*bufptr ++= '\'';
} else if (shell_TCSH && *arg == '!') {
/* Exclamation mark: replace it with: \! */
*bufptr ++= '\'';
*bufptr ++= '\\';
*bufptr ++= '!';
*bufptr ++= '\'';
} else if (shell_TCSH && *arg == '\n') {
/* Newline: replace it with: \n */ /* Newline: replace it with: \n */
*bufptr++ = '\\'; *bufptr++ = '\\';
*bufptr++ = 'n'; *bufptr++ = 'n';
} else if (shell_TCSH && isspace(*arg)) { } else
/* Non-newline whitespace: replace it with \<ws> */ if ((shell_TCSH && (*arg == '!' || isspace(*arg)))
|| *arg == '\''
) {
/* Quote exclamation marks, non-NL whitespace and quotes */
*bufptr++ = '\''; *bufptr++ = '\'';
*bufptr++ = '\\'; *bufptr++ = '\\';
*bufptr++ = *arg; *bufptr++ = *arg;
*bufptr++ = '\''; *bufptr++ = '\'';
} else } else {
/* Just copy */ /* Just copy */
*bufptr ++= *arg; *bufptr ++= *arg;
}
arg++; arg++;
} }
*bufptr++ = '\''; *bufptr++ = '\'';
@ -327,12 +313,18 @@ static struct option *add_long_options(struct option *long_options, char *option
static void set_shell(const char *new_shell) static void set_shell(const char *new_shell)
{ {
if (strcmp(new_shell, "bash") == 0 || strcmp(new_shell, "sh") == 0) switch (index_in_strings("bash\0sh\0tcsh\0csh\0", new_shell)) {
return; case 0:
if (strcmp(new_shell, "tcsh") == 0 || strcmp(new_shell, "csh") == 0) case 1:
break;
case 2:
case 3:
option_mask32 |= SHELL_IS_TCSH; option_mask32 |= SHELL_IS_TCSH;
else break;
default:
bb_error_msg("unknown shell '%s', assuming bash", new_shell); bb_error_msg("unknown shell '%s', assuming bash", new_shell);
break;
}
} }