zsh-workers
 help / color / mirror / code / Atom feed
From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@sunsite.auc.dk
Subject: Re: quote modifier for parameter expansion?
Date: Fri, 5 Feb 1999 09:50:01 +0100 (MET)	[thread overview]
Message-ID: <199902050850.JAA19408@beta.informatik.hu-berlin.de> (raw)
In-Reply-To: Sven Wischnowsky's message of Wed, 3 Feb 1999 17:28:18 +0100 (MET)


I wrote:

> But it's also useful if you stuff a string together in a parameter and 
> later use the value of that parameter for globbing. With `:q' you can
> prevent pattern characters in the original parameters from being
> interpreted as a pattern.
> 
> That's what makes it useful in functions like pfiles(). Without the
> patch below and using:
> 
>   zle -C my-comp complete-word main-complete
> 
> doing `foo *<TAB>' will give one all files as possible completions.

Yesterday evening I realised that the patch for the `:q' modifier
wasn't that useful in the form I sent it. The problem is that you
might want to use ${foo#...} or somthing like this on the result but
then the single quotes may become unbalanced and nasty things like
that (in fact, the completion examples do this and hence the patch for
the new-completion-examples-file breaks it).

So we should either make :q use backslashes to quote the string or not 
add it at all. The patch below uses the quotename() function from the
completion code for this, moving it to utils.c and renaming it.
Of course, this also makes it differ from the history modifier :q.

As for (t)csh, the effect of $foo:q is to keep the result from being
processed any further (namely globbing) which normally happens in
those shells (so this is one quoting level further down).

All this makes :q look less friendly for me (but it still may be
useful).

Bye
 Sven

diff -u os/subst.c Src/subst.c
--- os/subst.c	Thu Feb  4 21:43:14 1999
+++ Src/subst.c	Thu Feb  4 21:35:54 1999
@@ -1828,7 +1828,7 @@
 			    subst(&copy, hsubl, hsubr, gbal);
 			break;
 		    case 'q':
-			quote(&copy);
+			copy = bslashquote(copy, NULL, NULL, NULL, 0);
 			break;
 		    }
 		    tc = *tt;
@@ -1882,7 +1882,7 @@
 		    }
 		    break;
 		case 'q':
-		    quote(str);
+		    *str = bslashquote(*str, NULL, NULL, NULL, 0);
 		    break;
 		}
 	    }
diff -u os/utils.c Src/utils.c
--- os/utils.c	Thu Feb  4 21:43:14 1999
+++ Src/utils.c	Thu Feb  4 21:39:05 1999
@@ -3109,6 +3109,73 @@
     return 0;
 }
 
+/* Quote the string s and return the result.  If e is non-zero, the         *
+ * pointer it points to may point to a position in s and in e the position  *
+ * of the corresponding character in the quoted string is returned.  Like   *
+ * e, te may point to a position in the string and pl is used to return     *
+ * the position of the character pointed to by te in the quoted string.     *
+ * The last argument should be zero if this is to be used outside a string, *
+ * one if it is to be quoted for the inside of a single quoted string, and  *
+ * two if it is for the inside of  double quoted string.                    *
+ * The string may be metafied and contain tokens.                           */
+
+/**/
+char *
+bslashquote(const char *s, char **e, char *te, int *pl, int instring)
+{
+    const char *u, *tt;
+    char *v, buf[PATH_MAX * 2];
+    int sf = 0;
+
+    tt = v = buf;
+    u = s;
+    for (; *u; u++) {
+	if (e && *e == u)
+	    *e = v, sf |= 1;
+	if (te == u)
+	    *pl = v - tt, sf |= 2;
+	if (ispecial(*u) &&
+	    (!instring || (isset(BANGHIST) &&
+			   *u == (char)bangchar) ||
+	     (instring == 2 &&
+	      (*u == '$' || *u == '`' || *u == '\"')) ||
+	     (instring == 1 && *u == '\''))) {
+	    if (*u == '\n' || (instring == 1 && *u == '\'')) {
+		if (unset(RCQUOTES)) {
+		    *v++ = '\'';
+		    if (*u == '\'')
+			*v++ = '\\';
+		    *v++ = *u;
+		    *v++ = '\'';
+		} else if (*u == '\n')
+		    *v++ = '"', *v++ = '\n', *v++ = '"';
+		else
+		    *v++ = '\'', *v++ = '\'';
+		continue;
+	    } else
+		*v++ = '\\';
+	}
+	if(*u == Meta)
+	    *v++ = *u++;
+	*v++ = *u;
+    }
+    *v = '\0';
+    if (strcmp(buf, s))
+	tt = dupstring(buf);
+    else
+	tt = s;
+    v += tt - buf;
+    if (e && (sf & 1))
+	*e += tt - buf;
+
+    if (e && *e == u)
+	*e = v;
+    if (te == u)
+	*pl = v - tt;
+
+    return (char *) tt;
+}
+
 /* Unmetafy and output a string, quoted if it contains special characters. */
 
 /**/
diff -u os/Zle/comp1.c Src/Zle/comp1.c
--- os/Zle/comp1.c	Thu Feb  4 19:56:49 1999
+++ Src/Zle/comp1.c	Thu Feb  4 21:45:24 1999
@@ -104,14 +105,8 @@
      *compsuffix,
      *compiprefix;
 
-/* This variable and the functions rembslash() and quotename() came from     *
- * zle_tricky.c, but are now used in compctl.c, too.                         */
-
-/* 1 if we are completing in a string */
-
-/**/
-int instring;
-
+/* The function rembslash() came from zle_tricky.c, but is now used *
+ * in compctl.c, too.                                               */
 
 /**/
 static void
@@ -393,70 +388,6 @@
 	    s++;
 
     return t;
-}
-
-/* Quote the string s and return the result.  If e is non-zero, the        *
- * pointer it points to may point to a position in s and in e the position *
- * of the corresponding character in the quoted string is returned.  Like  *
- * e, te may point to a position in the string and pl is used to return    *
- * the position of the character pointed to by te in the quoted string.    *
- * The string is metafied and may contain tokens.                          */
-
-/**/
-char *
-quotename(const char *s, char **e, char *te, int *pl)
-{
-    const char *u, *tt;
-    char *v, buf[PATH_MAX * 2];
-    int sf = 0;
-
-    tt = v = buf;
-    u = s;
-    for (; *u; u++) {
-	if (e && *e == u)
-	    *e = v, sf |= 1;
-	if (te == u)
-	    *pl = v - tt, sf |= 2;
-	if (ispecial(*u) &&
-	    (!instring || (isset(BANGHIST) &&
-			   *u == (char)bangchar) ||
-	     (instring == 2 &&
-	      (*u == '$' || *u == '`' || *u == '\"')) ||
-	     (instring == 1 && *u == '\''))) {
-	    if (*u == '\n' || (instring == 1 && *u == '\'')) {
-		if (unset(RCQUOTES)) {
-		    *v++ = '\'';
-		    if (*u == '\'')
-			*v++ = '\\';
-		    *v++ = *u;
-		    *v++ = '\'';
-		} else if (*u == '\n')
-		    *v++ = '"', *v++ = '\n', *v++ = '"';
-		else
-		    *v++ = '\'', *v++ = '\'';
-		continue;
-	    } else
-		*v++ = '\\';
-	}
-	if(*u == Meta)
-	    *v++ = *u++;
-	*v++ = *u;
-    }
-    *v = '\0';
-    if (strcmp(buf, s))
-	tt = dupstring(buf);
-    else
-	tt = s;
-    v += tt - buf;
-    if (e && (sf & 1))
-	*e += tt - buf;
-
-    if (e && *e == u)
-	*e = v;
-    if (te == u)
-	*pl = v - tt;
-
-    return (char *) tt;
 }
 
 /**/
diff -u os/Zle/compctl.c Src/Zle/compctl.c
--- os/Zle/compctl.c	Thu Feb  4 19:56:49 1999
+++ Src/Zle/compctl.c	Thu Feb  4 21:41:18 1999
@@ -1385,7 +1385,7 @@
 	    untokenize(p);
 	    quotedzputs(p, stdout);
 	} else
-	    quotedzputs(quotename(s, NULL, NULL, NULL), stdout);
+	    quotedzputs(bslashquote(s, NULL, NULL, NULL, 0), stdout);
     }
 
     /* loop through flags w/o args that are set, printing them if so */
@@ -1515,7 +1515,7 @@
 		char *p = dupstring(s);
 
 		untokenize(p);
-		quotedzputs(quotename(p, NULL, NULL, NULL), stdout);
+		quotedzputs(bslashquote(p, NULL, NULL, NULL, 0), stdout);
 	    }
 	}
 	putchar('\n');
@@ -1547,8 +1547,6 @@
     cclist = 0;
     showmask = 0;
 
-    instring = 0;
-
     /* Parse all the arguments */
     if (*argv) {
 	/* Let's see if this is a global matcher definition. */
diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- os/Zle/zle_tricky.c	Thu Feb  4 20:08:12 1999
+++ Src/Zle/zle_tricky.c	Thu Feb  4 21:40:47 1999
@@ -487,6 +487,16 @@
 
 static int insubscr;
 
+/* 1 if we are completing in a string */
+
+/**/
+int instring;
+
+/* Convenience macro for calling bslashquote() (formerly quotename()). *
+ * This uses the instring variable above.                              */
+
+#define quotename(s, e, te, pl) bslashquote(s, e, te, pl, instring)
+
 /* Check if the given string is the name of a parameter and if this *
  * parameter is one worth expanding.                                */
 

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


             reply	other threads:[~1999-02-05  8:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-02-05  8:50 Sven Wischnowsky [this message]
  -- strict thread matches above, loose matches on Subject: below --
1999-02-03 16:28 Sven Wischnowsky
1999-02-03 15:52 Sven Wischnowsky
1999-02-03 16:02 ` Peter Stephenson
1999-02-03 17:20   ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199902050850.JAA19408@beta.informatik.hu-berlin.de \
    --to=wischnow@informatik.hu-berlin.de \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).