Subject: Re: CVS commit: basesrc/bin/sh
To: Alan Barrett <apb@cequrux.com>
From: Christos Zoulas <christos@zoulas.com>
List: source-changes
Date: 02/12/2002 12:20:49
On Feb 12, 11:56am, apb@cequrux.com (Alan Barrett) wrote:
-- Subject: Re: CVS commit: basesrc/bin/sh

Yup, and I'll back it out. Why don't you try to come up with a fix?

christos

| 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)
-- End of excerpt from Alan Barrett