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;

Reply via email to