mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-06-11 01:36:03 +02:00
28319: (z) splitting oddities
This commit is contained in:
parent
22899d3788
commit
8aac69241f
|
@ -1,5 +1,8 @@
|
|||
2010-10-06 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 28319: Src/hist.c, Test/D04parameter.ztst: ${(z)...}
|
||||
splitting oddities and some tests for consistency.
|
||||
|
||||
* 28285: Doc/Zsh/zle.yo, Src/Zle/zle_hist.c: add
|
||||
zle-isearch-update and zle-isearch-exit hooks.
|
||||
|
||||
|
@ -13700,5 +13703,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.5094 $
|
||||
* $Revision: 1.5095 $
|
||||
*****************************************************
|
||||
|
|
106
Src/hist.c
106
Src/hist.c
|
@ -2869,6 +2869,7 @@ bufferwords(LinkList list, char *buf, int *index)
|
|||
int num = 0, cur = -1, got = 0, ne = noerrs;
|
||||
int owb = wb, owe = we, oadx = addedx, ozp = zleparse, onc = nocomments;
|
||||
int ona = noaliases, ocs = zlemetacs, oll = zlemetall;
|
||||
int forloop = 0;
|
||||
char *p, *addedspaceptr;
|
||||
|
||||
if (!list)
|
||||
|
@ -2942,25 +2943,84 @@ bufferwords(LinkList list, char *buf, int *index)
|
|||
ctxtlex();
|
||||
if (tok == ENDINPUT || tok == LEXERR)
|
||||
break;
|
||||
if (tokstr && *tokstr) {
|
||||
untokenize((p = dupstring(tokstr)));
|
||||
if (ingetptr() == addedspaceptr + 1) {
|
||||
/*
|
||||
* Whoops, we've read past the space we added, probably
|
||||
* because we were expecting a terminator but when
|
||||
* it didn't turn up we shrugged our shoulders thinking
|
||||
* it might as well be a complete string anyway.
|
||||
* So remove the space. C.f. below for the case
|
||||
* where the missing terminator caused a lex error.
|
||||
* We use the same paranoid test.
|
||||
*/
|
||||
int plen = strlen(p);
|
||||
if (plen && p[plen-1] == ' ' &&
|
||||
(plen == 1 || p[plen-2] != Meta))
|
||||
p[plen-1] = '\0';
|
||||
if (tok == FOR) {
|
||||
/*
|
||||
* The way for (( expr1 ; expr2; expr3 )) is parsed is:
|
||||
* - a FOR tok
|
||||
* - a DINPAR with no tokstr
|
||||
* - two DINPARS with tokstr's expr1, expr2.
|
||||
* - a DOUTPAR with tokstr expr3.
|
||||
*
|
||||
* We'll decrement the variable forloop as we verify
|
||||
* the various stages.
|
||||
*
|
||||
* Don't ask me, ma'am, I'm just the programmer.
|
||||
*/
|
||||
forloop = 5;
|
||||
} else {
|
||||
switch (forloop) {
|
||||
case 1:
|
||||
if (tok != DOUTPAR)
|
||||
forloop = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (tok != DINPAR)
|
||||
forloop = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* nothing to do */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tokstr) {
|
||||
switch (tok) {
|
||||
case ENVARRAY:
|
||||
p = dyncat(tokstr, "=(");
|
||||
break;
|
||||
|
||||
case DINPAR:
|
||||
if (forloop) {
|
||||
/* See above. */
|
||||
p = dyncat(tokstr, ";");
|
||||
} else {
|
||||
/*
|
||||
* Mathematical expressions analysed as a single
|
||||
* word. That's correct because it behaves like
|
||||
* double quotes. Whitespace in the middle is
|
||||
* similarly retained, so just add the parentheses back.
|
||||
*/
|
||||
p = tricat("((", tokstr, "))");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
p = dupstring(tokstr);
|
||||
break;
|
||||
}
|
||||
if (*p) {
|
||||
untokenize(p);
|
||||
if (ingetptr() == addedspaceptr + 1) {
|
||||
/*
|
||||
* Whoops, we've read past the space we added, probably
|
||||
* because we were expecting a terminator but when
|
||||
* it didn't turn up we shrugged our shoulders thinking
|
||||
* it might as well be a complete string anyway.
|
||||
* So remove the space. C.f. below for the case
|
||||
* where the missing terminator caused a lex error.
|
||||
* We use the same paranoid test.
|
||||
*/
|
||||
int plen = strlen(p);
|
||||
if (plen && p[plen-1] == ' ' &&
|
||||
(plen == 1 || p[plen-2] != Meta))
|
||||
p[plen-1] = '\0';
|
||||
}
|
||||
addlinknode(list, p);
|
||||
num++;
|
||||
}
|
||||
addlinknode(list, p);
|
||||
num++;
|
||||
} else if (buf) {
|
||||
if (IS_REDIROP(tok) && tokfd >= 0) {
|
||||
char b[20];
|
||||
|
@ -2973,6 +3033,16 @@ bufferwords(LinkList list, char *buf, int *index)
|
|||
num++;
|
||||
}
|
||||
}
|
||||
if (forloop) {
|
||||
if (forloop == 1) {
|
||||
/*
|
||||
* Final "))" of for loop to match opening,
|
||||
* since we've just added the preceding element.
|
||||
*/
|
||||
addlinknode(list, dupstring("))"));
|
||||
}
|
||||
forloop--;
|
||||
}
|
||||
if (!got && !zleparse) {
|
||||
got = 1;
|
||||
cur = num - 1;
|
||||
|
|
|
@ -389,6 +389,34 @@
|
|||
>)
|
||||
>ten( more
|
||||
|
||||
strings=(
|
||||
'foo=(1 2 3)'
|
||||
'(( 3 + 1 == 8 / 2 ))'
|
||||
'for (( i = 1 ; i < 10 ; i++ ))'
|
||||
)
|
||||
for string in $strings; do
|
||||
array=(${(z)string})
|
||||
for (( i = 1; i <= ${#array}; i++ )); do
|
||||
print -r -- "${i}:${array[i]}:"
|
||||
done
|
||||
done
|
||||
0:Some syntactical expressions that are hard to split into words with (z).
|
||||
>1:foo=(:
|
||||
>2:1:
|
||||
>3:2:
|
||||
>4:3:
|
||||
>5:):
|
||||
>1:(( 3 + 1 == 8 / 2 )):
|
||||
>1:for:
|
||||
>2:((:
|
||||
# Leading whitespace is removed, because the word proper hasn't started;
|
||||
# trailing whitespace is left because the word is terminated by the
|
||||
# semicolon or double parentheses. Bit confusing but sort of consistent.
|
||||
>3:i = 1 ;:
|
||||
>4:i < 10 ;:
|
||||
>5:i++ :
|
||||
>6:)):
|
||||
|
||||
psvar=(dog)
|
||||
setopt promptsubst
|
||||
foo='It shouldn'\''t $(happen) to a %1v.'
|
||||
|
|
Loading…
Reference in New Issue