[Tcsh] "Readable" Unicode in setenv

Kimmo Suominen kim at netbsd.org
Tue Dec 7 14:32:16 UTC 2021


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
-------------- 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


More information about the Tcsh mailing list