On 6/17/20 1:22 PM, Rob Landley wrote:
> Trying to figure out when spaces are and aren't allowed in ${blah} led to 
> asking
> why echo ${!a* } is an error but ${!a@ } isn't (when there are no variables
> starting with a), and I eventually worked out that:
> 
>   $ X=PWD
>   $ echo ${!X@Q}
>   '/home/landley/toybox/clean'
> 
> Is going on? 

It's variable transformation. It's introduced by `@' and uses single-letter
operators. I cribbed the idea from mksh and extended it. The syntax is kind
of loose because I'm still experimenting with it.

Which is just weird, both because:
> 
>   $ echo ${PATH@ }
>   bash: ${PATH@ }: bad substitution
> 
> And because:
> 
>   $ ABC=defghi; echo ${#ABC@Q}
>   bash: ${#ABC@Q}: bad substitution

The #variable is the entire expansion, not the `parameter' part of an
expansion.

>   $ echo ${PWD:1:3@Q}
>   bash: PWD: 3@Q: value too great for base (error token is "3@Q")
>   $ echo ${PWD:1@Q}
>   bash: PWD: 1@Q: value too great for base (error token is "1@Q")

What's wrong with that? `@' and `Q' are valid characters in numeric
constants when the base is large enough to need them. You can use
bases up to 64 in base#constant.
> 
> Hmmm...
> 
>   $ echo ${!potato@walrus}
> 
>   $ echo ${!P@walrus}

Invalid transformations just expand to nothing rather than being errors.
That's part of what I'm still experimenting with.

>   $ echo ${!P@}
>   PATH PIPESTATUS PPID PS1 PS2 PS4 PWD

Yep, variable transformation isn't in effect when the expansion ends with
the `@'.

> 
>   $ X=PATH
>   $ echo ${!X@ }
>   bash: ${!X@ }: bad substitution
> 
>   $ ABC=123
>   $ echo ${!A@walrus}
> 
>   $ echo ${!ABC@}
>   ABC
>   $ echo ${!ABC@walrus}
> 
>   $ echo ${!A@ }
> 
> Ok, when X exists and points to another variable, then !X becomes the contents
> of that other variable and THEN the @ cares about trailing garbage. But * is a
> different codepath from @...?

It's a different expansion.

> 
> And when the ${!var} doesn't have contents pointing to another existing
> variable, it falls back to a codepath that tries the prefix stuff (and/or the
> array stuff, in some order?) and that codepath tries to parse trailing @Q and
> friends, but DOESN'T error out if it can't recognize the trailing stuff after 
> the @?

Not really, no. It grabs the parameter, which may begin with `!', looks at
the character following it, does one character of lookahead if that
character is `@', and branches to the appropriate thing: variable prefix
expansion or indirect expansion with the result being used as the parameter
for the rest of the expansion.

> 
> I'm pretty sure the array mangling logic ties in here somehow, but there's 
> some
> missing error checking somewhere...

Invalid transformation operators just expand to nothing.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    c...@case.edu    http://tiswww.cwru.edu/~chet/
_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to