summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2012-04-22 18:10:42 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2012-04-22 18:10:42 +0000
commit5eb53bf88d3153510f0a5304e921b46419fe5721 (patch)
tree944578b22dcca9b8a6d3e1b211dfd04386ced7a6
parent19fe2dcc03d6f3c418e738061e46d0ae013c2550 (diff)
downloadzsh-5eb53bf88d3153510f0a5304e921b46419fe5721.tar.gz
zsh-5eb53bf88d3153510f0a5304e921b46419fe5721.zip
30431 with typo in _typeset fix:
add ${...:|...} and ${...:*...} operators, as documented
-rw-r--r--ChangeLog10
-rw-r--r--Completion/Zsh/Command/_typeset6
-rw-r--r--Doc/Zsh/expn.yo13
-rw-r--r--Src/params.c2
-rw-r--r--Src/subst.c43
-rw-r--r--Test/D04parameter.ztst23
6 files changed, 93 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index ea0a02f06..64d199b15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-04-22 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 30431 (typo in _typeset fixed):
+ Completion/Zsh/Command/_typeset, Doc/Zsh/expn.yo, ASrc/params.c,
+ Src/subst.c, Test/D04parameter.ztst: add ${...:|...} and
+ ${...:*...} operators for removal or inclusion of results
+ by array element.
+
2012-04-21 Barton E. Schaefer <schaefer@zsh.org>
* 30433: Src/hist.c: double backslash is not line continuation.
@@ -16223,5 +16231,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5636 $
+* $Revision: 1.5637 $
*****************************************************
diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset
index 9c9165563..d44783d64 100644
--- a/Completion/Zsh/Command/_typeset
+++ b/Completion/Zsh/Command/_typeset
@@ -75,9 +75,11 @@ if [[ "$state" = vars_eq ]]; then
if (( $+opt_args[-w] ));then
_wanted files expl 'zwc file' _files -g '*.zwc(-.)'
elif [[ $service = autoload || -n $opt_args[(i)-[uU]] ]]; then
- args=(${^fpath}/*(:t))
+ args=(${^fpath}/*(-.:t))
# Filter out functions already loaded or marked for autoload.
- args=(${args:#(${(kj.|.)~functions})})
+ local -a funckeys
+ funckeys=(${(k)functions})
+ args=(${args:|funckeys})
_wanted functions expl 'shell function' compadd -a args
else
_functions
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 25c44f331..dbbdc5073 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -604,6 +604,19 @@ If var(name) is an array
the matching array elements are removed (use the `tt((M))' flag to
remove the non-matched elements).
)
+item(tt(${)var(name)tt(:|)var(arrayname)tt(}))(
+If var(arrayname) is the name (N.B., not contents) of an array
+variable, then any elements contained in var(arrayname) are removed
+from the substitution of var(name). If the substitution is scalar,
+either because var(name) is a scalar variable or the expression is
+quoted, the elements of var(arrayname) are instead tested against the
+entire expression.
+)
+item(tt(${)var(name)tt(:*)var(arrayname)tt(}))(
+Similar to the preceding subsitution, but in the opposite sense,
+so that entries present in both the original substitution and as
+elements of var(arrayname) are retained and others removed.
+)
xitem(tt(${)var(name)tt(:)var(offset)tt(}))
item(tt(${)var(name)tt(:)var(offset)tt(:)var(length)tt(}))(
This syntax gives effects similar to parameter subscripting
diff --git a/Src/params.c b/Src/params.c
index b18fb90a6..24062e03a 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3493,7 +3493,7 @@ arrayuniq_freenode(HashNode hn)
}
/**/
-static HashTable
+HashTable
newuniqtable(zlong size)
{
HashTable ht = newhashtable((int)size, "arrayuniq", NULL);
diff --git a/Src/subst.c b/Src/subst.c
index dac536f14..82645ccfa 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2876,6 +2876,49 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
}
break;
}
+ } else if (inbrace && (*s == '|' || *s == Bar ||
+ *s == '*' || *s == Star)) {
+ int intersect = (*s == '*' || *s == Star);
+ char **compare = getaparam(++s), **ap, **apsrc;
+ if (compare) {
+ HashTable ht = newuniqtable(arrlen(compare)+1);
+ int present;
+ for (ap = compare; *ap; ap++)
+ (void)addhashnode2(ht, *ap, (HashNode)
+ zhalloc(sizeof(struct hashnode)));
+ if (!vunset && isarr) {
+ if (!copied) {
+ aval = arrdup(aval);
+ copied = 1;
+ }
+ for (ap = apsrc = aval; *apsrc; apsrc++) {
+ untokenize(*apsrc);
+ present = (gethashnode2(ht, *apsrc) != NULL);
+ if (intersect ? present : !present) {
+ if (ap != apsrc) {
+ *ap = *apsrc;
+ }
+ ap++;
+ }
+ }
+ *ap = NULL;
+ } else {
+ if (vunset) {
+ if (unset(UNSET)) {
+ *idend = '\0';
+ zerr("%s: parameter not set", idbeg);
+ deletehashtable(ht);
+ return NULL;
+ }
+ val = dupstring("");
+ } else {
+ present = (gethashnode2(ht, val) != NULL);
+ if (intersect ? !present : present)
+ val = dupstring("");
+ }
+ }
+ deletehashtable(ht);
+ }
} else { /* no ${...=...} or anything, but possible modifiers. */
/*
* Handler ${+...}. TODO: strange, why do we handle this only
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 30e4ba0ab..d5a6a403e 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -169,6 +169,29 @@
>a-string-with-slashes
>a-string-with-slashes
+ args=('one' '#foo' '(bar' "'three'" two)
+ mod=('#foo' '(bar' "'three'" sir_not_appearing_in_this_film)
+ print ${args:|mod}
+ print ${args:*mod}
+ print "${(@)args:|mod}"
+ print "${(@)args:*mod}"
+ args=(two words)
+ mod=('one word' 'two words')
+ print "${args:|mod}"
+ print "${args:*mod}"
+ scalar='two words'
+ print ${scalar:|mod}
+ print ${scalar:*mod}
+0:"|" array exclusion and "*" array intersection
+>one two
+>#foo (bar 'three'
+>one two
+>#foo (bar 'three'
+>
+>two words
+>
+>two words
+
str1='twocubed'
array=(the number of protons in an oxygen nucleus)
print $#str1 ${#str1} "$#str1 ${#str1}" $#array ${#array} "$#array ${#array}"