mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-30 07:10:58 +02:00
37074: extend previous fix to over whitespace at end
This commit is contained in:
parent
0fcc6c8fb2
commit
e8d6041f69
3 changed files with 73 additions and 46 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2015-11-07 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 37074: Src/subst.c, Test/D04parameter.ztst: extend previous
|
||||||
|
fix to cover whitespace at end of substitution.
|
||||||
|
|
||||||
2015-11-06 Peter Stephenson <p.stephenson@samsung.com>
|
2015-11-06 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
* 37073: Src/subst.c, Test/D04parameter.ztst: fix case of
|
* 37073: Src/subst.c, Test/D04parameter.ztst: fix case of
|
||||||
|
|
50
Src/subst.c
50
Src/subst.c
|
@ -420,6 +420,22 @@ singsub(char **s)
|
||||||
DPUTS(nonempty(&foo), "BUG: singsub() produced more than one word!");
|
DPUTS(nonempty(&foo), "BUG: singsub() produced more than one word!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bit flags passed back from multsub() to paramsubst().
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* Set if the string had whitespace at the start
|
||||||
|
* that should cause word splitting against any preceeding string.
|
||||||
|
*/
|
||||||
|
WS_AT_START = 1,
|
||||||
|
/*
|
||||||
|
* Set if the string had whitespace at the end
|
||||||
|
* that should cause word splitting against any following string.
|
||||||
|
*/
|
||||||
|
WS_AT_END = 2
|
||||||
|
};
|
||||||
|
|
||||||
/* Perform substitution on a single word, *s. Unlike with singsub(), the
|
/* Perform substitution on a single word, *s. Unlike with singsub(), the
|
||||||
* result can be more than one word. If split is non-zero, the string is
|
* result can be more than one word. If split is non-zero, the string is
|
||||||
* first word-split using IFS, but only for non-quoted "whitespace" (as
|
* first word-split using IFS, but only for non-quoted "whitespace" (as
|
||||||
|
@ -432,14 +448,13 @@ singsub(char **s)
|
||||||
* NULL to use IFS). The return value is true iff the expansion resulted
|
* NULL to use IFS). The return value is true iff the expansion resulted
|
||||||
* in an empty list.
|
* in an empty list.
|
||||||
*
|
*
|
||||||
* *ws_at_start is set to 1 if the string had whitespace at thes start
|
* *ws_at_start is set to bits in the enum above as neeed.
|
||||||
* that should cause word splitting against any preceeding string.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
|
multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
|
||||||
int *ws_at_start)
|
int *ws_sub)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
char **r, **p, *x = *s;
|
char **r, **p, *x = *s;
|
||||||
|
@ -455,7 +470,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
|
||||||
l++;
|
l++;
|
||||||
if (!iwsep(STOUC(c)))
|
if (!iwsep(STOUC(c)))
|
||||||
break;
|
break;
|
||||||
*ws_at_start = 1;
|
*ws_sub |= WS_AT_START;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,8 +502,10 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
|
||||||
if (!WC_ZISTYPE(c, ISEP))
|
if (!WC_ZISTYPE(c, ISEP))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!*x)
|
if (!*x) {
|
||||||
|
*ws_sub |= WS_AT_END;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
insertlinknode(&foo, n, (void *)x), incnode(n);
|
insertlinknode(&foo, n, (void *)x), incnode(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1730,7 +1747,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
* whitespace. However, if there's no "x" the whitespace is
|
* whitespace. However, if there's no "x" the whitespace is
|
||||||
* simply removed.
|
* simply removed.
|
||||||
*/
|
*/
|
||||||
int ws_at_start = 0;
|
int ws_sub = 0;
|
||||||
|
|
||||||
*s++ = '\0';
|
*s++ = '\0';
|
||||||
/*
|
/*
|
||||||
|
@ -2280,7 +2297,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
* necessary, when we handle (P) lower down.
|
* necessary, when we handle (P) lower down.
|
||||||
*/
|
*/
|
||||||
if (multsub(&val, 0, (aspar ? NULL : &aval), &isarr, NULL,
|
if (multsub(&val, 0, (aspar ? NULL : &aval), &isarr, NULL,
|
||||||
&ws_at_start) && quoted) {
|
&ws_sub) && quoted) {
|
||||||
/* Empty quoted string --- treat as null string, not elided */
|
/* Empty quoted string --- treat as null string, not elided */
|
||||||
isarr = -1;
|
isarr = -1;
|
||||||
aval = (char **) hcalloc(sizeof(char *));
|
aval = (char **) hcalloc(sizeof(char *));
|
||||||
|
@ -2751,7 +2768,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
split_flags = PREFORK_NOSHWORDSPLIT;
|
split_flags = PREFORK_NOSHWORDSPLIT;
|
||||||
}
|
}
|
||||||
multsub(&val, split_flags, (aspar ? NULL : &aval),
|
multsub(&val, split_flags, (aspar ? NULL : &aval),
|
||||||
&isarr, NULL, &ws_at_start);
|
&isarr, NULL, &ws_sub);
|
||||||
copied = 1;
|
copied = 1;
|
||||||
spbreak = 0;
|
spbreak = 0;
|
||||||
/* Leave globsubst on if forced */
|
/* Leave globsubst on if forced */
|
||||||
|
@ -2780,14 +2797,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
* behavior on caller choice of PREFORK_SHWORDSPLIT. */
|
* behavior on caller choice of PREFORK_SHWORDSPLIT. */
|
||||||
multsub(&val,
|
multsub(&val,
|
||||||
spbreak ? PREFORK_SINGLE : PREFORK_NOSHWORDSPLIT,
|
spbreak ? PREFORK_SINGLE : PREFORK_NOSHWORDSPLIT,
|
||||||
NULL, &isarr, NULL, &ws_at_start);
|
NULL, &isarr, NULL, &ws_sub);
|
||||||
} else {
|
} else {
|
||||||
if (spbreak)
|
if (spbreak)
|
||||||
split_flags = PREFORK_SPLIT|PREFORK_SHWORDSPLIT;
|
split_flags = PREFORK_SPLIT|PREFORK_SHWORDSPLIT;
|
||||||
else
|
else
|
||||||
split_flags = PREFORK_NOSHWORDSPLIT;
|
split_flags = PREFORK_NOSHWORDSPLIT;
|
||||||
multsub(&val, split_flags, &aval, &isarr, NULL,
|
multsub(&val, split_flags, &aval, &isarr, NULL,
|
||||||
&ws_at_start);
|
&ws_sub);
|
||||||
spbreak = 0;
|
spbreak = 0;
|
||||||
}
|
}
|
||||||
if (arrasg) {
|
if (arrasg) {
|
||||||
|
@ -3319,7 +3336,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
}
|
}
|
||||||
if (haserr || errflag)
|
if (haserr || errflag)
|
||||||
return NULL;
|
return NULL;
|
||||||
ws_at_start = 0;
|
ws_sub = 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* This handles taking a length with ${#foo} and variations.
|
* This handles taking a length with ${#foo} and variations.
|
||||||
|
@ -3358,7 +3375,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
sprintf(buf, "%ld", len);
|
sprintf(buf, "%ld", len);
|
||||||
val = dupstring(buf);
|
val = dupstring(buf);
|
||||||
isarr = 0;
|
isarr = 0;
|
||||||
ws_at_start = 0;
|
ws_sub = 0;
|
||||||
}
|
}
|
||||||
/* At this point we make sure that our arrayness has affected the
|
/* At this point we make sure that our arrayness has affected the
|
||||||
* arrayness of the linked list. Then, we can turn our value into
|
* arrayness of the linked list. Then, we can turn our value into
|
||||||
|
@ -3388,7 +3405,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
if (isarr) {
|
if (isarr) {
|
||||||
val = sepjoin(aval, sep, 1);
|
val = sepjoin(aval, sep, 1);
|
||||||
isarr = 0;
|
isarr = 0;
|
||||||
ws_at_start = 0;
|
ws_sub = 0;
|
||||||
}
|
}
|
||||||
if (!ssub && (spbreak || spsep)) {
|
if (!ssub && (spbreak || spsep)) {
|
||||||
aval = sepsplit(val, spsep, 0, 1);
|
aval = sepsplit(val, spsep, 0, 1);
|
||||||
|
@ -3673,10 +3690,15 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
|
||||||
* If a multsub result had whitespace at the start and we're
|
* If a multsub result had whitespace at the start and we're
|
||||||
* splitting and there's a previous string, now's the time to do so.
|
* splitting and there's a previous string, now's the time to do so.
|
||||||
*/
|
*/
|
||||||
if (ws_at_start && aptr > ostr) {
|
if ((ws_sub & WS_AT_START) && aptr > ostr) {
|
||||||
insertlinknode(l, n, dupstrpfx(ostr, aptr - ostr)), incnode(n);
|
insertlinknode(l, n, dupstrpfx(ostr, aptr - ostr)), incnode(n);
|
||||||
ostr = aptr;
|
ostr = aptr;
|
||||||
}
|
}
|
||||||
|
/* Likewise at the end */
|
||||||
|
if ((ws_sub & WS_AT_END) && *fstr) {
|
||||||
|
insertlinknode(l, n, dupstring(fstr)); /* appended, no incnode */
|
||||||
|
*fstr = '\0';
|
||||||
|
}
|
||||||
if (isarr) {
|
if (isarr) {
|
||||||
char *x;
|
char *x;
|
||||||
char *y;
|
char *y;
|
||||||
|
|
|
@ -1751,26 +1751,26 @@
|
||||||
}
|
}
|
||||||
foo=bar
|
foo=bar
|
||||||
foo2="bar bar"
|
foo2="bar bar"
|
||||||
do_test ${:- foo}
|
do_test ${:- foo }
|
||||||
do_test ${:- foo bar}
|
do_test ${:- foo bar }
|
||||||
do_test ${:- $foo}
|
do_test ${:- $foo }
|
||||||
do_test ${:- $foo2}
|
do_test ${:- $foo2 }
|
||||||
do_test x${:- foo}
|
do_test x${:- foo }y
|
||||||
do_test x${:- foo bar}
|
do_test x${:- foo bar }y
|
||||||
do_test x${:- $foo}
|
do_test x${:- $foo }y
|
||||||
do_test x${:- $foo2}
|
do_test x${:- $foo2 }y
|
||||||
do_test x${foo:+ $foo}
|
do_test x${foo:+ $foo }y
|
||||||
)
|
)
|
||||||
0:We Love SH_WORD_SPLIT Day celebrated with space at start of internal subst
|
0:We Love SH_WORD_SPLIT Day celebrated with space at start of internal subst
|
||||||
>1: foo
|
>1: foo
|
||||||
>2: foo bar
|
>2: foo bar
|
||||||
>1: bar
|
>1: bar
|
||||||
>2: bar bar
|
>2: bar bar
|
||||||
>2: x foo
|
>3: x foo y
|
||||||
>3: x foo bar
|
>4: x foo bar y
|
||||||
>2: x bar
|
>3: x bar y
|
||||||
>3: x bar bar
|
>4: x bar bar y
|
||||||
>2: x bar
|
>3: x bar y
|
||||||
|
|
||||||
(unsetopt shwordsplit # default, for clarity
|
(unsetopt shwordsplit # default, for clarity
|
||||||
do_test() {
|
do_test() {
|
||||||
|
@ -1778,23 +1778,23 @@
|
||||||
}
|
}
|
||||||
foo=bar
|
foo=bar
|
||||||
foo2="bar bar"
|
foo2="bar bar"
|
||||||
do_test ${:- foo}
|
do_test ${:- foo }
|
||||||
do_test ${:- foo bar}
|
do_test ${:- foo bar }
|
||||||
do_test ${:- $foo}
|
do_test ${:- $foo }
|
||||||
do_test ${:- $foo2}
|
do_test ${:- $foo2 }
|
||||||
do_test x${:- foo}
|
do_test x${:- foo }y
|
||||||
do_test x${:- foo bar}
|
do_test x${:- foo bar }y
|
||||||
do_test x${:- $foo}
|
do_test x${:- $foo }y
|
||||||
do_test x${:- $foo2}
|
do_test x${:- $foo2 }y
|
||||||
do_test x${foo:+ $foo}
|
do_test x${foo:+ $foo }y
|
||||||
)
|
)
|
||||||
0:We Love NO_SH_WORD_SPLIT Even More Day celebrated as sanity check
|
0:We Love NO_SH_WORD_SPLIT Even More Day celebrated as sanity check
|
||||||
>1: foo
|
>1: foo
|
||||||
>1: foo bar
|
>1: foo bar
|
||||||
>1: bar
|
>1: bar
|
||||||
>1: bar bar
|
>1: bar bar
|
||||||
>1: x foo
|
>1: x foo y
|
||||||
>1: x foo bar
|
>1: x foo bar y
|
||||||
>1: x bar
|
>1: x bar y
|
||||||
>1: x bar bar
|
>1: x bar bar y
|
||||||
>1: x bar
|
>1: x bar y
|
||||||
|
|
Loading…
Reference in a new issue