Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug report: assigning $! to an array element doesn't work



On Wed, Aug 14, 2024 at 4:06 PM Frava <fravadona@xxxxxxxxx> wrote:
>
> arr[1]=$!
> typeset -p arr
>
> output:
>
> typeset -a arr=( '$!' )

Hmm, interesting.  When doing lexical analysis of an assignment to an
array element, the ! is tokenized, so $! becomes a plain string. That
can be avoided by:

% arr[1]=($!)

The oddity results from this bit of code in lex.c (pardon possible
loss of tab stop indentation):

1390        case LX2_DASH:
1391            /*
1392             * - shouldn't be treated as a special character unless
1393             * we're in a pattern.  Unfortunately, working out for
1394             * sure in complicated expressions whether we're in a
1395             * pattern is tricky.  So we'll make it special and
1396             * turn it back any time we don't need it special.
1397             * This is not ideal as it's a lot of work.
1398             */
1399            c = Dash;
1400               break;
1401        case LX2_BANG:
1402            /*
1403             * Same logic as Dash, for ! to perform negation in range.
1404             */
1405            if (seen_brct)
1406            c = Bang;
1407            else
1408            c = '!';

The trouble is that seen_brct == 1 because of encountering the open
bracket of the array subscript.  Does anyone (*cough*PWS*cough*)
recall why we need and use seen_brct there rather than just brct ?
seen_brct was introduced for Dash in workers/37678, extended to Bang
in workers/37689, then removed from Dash in workers/40760 without
addressing Bang.  The only case where seen_brct is zero while brct
might be nonzero was introduced by workers/37705.

Changing line 1405 to

1405            if (seen_brct && brct)

still passes all "make check" tests, and fixes the assignment.

> The double-quoting doesn't work either:
> unmatched "

On the other hand that one looks like you have the BANG_HIST option set.

% unsetopt banghist
% sleep 2 &
[1] 71890
% arr[1]="$!"
[1]  + done       sleep 2
% typeset -p arr
typeset -a arr=( 71890 )
% setopt banghist
% arr[1]="$!"
dquote>

However, I can't reproduce that error with a script file even with
"zsh -o banghist", for me it "fails" only at the command line.




Messages sorted by: Reverse Date, Date, Thread, Author