diff options
author | Jared Yanovich <jaredy@cvs.openbsd.org> | 2004-11-25 04:36:48 +0000 |
---|---|---|
committer | Jared Yanovich <jaredy@cvs.openbsd.org> | 2004-11-25 04:36:48 +0000 |
commit | 87f9e0419f942c38cab6cf5f29b1b22b6d721f25 (patch) | |
tree | 40a2d7ca1977ef031cc8a67c8a7ef38795626f61 /bin/ksh/eval.c | |
parent | 8ba9ee297569629e9f753d9c85ff7051169d8fa4 (diff) |
Change the behavior of IFS word-splitting: split words
when the current character is IFS space and the last
character was a word character or it was non-white IFS
space and the current character is non-white IFS space.
This deviates from the previous behavior because the
latter splits words when the last character is any IFS
space and the current is non-white IFS, resulting in
more fields most of the time.
This new behavior follows what the man page describes;
i.e., that a field is delimited by one or more IFS
whitespace characters followed by zero or one non-white
IFS characters.
Requires addition of a new substitution expansion state
to handle the special case of empty fields at the
beginning.
testing by naddy
ok jmc, millert, otto, deraadt
Diffstat (limited to 'bin/ksh/eval.c')
-rw-r--r-- | bin/ksh/eval.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/bin/ksh/eval.c b/bin/ksh/eval.c index cf29ff9fee4..92c6e55ada9 100644 --- a/bin/ksh/eval.c +++ b/bin/ksh/eval.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eval.c,v 1.14 2003/11/10 21:26:39 millert Exp $ */ +/* $OpenBSD: eval.c,v 1.15 2004/11/25 04:36:47 jaredy Exp $ */ /* * Expansion - quoting, separation, substitution, globbing @@ -34,6 +34,7 @@ typedef struct Expand { #define XARG 3 /* expanding $*, $@ */ #define XCOM 4 /* expanding $() */ #define XNULLSUB 5 /* "$@" when $# is 0 (don't generate word) */ +#define XSUBMID 6 /* middle of expanding ${} */ /* States used for field splitting */ #define IFS_WORD 0 /* word has chars (or quotes) */ @@ -278,7 +279,7 @@ expand(cp, wp, f) /* format is: * OSUBST [{x] plain-variable-part \0 * compiled-word-part CSUBST [}x] - * This is were all syntax checking gets done... + * This is where all syntax checking gets done... */ { char *varname = ++sp; /* skip the { or x (}) */ @@ -477,6 +478,7 @@ expand(cp, wp, f) continue; case XSUB: + case XSUBMID: if ((c = *x.str++) == 0) { type = XBASE; if (f&DOBLANK) @@ -559,7 +561,7 @@ expand(cp, wp, f) * doesn't do this, but POSIX does). */ if (word == IFS_WORD - || (!ctype(c, C_IFSWS) && (c || word == IFS_NWS))) + || (!ctype(c, C_IFSWS) && c && word == IFS_NWS)) { char *p; @@ -590,6 +592,19 @@ expand(cp, wp, f) if (word != IFS_NWS) word = ctype(c, C_IFSWS) ? IFS_WS : IFS_NWS; } else { + if (type == XSUB) { + if (word == IFS_NWS && + Xlength(ds, dp) == 0) { + char *p; + + if ((p = strdup("")) == NULL) + internal_errorf(1, "unable " + "to allocate memory"); + XPput(*wp, p); + } + type = XSUBMID; + } + /* age tilde_ok info - ~ code tests second bit */ tilde_ok <<= 1; /* mark any special second pass chars */ |