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)