On 27.04.2019 18:30, Samuel Thibault wrote:
> E.g. BSD and Solaris even use locale-specific encoding there.
>
> We thus have to go through the native multibyte representation and use
> mbtowc/wctomb to make a proper conversion.
>
> Signed-off-by: Samuel Thibault
Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
Borders are printed correctly.
Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
I'm also unsure whether to reset conversion state between a multibyte
character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
recommended to use in code examples examples. I think it doesn't make
any harm to use it.
I'm not sure if this is related, but "qemu-system-hppa -curses" is
broken for me. I didn't use it in the past as it just recently acquired
NetBSD guest support.
(lldb) bt
* thread #1, stop reason = signal SIGSEGV
frame #0: 0x7f7ff6c1fb98
libcurses.so.7`wmove(win=0x, y=0, x=0) at move.c:71
frame #1: 0x7f7ff6c0ca9b
libcurses.so.7`mvwadd_wchnstr(win=0x, y=,
x=, wchstr=0x7f7fe020, n=0) at add_wchstr.c:123
* frame #2: 0x0078629e
qemu-system-hppa`curses_update(dcl=0x7f7ff7bd8bc0, x=0, y=0, w=79,
h=24) at curses.c:86:9
frame #3: 0x00753dae
qemu-system-hppa`dpy_text_update(con=0x7f7ff7bae580, x=0, y=0, w=79,
h=24) at console.c:1658:13
frame #4: 0x00758abe
qemu-system-hppa`text_console_update(opaque=0x7f7ff7bae580,
chardata=0x0118e490) at console.c:1264:9
frame #5: 0x00751ef8
qemu-system-hppa`graphic_hw_text_update(con=0x7f7ff7bae580,
chardata=0x0118c690) at console.c:389:9
frame #6: 0x00785bcb
qemu-system-hppa`curses_refresh(dcl=0x7f7ff7bd8bc0) at curses.c:273:5
frame #7: 0x00758248
qemu-system-hppa`dpy_refresh(s=0x7f7ff7bd8770) at console.c:1622:13
frame #8: 0x0075809d
qemu-system-hppa`gui_update(opaque=0x7f7ff7bd8770) at console.c:205:5
frame #9: 0x008d9f4d
qemu-system-hppa`timerlist_run_timers(timer_list=0x7f7ff7e57d20) at
qemu-timer.c:574:9
frame #10: 0x008da01d
qemu-system-hppa`qemu_clock_run_timers(type=QEMU_CLOCK_REALTIME) at
qemu-timer.c:588:12
frame #11: 0x008da4ea
qemu-system-hppa`qemu_clock_run_all_timers at qemu-timer.c:708:25
frame #12: 0x008da962
qemu-system-hppa`main_loop_wait(nonblocking=0) at main-loop.c:519:5
frame #13: 0x005570a4 qemu-system-hppa`main_loop at vl.c:1970:9
frame #14: 0x00551fa4 qemu-system-hppa`main(argc=2,
argv=0x7f7fe768, envp=0x7f7fe780) at vl.c:4604:5
frame #15: 0x0040e7ad qemu-system-hppa`___start + 280
(lldb) p screenpad
(WINDOW *) $2 = 0x
We pass NULL window argument to mvwadd_wchnstr(3) and crash. Can you
reproduce it locally?
I will try to investigate it.
> ---
> ui/curses.c | 151
> 1 file changed, 94 insertions(+), 57 deletions(-)
>
> diff --git a/ui/curses.c b/ui/curses.c
> index fb63945188..395f9545e9 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -400,65 +400,102 @@ static void curses_atexit(void)
> endwin();
> }
>
> +/*
> + * In the following:
> + * - fch is the font glyph number
> + * - uch is the unicode value
> + * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
> + * - mbch is the native local-dependent multibyte representation
> + */
> +
> /* Setup wchar glyph for one UCS-2 char */
> -static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
> +static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
> {
> +char mbch[MB_CUR_MAX];
> wchar_t wch;
> -char *pch, *pwch;
> -size_t sch, swch;
> -
> -pch = (char *) &ch;
> -pwch = (char *) &wch;
> -sch = sizeof(ch);
> -swch = sizeof(wch);
> +char *puch, *pmbch;
> +size_t such, smbch;
> +
> +puch = (char *) &uch;
> +pmbch = (char *) mbch;
> +such = sizeof(uch);
> +smbch = sizeof(mbch);
> +
> +if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
> +fprintf(stderr, "Could not convert 0x%04x "
> +"from UCS-2 to a multibyte character: %s\n",
> +uch, strerror(errno));
> +return;
> +}
>
> -if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> -fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T:
> %s\n",
> -ch, strerror(errno));
> -} else {
> -vga_to_curses[glyph].chars[0] = wch;
> +if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> +fprintf(stderr, "Could not convert 0x%04x "
> +"from a multibyte character to wchar_t: %s\n",
> +uch, strerror(errno));
> +return;
> }
> +vga_to_curses[fch].chars[0] = wch;
> }
>
> /* Setup wchar glyph for one font character */
> -static