bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Parsing error when "case" in "for" in $()


From: Dan Douglas
Subject: Re: Parsing error when "case" in "for" in $()
Date: Tue, 11 Sep 2012 18:01:30 -0500
User-agent: KMail/4.8.3 (Linux/3.4.6-pf+; KDE/4.8.3; x86_64; ; )

On Tuesday, September 11, 2012 05:31:36 PM Steven W. Orr wrote:
> On 09/11/12 17:20, quoth Chris F.A. Johnson:
> > On Tue, 11 Sep 2012, Benoit Vaugon wrote:
> > ...
> >> Description:
> >>  Cannot use "case" construction in a "for" loop in a $() sub shell.
> >>  Should work but produces parsing error.
> >>
> >> Repeat-By:
> >>  echo $(for x in whatever; do case y in *) echo 42;; esac; done)
> >
> >  The closing parentheses in the case statement is being interpreted as the
> >     closing for $(
> >
> >> Fix:
> >>  Probably by fixing the bash parser.
> >
> >     Balance the parentheses in the case statement:
> >
> > echo $(for x in whatever; do case y in (*) echo 42;; esac; done)
> >
> 
> Thanks. I didn't know that the opening paren was optional and was needed in 
> such a case as a disambiguator. Very nice. And if you really want to match 
> something that starts with an open paren, just backslash it.
> 
> As a style issue, it makes me wonder if I should always use the optional
> open paren as syntactic sugar...

I could only reproduce it with an unquoted command substitution. It may still 
not be correct even though there are workarounds. The existance of an 
enclosing compound command shouldn't affect the parsing of the inner one.

The workaround might be a good idea anyway. ksh fails this in some 
permutations but not others, while most other shells seem to be able to handle 
it (except zsh which usually fails). CC'd ast-devel in case they consider it a 
bug worth fixing.

: $(case . in .) :; esac)
fails: zsh

: $(case . in (.) :; esac)
fails:

: $({ case . in .) :; esac; })
fails: sh bash zsh

: "$({ case . in .) :; esac; })"
fails: zsh

: $(for x in .; do case . in .) :; esac; done)
fails: sh bash zsh ksh

: "$(for x in .; do case . in .) :; esac; done)"
fails: zsh

bash/ksh compatable testcase:
---
#!/usr/bin/env bash

shells=( sh {{b,d}a,z,{,m}k}sh bb )

while IFS= read -r testCase; do
    printf '%s\nfails: ' "$testCase"
    for sh in "${shells[@]}"; do
        "$sh" -c "$testCase" 2>/dev/null || printf '%s ' "$sh"
    done
    echo $'\n'
done <<"EOF"
: $(case . in .) :; esac)
: $(case . in (.) :; esac)
: $({ case . in .) :; esac; })
: "$({ case . in .) :; esac; })"
: $(for x in .; do case . in .) :; esac; done)
: "$(for x in .; do case . in .) :; esac; done)"
EOF

-- 
Dan Douglas

Attachment: signature.asc
Description: This is a digitally signed message part.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]