Greetings all,

I've identified a mismatch between documentation and actual behaviour
—documentation states:

>    Some of the code points are ’combining characters’ that are not meant
> to be printed by themselves but are instead meant to modify the
> appearance of the previous character.  For combining characters, an
> alternate form of the character literal is ‘#\’ followed by U+25CC (a
> small, dotted circle), followed by the combining character.  This allows
> the combining character to be drawn on the circle, not on the backslash
> of ‘#\’.

For every Guile I tried including a build of the latest Git source
reproducing these steps caused an error 'unknown character name'.
What /does/ work currently is reversing the order of the dotted circle
and the combining character, so entering '#\' then some combining
character and then finally (optionally) ◌.

On some terminals/GUIs (Emacs for example) this can look identical to
the order specified in documentation, dotted circle first and then
combining character.  Also as the test suite confirms there is no
issue with writing out combining characters in this form.

I've made up a patch containing some tests that should accurately
describe the intended behaviour and then my attempt at a fix.  My fix
works as far as I've been able to test, but I'm unfamiliar with
debugging Guile itself so please forgive me if I've failed to fully
understand the scope of the problem.  I tested this by building from
source and using the following command:
> cd test-suite && ../meta/guile -L . -e main -s guile-test --test-suite tests 
> chars.test

I'm unfamiliar also with the etiquette for sending contributions to
Guile so I'll attach both the patch in `git-format' form to this post
and a link to my fork on Codeberg:
https://codeberg.org/lee-thomp/guile/commit/319cfab7aa854c4d36e3bff6332352b8c9968c04

Thanks all

>From 319cfab7aa854c4d36e3bff6332352b8c9968c04 Mon Sep 17 00:00:00 2001
From: Lee Thompson <[email protected]>
Date: Mon, 13 Jul 2026 23:05:55 +0100
Subject: [PATCH] Correct behaviour of dotted-circle character literals

* test-suite/tests/chars.test: ("basic char handling"): Add tests for
checking combining character literals are read correctly both alone and
combined with a #x25CC dotted circle.
* module/ice-9/read.scm (%read): Correct behaviour of skipping dotted
circle.
---
 module/ice-9/read.scm       |  4 ++--
 test-suite/tests/chars.test | 19 ++++++++++++++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/module/ice-9/read.scm b/module/ice-9/read.scm
index d0b2309b7..ba44969ba 100644
--- a/module/ice-9/read.scm
+++ b/module/ice-9/read.scm
@@ -378,11 +378,11 @@
                        (lp (cdr alist))))))
           (cond
            ((= len 1) ch)
-           ((and (= len 2) (eqv? (string-ref tok 1) dotted-circle))
+           ((and (= len 2) (eqv? (string-ref tok 0) dotted-circle))
             ;; Ignore dotted circles, which may be used to keep
             ;; combining characters from combining with the backslash in
             ;; #\charname.
-            ch)
+            (string-ref tok 1))
            ((and (<= (char->integer #\0) (char->integer ch) (char->integer #\7))
                  (string->number tok 8))
             ;; Specifying a codepoint as an octal value.
diff --git a/test-suite/tests/chars.test b/test-suite/tests/chars.test
index 0a3b31491..6f100749e 100644
--- a/test-suite/tests/chars.test
+++ b/test-suite/tests/chars.test
@@ -320,4 +320,21 @@
       (let ((x (integer->char #x0353))) ; COMBINING X BELOW
         (string=?
          (with-output-to-string (lambda () (write x)))
-         "#\\◌͓")))))
+         "#\\◌͓")))
+
+    (pass-if "combining accent literal is read correctly"
+      (let ((accent (integer->char #x030f))
+            (chars (list #\# #\\
+                         #\x030f)))     ; COMBINING DOUBLE GRAVE ACCENT
+        (char=?
+         accent
+         (call-with-input-string (list->string chars) read))))
+
+    (pass-if "combining accent over dotted circle is read correctly"
+      (let ((accent (integer->char #x030f))
+            (chars (list #\# #\\
+                         #\◌            ; DOTTED CIRCLE
+                         #\x030f)))
+        (char=?
+         accent
+         (call-with-input-string (list->string chars) read))))))

base-commit: 7f0f63d0865ed0d233b070113adecba9c74ffc8a
-- 
2.54.0

Reply via email to