about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-09-25 02:54:15 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-09-25 02:54:15 +0000
commit9b85146a0884c3d5025392bae4911efff391731e (patch)
treec99fdaf820703db8f76c6eda9d60f0c5a8a7147a /Src
parent0b6eb901634da245dbbf4c2e072d24a06ee08f33 (diff)
downloadzsh-9b85146a0884c3d5025392bae4911efff391731e.tar.gz
zsh-9b85146a0884c3d5025392bae4911efff391731e.tar.xz
zsh-9b85146a0884c3d5025392bae4911efff391731e.zip
zsh-workers/8042
Diffstat (limited to 'Src')
-rw-r--r--Src/subst.c49
-rw-r--r--Src/utils.c59
2 files changed, 92 insertions, 16 deletions
diff --git a/Src/subst.c b/Src/subst.c
index 45b58aef6..ffe6217f0 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -723,6 +723,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
     int sortit = 0, casind = 0;
     int casmod = 0;
     int quotemod = 0, quotetype = 0, quoteerr = 0;
+    int visiblemod = 0;
     char *sep = NULL, *spsep = NULL;
     char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
     char *replstr = NULL;	/* replacement string for /orig/repl */
@@ -826,6 +827,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    casind = 1;
 		    break;
 
+		case 'V':
+		    visiblemod++;
+		    break;
+
 		case 'q':
 		    quotemod++, quotetype++;
 		    break;
@@ -1628,20 +1633,20 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	    ap = aval;
 
 	    if (quotemod > 0) {
-		if (quotetype == 3)
-		    for (; *ap; ap++)
-			*ap = nicedupstring(*ap);
-		else if (quotetype) {
+		if (quotetype) {
 		    int sl;
 		    char *tmp;
 
 		    for (; *ap; ap++) {
+			int pre = quotetype != 3 ? 1 : 2;
 			tmp = bslashquote(*ap, NULL, quotetype);
 			sl = strlen(tmp);
-			*ap = (char *) zhalloc(sl + 3);
-			strcpy((*ap) + 1, tmp);
-			ap[0][0] = ap[0][sl + 1] = (quotetype == 1 ? '\'' : '"');
-			ap[0][sl + 2] = '\0';
+			*ap = (char *) zhalloc(pre + sl + 2);
+			strcpy((*ap) + pre, tmp);
+			ap[0][pre - 1] = ap[0][pre + sl] = (quotetype != 2 ? '\'' : '"');
+			ap[0][pre + sl + 1] = '\0';
+			if (quotetype == 3)
+			  ap[0][0] = '$';
 		    }
 		} else
 		    for (; *ap; ap++)
@@ -1668,18 +1673,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	    if (!copied)
 		val = dupstring(val), copied = 1;
 	    if (quotemod > 0) {
-		if (quotetype == 3)
-		    val = nicedupstring(val);
-		else if (quotetype) {
+		if (quotetype) {
+		    int pre = quotetype != 3 ? 1 : 2;
 		    int sl;
 		    char *tmp;
 
 		    tmp = bslashquote(val, NULL, quotetype);
 		    sl = strlen(tmp);
-		    val = (char *) zhalloc(sl + 3);
-		    strcpy(val + 1, tmp);
-		    val[0] = val[sl + 1] = (quotetype == 1 ? '\'' : '"');
-		    val[sl + 2] = '\0';
+		    val = (char *) zhalloc(pre + sl + 2);
+		    strcpy(val + pre, tmp);
+		    val[pre - 1] = val[pre + sl] = (quotetype != 2 ? '\'' : '"');
+		    val[pre + sl + 1] = '\0';
+		    if (quotetype == 3)
+		      val[0] = '$';
 		} else
 		    val = bslashquote(val, NULL, 0);
 	    } else {
@@ -1700,6 +1706,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	    }
 	}
     }
+    if (visiblemod) {
+	if (isarr) {
+	    char **ap;
+	    if (!copied)
+		aval = arrdup(aval), copied = 1;
+	    for (ap = aval; *ap; ap++)
+		*ap = nicedupstring(*ap);
+	} else {
+	    if (!copied)
+		val = dupstring(val), copied = 1;
+	    val = nicedupstring(val);
+	}
+    }
     if (isarr) {
 	char *x;
 	char *y;
diff --git a/Src/utils.c b/Src/utils.c
index 5f9e89882..7494837cf 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2984,7 +2984,64 @@ bslashquote(const char *s, char **e, int instring)
     for (; *u; u++) {
 	if (e && *e == u)
 	    *e = v, sf = 1;
-	if (ispecial(*u) &&
+	if (instring == 3) {
+	  int c = *u;
+	  if (c == Meta) {
+	    c = *++u ^ 32;
+	  }
+	  c &= 0xff;
+	  if(isprint(c)) {
+	    switch (c) {
+	    case '\\':
+	    case '\'':
+	      *v++ = '\\';
+	      *v++ = c;
+	      break;
+
+	    default:
+	      if(imeta(c)) {
+		*v++ = Meta;
+		*v++ = c ^ 32;
+	      }
+	      else {
+		if (isset(BANGHIST) && c == bangchar) {
+		  *v++ = '\\';
+		}
+		*v++ = c;
+	      }
+	      break;
+	    }
+	  }
+	  else {
+	    switch (c) {
+	    case '\0':
+	      *v++ = '\\';
+	      *v++ = '0';
+	      if ('0' <= u[1] && u[1] <= '7') {
+		*v++ = '0';
+		*v++ = '0';
+	      }
+	      break;
+
+	    case '\007': *v++ = '\\'; *v++ = 'a'; break;
+	    case '\b': *v++ = '\\'; *v++ = 'b'; break;
+	    case '\f': *v++ = '\\'; *v++ = 'f'; break;
+	    case '\n': *v++ = '\\'; *v++ = 'n'; break;
+	    case '\r': *v++ = '\\'; *v++ = 'r'; break;
+	    case '\t': *v++ = '\\'; *v++ = 't'; break;
+	    case '\v': *v++ = '\\'; *v++ = 'v'; break;
+
+	    default:
+	      *v++ = '\\';
+	      *v++ = '0' + ((c >> 6) & 7);
+	      *v++ = '0' + ((c >> 3) & 7);
+	      *v++ = '0' + (c & 7);
+	      break;
+	    }
+	  }
+	  continue;
+	}
+	else if (ispecial(*u) &&
 	    (!instring ||
 	     (isset(BANGHIST) && *u == (char)bangchar) ||
 	     (instring == 2 &&