diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 3 | ||||
-rw-r--r-- | Doc/Zsh/options.yo | 3 | ||||
-rw-r--r-- | Src/params.c | 10 | ||||
-rw-r--r-- | Src/zsh.h | 29 | ||||
-rw-r--r-- | Test/D04parameter.ztst | 34 |
6 files changed, 70 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog index 756ef0bdd..16e9150ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-10-09 Peter Stephenson <pws@csr.com> + + * 25831: Doc/Zsh/expn.yo, Doc/Zsh/options.yo, Src/params.c, + Src/zsh.h, Test/D04parameter.ztst: ensure failed subscript matches + of a type that are documented as strings rather than arrays + return an empty string rather than an empty array to avoid + strange RC_EXPAND_PARAM behaviour. + 2008-10-08 Peter Stephenson <pws@csr.com> * Nikolai Weibull: 25828: Completion/Unix/Command/_rm, diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index e2434431a..02b95d4f0 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -611,7 +611,8 @@ var(foo)tt(${)var(xx)tt(})var(bar), where the parameter var(xx) is set to tt(LPAR())var(a b c)tt(RPAR()), are substituted with `var(fooabar foobbar foocbar)' instead of the default -`var(fooa b cbar)'. +`var(fooa b cbar)'. Note that an empty array will therefore cause +all arguments to be removed. Internally, each such expansion is converted into the equivalent list for brace expansion. E.g., tt(${^var}) becomes diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 5c7b29cfd..e3bc27127 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -485,7 +485,8 @@ Array expansions of the form `var(foo)tt(${)var(xx)tt(})var(bar)', where the parameter var(xx) is set to tt(LPAR())var(a b c)tt(RPAR()), are substituted with `var(fooabar foobbar foocbar)' instead of the default -`var(fooa b cbar)'. +`var(fooa b cbar)'. Note that an empty array will therefore cause +all arguments to be removed. ) pindex(REMATCH_PCRE) cindex(regexp, PCRE) diff --git a/Src/params.c b/Src/params.c index 65b3ecff8..71cb2a907 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1810,11 +1810,10 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) /* Overload v->isarr as the flag bits for hashed arrays. */ v->isarr = flags | (isvarat ? SCANPM_ISVAR_AT : 0); /* If no flags were passed, we need something to represent * - * `true' yet differ from an explicit WANTVALS. This is a * - * bit of a hack, but makes some sense: When no subscript * - * is provided, all values are substituted. */ + * `true' yet differ from an explicit WANTVALS. Use a * + * special flag for this case. */ if (!v->isarr) - v->isarr = SCANPM_MATCHMANY; + v->isarr = SCANPM_ARRONLY; } v->pm = pm; v->flags = 0; @@ -2188,7 +2187,8 @@ setstrvalue(Value v, char *val) zsfree(val); return; } - if ((v->pm->node.flags & PM_HASHED) && (v->isarr & SCANPM_MATCHMANY)) { + if ((v->pm->node.flags & PM_HASHED) && + (v->isarr & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) { zerr("%s: attempt to set slice of associative array", v->pm->node.nam); zsfree(val); return; diff --git a/Src/zsh.h b/Src/zsh.h index 2ceab1dca..94d4503e4 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1532,16 +1532,25 @@ struct tieddata { #define TYPESET_OPTNUM "LRZiEF" /* Flags for extracting elements of arrays and associative arrays */ -#define SCANPM_WANTVALS (1<<0) -#define SCANPM_WANTKEYS (1<<1) -#define SCANPM_WANTINDEX (1<<2) -#define SCANPM_MATCHKEY (1<<3) -#define SCANPM_MATCHVAL (1<<4) -#define SCANPM_MATCHMANY (1<<5) -#define SCANPM_ASSIGNING (1<<6) -#define SCANPM_KEYMATCH (1<<7) -#define SCANPM_DQUOTED (1<<8) -#define SCANPM_ISVAR_AT ((-1)<<15) /* Only sign bit is significant */ +#define SCANPM_WANTVALS (1<<0) /* Return value includes hash values */ +#define SCANPM_WANTKEYS (1<<1) /* Return value includes hash keys */ +#define SCANPM_WANTINDEX (1<<2) /* Return value includes array index */ +#define SCANPM_MATCHKEY (1<<3) /* Subscript matched against key */ +#define SCANPM_MATCHVAL (1<<4) /* Subscript matched against value */ +#define SCANPM_MATCHMANY (1<<5) /* Subscript matched repeatedly, return all */ +#define SCANPM_ASSIGNING (1<<6) /* Assigning whole array/hash */ +#define SCANPM_KEYMATCH (1<<7) /* keys of hash treated as patterns */ +#define SCANPM_DQUOTED (1<<8) /* substitution was double-quoted + * (only used for testing early end of + * subscript) + */ +#define SCANPM_ARRONLY (1<<9) /* value is array but we don't + * necessarily want to match multiple + * elements + */ +#define SCANPM_ISVAR_AT ((-1)<<15) /* "$foo[@]"-style substitution + * Only sign bit is significant + */ /* * Flags for doing matches inside parameter substitutions, i.e. diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 376932b34..4cd137bbd 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1086,3 +1086,37 @@ >no >no >no + + rcexbug() { + emulate -L zsh + setopt rcexpandparam + local -A hash + local -a full empty + full=(X x) + hash=(X x) + print ORDINARY ARRAYS + : The following behaves as documented in zshoptions + print FULL expand=$full + : Empty arrays remove the adjacent argument + print EMPTY expand=$empty + print ASSOCIATIVE ARRAY + print Subscript flags returning many values + print FOUND key=$hash[(I)X] val=$hash[(R)x] + : This should behave like $empty, and does + print LOST key=$hash[(I)y] val=$hash[(R)Y] + print Subscript flags returning single values + : Doc says "substitutes ... empty string" + : so must not behave like an empty array + print STRING key=$hash[(i)y] val=$hash[(r)Y] + } + rcexbug +0:Lookup failures on elements of arrays with RC_EXPAND_PARAM +>ORDINARY ARRAYS +>FULL expand=X expand=x +>EMPTY +>ASSOCIATIVE ARRAY +>Subscript flags returning many values +>FOUND key=X val=x +>LOST +>Subscript flags returning single values +>STRING key= val= |