On 2026-08-17 08:21, Bruno Haible wrote:
The weekly CI shows two test failures on Cygwin 3.3.6 and Cygwin 3.6.10,
that were not present last week (on 2026-08-13):

FAIL: testsuite/8to7
FAIL: testsuite/bsd-wrapper

Find attached the test-suite.log file.

Similarly on OpenBSD 7.7.

I think these test failures occur because c32isprint disagrees with isprint on those 
platforms. For example, in the C locale isprint(0xA1) is 0 because that character is not 
printable (this is required for conformance to POSIX), but if you give "\xA1" 
to mbrtoc32 it succeeds and yields (char32_t){0xA1}, and c32isprint(0xA1) is 1 because 
U+00A1 INVERTED EXCLAMATION MARK is printable.

You can see the problem by applying the attached (incomplete) patch to Gnulib and then 
using "./gnulib-tool --create-testdir --dir foo -h c32isprint" to create a test 
directory. On OpenBSD 7.9 in that test directory, gltests/test-c32isprint fails as 
follows:

test-c32isprint.c:119: c32isprint (0xa0) = 1, isprint (0xa0) == 0
test-c32isprint.c:122: assertion 'is != 0' failed

I see several possible fixes:

(1) Skip the sed tests on problematic platforms.

(2) Change Gnulib c32isprint so that in a single-byte locale, it succeeds if 
and only if given one of the at most 255 char32_t values corresponding to the 
unsigned char value that isprint succeeds on.

(3) Replace mbrtoc32 on problematic platforms where in single-byte locales it 
can yield values that cause isprint to be inconsistent with c32isprint.

(4) Change 'sed' so that in single-byte locales it uses only traditional <ctype.h> 
primitives like isprint, and never uses <uchar.h> functions.

Of these fixes (2) sounds best to me. (4) is bad, as that will complicate 
'sed', and I imagine the problem exists in other programs (even if we haven't 
observed it there yet) so would we need to change them all?

Perhaps there are better fixes?

cc'ing to bug-gnulib.

From 269d137d0c553da4a10d8c34972c87cdd964a3b7 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Mon, 17 Aug 2026 12:16:05 -0700
Subject: [PATCH] c32isprint-tests: check isprint compatibility

* tests/test-c32isprint.c: Include ctype.h, limits.h.
Use only C89 features, so no need to depend on the
corresponding Gnulib modules.
(main): Test that mbrtoc32+c32isprint agrees with isprint
whenever mbrtoc32 sees a single-byte character.
---
 tests/test-c32isprint.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tests/test-c32isprint.c b/tests/test-c32isprint.c
index 9d91ef3640..8ff5b03cb8 100644
--- a/tests/test-c32isprint.c
+++ b/tests/test-c32isprint.c
@@ -21,6 +21,8 @@
 #include "signature.h"
 SIGNATURE_CHECK (c32isprint, int, (wint_t));
 
+#include <ctype.h>
+#include <limits.h>
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
@@ -101,6 +103,26 @@ main (int argc, char *argv[])
         break;
       }
 
+  for (int c = CHAR_MIN; c <= CHAR_MAX; c++)
+    {
+      char ch = c;
+      mbstate_t state = {0};
+      char32_t wc;
+      if (mbrtoc32 (&wc, &ch, 1, &(mbstate_t) {0}) == 1)
+        {
+          unsigned char uch = ch;
+          int is32 = c32isprint (wc), isctype = isprint (uch);
+          is = !is32 == !isctype;
+          if (is == 0)
+            fprintf (ASSERT_STREAM,
+                     "%s:%d: c32isprint (0x%x) = %d, isprint (0x%x) == %d\n",
+                     __FILE__, __LINE__,
+                     (unsigned int) {wc}, is32,
+                     (unsigned int) {uch}, isctype);
+          ASSERT (is != 0);
+        }
+    }
+
   if (argc > 1)
     switch (argv[1][0])
       {
-- 
2.55.0

Reply via email to