sh: Don't scan word twice in ${param#%##%%word}.

If word is expanded, use the found end instead of iterating over the data
again.
This commit is contained in:
Jilles Tjoelker 2017-04-02 13:29:27 +00:00
parent c422c270b5
commit e2708b1624
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=316416

View File

@ -96,7 +96,8 @@ static const char *exptilde(const char *, int);
static const char *expari(const char *, struct nodelist **restrict, int, static const char *expari(const char *, struct nodelist **restrict, int,
struct worddest *); struct worddest *);
static void expbackq(union node *, int, int, struct worddest *); static void expbackq(union node *, int, int, struct worddest *);
static void subevalvar_trim(const char *, struct nodelist *, int, int, int); static const char *subevalvar_trim(const char *, struct nodelist **restrict,
int, int, int);
static void subevalvar_misc(const char *, struct nodelist *, const char *, int, static void subevalvar_misc(const char *, struct nodelist *, const char *, int,
int, int); int, int);
static const char *evalvar(const char *, struct nodelist **restrict, int, static const char *evalvar(const char *, struct nodelist **restrict, int,
@ -540,18 +541,17 @@ recordleft(const char *str, const char *loc, char *startp)
*startp++ = *loc++; *startp++ = *loc++;
} }
static void static const char *
subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc, subevalvar_trim(const char *p, struct nodelist **restrict argbackq, int strloc,
int subtype, int startloc) int subtype, int startloc)
{ {
char *startp; char *startp;
char *loc = NULL; char *loc = NULL;
char *str; char *str;
int c = 0; int c = 0;
struct nodelist *argbackqcopy = argbackq;
int amount; int amount;
argstr(p, &argbackqcopy, EXP_CASE | EXP_TILDE, NULL); p = argstr(p, argbackq, EXP_CASE | EXP_TILDE, NULL);
STACKSTRNUL(expdest); STACKSTRNUL(expdest);
startp = stackblock() + startloc; startp = stackblock() + startloc;
str = stackblock() + strloc; str = stackblock() + strloc;
@ -564,7 +564,7 @@ subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc,
if (patmatch(str, startp)) { if (patmatch(str, startp)) {
*loc = c; *loc = c;
recordleft(str, loc, startp); recordleft(str, loc, startp);
return; return p;
} }
*loc = c; *loc = c;
} }
@ -577,7 +577,7 @@ subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc,
if (patmatch(str, startp)) { if (patmatch(str, startp)) {
*loc = c; *loc = c;
recordleft(str, loc, startp); recordleft(str, loc, startp);
return; return p;
} }
*loc = c; *loc = c;
loc--; loc--;
@ -589,7 +589,7 @@ subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc,
if (patmatch(str, loc)) { if (patmatch(str, loc)) {
amount = loc - expdest; amount = loc - expdest;
STADJUST(amount, expdest); STADJUST(amount, expdest);
return; return p;
} }
loc--; loc--;
} }
@ -600,7 +600,7 @@ subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc,
if (patmatch(str, loc)) { if (patmatch(str, loc)) {
amount = loc - expdest; amount = loc - expdest;
STADJUST(amount, expdest); STADJUST(amount, expdest);
return; return p;
} }
} }
break; break;
@ -611,6 +611,7 @@ subevalvar_trim(const char *p, struct nodelist *argbackq, int strloc,
} }
amount = (expdest - stackblock() - strloc) + 1; amount = (expdest - stackblock() - strloc) + 1;
STADJUST(-amount, expdest); STADJUST(-amount, expdest);
return p;
} }
@ -776,11 +777,11 @@ evalvar(const char *p, struct nodelist **restrict argbackq, int flag,
*/ */
STPUTC('\0', expdest); STPUTC('\0', expdest);
patloc = expdest - stackblock(); patloc = expdest - stackblock();
subevalvar_trim(p, *argbackq, patloc, subtype, startloc); p = subevalvar_trim(p, argbackq, patloc, subtype, startloc);
reprocess(startloc, flag, VSNORMAL, varflags & VSQUOTE, dst); reprocess(startloc, flag, VSNORMAL, varflags & VSQUOTE, dst);
if (flag & EXP_SPLIT && *var == '@' && varflags & VSQUOTE) if (flag & EXP_SPLIT && *var == '@' && varflags & VSQUOTE)
dst->state = WORD_QUOTEMARK; dst->state = WORD_QUOTEMARK;
break; return p;
case VSASSIGN: case VSASSIGN:
case VSQUESTION: case VSQUESTION: