sh: Split subevalvar() in #/##/%/%% and =/? parts.

This commit is contained in:
jilles 2015-12-29 20:51:29 +00:00
parent 905c80cf71
commit d5b4026ea6

View File

@ -101,7 +101,8 @@ static char *argstr(char *, int);
static char *exptilde(char *, int); static char *exptilde(char *, int);
static char *expari(char *); static char *expari(char *);
static void expbackq(union node *, int, int); static void expbackq(union node *, int, int);
static int subevalvar(char *, char *, int, int, int, int, int); static int subevalvar_trim(char *, int, int, int, int);
static int subevalvar_misc(char *, const char *, int, int, int);
static char *evalvar(char *, int); static char *evalvar(char *, int);
static int varisset(const char *, int); static int varisset(const char *, int);
static void strtodest(const char *, int, int, int); static void strtodest(const char *, int, int, int);
@ -521,42 +522,23 @@ recordleft(const char *str, const char *loc, char *startp)
} }
static int static int
subevalvar(char *p, char *str, int strloc, int subtype, int startloc, subevalvar_trim(char *p, int strloc, int subtype, int startloc, int quotes)
int varflags, int quotes)
{ {
char *startp; char *startp;
char *loc = NULL; char *loc = NULL;
char *q; char *q;
char *str;
int c = 0; int c = 0;
struct nodelist *saveargbackq = argbackq; struct nodelist *saveargbackq = argbackq;
int amount; int amount;
argstr(p, (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX || argstr(p, EXP_CASE | EXP_TILDE);
subtype == VSTRIMRIGHT || subtype == VSTRIMRIGHTMAX ?
EXP_CASE : 0) | EXP_TILDE);
STACKSTRNUL(expdest); STACKSTRNUL(expdest);
argbackq = saveargbackq; argbackq = saveargbackq;
startp = stackblock() + startloc; startp = stackblock() + startloc;
if (str == NULL) str = stackblock() + strloc;
str = stackblock() + strloc;
switch (subtype) { switch (subtype) {
case VSASSIGN:
setvar(str, startp, 0);
amount = startp - expdest;
STADJUST(amount, expdest);
varflags &= ~VSNUL;
return 1;
case VSQUESTION:
if (*p != CTLENDVAR) {
outfmt(out2, "%s\n", startp);
error((char *)NULL);
}
error("%.*s: parameter %snot set", (int)(p - str - 1),
str, (varflags & VSNUL) ? "null or " : "");
return 0;
case VSTRIMLEFT: case VSTRIMLEFT:
for (loc = startp; loc < str; loc++) { for (loc = startp; loc < str; loc++) {
c = *loc; c = *loc;
@ -630,6 +612,41 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc,
} }
static int
subevalvar_misc(char *p, const char *var, int subtype, int startloc,
int varflags)
{
char *startp;
struct nodelist *saveargbackq = argbackq;
int amount;
argstr(p, EXP_TILDE);
STACKSTRNUL(expdest);
argbackq = saveargbackq;
startp = stackblock() + startloc;
switch (subtype) {
case VSASSIGN:
setvar(var, startp, 0);
amount = startp - expdest;
STADJUST(amount, expdest);
return 1;
case VSQUESTION:
if (*p != CTLENDVAR) {
outfmt(out2, "%s\n", startp);
error((char *)NULL);
}
error("%.*s: parameter %snot set", (int)(p - var - 1),
var, (varflags & VSNUL) ? "null or " : "");
return 0;
default:
abort();
}
}
/* /*
* Expand a variable, and return a pointer to the next character in the * Expand a variable, and return a pointer to the next character in the
* input string. * input string.
@ -760,8 +777,8 @@ evalvar(char *p, int flag)
*/ */
STPUTC('\0', expdest); STPUTC('\0', expdest);
patloc = expdest - stackblock(); patloc = expdest - stackblock();
if (subevalvar(p, NULL, patloc, subtype, if (subevalvar_trim(p, patloc, subtype,
startloc, varflags, quotes) == 0) { startloc, quotes) == 0) {
int amount = (expdest - stackblock() - patloc) + 1; int amount = (expdest - stackblock() - patloc) + 1;
STADJUST(-amount, expdest); STADJUST(-amount, expdest);
} }
@ -773,8 +790,8 @@ evalvar(char *p, int flag)
case VSASSIGN: case VSASSIGN:
case VSQUESTION: case VSQUESTION:
if (!set) { if (!set) {
if (subevalvar(p, var, 0, subtype, startloc, varflags, if (subevalvar_misc(p, var, subtype, startloc,
quotes)) { varflags)) {
varflags &= ~VSNUL; varflags &= ~VSNUL;
/* /*
* Remove any recorded regions beyond * Remove any recorded regions beyond