summaryrefslogtreecommitdiff
path: root/bin/ksh/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/ksh/eval.c')
-rw-r--r--bin/ksh/eval.c211
1 files changed, 100 insertions, 111 deletions
diff --git a/bin/ksh/eval.c b/bin/ksh/eval.c
index 48466f17c62..e30a5ad9546 100644
--- a/bin/ksh/eval.c
+++ b/bin/ksh/eval.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eval.c,v 1.26 2005/02/25 11:21:16 deraadt Exp $ */
+/* $OpenBSD: eval.c,v 1.27 2005/03/30 17:16:37 deraadt Exp $ */
/*
* Expansion - quoting, separation, substitution, globbing
@@ -191,28 +191,28 @@ expand(char *cp, /* input word */
Xcheck(ds, dp);
switch (type) {
- case XBASE: /* original prefixed string */
+ case XBASE: /* original prefixed string */
c = *sp++;
switch (c) {
- case EOS:
+ case EOS:
c = 0;
break;
- case CHAR:
+ case CHAR:
c = *sp++;
break;
- case QCHAR:
+ case QCHAR:
quote |= 2; /* temporary quote */
c = *sp++;
break;
- case OQUOTE:
+ case OQUOTE:
word = IFS_WORD;
tilde_ok = 0;
quote = 1;
continue;
- case CQUOTE:
+ case CQUOTE:
quote = 0;
continue;
- case COMSUB:
+ case COMSUB:
tilde_ok = 0;
if (f & DONTRUNCOMMAND) {
word = IFS_WORD;
@@ -230,7 +230,7 @@ expand(char *cp, /* input word */
newlines = 0;
}
continue;
- case EXPRSUB:
+ case EXPRSUB:
word = IFS_WORD;
tilde_ok = 0;
if (f & DONTRUNCOMMAND) {
@@ -248,7 +248,7 @@ expand(char *cp, /* input word */
v.type = 10; /* not default */
v.name[0] = '\0';
v_evaluate(&v, substitute(sp, 0),
- KSH_UNWIND_ERROR, true);
+ KSH_UNWIND_ERROR, true);
sp = strchr(sp, 0) + 1;
for (p = str_val(&v); *p; ) {
Xcheck(ds, dp);
@@ -256,13 +256,13 @@ expand(char *cp, /* input word */
}
}
continue;
- case OSUBST: /* ${{#}var{:}[=+-?#%]word} */
+ case OSUBST: /* ${{#}var{:}[=+-?#%]word} */
/* format is:
* OSUBST [{x] plain-variable-part \0
* compiled-word-part CSUBST [}x]
* This is where all syntax checking gets done...
*/
- {
+ {
char *varname = ++sp; /* skip the { or x (}) */
int stype;
int slen;
@@ -290,7 +290,7 @@ expand(char *cp, /* input word */
SubType *newst;
newst = (SubType *) alloc(
- sizeof(SubType), ATEMP);
+ sizeof(SubType), ATEMP);
newst->next = (SubType *) 0;
newst->prev = st;
st->next = newst;
@@ -305,11 +305,11 @@ expand(char *cp, /* input word */
if (stype)
sp += slen;
switch (stype & 0x7f) {
- case '#':
- case '%':
+ case '#':
+ case '%':
/* ! DOBLANK,DOBRACE_,DOTILDE */
- f = DOPAT | (f&DONTRUNCOMMAND)
- | DOTEMP_;
+ f = DOPAT | (f&DONTRUNCOMMAND) |
+ DOTEMP_;
quote = 0;
/* Prepend open pattern (so |
* in a trim will work as
@@ -318,7 +318,7 @@ expand(char *cp, /* input word */
*dp++ = MAGIC;
*dp++ = '@' + 0x80;
break;
- case '=':
+ case '=':
/* Enabling tilde expansion
* after :'s here is
* non-standard ksh, but is
@@ -341,11 +341,11 @@ expand(char *cp, /* input word */
f &= ~(DOBLANK|DOGLOB|DOBRACE_);
tilde_ok = 1;
break;
- case '?':
+ case '?':
f &= ~DOBLANK;
f |= DOTEMP_;
/* fall through */
- default:
+ default:
/* Enable tilde expansion */
tilde_ok = 1;
f |= DOTILDE;
@@ -354,8 +354,8 @@ expand(char *cp, /* input word */
/* skip word */
sp = (char *) wdscan(sp, CSUBST);
continue;
- }
- case CSUBST: /* only get here if expanding word */
+ }
+ case CSUBST: /* only get here if expanding word */
sp++; /* ({) skip the } or x */
tilde_ok = 0; /* in case of ${unset:-} */
*dp = '\0';
@@ -364,8 +364,8 @@ expand(char *cp, /* input word */
if (f&DOBLANK)
doblank--;
switch (st->stype&0x7f) {
- case '#':
- case '%':
+ case '#':
+ case '%':
/* Append end-pattern */
*dp++ = MAGIC; *dp++ = ')'; *dp = '\0';
dp = Xrestpos(ds, dp, st->base);
@@ -380,7 +380,7 @@ expand(char *cp, /* input word */
doblank++;
st = st->prev;
continue;
- case '=':
+ case '=':
/* Restore our position and substitute
* the value of st->var (may not be
* the assigned value in the presence
@@ -401,47 +401,46 @@ expand(char *cp, /* input word */
len = strlen(dp) + 1;
setstr(st->var,
debunk((char *) alloc(len, ATEMP),
- dp, len),
- KSH_UNWIND_ERROR);
+ dp, len), KSH_UNWIND_ERROR);
x.str = str_val(st->var);
type = XSUB;
if (f&DOBLANK)
doblank++;
st = st->prev;
continue;
- case '?':
+ case '?':
{
char *s = Xrestpos(ds, dp, st->base);
errorf("%s: %s", st->var->name,
dp == s ?
- "parameter null or not set"
- : (debunk(s, s, strlen(s) + 1), s));
+ "parameter null or not set" :
+ (debunk(s, s, strlen(s) + 1), s));
}
}
st = st->prev;
type = XBASE;
continue;
- case OPAT: /* open pattern: *(foo|bar) */
+ case OPAT: /* open pattern: *(foo|bar) */
/* Next char is the type of pattern */
make_magic = 1;
c = *sp++ + 0x80;
break;
- case SPAT: /* pattern separator (|) */
+ case SPAT: /* pattern separator (|) */
make_magic = 1;
c = '|';
break;
- case CPAT: /* close pattern */
+ case CPAT: /* close pattern */
make_magic = 1;
c = /*(*/ ')';
break;
}
break;
- case XNULLSUB:
+ case XNULLSUB:
/* Special case for "$@" (and "${foo[@]}") - no
* word is generated if $# is 0 (unless there is
* other stuff inside the quotes).
@@ -458,8 +457,8 @@ expand(char *cp, /* input word */
}
continue;
- case XSUB:
- case XSUBMID:
+ case XSUB:
+ case XSUBMID:
if ((c = *x.str++) == 0) {
type = XBASE;
if (f&DOBLANK)
@@ -468,10 +467,10 @@ expand(char *cp, /* input word */
}
break;
- case XARGSEP:
+ case XARGSEP:
type = XARG;
quote = 1;
- case XARG:
+ case XARG:
if ((c = *x.str++) == '\0') {
/* force null words to be created so
* set -- '' 2 ''; foo "$@" will do
@@ -499,7 +498,7 @@ expand(char *cp, /* input word */
}
break;
- case XCOM:
+ case XCOM:
if (newlines) { /* Spit out saved nl's */
c = '\n';
--newlines;
@@ -527,9 +526,8 @@ expand(char *cp, /* input word */
}
/* check for end of word or IFS separation */
- if (c == 0 || (!quote && (f & DOBLANK) && doblank && !make_magic
- && ctype(c, C_IFS)))
- {
+ if (c == 0 || (!quote && (f & DOBLANK) && doblank &&
+ !make_magic && ctype(c, C_IFS))) {
/* How words are broken up:
* | value of c
* word | ws nws 0
@@ -541,9 +539,8 @@ expand(char *cp, /* input word */
* Note that IFS_NWS/0 generates a word (at&t ksh
* doesn't do this, but POSIX does).
*/
- if (word == IFS_WORD
- || (!ctype(c, C_IFSWS) && c && word == IFS_NWS))
- {
+ if (word == IFS_WORD ||
+ (!ctype(c, C_IFSWS) && c && word == IFS_NWS)) {
char *p;
*dp++ = '\0';
@@ -552,8 +549,8 @@ expand(char *cp, /* input word */
if (fdo & DOBRACE_)
/* also does globbing */
alt_expand(wp, p, p,
- p + Xlength(ds, (dp - 1)),
- fdo | (f & DOMARKDIRS));
+ p + Xlength(ds, (dp - 1)),
+ fdo | (f & DOMARKDIRS));
else
#endif /* BRACE_EXPAND */
if (fdo & DOGLOB)
@@ -591,10 +588,10 @@ expand(char *cp, /* input word */
/* mark any special second pass chars */
if (!quote)
switch (c) {
- case '[':
- case NOT:
- case '-':
- case ']':
+ case '[':
+ case NOT:
+ case '-':
+ case ']':
/* For character classes - doesn't hurt
* to have magic !,-,]'s outside of
* [...] expressions.
@@ -606,53 +603,51 @@ expand(char *cp, /* input word */
*dp++ = MAGIC;
}
break;
- case '*':
- case '?':
+ case '*':
+ case '?':
if (f & (DOPAT | DOGLOB)) {
fdo |= DOMAGIC_ | (f & DOGLOB);
*dp++ = MAGIC;
}
break;
#ifdef BRACE_EXPAND
- case OBRACE:
- case ',':
- case CBRACE:
- if ((f & DOBRACE_) && (c == OBRACE
- || (fdo & DOBRACE_)))
- {
+ case OBRACE:
+ case ',':
+ case CBRACE:
+ if ((f & DOBRACE_) && (c == OBRACE ||
+ (fdo & DOBRACE_))) {
fdo |= DOBRACE_|DOMAGIC_;
*dp++ = MAGIC;
}
break;
#endif /* BRACE_EXPAND */
- case '=':
+ case '=':
/* Note first unquoted = for ~ */
if (!(f & DOTEMP_) && !saw_eq) {
saw_eq = 1;
tilde_ok = 1;
}
break;
- case ':': /* : */
+ case ':': /* : */
/* Note unquoted : for ~ */
if (!(f & DOTEMP_) && (f & DOASNTILDE))
tilde_ok = 1;
break;
- case '~':
+ case '~':
/* tilde_ok is reset whenever
* any of ' " $( $(( ${ } are seen.
* Note that tilde_ok must be preserved
* through the sequence ${A=a=}~
*/
- if (type == XBASE
- && (f & (DOTILDE|DOASNTILDE))
- && (tilde_ok & 2))
- {
+ if (type == XBASE &&
+ (f & (DOTILDE|DOASNTILDE)) &&
+ (tilde_ok & 2)) {
char *p, *dp_x;
dp_x = dp;
p = maybe_expand_tilde(sp,
- &ds, &dp_x,
- f & DOASNTILDE);
+ &ds, &dp_x,
+ f & DOASNTILDE);
if (p) {
if (dp != dp_x)
word = IFS_WORD;
@@ -764,9 +759,9 @@ varsub(Expand *xp, char *sp, char *word,
c = sp[0];
if (c == '*' || c == '@') {
switch (stype & 0x7f) {
- case '=': /* can't assign to a vector */
- case '%': /* can't trim a vector (yet) */
- case '#':
+ case '=': /* can't assign to a vector */
+ case '%': /* can't trim a vector (yet) */
+ case '#':
return -1;
}
if (e->loc->argc == 0) {
@@ -784,10 +779,10 @@ varsub(Expand *xp, char *sp, char *word,
XPtrV wv;
switch (stype & 0x7f) {
- case '=': /* can't assign to a vector */
- case '%': /* can't trim a vector (yet) */
- case '#':
- case '?':
+ case '=': /* can't assign to a vector */
+ case '%': /* can't trim a vector (yet) */
+ case '#':
+ case '?':
return -1;
}
XPinit(wv, 32);
@@ -810,8 +805,8 @@ varsub(Expand *xp, char *sp, char *word,
}
} else {
/* Can't assign things like $! or $1 */
- if ((stype & 0x7f) == '='
- && (ctype(*sp, C_VAR1) || digit(*sp)))
+ if ((stype & 0x7f) == '=' &&
+ (ctype(*sp, C_VAR1) || digit(*sp)))
return -1;
xp->var = global(sp);
xp->str = str_val(xp->var);
@@ -823,10 +818,10 @@ varsub(Expand *xp, char *sp, char *word,
/* test the compiler's code generator */
if (ctype(c, C_SUBOP2) ||
(((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */
- c == '=' || c == '-' || c == '?' : c == '+'))
+ c == '=' || c == '-' || c == '?' : c == '+'))
state = XBASE; /* expand word instead of variable value */
- if (Flag(FNOUNSET) && xp->str == null
- && (ctype(c, C_SUBOP2) || (state != XBASE && c != '+')))
+ if (Flag(FNOUNSET) && xp->str == null &&
+ (ctype(c, C_SUBOP2) || (state != XBASE && c != '+')))
errorf("%s: parameter not set", sp);
return state;
}
@@ -857,7 +852,7 @@ comsub(Expand *xp, char *cp)
if ((io->flag&IOTYPE) != IOREAD)
errorf("funny $() command: %s",
- snptreef((char *) 0, 32, "%R", io));
+ snptreef((char *) 0, 32, "%R", io));
shf = shf_open(name = evalstr(io->name, DOTILDE), O_RDONLY, 0,
SHF_MAPHI|SHF_CLEXEC);
if (shf == NULL)
@@ -893,7 +888,7 @@ trimsub(char *str, char *pat, int how)
char *p, c;
switch (how&0xff) { /* UCHAR_MAX maybe? */
- case '#': /* shortest at beginning */
+ case '#': /* shortest at beginning */
for (p = str; p <= end; p++) {
c = *p; *p = '\0';
if (gmatch(str, pat, false)) {
@@ -903,7 +898,7 @@ trimsub(char *str, char *pat, int how)
*p = c;
}
break;
- case '#'|0x80: /* longest match at beginning */
+ case '#'|0x80: /* longest match at beginning */
for (p = end; p >= str; p--) {
c = *p; *p = '\0';
if (gmatch(str, pat, false)) {
@@ -913,13 +908,13 @@ trimsub(char *str, char *pat, int how)
*p = c;
}
break;
- case '%': /* shortest match at end */
+ case '%': /* shortest match at end */
for (p = end; p >= str; p--) {
if (gmatch(p, pat, false))
return str_nsave(str, p - str, ATEMP);
}
break;
- case '%'|0x80: /* longest match at end */
+ case '%'|0x80: /* longest match at end */
for (p = str; p <= end; p++) {
if (gmatch(p, pat, false))
return str_nsave(str, p - str, ATEMP);
@@ -992,9 +987,8 @@ globit(XString *xs, /* dest string */
* any patterns were expanded and the markdirs option is set.
* Symlinks make things a bit tricky...
*/
- if ((check & GF_EXCHECK)
- || ((check & GF_MARKDIR) && (check & GF_GLOBBED)))
- {
+ if ((check & GF_EXCHECK) ||
+ ((check & GF_MARKDIR) && (check & GF_GLOBBED))) {
#define stat_check() (stat_done ? stat_done : \
(stat_done = stat(Xstring(*xs, xp), &statb) < 0 \
? -1 : 1))
@@ -1007,25 +1001,20 @@ globit(XString *xs, /* dest string */
* slashes from regular files (eg, /etc/passwd/).
* SunOS 4.1.3 does this...
*/
- if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp)
- && xp[-1] == '/' && !S_ISDIR(lstatb.st_mode)
- && (!S_ISLNK(lstatb.st_mode)
- || stat_check() < 0
- || !S_ISDIR(statb.st_mode))
- )
+ if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp) &&
+ xp[-1] == '/' && !S_ISDIR(lstatb.st_mode) &&
+ (!S_ISLNK(lstatb.st_mode) ||
+ stat_check() < 0 || !S_ISDIR(statb.st_mode)))
return;
/* Possibly tack on a trailing / if there isn't already
* one and if the file is a directory or a symlink to a
* directory
*/
- if (((check & GF_MARKDIR) && (check & GF_GLOBBED))
- && xp > Xstring(*xs, xp) && xp[-1] != '/'
- && (S_ISDIR(lstatb.st_mode)
- || (S_ISLNK(lstatb.st_mode)
- && stat_check() > 0
- && S_ISDIR(statb.st_mode))
- ))
- {
+ if (((check & GF_MARKDIR) && (check & GF_GLOBBED)) &&
+ xp > Xstring(*xs, xp) && xp[-1] != '/' &&
+ (S_ISDIR(lstatb.st_mode) ||
+ (S_ISLNK(lstatb.st_mode) && stat_check() > 0 &&
+ S_ISDIR(statb.st_mode)))) {
*xp++ = '/';
*xp = '\0';
}
@@ -1081,8 +1070,8 @@ globit(XString *xs, /* dest string */
if (name[0] == '.' &&
(name[1] == 0 || (name[1] == '.' && name[2] == 0)))
continue; /* always ignore . and .. */
- if ((*name == '.' && *sp != '.')
- || !gmatch(name, sp, true))
+ if ((*name == '.' && *sp != '.') ||
+ !gmatch(name, sp, true))
continue;
len = strlen(d->d_name) + 1;
@@ -1154,8 +1143,8 @@ debunk(char *dp, const char *sp, size_t dlen)
return dp;
memcpy(dp, sp, s - sp);
for (d = dp + (s - sp); *s && (d - dp < dlen); s++)
- if (!ISMAGIC(*s) || !(*++s & 0x80)
- || !strchr("*+?@! ", *s & 0x7f))
+ if (!ISMAGIC(*s) || !(*++s & 0x80) ||
+ !strchr("*+?@! ", *s & 0x7f))
*d++ = *s;
else {
/* extended pattern operators: *+?@! */
@@ -1190,7 +1179,8 @@ maybe_expand_tilde(char *p, XString *dsp, char **dpp, int isassign)
p += 2;
}
*tp = '\0';
- r = (p[0] == EOS || p[0] == CHAR || p[0] == CSUBST) ? tilde(Xstring(ts, tp)) : (char *) 0;
+ r = (p[0] == EOS || p[0] == CHAR || p[0] == CSUBST) ?
+ tilde(Xstring(ts, tp)) : (char *) 0;
Xfree(ts, tp);
if (r) {
while (*r) {
@@ -1309,9 +1299,8 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
if (ISMAGIC(*p)) {
if (*++p == OBRACE)
count++;
- else if ((*p == CBRACE && --count == 0)
- || (*p == ',' && count == 1))
- {
+ else if ((*p == CBRACE && --count == 0) ||
+ (*p == ',' && count == 1)) {
char *new;
int l1, l2, l3;
@@ -1324,7 +1313,7 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
memcpy(new + l1 + l2, brace_end, l3);
new[l1 + l2 + l3] = '\0';
alt_expand(wp, new, new + l1,
- new + l1 + l2 + l3, fdo);
+ new + l1 + l2 + l3, fdo);
field_start = p + 1;
}
}