diff options
author | Bart Schaefer <barts@users.sourceforge.net> | 2011-05-18 01:49:15 +0000 |
---|---|---|
committer | Bart Schaefer <barts@users.sourceforge.net> | 2011-05-18 01:49:15 +0000 |
commit | 6699851bcb535f3b2eb707a91cdc1a27f65a05a2 (patch) | |
tree | d0bea1b4a73e95af5f9fe6d8d02bd83195279936 | |
parent | 86b900ad9772b26b5aaa765237760a7a170d7dec (diff) | |
download | zsh-6699851bcb535f3b2eb707a91cdc1a27f65a05a2.tar.gz zsh-6699851bcb535f3b2eb707a91cdc1a27f65a05a2.tar.xz zsh-6699851bcb535f3b2eb707a91cdc1a27f65a05a2.zip |
29313: better sh emulation with SHWORDPLIT and empty $IFS
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/subst.c | 31 |
2 files changed, 23 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog index fb0bf70ae..032691f11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-05-17 Barton E. Schaefer <schaefer@zsh.org> + * 29313: Src/subst.c: when SHWORDSPLIT is in effect, the state of + the (@) expansion flag depends on the value of $IFS so as to mimic + Bourne shell join/split behavior more closely (see users/15442). + * 29312, users/16032: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: add "zparseopts -M" which allows option descriptions to map synonymous option names onto a single name. @@ -14738,5 +14742,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5309 $ +* $Revision: 1.5310 $ ***************************************************** diff --git a/Src/subst.c b/Src/subst.c index 7838d67d9..efa3c34fc 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -1611,7 +1611,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) * This is one of the things that decides whether multsub * will produce an array, but in an extremely indirect fashion. */ - int nojoin = 0; + int nojoin = isset(SHWORDSPLIT) ? !(ifs && *ifs) : 0; /* * != 0 means ${...}, otherwise $... What works without braces * is largely a historical artefact (everything works with braces, @@ -1717,7 +1717,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) ++arrasg; break; case '@': - nojoin = 1; + nojoin = 2; /* nojoin = 2 means force */ break; case 'M': flags |= SUB_MATCH; @@ -2033,9 +2033,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) /* SH_WORD_SPLIT on or off (doubled). spbreak = 2 means force */ if ((c = *++s) == '=' || c == Equals) { spbreak = 0; + if (nojoin < 2) + nojoin = 0; s++; - } else + } else { spbreak = 2; + if (nojoin < 2) + nojoin = !(ifs && *ifs); + } } else if ((c == '#' || c == Pound) && (itype_end(s+1, IIDENT, 0) != s + 1 || (cc = s[1]) == '*' || cc == Star || cc == '@' @@ -2653,14 +2658,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) *idend = sav; copied = 1; if (isarr) { - if (nojoin) - isarr = -1; - if (qt && !getlen && isarr > 0 && !spsep && spbreak < 2) { - val = sepjoin(aval, sep, 1); - isarr = 0; - } - sep = spsep = NULL; - spbreak = 0; + if (nojoin) + isarr = -1; + if (qt && !getlen && isarr > 0 && !spsep && spbreak < 2) { + val = sepjoin(aval, sep, 1); + isarr = 0; + } + sep = spsep = NULL; + spbreak = 0; } } break; @@ -3018,7 +3023,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) /* At this point we make sure that our arrayness has affected the * arrayness of the linked list. Then, we can turn our value into * a scalar for convenience sake without affecting the arrayness - * of the resulting value. */ + * of the resulting value. ## This is the YUK chunk. ## */ if (isarr) l->list.flags |= LF_ARRAY; else @@ -3040,7 +3045,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) * done any requested splitting of the word value with quoting preserved. * "ssub" is true when we are called from singsub (via prefork): * it means that we must join arrays and should not split words. */ - if (ssub || spbreak || spsep || sep) { + if (ssub || (spbreak && isarr >= 0) || spsep || sep) { if (isarr) { val = sepjoin(aval, sep, 1); isarr = 0; |