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 the output from sh -x - use less u...



details:   https://anonhg.NetBSD.org/src/rev/27d941f273f3
branches:  trunk
changeset: 344087:27d941f273f3
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Mar 12 14:59:26 2016 +0000

description:
Improve quoting in the output from sh -x - use less unnecessary
quotes ('_' and '.' do not need quoting) and never quote the '=' in
an assignment (or it would not be one.) From kre, with some refactoring
to be blamed to me.

diffstat:

 bin/sh/eval.c   |  23 ++++++++++++++++++++---
 bin/sh/output.c |  57 +++++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 63 insertions(+), 17 deletions(-)

diffs (142 lines):

diff -r 1190ee69b451 -r 27d941f273f3 bin/sh/eval.c
--- a/bin/sh/eval.c     Sat Mar 12 14:58:03 2016 +0000
+++ b/bin/sh/eval.c     Sat Mar 12 14:59:26 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.115 2016/02/29 23:51:36 christos Exp $      */
+/*     $NetBSD: eval.c,v 1.116 2016/03/12 14:59:26 christos Exp $      */
 
 /*-
  * Copyright (c) 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)eval.c     8.9 (Berkeley) 6/8/95";
 #else
-__RCSID("$NetBSD: eval.c,v 1.115 2016/02/29 23:51:36 christos Exp $");
+__RCSID("$NetBSD: eval.c,v 1.116 2016/03/12 14:59:26 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <signal.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include <limits.h>
 #include <unistd.h>
@@ -807,9 +808,25 @@
                char sep = 0;
                out2str(ps4val());
                for (sp = varlist.list ; sp ; sp = sp->next) {
+                       char *p;
+
                        if (sep != 0)
                                outc(sep, &errout);
-                       out2shstr(sp->text);
+
+                       /*
+                        * The "var=" part should not be quoted, regardless
+                        * of the value, or it would not represent an
+                        * assignment, but rather a command
+                        */
+                       p = strchr(sp->text, '=');
+                       if (p != NULL) {
+                               *p = '\0';      /*XXX*/
+                               out2shstr(sp->text);
+                               out2c('=');
+                               *p++ = '=';     /*XXX*/
+                       } else
+                               p = sp->text;
+                       out2shstr(p);
                        sep = ' ';
                }
                for (sp = arglist.list ; sp ; sp = sp->next) {
diff -r 1190ee69b451 -r 27d941f273f3 bin/sh/output.c
--- a/bin/sh/output.c   Sat Mar 12 14:58:03 2016 +0000
+++ b/bin/sh/output.c   Sat Mar 12 14:59:26 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: output.c,v 1.34 2016/02/28 23:12:23 christos Exp $     */
+/*     $NetBSD: output.c,v 1.35 2016/03/12 14:59:26 christos 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.34 2016/02/28 23:12:23 christos Exp $");
+__RCSID("$NetBSD: output.c,v 1.35 2016/03/12 14:59:26 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -146,29 +146,58 @@
 }
 
 
+static const char norm_chars [] = \
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-=_.'";
+
+static int
+inquote(const char *p)
+{
+       size_t l = strspn(p, norm_chars);
+       char *s = strchr(p, '\'');
+
+       return s == NULL ? p[l] != '\0' : s - p > (off_t)l;
+}
+
+
 void
 outshstr(const char *p, struct output *file)
 {
-       static const char norm_chars [] \
-               = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-=";
+       /*
+        * ' 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 inq;
        char c;
 
-       if (need_q)
-               outc('\'', file);
+       /*
+        * Don't emit ' unless something needs quoting before closing '
+        */
+       if (need_q) {
+               if ((inq = inquote(p)) != 0)
+                               outc('\'', file);
+       } else
+               inq = 0;
 
-       while (c = *p++, c != 0){
-               if (c != '\''){
+       while ((c = *p++) != '\0') {
+               if (c != '\'') {
                        outc(c, file);
-               }else{
-                       outc('\'', file);
-                       outc('\\', file);
-                       outc(c, file);
-                       outc('\'', file);
+                       continue;
                }
+
+               if (inq)
+                       outc('\'', file);       /* inq = 0, implicit */
+               outc('\\', file);
+               outc(c, file);
+               if (need_q && *p != '\0') {
+                       if ((inq = inquote(p)) != 0)
+                               outc('\'', file);
+               } else
+                       inq = 0;
        }
 
-       if (need_q)
+       if (inq)
                outc('\'', file);
 
        if (file == out2)



Home | Main Index | Thread Index | Old Index