Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh PR/43469: Antii Kantee: test/util/sh/t_expand:strip f...



details:   https://anonhg.NetBSD.org/src/rev/900a5ae2bc00
branches:  trunk
changeset: 758823:900a5ae2bc00
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Nov 16 18:17:32 2010 +0000

description:
PR/43469: Antii Kantee: test/util/sh/t_expand:strip fails.
Bring back fixes from revision 1.75:

- Fix a couple of bugs to make the following two echo statements print the
  same output as they should:

    line='#define bindir "/usr/bin" /* comment */'
    echo "${line%%/\**}"
    echo ${line%%/\**}

1. ISDBLQUOTE() was not working properly for non VSNORMAL expansions because
   varnest was incremented before the variable was completely parsed. Add
   an insub adjustment to keep track of that.
2. When we have a quoted backslash, we either need to escape twice, because
   one level of escaping will be stripped later (in the variable substitution
   case) or simply enter the backslash.

diffstat:

 bin/sh/parser.c |  52 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 36 insertions(+), 16 deletions(-)

diffs (123 lines):

diff -r 946df842a126 -r 900a5ae2bc00 bin/sh/parser.c
--- a/bin/sh/parser.c   Tue Nov 16 17:55:56 2010 +0000
+++ b/bin/sh/parser.c   Tue Nov 16 18:17:32 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.76 2010/11/14 19:49:16 christos Exp $     */
+/*     $NetBSD: parser.c,v 1.77 2010/11/16 18:17:32 christos Exp $     */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c   8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.76 2010/11/14 19:49:16 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.77 2010/11/16 18:17:32 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -896,20 +896,27 @@
  * This code assumes that an int is 32 bits. We don't use uint32_t,
  * because the rest of the code does not.
  */
-#define ISDBLQUOTE() ((varnest < 32) ? (dblquote & (1 << varnest)) : \
-    (dblquotep[(varnest / 32) - 1] & (1 << (varnest % 32))))
+#define VN (varnest - insub)
+#define ISDBLQUOTE() ((VN < 32) ? (dblquote & (1 << VN)) : \
+    (dblquotep[(VN / 32) - 1] & (1 << (VN % 32))))
 
 #define SETDBLQUOTE() \
-    if (varnest < 32) \
-       dblquote |= (1 << varnest); \
-    else \
-       dblquotep[(varnest / 32) - 1] |= (1 << (varnest % 32))
+    do { \
+           TRACE(("setdblquote varnest=%d insub=%d\n", varnest, insub)); \
+           if (VN < 32) \
+                   dblquote |= (1 << VN); \
+           else \
+                   dblquotep[(VN / 32) - 1] |= (1 << (VN % 32));\
+    } while (/*CONSTCOND*/0)
 
 #define CLRDBLQUOTE() \
-    if (varnest < 32) \
-       dblquote &= ~(1 << varnest); \
-    else \
-       dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 32))
+    do { \
+           TRACE(("clrdblquote varnest=%d insub=%d\n", varnest, insub)); \
+           if (VN < 32) \
+                   dblquote &= ~(1 << VN); \
+           else \
+                   dblquotep[(VN / 32) - 1] &= ~(1 << (VN % 32)); \
+    } while (/*CONSTCOND*/0)
 
 STATIC int
 readtoken1(int firstc, char const *syn, char *eofmark, int striptabs)
@@ -928,6 +935,7 @@
        volatile int arinest;   /* levels of arithmetic expansion */
        volatile int parenlevel;        /* levels of parens in arithmetic */
        volatile int oldstyle;
+       volatile int insub;
        char const * volatile prevsyntax;       /* syntax before arithmetic */
 #ifdef __GNUC__
        prevsyntax = NULL;      /* XXX gcc4 */
@@ -936,9 +944,9 @@
        startlinno = plinno;
        dblquote = 0;
        varnest = 0;
-       if (syntax == DQSYNTAX) {
+       insub = 0;
+       if (syntax == DQSYNTAX)
                SETDBLQUOTE();
-       }
        quotef = 0;
        bqlist = NULL;
        arinest = 0;
@@ -994,10 +1002,17 @@
                                        break;
                                }
                                quotef = 1;
+                               TRACE(("varnest=%d doubleq=%d c=%c\n",
+                                   varnest, ISDBLQUOTE(), c));
                                if (ISDBLQUOTE() && c != '\\' &&
                                    c != '`' && c != '$' &&
-                                   (c != '"' || eofmark != NULL))
-                                       USTPUTC('\\', out);
+                                   (c != '"' || eofmark != NULL)) {
+                                       if (insub) {
+                                               USTPUTC(CTLESC, out);
+                                               USTPUTC(CTLESC, out);
+                                       } else
+                                               USTPUTC('\\', out);
+                               }
                                if (SQSYNTAX[c] == CCTL)
                                        USTPUTC(CTLESC, out);
                                else if (eofmark == NULL) {
@@ -1053,6 +1068,8 @@
                                }
                                if (eofmark != NULL)
                                        break;
+                               TRACE(("CDQUOTE %d varnest=%d insub=%d\n",
+                                   ISDBLQUOTE(), varnest, insub));
                                if (ISDBLQUOTE()) {
                                        if (varnest != 0)
                                                USTPUTC(CTLQUOTEEND, out);
@@ -1068,6 +1085,7 @@
                                PARSESUB();             /* parse substitution */
                                break;
                        case CENDVAR:   /* CLOSEBRACE */
+                               insub = 0;
                                if (varnest > 0 && !ISDBLQUOTE()) {
                                        varnest--;
                                        USTPUTC(CTLENDVAR, out);
@@ -1340,7 +1358,9 @@
                        flags |= VSQUOTE;
                *(stackblock() + typeloc) = subtype | flags;
                if (subtype != VSNORMAL) {
+                       TRACE(("varnest=%d subtype=%d\n", varnest, subtype));
                        varnest++;
+                       insub = 1;
                        if (varnest >= maxnest) {
                                dblquotep = ckrealloc(dblquotep, maxnest / 8);
                                dblquotep[(maxnest / 32) - 1] = 0;



Home | Main Index | Thread Index | Old Index