zsh-workers
 help / color / mirror / code / Atom feed
* (#m) and "case" alternation
@ 2014-11-11 12:54 Stephane Chazelas
  2014-11-11 13:23 ` Mikael Magnusson
  2014-11-11 15:44 ` Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: Stephane Chazelas @ 2014-11-11 12:54 UTC (permalink / raw)
  To: Zsh hackers list

Hello.

Some unexpected behaviour:

$ case abc in ((#m)a* | b*) echo $MATCH; esac

$ case abc in ((#m)a* | (#m)b*) echo $MATCH; esac
abc
$ case abc in (a* | (#m)b*) echo $MATCH; esac
abc
$ case bcd in ((#m)a* | b*) echo $MATCH; esac
bcd


(#b) is OK:

$ case abc in (#b)(a)* | (#b)(b)*) echo $match; esac
a
$ case bcd in (#b)(a)* | (#b)(b)*) echo $match; esac
b
$ case abc in (#b)(a)* | (#b)(ab)*) echo $match; esac
a
$ case abc in (#b)(ab)* | (#b)(a)*) echo $match; esac
ab
$ case bcd in (#b)(ab)* | (b)*) echo $match; esac


Cheers,
Stephane


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: (#m) and "case" alternation
  2014-11-11 12:54 (#m) and "case" alternation Stephane Chazelas
@ 2014-11-11 13:23 ` Mikael Magnusson
  2014-11-11 15:44 ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Mikael Magnusson @ 2014-11-11 13:23 UTC (permalink / raw)
  To: Zsh hackers list

On Tue, Nov 11, 2014 at 1:54 PM, Stephane Chazelas
<stephane.chazelas@gmail.com> wrote:
> Hello.
>
> Some unexpected behaviour:
>
> $ case abc in ((#m)a* | b*) echo $MATCH; esac
>
> $ case abc in ((#m)a* | (#m)b*) echo $MATCH; esac
> abc
> $ case abc in (a* | (#m)b*) echo $MATCH; esac
> abc
> $ case bcd in ((#m)a* | b*) echo $MATCH; esac
> bcd

I don't get "bcd" output for the last of these. Also a note to people
reproducing this, make sure to unset MATCH between each command; if
you run the second one and then the first one you'll get abc output
for both.

> (#b) is OK:
>
> $ case abc in (#b)(a)* | (#b)(b)*) echo $match; esac
> a
> $ case bcd in (#b)(a)* | (#b)(b)*) echo $match; esac
> b
> $ case abc in (#b)(a)* | (#b)(ab)*) echo $match; esac
> a
> $ case abc in (#b)(ab)* | (#b)(a)*) echo $match; esac
> ab
> $ case bcd in (#b)(ab)* | (b)*) echo $match; esac

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: (#m) and "case" alternation
  2014-11-11 12:54 (#m) and "case" alternation Stephane Chazelas
  2014-11-11 13:23 ` Mikael Magnusson
@ 2014-11-11 15:44 ` Bart Schaefer
  2014-11-11 17:43   ` Stephane Chazelas
  1 sibling, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2014-11-11 15:44 UTC (permalink / raw)
  To: Stephane Chazelas, Zsh hackers list

On Nov 11, 12:54pm, Stephane Chazelas wrote:
}
} Some unexpected behaviour:
} 
} $ case abc in ((#m)a* | b*) echo $MATCH; esac

It shouldn't be unexpected, because it's documented:

m
     Set references to the match data for the entire string matched;
     this is similar to backreferencing and does not work in filename
     generation.  THE FLAG MUST BE IN EFFECT AT THE END OF THE PATTERN,
     i.e. NOT LOCAL TO A GROUP.

(all-caps mine).


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: (#m) and "case" alternation
  2014-11-11 15:44 ` Bart Schaefer
@ 2014-11-11 17:43   ` Stephane Chazelas
  2014-11-11 17:59     ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Stephane Chazelas @ 2014-11-11 17:43 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list

2014-11-11 07:44:07 -0800, Bart Schaefer:
> On Nov 11, 12:54pm, Stephane Chazelas wrote:
> }
> } Some unexpected behaviour:
> } 
> } $ case abc in ((#m)a* | b*) echo $MATCH; esac
> 
> It shouldn't be unexpected, because it's documented:
> 
> m
>      Set references to the match data for the entire string matched;
>      this is similar to backreferencing and does not work in filename
>      generation.  THE FLAG MUST BE IN EFFECT AT THE END OF THE PATTERN,
>      i.e. NOT LOCAL TO A GROUP.
> 
> (all-caps mine).

OK, but in:

case abc in (#m)a* | b*) echo $MATCH; esac

my understanding was that we've got two patterns as that's the
"|" case alternation operator, not the "|" glob operator (with
which you can't have spaces on either side)..

Now, it looks like my understanding is wrong as

$ case bcd in ((#b)(a*) | (#b)(b*)) print -l "$match[@]";;esac

bcd

(bcd is in $match[2], so the second group of a *single*
pattern).

So thanks for the clarification, you may disregard my report.

-- 
Stephane


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: (#m) and "case" alternation
  2014-11-11 17:43   ` Stephane Chazelas
@ 2014-11-11 17:59     ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2014-11-11 17:59 UTC (permalink / raw)
  To: Zsh hackers list

On Tue, 11 Nov 2014 17:43:26 +0000
Stephane Chazelas <stephane.chazelas@gmail.com> wrote:
> OK, but in:
> 
> case abc in (#m)a* | b*) echo $MATCH; esac
> 
> my understanding was that we've got two patterns as that's the
> "|" case alternation operator, not the "|" glob operator (with
> which you can't have spaces on either side)..

zsh is a bit different from other shells and the difference is a little
bit fudged --- so you and Bart are kind of both right.  We parse case
patterns separately, hence the whitespace handling, but after parsing we
weld the alternatives back together as one big group with an "or".  See
par_case() in parse.c, though that's probably not going to tell you much
further of interest.

It probably wouldn't hurt to document this.  Suggest improvements if the
following isn't clear enough...

diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo
index 4d04c24..63d90df 100644
--- a/Doc/Zsh/grammar.yo
+++ b/Doc/Zsh/grammar.yo
@@ -239,7 +239,11 @@ item(tt(case) var(word) tt(in) [ [tt(LPAR())] var(pattern) [ tt(|) var(pattern)
 Execute the var(list) associated with the first var(pattern)
 that matches var(word), if any.  The form of the patterns
 is the same as that used for filename generation.  See
-noderef(Filename Generation).
+noderef(Filename Generation).  Note further that the whole
+pattern with alternatives is treated by the shell as equivalent
+to a group of patterns within parentheses, even though in
+the tt(case) syntax whitespace may appear about the parentheses and the
+vertical bar.
 
 If the var(list) that is executed is terminated with tt(;&) rather than
 tt(;;), the following list is also executed.  The rule for

pws


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-11-11 17:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-11 12:54 (#m) and "case" alternation Stephane Chazelas
2014-11-11 13:23 ` Mikael Magnusson
2014-11-11 15:44 ` Bart Schaefer
2014-11-11 17:43   ` Stephane Chazelas
2014-11-11 17:59     ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).