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