ash: code shrink around varvalue

Based on commit c989d72 from git://git.kernel.org/pub/scm/utils/dash/dash.git
by Herbert Xu

function                                             old     new   delta
strtodest                                              -      40     +40
memtodest                                            123     147     +24
parse_command                                       1443    1440      -3
readtoken1                                          3205    3199      -6
argstr                                              1203    1180     -23
varvalue                                             788     660    -128
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/4 up/down: 64/-160)           Total: -96 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 2015-05-18 09:49:28 +02:00 committed by Denys Vlasenko
parent e0a4e107aa
commit d68d1fbd6c

View File

@ -5539,6 +5539,11 @@ ash_arith(const char *s)
#define RMESCAPE_GROW 0x8 /* Grow strings instead of stalloc */ #define RMESCAPE_GROW 0x8 /* Grow strings instead of stalloc */
#define RMESCAPE_HEAP 0x10 /* Malloc strings instead of stalloc */ #define RMESCAPE_HEAP 0x10 /* Malloc strings instead of stalloc */
/* Add CTLESC when necessary. */
#define QUOTES_ESC (EXP_FULL | EXP_CASE | EXP_REDIR)
/* Do not skip NUL characters. */
#define QUOTES_KEEPNUL EXP_TILDE
/* /*
* Structure specifying which parts of the string should be searched * Structure specifying which parts of the string should be searched
* for IFS characters. * for IFS characters.
@ -5695,29 +5700,34 @@ preglob(const char *pattern, int quoted, int flag)
static void static void
memtodest(const char *p, size_t len, int syntax, int quotes) memtodest(const char *p, size_t len, int syntax, int quotes)
{ {
char *q = expdest; char *q;
q = makestrspace(quotes ? len * 2 : len, q); if (!len)
return;
while (len--) { q = makestrspace((quotes & QUOTES_ESC) ? len * 2 : len, expdest);
do {
unsigned char c = *p++; unsigned char c = *p++;
if (c == '\0') if (c) {
continue;
if (quotes) {
int n = SIT(c, syntax); int n = SIT(c, syntax);
if (n == CCTL || n == CBACK) if ((quotes & QUOTES_ESC) &&
(n == CCTL || n == CBACK))
USTPUTC(CTLESC, q); USTPUTC(CTLESC, q);
} } else if (!(quotes & QUOTES_KEEPNUL))
continue;
USTPUTC(c, q); USTPUTC(c, q);
} } while (--len);
expdest = q; expdest = q;
} }
static void static size_t
strtodest(const char *p, int syntax, int quotes) strtodest(const char *p, int syntax, int quotes)
{ {
memtodest(p, strlen(p), syntax, quotes); size_t len = strlen(p);
memtodest(p, len, syntax, quotes);
return len;
} }
/* /*
@ -5790,7 +5800,7 @@ exptilde(char *startp, char *p, int flags)
char *name; char *name;
struct passwd *pw; struct passwd *pw;
const char *home; const char *home;
int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); int quotes = flags & QUOTES_ESC;
name = p + 1; name = p + 1;
@ -6043,7 +6053,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
'\0' '\0'
}; };
const char *reject = spclchars; const char *reject = spclchars;
int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */ int quotes = flags & QUOTES_ESC;
int breakall = flags & EXP_WORD; int breakall = flags & EXP_WORD;
int inquotes; int inquotes;
size_t length; size_t length;
@ -6608,13 +6618,16 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
const char *p; const char *p;
int num; int num;
int i; int i;
int sepq = 0;
ssize_t len = 0; ssize_t len = 0;
int subtype = varflags & VSTYPE; int sep;
int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quoted = varflags & VSQUOTE; int quoted = varflags & VSQUOTE;
int subtype = varflags & VSTYPE;
int discard = subtype == VSPLUS || subtype == VSLENGTH;
int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
int syntax = quoted ? DQSYNTAX : BASESYNTAX; int syntax = quoted ? DQSYNTAX : BASESYNTAX;
sep = quoted ? ((flags & EXP_FULL) << CHAR_BIT) : 0;
switch (*name) { switch (*name) {
case '$': case '$':
num = rootpid; num = rootpid;
@ -6649,7 +6662,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
break; break;
case '@': { case '@': {
char **ap; char **ap;
int sep; char sepc;
if (quoted && (flags & EXP_FULL)) { if (quoted && (flags & EXP_FULL)) {
/* note: this is not meant as PEOF value */ /* note: this is not meant as PEOF value */
@ -6659,39 +6672,20 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
/* fall through */ /* fall through */
case '*': case '*':
sep = ifsset() ? (unsigned char)(ifsval()[0]) : ' '; sep = ifsset() ? (unsigned char)(ifsval()[0]) : ' ';
i = SIT(sep, syntax);
if (quotes && (i == CCTL || i == CBACK))
sepq = 1;
param: param:
ap = shellparam.p; ap = shellparam.p;
sepc = sep;
if (!ap) if (!ap)
return -1; return -1;
while ((p = *ap++) != NULL) { while ((p = *ap++) != NULL) {
size_t partlen; len += strtodest(p, syntax, quotes);
partlen = strlen(p);
len += partlen;
if (!(subtype == VSPLUS || subtype == VSLENGTH))
memtodest(p, partlen, syntax, quotes);
if (*ap && sep) { if (*ap && sep) {
char *q;
len++; len++;
if (subtype == VSPLUS || subtype == VSLENGTH) { memtodest(&sepc, 1, syntax, quotes);
continue;
}
q = expdest;
if (sepq)
STPUTC(CTLESC, q);
/* note: may put NUL despite sep != 0
* (see sep = 1 << CHAR_BIT above) */
STPUTC(sep, q);
expdest = q;
} }
} }
return len; break;
} /* case '@' and '*' */ } /* case '@' and '*' */
case '0': case '0':
case '1': case '1':
@ -6740,9 +6734,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
if (!p) if (!p)
return -1; return -1;
len = strlen(p); len = strtodest(p, syntax, quotes);
if (!(subtype == VSPLUS || subtype == VSLENGTH))
memtodest(p, len, syntax, quotes);
#if ENABLE_UNICODE_SUPPORT #if ENABLE_UNICODE_SUPPORT
if (subtype == VSLENGTH && len > 0) { if (subtype == VSLENGTH && len > 0) {
reinit_unicode_for_ash(); reinit_unicode_for_ash();
@ -6751,10 +6743,10 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
} }
} }
#endif #endif
return len; break;
} }
if (subtype == VSPLUS || subtype == VSLENGTH) if (discard)
STADJUST(-len, expdest); STADJUST(-len, expdest);
return len; return len;
} }
@ -6870,7 +6862,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
patloc = expdest - (char *)stackblock(); patloc = expdest - (char *)stackblock();
if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
startloc, varflags, startloc, varflags,
/* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR), /* quotes: */ flags & QUOTES_ESC,
var_str_list) var_str_list)
) { ) {
int amount = expdest - ( int amount = expdest - (