Subject: Re: CVS commit: basesrc/bin/sh
To: Christos Zoulas <christos@netbsd.org>
From: Alan Barrett <apb@cequrux.com>
List: source-changes
Date: 02/12/2002 11:56:10
On Mon, 11 Feb 2002, Christos Zoulas wrote:
> Log Message:
> PR/15579: Alan Barrett: }'s inside variable specs were taken into account
> even if quoted:
>     foo=${foo:-"'{}'"}; echo $foo
> would display '{'} instead of '{}'.
> 
> To generate a diff of this commit:
> cvs rdiff -r1.48 -r1.49 basesrc/bin/sh/parser.c

No, that won't work.  You need to keep track of which sets of curly
braces are inside the double quotes and which are outside.  I think the
syntax allows nested levels of quotes inside variable expansions inside
quotes, to arbitrary levels, and a simple counter for nested levels of
variable expansions is clearly not enough.  It probably needs a stack to
keep track of nesting.

Consider foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}" as a more difficult
test case.  Assuming that a, b, c and d are undefined, that should
have the effect of setting foo="x}y}z}".  The quotes and variable
sunstitutions nest as follows (with '*' denoting a right-brace character
that does not terminate a variable substitution):

         foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}"
             "                                z*"
              ${a:-                          } 
                   ${b:-                    }
                        "                y*"
                         ${c:-          }
                              ${d:-    } 
                                   "x*"  

BTW, NetBSD's /bin/ksh, and /usr/pkg/bin/bash, both get the above case
right.  NetBSD's /bin/sh and FreeBSD's /bin/sh both get it wrong,
setting foo="xy}}z}" instead of foo="x}y}z}".

--apb (Alan Barrett)