Source-Changes-HG archive

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

[src/trunk]: src/bin/sh Improve quoting in xtrace (-x) output ... if a string...



details:   https://anonhg.NetBSD.org/src/rev/3ac529cd3a48
branches:  trunk
changeset: 827888:3ac529cd3a48
user:      kre <kre%NetBSD.org@localhost>
date:      Thu Nov 16 19:41:02 2017 +0000

description:
Improve quoting in xtrace (-x) output ... if a string ("word") to be
output includes a single quote (') then see if using double-quotes
to quote it is reasonable (if no chars that are magic in " also appear).
If so, and if the string is not entirely the ' character, then
use " quoting.  This avoids some ugly looking results (occasionally).

Also, fix a bug introduced about 20 months ago where null strings
in xtrace output are dropped, instead of made explicit ('').
To observe this, before you get the fix: set -x; echo ''   (or similar.)

Move a comment from the wrong place to the right place.

diffstat:

 bin/sh/output.c |  46 ++++++++++++++++++++++++++++++++++------------
 1 files changed, 34 insertions(+), 12 deletions(-)

diffs (83 lines):

diff -r 34a2de6abc03 -r 3ac529cd3a48 bin/sh/output.c
--- a/bin/sh/output.c   Thu Nov 16 18:40:28 2017 +0000
+++ b/bin/sh/output.c   Thu Nov 16 19:41:02 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: output.c,v 1.36 2017/05/18 13:31:10 kre Exp $  */
+/*     $NetBSD: output.c,v 1.37 2017/11/16 19:41:02 kre Exp $  */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)output.c   8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: output.c,v 1.36 2017/05/18 13:31:10 kre Exp $");
+__RCSID("$NetBSD: output.c,v 1.37 2017/11/16 19:41:02 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -146,6 +146,11 @@
 }
 
 
+/*
+ * ' is in this list, not because it does not require quoting
+ * (which applies to all the others) but because '' quoting cannot
+ * be used to quote it.
+ */
 static const char norm_chars [] = \
     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/+-=_,.'";
 
@@ -158,25 +163,42 @@
        return s == NULL ? p[l] != '\0' : s - p > (off_t)l;
 }
 
-
 void
 outshstr(const char *p, struct output *file)
 {
-       /*
-        * ' is in this list, not because it does not require quoting
-        * (which applies to all the others) but because '' quoting cannot
-        * be used to quote it.
-        */
-       int need_q = p[0] == 0 || p[strspn(p, norm_chars)] != 0;
+       int need_q;
        int inq;
        char c;
 
+       if (strchr(p, '\'') != NULL && p[1] != '\0') {
+               /*
+                * string contains ' in it, and is not only the '
+                * see if " quoting will work
+                */
+               size_t i = strcspn(p, "\\\"$`");
+
+               if (p[i] == '\0') {
+                       /*
+                        * string contains no $ ` \ or " chars, perfect...
+                        *
+                        * We know it contains ' so needs quoting, so
+                        * this is easy...
+                        */
+                       outc('"', file);
+                       outstr(p, file);
+                       outc('"', file);
+                       return;
+               }
+       }
+
+       need_q = p[0] == 0 || p[strspn(p, norm_chars)] != 0;
+
        /*
         * Don't emit ' unless something needs quoting before closing '
         */
-       if (need_q) {
-               if ((inq = inquote(p)) != 0)
-                       outc('\'', file);
+       if (need_q && (p[0] == 0 || inquote(p) != 0)) {
+               outc('\'', file);
+               inq = 1;
        } else
                inq = 0;
 



Home | Main Index | Thread Index | Old Index