zsh-workers
 help / color / Atom feed
* globbing in the repeat-count word gives "illegal character"
@ 2020-03-17  3:29 Daniel Shahaf
  2020-03-17 18:37 ` Mikael Magnusson
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Shahaf @ 2020-03-17  3:29 UTC (permalink / raw)
  To: zsh-workers

[[[
$ Src/zsh -f
% cd "$(mktemp -d)"
% repeat ? true 
zsh: bad math expression: illegal character: \M-W
% 
]]]

[[[
frame #1: 0x0000000000487eac zsh`matheval(s="\x97") at math.c:1479
   1476     x = mathevall(s, MPREC_TOP, &junk);
   1477     mtok = xmtok;
   1478     if (*junk)
-> 1479         zerr("bad math expression: illegal character: %c", *junk);
   1480     return x;
   1481 }
   1482
(lldb) p *junk
(char) $0 = '\x97'
]]]

[[[
% ag 0x97 | cat
Src/zsh.h:191:#define Quest             ((char) 0x97)
% 
]]]

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

* Re: globbing in the repeat-count word gives "illegal character"
  2020-03-17  3:29 globbing in the repeat-count word gives "illegal character" Daniel Shahaf
@ 2020-03-17 18:37 ` Mikael Magnusson
  2020-03-23  5:31   ` Daniel Shahaf
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2020-03-17 18:37 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: zsh-workers

On 3/17/20, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> [[[
> $ Src/zsh -f
> % cd "$(mktemp -d)"
> % repeat ? true
> zsh: bad math expression: illegal character: \M-W
> %
> ]]]
>
> [[[
> frame #1: 0x0000000000487eac zsh`matheval(s="\x97") at math.c:1479
>    1476     x = mathevall(s, MPREC_TOP, &junk);
>    1477     mtok = xmtok;
>    1478     if (*junk)
> -> 1479         zerr("bad math expression: illegal character: %c", *junk);
>    1480     return x;
>    1481 }
>    1482
> (lldb) p *junk
> (char) $0 = '\x97'
> ]]]
>
> [[[
> % ag 0x97 | cat
> Src/zsh.h:191:#define Quest             ((char) 0x97)
> %
> ]]]

Not limited to globbing characters,

% repeat { false
zsh: bad math expression: illegal character: \M-O


-- 
Mikael Magnusson

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

* Re: globbing in the repeat-count word gives "illegal character"
  2020-03-17 18:37 ` Mikael Magnusson
@ 2020-03-23  5:31   ` Daniel Shahaf
  2020-03-23  6:53     ` Mikael Magnusson
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Shahaf @ 2020-03-23  5:31 UTC (permalink / raw)
  To: zsh-workers

Mikael Magnusson wrote on Tue, 17 Mar 2020 19:37 +0100:
> On 3/17/20, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> > [[[
> > $ Src/zsh -f
> > % cd "$(mktemp -d)"
> > % repeat ? true
> > zsh: bad math expression: illegal character: \M-W
> > %
> > ]]]
> >
> > [[[
> > frame #1: 0x0000000000487eac zsh`matheval(s="\x97") at math.c:1479
> >    1476     x = mathevall(s, MPREC_TOP, &junk);
> >    1477     mtok = xmtok;
> >    1478     if (*junk)  
> > -> 1479         zerr("bad math expression: illegal character: %c", *junk);  
> >    1480     return x;
> >    1481 }
> >    1482
> > (lldb) p *junk
> > (char) $0 = '\x97'
> > ]]]
> >
> > [[[
> > % ag 0x97 | cat
> > Src/zsh.h:191:#define Quest             ((char) 0x97)
> > %
> > ]]]  
> 
> Not limited to globbing characters,
> 
> % repeat { false
> zsh: bad math expression: illegal character: \M-O

And what about this one? —
.
    % repeat 2*2 pwd
    zsh: bad math expression: illegal character: \M-G

What's the expected behaviour on this one?  Should it report a different
error, or perform globbing, or take «2*2» as a valid arithmetic
expression and run 4 iterations of the loop body?

Code-wise, execrepeat() calls singsub() when the "has tokens" flag is set:

   487	int
   487	execrepeat(Estate state, UNUSED(int do_exec))
   488	{
   ⋮
   500	    lastval = 0;
   501	    tmp = ecgetstr(state, EC_DUPTOK, &htok);
   502	    if (htok)
   503		singsub(&tmp);
   504	    count = mathevali(tmp);
   505	    if (errflag)
   506		return 1;

When singsub() returns, there are still tokens in the string (Quest,
Inbrace, or Star, respectively).  Is that expected, or should singsub()
have converted those tokens to their ASCII equivalents?

Is the fix just to call untokenize() after singsub()?  Some singsub()
callers do this, but some don't, and I haven't figured out the rule (if
there is one).  I tried this and it seemed to work, but…

Cheers,

Daniel

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

* Re: globbing in the repeat-count word gives "illegal character"
  2020-03-23  5:31   ` Daniel Shahaf
@ 2020-03-23  6:53     ` Mikael Magnusson
  2020-03-25 21:09       ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2020-03-23  6:53 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: zsh-workers

On 3/23/20, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> Mikael Magnusson wrote on Tue, 17 Mar 2020 19:37 +0100:
>> On 3/17/20, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>> > [[[
>> > $ Src/zsh -f
>> > % cd "$(mktemp -d)"
>> > % repeat ? true
>> > zsh: bad math expression: illegal character: \M-W
>> > %
>> > ]]]
>> >
>> > [[[
>> > frame #1: 0x0000000000487eac zsh`matheval(s="\x97") at math.c:1479
>> >    1476     x = mathevall(s, MPREC_TOP, &junk);
>> >    1477     mtok = xmtok;
>> >    1478     if (*junk)
>> > -> 1479         zerr("bad math expression: illegal character: %c",
>> > *junk);
>> >    1480     return x;
>> >    1481 }
>> >    1482
>> > (lldb) p *junk
>> > (char) $0 = '\x97'
>> > ]]]
>> >
>> > [[[
>> > % ag 0x97 | cat
>> > Src/zsh.h:191:#define Quest             ((char) 0x97)
>> > %
>> > ]]]
>>
>> Not limited to globbing characters,
>>
>> % repeat { false
>> zsh: bad math expression: illegal character: \M-O
>
> And what about this one? —
> .
>     % repeat 2*2 pwd
>     zsh: bad math expression: illegal character: \M-G
>
> What's the expected behaviour on this one?  Should it report a different
> error, or perform globbing, or take «2*2» as a valid arithmetic
> expression and run 4 iterations of the loop body?

Same as for return, I feel, ie,

% () { return 2*2 }
(anon): no matches found: 2*2
% () { return 2\*2 }; echo $?
4

But if, due to hysterical raisins, globbing never runs for repeat
here, I guess we may as well just have it do arithmetic unquoted
there... but#2 it's probably confusing wrt spaces around the * in that
case... So yeah, I guess I'm not too sure :).

My brain isn't in zsh-code-mode so I can't comment on the rest...

> Code-wise, execrepeat() calls singsub() when the "has tokens" flag is set:
>
>    487	int
>    487	execrepeat(Estate state, UNUSED(int do_exec))
>    488	{
>    ⋮
>    500	    lastval = 0;
>    501	    tmp = ecgetstr(state, EC_DUPTOK, &htok);
>    502	    if (htok)
>    503		singsub(&tmp);
>    504	    count = mathevali(tmp);
>    505	    if (errflag)
>    506		return 1;
>
> When singsub() returns, there are still tokens in the string (Quest,
> Inbrace, or Star, respectively).  Is that expected, or should singsub()
> have converted those tokens to their ASCII equivalents?
>
> Is the fix just to call untokenize() after singsub()?  Some singsub()
> callers do this, but some don't, and I haven't figured out the rule (if
> there is one).  I tried this and it seemed to work, but…
>
> Cheers,
>
> Daniel
>


-- 
Mikael Magnusson

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

* Re: globbing in the repeat-count word gives "illegal character"
  2020-03-23  6:53     ` Mikael Magnusson
@ 2020-03-25 21:09       ` Peter Stephenson
       [not found]         ` <20200325234655.786e8a88@tarpaulin.shahaf.local2>
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 2020-03-25 21:09 UTC (permalink / raw)
  To: zsh-workers

This is straightforward.  There is no reason to propagate tokens.

diff --git a/Src/loop.c b/Src/loop.c
index 95ef48b33..f13c8c4a9 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -499,8 +499,10 @@ execrepeat(Estate state, UNUSED(int do_exec))
 
     lastval = 0;
     tmp = ecgetstr(state, EC_DUPTOK, &htok);
-    if (htok)
+    if (htok) {
 	singsub(&tmp);
+	untokenize(tmp);
+    }
     count = mathevali(tmp);
     if (errflag)
 	return 1;
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 0dbf468f6..cefa1c974 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -557,6 +557,14 @@
 >Hip hip hooray
 >Hip hip hooray
 
+  (setopt nonomatch
+  repeat 2*2 print yeah)
+0:Tokens in repeat argument
+>yeah
+>yeah
+>yeah
+>yeah
+
   case bravo {
     (alpha) print schmalpha
 	    ;;


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

* Re: globbing in the repeat-count word gives "illegal character"
       [not found]         ` <20200325234655.786e8a88@tarpaulin.shahaf.local2>
@ 2020-03-26 20:58           ` Peter Stephenson
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Stephenson @ 2020-03-26 20:58 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 2020-03-25 at 23:46 +0000, Daniel Shahaf wrote:
> Peter Stephenson wrote on Wed, 25 Mar 2020 21:09 +0000:
> > This is straightforward.  There is no reason to propagate tokens.
> > 
> > +++ b/Test/A01grammar.ztst
> > @@ -557,6 +557,14 @@
> > +  (setopt nonomatch
> > +  repeat 2*2 print yeah)
> > +0:Tokens in repeat argument
> > +>yeah
> > +>yeah
> > +>yeah
> > +>yeah  
> > +
> 
> By the way, it behaves the same way under `setopt nomatch` too.  I.e.,
> the repeat count word doesn't undergo globbing.

Right, it's a single word substitution, so I removed the option.

cheers
pws


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

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-17  3:29 globbing in the repeat-count word gives "illegal character" Daniel Shahaf
2020-03-17 18:37 ` Mikael Magnusson
2020-03-23  5:31   ` Daniel Shahaf
2020-03-23  6:53     ` Mikael Magnusson
2020-03-25 21:09       ` Peter Stephenson
     [not found]         ` <20200325234655.786e8a88@tarpaulin.shahaf.local2>
2020-03-26 20:58           ` Peter Stephenson

zsh-workers

Archives are clonable: git clone --mirror http://inbox.vuxu.org/zsh-workers

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git