Source-Changes-HG archive

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

[src/trunk]: src/bin/sh - Fix a couple of bugs to make the following two echo...



details:   https://anonhg.NetBSD.org/src/rev/bd914c64e93d
branches:  trunk
changeset: 758745:bd914c64e93d
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Nov 14 19:43:38 2010 +0000

description:
- 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 need to escape twice, because one
   level of escaping will be stripped later. (XXX: Do that when insub == 1
   only?)

- Make macros statements

diffstat:

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

diffs (111 lines):

diff -r 3eef7e738550 -r bd914c64e93d bin/sh/parser.c
--- a/bin/sh/parser.c   Sun Nov 14 19:36:07 2010 +0000
+++ b/bin/sh/parser.c   Sun Nov 14 19:43:38 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.74 2009/01/18 00:30:54 lukem Exp $        */
+/*     $NetBSD: parser.c,v 1.75 2010/11/14 19:43:38 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.74 2009/01/18 00:30:54 lukem Exp $");
+__RCSID("$NetBSD: parser.c,v 1.75 2010/11/14 19:43:38 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 %d\n", varnest)); \
+           if (varnest < 32) \
+                   dblquote |= (1 << varnest); \
+           else \
+                   dblquotep[(varnest / 32) - 1] |= (1 << (varnest % 32));\
+    } while (/*CONSTCOND*/0)
 
 #define CLRDBLQUOTE() \
-    if (varnest < 32) \
-       dblquote &= ~(1 << varnest); \
-    else \
-       dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 32))
+    do { \
+           TRACE(("clrdblquote %d\n", varnest)); \
+           if (varnest < 32) \
+                   dblquote &= ~(1 << varnest); \
+           else \
+                   dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 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,14 @@
                                        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)) {
+                                       USTPUTC(CTLESC, out);
+                                       USTPUTC(CTLESC, out);
+                               }
                                if (SQSYNTAX[c] == CCTL)
                                        USTPUTC(CTLESC, out);
                                else if (eofmark == NULL) {
@@ -1068,6 +1080,7 @@
                                PARSESUB();             /* parse substitution */
                                break;
                        case CENDVAR:   /* CLOSEBRACE */
+                               insub = 0;
                                if (varnest > 0 && !ISDBLQUOTE()) {
                                        varnest--;
                                        USTPUTC(CTLENDVAR, out);
@@ -1340,7 +1353,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