Dmitrij D. Czarkoff said:
> I recently came across a shell script that uses idiom
>
> var1=var1
> var2=var2
> echo "${var1+($var2)}"
>
> ksh(1) doesn't like it:
>
> ksh: ${var1+($var2)}": bad substitution
>
> Meanwhile bash and dash just print:
>
> (var2)
>
> Apparently ksh tries to parse parenthesis within substituted word.
> According to 2.2.3 Double-Quotes[1] of POSIX Shell Command Language,
> parentheses should not be parsed within double quotes, although 2.6.2
> Parameter Expansion[2] sets special rules for parameter substitution
> within double quotes, and those don't mention whether substituted word
> should be considered quoted or not.
>
> Patch below changes ksh's behavior to match that of bash and dash. I am
> not decided on the matter.
>
> [1]
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
> [2]
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
As pointed out by otto@, my original diff didn't pass regression tests
for ksh. Indeed, I was skipping an important check.
This also reminded me that regression test for the issue I am fixing
won't hurt.
OKs?
--
Dmitrij D. Czarkoff
Index: bin/ksh/lex.c
===================================================================
RCS file: /cvs/src/bin/ksh/lex.c,v
retrieving revision 1.67
diff -u -p -r1.67 lex.c
--- bin/ksh/lex.c 30 Dec 2015 09:07:00 -0000 1.67
+++ bin/ksh/lex.c 2 Mar 2016 23:19:44 -0000
@@ -582,6 +582,15 @@ yylex(int cf)
break;
case SBRACEQ:
+ /*{*/
+ if (c == '}') {
+ POP_STATE();
+ *wp++ = CSUBST;
+ *wp++ = /*{*/ '}';
+ } else
+ goto Sbase2;
+ break;
+
case SBRACE:
/*{*/
if (c == '}') {
Index: regress/bin/ksh/unclass1.t
===================================================================
RCS file: /cvs/src/regress/bin/ksh/unclass1.t,v
retrieving revision 1.1
diff -u -p -r1.1 unclass1.t
--- regress/bin/ksh/unclass1.t 2 Dec 2013 20:39:44 -0000 1.1
+++ regress/bin/ksh/unclass1.t 2 Mar 2016 23:35:52 -0000
@@ -73,6 +73,14 @@ expected-stdout:
a*
---
+name: xxx-what-do-you-call-this-2
+stdin:
+ foo='bar'
+ echo "${foo+(a)}*"
+expected-stdout:
+ (a)*
+---
+
name: xxx-prefix-strip-1
stdin:
foo='a cdef'