Now with Philip's fix applied. * Philip Guenther <guent...@gmail.com> [120815 15:40]: > On Sun, Aug 12, 2012 at 12:43 PM, Alexander Polakov <p...@sdf.org> wrote: > > Ok, second attempt > > Nice. One fix; > > > > @@ -342,7 +346,10 @@ > > PUSH_STATE(STBRACE); > > } else { > > ungetsc(c); > > - PUSH_STATE(SBRACE); > > + if (state == SDQUOTE) > > + PUSH_STATE(SBRACEQ); > > + else > > + PUSH_STATE(SBRACE); > > That should be > if (state == SDQUOTE || > state == SBRACEQ) > ... > > so that doubly nested forms like > foo=1; echo "${foo:+${foo:+'blah $foo'}}" > give > 'blah 1' > > ...and yes, I now have a still bigger diff to unclass2.t that includes > that test. :-) > > > I think the lex.h diff is nicer if the new SBRACEQ state is stuck at > the end of the existing list instead of renumbering additional states, > but I can be argued into renumbering them...
I don't really have a strong opinion on this, but it looks better to me when SBRACE & SBRACEQ are together, because they're similar. Index: lex.c =================================================================== RCS file: /cvs/src/bin/ksh/lex.c,v retrieving revision 1.45 diff -u -r1.45 lex.c --- lex.c 9 Mar 2011 09:30:39 -0000 1.45 +++ lex.c 15 Aug 2012 22:40:26 -0000 @@ -113,7 +113,7 @@ Again: states[0].ls_state = -1; - states[0].ls_info.base = (Lex_state *) 0; + states[0].ls_info.base = (Lex_state *) NULL; statep = &states[1]; state_info.base = states; state_info.end = &states[STATE_BSIZE]; @@ -270,6 +270,10 @@ *wp++ = QCHAR, *wp++ = c; break; case '\'': + if ((cf & HEREDOC) || state == SBRACEQ) { + *wp++ = CHAR, *wp++ = c; + break; + } *wp++ = OQUOTE; ignore_backslash_newline++; PUSH_STATE(SSQUOTE); @@ -342,7 +346,11 @@ PUSH_STATE(STBRACE); } else { ungetsc(c); - PUSH_STATE(SBRACE); + if (state == SDQUOTE || + state == SBRACEQ) + PUSH_STATE(SBRACEQ); + else + PUSH_STATE(SBRACE); } } else if (ctype(c, C_ALPHA)) { *wp++ = OSUBST; @@ -419,6 +427,10 @@ case SSQUOTE: if (c == '\'') { POP_STATE(); + if (state == SBRACEQ) { + *wp++ = CHAR, *wp++ = c; + break; + } *wp++ = CQUOTE; ignore_backslash_newline--; } else @@ -525,6 +537,7 @@ *wp++ = c; break; + case SBRACEQ: case SBRACE: /*{*/ if (c == '}') { Index: lex.h =================================================================== RCS file: /cvs/src/bin/ksh/lex.h,v retrieving revision 1.11 diff -u -r1.11 lex.h --- lex.h 29 May 2006 18:22:24 -0000 1.11 +++ lex.h 15 Aug 2012 22:40:26 -0000 @@ -51,19 +51,20 @@ /* * states while lexing word */ -#define SBASE 0 /* outside any lexical constructs */ -#define SWORD 1 /* implicit quoting for substitute() */ -#define SLETPAREN 2 /* inside (( )), implicit quoting */ -#define SSQUOTE 3 /* inside '' */ -#define SDQUOTE 4 /* inside "" */ -#define SBRACE 5 /* inside ${} */ -#define SCSPAREN 6 /* inside $() */ -#define SBQUOTE 7 /* inside `` */ -#define SASPAREN 8 /* inside $(( )) */ -#define SHEREDELIM 9 /* parsing <<,<<- delimiter */ -#define SHEREDQUOTE 10 /* parsing " in <<,<<- delimiter */ -#define SPATTERN 11 /* parsing *(...|...) pattern (*+?@!) */ -#define STBRACE 12 /* parsing ${..[#%]..} */ +#define SBASE 0 /* outside any lexical constructs */ +#define SWORD 1 /* implicit quoting for substitute() */ +#define SLETPAREN 2 /* inside (( )), implicit quoting */ +#define SSQUOTE 3 /* inside '' */ +#define SDQUOTE 4 /* inside "" */ +#define SBRACE 5 /* inside ${} */ +#define SBRACEQ 6 /* inside "${}" */ +#define SCSPAREN 7 /* inside $() */ +#define SBQUOTE 8 /* inside `` */ +#define SASPAREN 9 /* inside $(( )) */ +#define SHEREDELIM 10 /* parsing <<,<<- delimiter */ +#define SHEREDQUOTE 11 /* parsing " in <<,<<- delimiter */ +#define SPATTERN 12 /* parsing *(...|...) pattern (*+?@!) */ +#define STBRACE 13 /* parsing ${..[#%]..} */ typedef union { int i; . or with SBRACEQ at the end Index: lex.h =================================================================== RCS file: /cvs/src/bin/ksh/lex.h,v retrieving revision 1.11 diff -u -r1.11 lex.h --- lex.h 29 May 2006 18:22:24 -0000 1.11 +++ lex.h 15 Aug 2012 22:50:30 -0000 @@ -64,6 +64,7 @@ #define SHEREDQUOTE 10 /* parsing " in <<,<<- delimiter */ #define SPATTERN 11 /* parsing *(...|...) pattern (*+?@!) */ #define STBRACE 12 /* parsing ${..[#%]..} */ +#define SBRACEQ 13 /* parsing "${}" */ typedef union { int i;