wchar.h: tweak wcwidth prototype parameter wchar_t -> wint_t

Message ID 93dc6225-0cd9-4ce0-b042-3ab88249fb7f@towo.net
State New
Headers
Series wchar.h: tweak wcwidth prototype parameter wchar_t -> wint_t |

Commit Message

Thomas Wolff May 29, 2026, 4:58 a.m. UTC
  to make it compliant with newlib and the manual page;
fixes cases of wrong width calculation:
https://cygwin.com/pipermail/cygwin/2026-April/259597.html
as mentioned in
https://cygwin.com/pipermail/cygwin/2026-May/259734.html
as described in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
From 29783bf893ea867282f591fd97feb5ecffd661be Mon Sep 17 00:00:00 2001
From: Thomas Wolff <towo@towo.net>
Date: Fri, 29 May 2026 00:00:00 +0000
Subject: [PATCH] wchar.h: tweak wcwidth prototype parameter wchar_t -> wint_t

to make it compliant with newlib and the manual page;
fixes cases of wrong width calculation:
https://cygwin.com/pipermail/cygwin/2026-April/259597.html
as mentioned in
https://cygwin.com/pipermail/cygwin/2026-May/259734.html
as described in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
---
 newlib/libc/include/wchar.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
  

Comments

Brian Inglis May 31, 2026, 3:50 a.m. UTC | #1
On 2026-05-28 22:58, Thomas Wolff wrote:
> to make it compliant with newlib and the manual page;
> fixes cases of wrong width calculation:
> https://cygwin.com/pipermail/cygwin/2026-April/259597.html
> as mentioned in
> https://cygwin.com/pipermail/cygwin/2026-May/259734.html
> as described in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
 > attachment: 0001-wchar.h-tweak-wcwidth-prototype-parameter-wchar_t-wi.patch

The existing wcwidth declaration in newlib/libc/include/wchar.h agrees with
POSIX 8 SUS V5.

It is the man doc, definition, and implementation in
newlib/libc/string/wcwidth.c which need changed to match the specification and 
return codes in:

	https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcwidth.html
  
Thomas Wolff May 31, 2026, 8:06 a.m. UTC | #2
Hi Brian,

Am 31.05.2026 um 05:50 schrieb Brian Inglis via Cygwin:
> On 2026-05-28 22:58, Thomas Wolff wrote:
>> to make it compliant with newlib and the manual page;
>> fixes cases of wrong width calculation:
>> https://cygwin.com/pipermail/cygwin/2026-April/259597.html
>> as mentioned in
>> https://cygwin.com/pipermail/cygwin/2026-May/259734.html
>> as described in
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
> > attachment: 
> 0001-wchar.h-tweak-wcwidth-prototype-parameter-wchar_t-wi.patch
>
> The existing wcwidth declaration in newlib/libc/include/wchar.h agrees 
> with
> POSIX 8 SUS V5.
>
> It is the man doc, definition, and implementation in
> newlib/libc/string/wcwidth.c which need changed to match the 
> specification and return codes in:
>
>     https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcwidth.html
Your argument overlooks one significant deviation: in POSIX, wchar_t has 
32 bits, in cygwin only 16.
So to make wcwidth work for *all* Unicode character code points, the 32 
bit version must be used.
I tested positively that this fixes the broken test case with gcc 16 I 
had reported to the cygwin list.
  
Takashi Yano May 31, 2026, 11:57 a.m. UTC | #3
Hi Thomas,

On Sun, 31 May 2026 10:06:12 +0200
Thomas Wolff wrote:
> Hi Brian,
> 
> Am 31.05.2026 um 05:50 schrieb Brian Inglis via Cygwin:
> > On 2026-05-28 22:58, Thomas Wolff wrote:
> >> to make it compliant with newlib and the manual page;
> >> fixes cases of wrong width calculation:
> >> https://cygwin.com/pipermail/cygwin/2026-April/259597.html
> >> as mentioned in
> >> https://cygwin.com/pipermail/cygwin/2026-May/259734.html
> >> as described in
> >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
> > > attachment: 
> > 0001-wchar.h-tweak-wcwidth-prototype-parameter-wchar_t-wi.patch
> >
> > The existing wcwidth declaration in newlib/libc/include/wchar.h agrees 
> > with
> > POSIX 8 SUS V5.
> >
> > It is the man doc, definition, and implementation in
> > newlib/libc/string/wcwidth.c which need changed to match the 
> > specification and return codes in:
> >
> >     https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcwidth.html
> Your argument overlooks one significant deviation: in POSIX, wchar_t has 
> 32 bits, in cygwin only 16.
> So to make wcwidth work for *all* Unicode character code points, the 32 
> bit version must be used.
> I tested positively that this fixes the broken test case with gcc 16 I 
> had reported to the cygwin list.

However, newlib is not used only by Cygwin, so I think newlib itself should
follow POSIX. Shouldn't we have our own wcwidth() implementation for Cygwin?

On second thought, since a 16‑bit wchar_t needs to be converted to a 32‑bit
Unicode code point especially for surrogate pair, we cannot use wcwidth in
the same way as Linux does. I wonder what the correct approach would be.
  
Thomas Wolff June 1, 2026, 4:02 p.m. UTC | #4
Am 31.05.2026 um 13:57 schrieb Takashi Yano:
> Hi Thomas,
>
> On Sun, 31 May 2026 10:06:12 +0200
> Thomas Wolff wrote:
>> Hi Brian,
>>
>> Am 31.05.2026 um 05:50 schrieb Brian Inglis via Cygwin:
>>> On 2026-05-28 22:58, Thomas Wolff wrote:
>>>> to make it compliant with newlib and the manual page;
>>>> fixes cases of wrong width calculation:
>>>> https://cygwin.com/pipermail/cygwin/2026-April/259597.html
>>>> as mentioned in
>>>> https://cygwin.com/pipermail/cygwin/2026-May/259734.html
>>>> as described in
>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125451#c14
>>>> attachment:
>>> 0001-wchar.h-tweak-wcwidth-prototype-parameter-wchar_t-wi.patch
>>>
>>> The existing wcwidth declaration in newlib/libc/include/wchar.h agrees
>>> with
>>> POSIX 8 SUS V5.
>>>
>>> It is the man doc, definition, and implementation in
>>> newlib/libc/string/wcwidth.c which need changed to match the
>>> specification and return codes in:
>>>
>>>      https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcwidth.html
>> Your argument overlooks one significant deviation: in POSIX, wchar_t has
>> 32 bits, in cygwin only 16.
>> So to make wcwidth work for *all* Unicode character code points, the 32
>> bit version must be used.
>> I tested positively that this fixes the broken test case with gcc 16 I
>> had reported to the cygwin list.
> However, newlib is not used only by Cygwin, so I think newlib itself should
> follow POSIX. Shouldn't we have our own wcwidth() implementation for Cygwin?
>
> On second thought, since a 16‑bit wchar_t needs to be converted to a 32‑bit
> Unicode code point especially for surrogate pair, we cannot use wcwidth in
> the same way as Linux does. I wonder what the correct approach would be.
I don't there is a "correct" approach as POSIX probably did not consider 
this problem.
But I just responded to a cute idea on the cygwin mailing list, which 
was unfeasible but I modified it with a proposal to return width 1 for a 
high surrogate, remember it, and then return 1 or 0 for the low 
surrogate, respectively.
  

Patch

diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h
index 7c37427e6..9bb3eaa42 100644
--- a/newlib/libc/include/wchar.h
+++ b/newlib/libc/include/wchar.h
@@ -179,7 +179,7 @@  extern size_t wcsxfrm_l (wchar_t *__restrict, const wchar_t *__restrict, size_t,
 #endif
 
 #if __XSI_VISIBLE
-int	wcwidth (const wchar_t);
+int	wcwidth (const wint_t);
 #endif
 wchar_t	*wmemchr (const wchar_t *, wchar_t, size_t);
 int	wmemcmp (const wchar_t *, const wchar_t *, size_t);