From 19f274f01b94b0e10d4a6ce789b369d7ad3b12b4 Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Fri, 29 Jan 2021 17:30:03 -0800
Subject: [PATCH] ldb prints out Unicode characters

When printing out a base-char, only the low 8 bits of the code were
used.  But with Unicode support, we need to take all the bits and
print them out.  For control codes we use the form "#\^x".  (Was
#\C-x, which isn't a valid supported character form.)  Ascii is
printed as normal "#\a", and everything else use uses "#\u+<hex>".

While we're at it, we also added special cases like #\Vt that are
listed in
https://cmucl.org/docs/cmu-user/html/Characters.html#Characters.

With this, we can print out all unicode characters in a form that can
be pasted back into lisp.
---
 src/lisp/print.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/src/lisp/print.c b/src/lisp/print.c
index 8d79486d2..0e4d7709d 100644
--- a/src/lisp/print.c
+++ b/src/lisp/print.c
@@ -212,12 +212,15 @@ static void
 brief_otherimm(lispobj obj)
 {
     int type, c, idx;
-    char buffer[10];
 
     type = TypeOf(obj);
     switch (type) {
       case type_BaseChar:
-	  c = (obj >> 8) & 0xff;
+          /*
+           * A base-char should only be 16 bits long now.  But
+           * sometimes it uses all 24.  So just grab all the bits.
+           */
+	  c = (obj >> 8) & 0xfffff;
 	  switch (c) {
 	    case '\0':
 		printf("#\\Null");
@@ -228,20 +231,35 @@ brief_otherimm(lispobj obj)
 	    case '\b':
 		printf("#\\Backspace");
 		break;
+            case '\11':
+                printf("#\\Tab");
+                break;
+            case '\13':
+                printf("#\\Vt");
+                break;
+            case '\15':
+                printf("#\\Return");
+                break;
+            case '\33':
+                printf("#\\Escape");
+                break;
+            case '\40':
+                printf("#\\Space");
+                break;
 	    case '\177':
 		printf("#\\Delete");
 		break;
 	    default:
-		strcpy(buffer, "#\\");
 		if (c >= 128) {
-		    strcat(buffer, "m-");
-		    c -= 128;
-		}
-		if (c < 32) {
-		    strcat(buffer, "c-");
-		    c += '@';
-		}
-		printf("%s%c", buffer, c);
+                    /* Just print out the code value */
+		    printf("#\\u+%04X", c);
+		} else if (c < 32) {
+                    /* Print it out as a control character */
+                    printf("#\\^%c", c + '@');
+		} else {
+                    /* Plain ASCII character */
+                    printf("#\\%c", c);
+                }
 		break;
 	  }
 	  break;
-- 
GitLab