Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: globbing in conditional expressions
Bart Schaefer wrote on Fri, May 30, 2014 at 21:43:20 -0700:
> On May 30, 8:55am, Bart Schaefer wrote:
> }
> } Is there a non-convoluted way to have the special case of a glob with
> } BOTH of the (NY) qualifiers return empty string rather than nularg when
> } it finds no match? Empty string is an illegal file name so for most
> } purposes it wouldn't otherwise affect usage.
I beg to differ. Making *(NY) return empty strings upon no match is
(by design) convenient for the [ -n *(NY) ] case, but it breaks other
use-cases. For example,
frob *.foo(NY) *.bar(NY)
would suddenly need to handle "" files in the argument list.
For testing whether the pattern expands to anything, this is already possible:
if (){(($#@))} *(NY)
and after naming the anon func, it becomes:
if has_any_matches *(NY)
which seems to me as readable as [ -n *(NY) ]. (For that matter, we could
define a unary test operator [ --is-not-null ] that acts like -n except
that it returns False rather than True in the nularg case, and write
[ --is-not-null *(NY) ].)
Perhaps an assignment-ish syntax would be useful? Something like
if [ -n ${(X)fname:=*(NY)} ]
as shorthand for:
if _tmp=(*(NY)) && (( $#_tmp )) && fname=$_tmp[1] && [ -n $fname ]
? That way also makes the matching filename available for the if's
body. (The X stands for an expansion modifier that would make the RHS
be treated as a glob rather than as a literal string.)
Cheers,
Daniel
> This turns out to be pretty simple. It'd additionally be nice if the
> CSH_NULL_GLOB option caused any such empty strings to be removed when
> some other pattern succeeds, but that seems rather far-reaching. (The
> following will require a tweak to Daniel's test in D02glob.)
>
> diff --git a/Src/glob.c b/Src/glob.c
> index 07dd7c2..5aa306b 100644
> --- a/Src/glob.c
> +++ b/Src/glob.c
> @@ -1748,6 +1761,11 @@ zglob(LinkList list, LinkNode np, int nountok)
> matchptr++;
> matchct = 1;
> }
> + } else if (shortcircuit) {
> + /* treat as an empty string */
> + matchptr->name = dupstring("");
> + matchptr++;
> + matchct = 1;
> }
>
> if (!(gf_sortlist[0].tp & GS_NONE)) {
Messages sorted by:
Reverse Date,
Date,
Thread,
Author