summaryrefslogtreecommitdiff
path: root/bin/ksh/eval.c
diff options
context:
space:
mode:
authorJared Yanovich <jaredy@cvs.openbsd.org>2004-11-25 04:36:48 +0000
committerJared Yanovich <jaredy@cvs.openbsd.org>2004-11-25 04:36:48 +0000
commit87f9e0419f942c38cab6cf5f29b1b22b6d721f25 (patch)
tree40a2d7ca1977ef031cc8a67c8a7ef38795626f61 /bin/ksh/eval.c
parent8ba9ee297569629e9f753d9c85ff7051169d8fa4 (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.c21
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 */