1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2026-01-02 08:21:09 +01:00

29313: better sh emulation with SHWORDPLIT and empty $IFS

This commit is contained in:
Bart Schaefer 2011-05-18 01:49:15 +00:00
parent 86b900ad97
commit 6699851bcb
2 changed files with 23 additions and 14 deletions

View file

@ -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 $
*****************************************************

View file

@ -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;