[Tcsh] "Readable" Unicode in setenv

Kimmo Suominen kim at netbsd.org
Tue Dec 7 15:20:30 UTC 2021


Thank you, Christos.

So how close to a finished feature is the attached patch?

Cheers,
+ Kimmo

On Tue, 7 Dec 2021 at 16:38, Christos Zoulas <christos at zoulas.com> wrote:
>
> I think that's hard (because you don't know when to quote and when not), but
> the function you are looking for is sprlex().
>
> christos
>
> > On Dec 7, 2021, at 9:32 AM, Kimmo Suominen <kim at netbsd.org> wrote:
> >
> > So I'm pretty lost inside tcsh most of the time...
> >
> > How do I make the $'foo' not come up as $\'foo\' from history? I'm yet
> > to find where the "& QUOTE" is happening...
> >
> > This is incomplete, but it doesn't dump core anymore (at least for
> > simple cases).
> >
> > Cheers,
> > + Kimmo
> >
> >
> > On Thu, 18 Nov 2021 at 15:07, Jamie Landeg-Jones <jamie at catflap.org> wrote:
> >>
> >> Kimmo Suominen <kim at netbsd.org> wrote:
> >>
> >>> That looks very appealing to me.
> >>>
> >>> I would like to cut 6.23.01 as there have been a number of fixes
> >>> committed. But I'm wary of releasing the changed echo. Should I just
> >>> #ifdef NOTYET the \x and \u cases from parseescape() and comment out
> >>> the "$ echo_hex" test?
> >>
> >> No offence to Merijn. His code and suggestions are good, but as the
> >> format may change, I think you are right to release the next version
> >> without it - especially as it appears to be a bug fix incremental release.
> >>
> >> Cheers, Jamie
> > <tcsh-dolsq.diff.txt>--
> > Tcsh mailing list
> > Tcsh at astron.com
> > https://mailman.astron.com/mailman/listinfo/tcsh
>
-------------- next part --------------
diff --git a/sh.dol.c b/sh.dol.c
index 677fb93..ab95a92 100644
--- a/sh.dol.c
+++ b/sh.dol.c
@@ -30,6 +30,8 @@
  * SUCH DAMAGE.
  */
 #include "sh.h"
+#include "ed.h"
+#include "tw.h"
 
 /*
  * C shell
@@ -386,6 +388,34 @@ Dgetdol(void)
       stderror(ERR_SYNTAX);
       return;
     }
+    if ((c & TRIM) == '\'') {
+	/* XXX */
+	const Char *cp;
+	struct Strbuf *expanded = Strbuf_alloc();
+
+	for (;;) {
+	    c = DgetC(0);
+	    if ((c & TRIM) == '\'')
+		break;
+	    if (c == '\n' || c == DEOF) {
+		stderror(ERR_MISSING, '\'');
+		return;
+	    }
+	    Strbuf_append1(name, (Char) c);
+	}
+	Strbuf_terminate(name);
+	cleanup_push(expanded, Strbuf_free);
+	for (cp = name->s; (c = *cp) != 0; cp++) {
+	    if (c == '\\')
+		if ((c = parseescape(&cp, TRUE)) == CHAR_ERR)
+		    c = '\\';
+	    Strbuf_append1(expanded, (Char) c | QUOTE);
+	}
+	Strbuf_terminate(expanded);
+	addla(expanded->s);
+	cleanup_until(name);
+	return;
+    }
     if (c == '{')
 	c = DgetC(0);		/* sc is { to take } later */
     if ((c & TRIM) == '#')
diff --git a/sh.lex.c b/sh.lex.c
index afe053e..07ae6be 100644
--- a/sh.lex.c
+++ b/sh.lex.c
@@ -511,6 +511,21 @@ getdol(void)
     }
     cleanup_push(&name, Strbuf_cleanup);
     Strbuf_append1(&name, '$');
+    if (c == '\'') {
+	/* XXX */
+	Strbuf_append1(&name, c);
+	do {
+	    c = getC(DOEXCL);
+	    if (c == '\n') {
+		ungetD(c);
+		name.len--;
+		stderror(ERR_MISSING, '\'');
+		goto end;
+	    }
+	    Strbuf_append1(&name, c);
+	} while (c != '\'');
+	goto end;
+    }
     if (c == '{')
 	Strbuf_append1(&name, c), c = getC(DOEXCL);
     if (c == '#' || c == '?' || c == '%')
diff --git a/tc.bind.c b/tc.bind.c
index 86e2d3e..48a6265 100644
--- a/tc.bind.c
+++ b/tc.bind.c
@@ -32,6 +32,7 @@
 #include "sh.h"
 #include "ed.h"
 #include "ed.defns.h"
+#include "tw.h"
 
 static	void   printkey		(const KEYCMD *, CStr *);
 static	KEYCMD parsecmd		(Char *);
@@ -385,7 +386,7 @@ parsestring(const Char *str, CStr *buf)
     cleanup_push(&b, Strbuf_cleanup);
     for (p = str; *p != 0; p++) {
 	if ((*p & CHAR) == '\\' || (*p & CHAR) == '^') {
-	    if ((es = parseescape(&p, 1)) == CHAR_ERR) {
+	    if ((es = parseescape(&p, TRUE)) == CHAR_ERR) {
 		cleanup_until(&b);
 		return 0;
 	    } else
diff --git a/tc.func.c b/tc.func.c
index fa0cba1..8f6b721 100644
--- a/tc.func.c
+++ b/tc.func.c
@@ -98,7 +98,7 @@ expand_lex(const struct wordent *sp0, int from, int to)
     const struct wordent *sp;
     Char *s;
     Char prev_c;
-    int i;
+    int i, inside_dolsq = 0;
 
     prev_c = '\0';
 
@@ -113,11 +113,27 @@ expand_lex(const struct wordent *sp0, int from, int to)
 		 * character {(PWP) and backslash} seem to be dealt with
 		 * elsewhere.
 		 */
-		if ((*s & QUOTE)
-		    && (((*s & TRIM) == HIST && HIST != '\0') ||
-			(((*s & TRIM) == '\'') && (prev_c != '\\')) ||
-			(((*s & TRIM) == '\"') && (prev_c != '\\')))) {
-		    Strbuf_append1(&buf, '\\');
+		if (*s & QUOTE) {
+		    if ((*s & TRIM) == HIST && HIST == '\0')
+			;
+		    else
+			switch (*s & TRIM) {
+			case '\'':
+			    if (inside_dolsq != 0) {
+				inside_dolsq = 0;
+				break;
+			    }
+			    if (prev_c == '$') {
+				inside_dolsq = 1;
+				break;
+			    }
+			    /* FALLTHROUGH */
+			case '\"':
+			    if (prev_c == '\\') break;
+			default:
+			    if (inside_dolsq != 0) break;
+			    Strbuf_append1(&buf, '\\');
+			}
 		}
 #if INVALID_BYTE != 0
 		if ((*s & INVALID_BYTE) != INVALID_BYTE) /* *s < INVALID_BYTE */


More information about the Tcsh mailing list