diff --git a/eval.c b/eval.c index 3980f34..46f0d0f 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.163 2015/02/06 10:09:05 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.164 2015/02/19 22:01:13 tg Exp $"); /* * string expansion @@ -59,10 +59,11 @@ typedef struct { #define XSUBMID 6 /* middle of expanding ${} */ /* States used for field splitting */ -#define IFS_WORD 0 /* word has chars (or quotes) */ +#define IFS_WORD 0 /* word has chars (or quotes except "$@") */ #define IFS_WS 1 /* have seen IFS white-space */ #define IFS_NWS 2 /* have seen IFS non-white-space */ #define IFS_IWS 3 /* begin of word, ignore IFS WS */ +#define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */ static int varsub(Expand *, const char *, const char *, int *, int *); static int comsub(Expand *, const char *, int); @@ -290,7 +291,7 @@ expand( c = *sp++; break; case OQUOTE: - word = IFS_WORD; + word = IFS_QUOTE; tilde_ok = 0; quote = 1; continue; @@ -383,6 +384,8 @@ expand( if (f & DOBLANK) doblank++; tilde_ok = 0; + if (word == IFS_QUOTE && type != XNULLSUB) + word = IFS_WORD; if (type == XBASE) { /* expand? */ if (!st->next) { @@ -709,8 +712,14 @@ expand( if (x.str[0] != '\0') { word = IFS_IWS; type = XSUB; - } else - type = quote ? XSUB : XNULLSUB; + } else if (quote) { + word = IFS_WORD; + type = XSUB; + } else { + if (dp == Xstring(ds, dp)) + word = IFS_IWS; + type = XNULLSUB; + } if (f & DOBLANK) doblank++; st = st->prev; @@ -803,7 +812,7 @@ expand( type = XBASE; if (f & DOBLANK) { doblank--; - if (dp == Xstring(ds, dp)) + if (dp == Xstring(ds, dp) && word != IFS_WORD) word = IFS_IWS; } continue; @@ -915,7 +924,7 @@ expand( * IFS_IWS -/WS w/NWS - * (w means generate a word) */ - if ((word == IFS_WORD) || (c && + if ((word == IFS_WORD) || (word == IFS_QUOTE) || (c && (word == IFS_IWS || word == IFS_NWS) && !ctype(c, C_IFSWS))) { emit_word: