From: James Prestwood <prestwoj@gmail.com>
To: Pinghao Wu <xdavidwuph@gmail.com>, iwd@lists.linux.dev
Subject: Re: [PATCH] client: handle wide chars for table rows
Date: Mon, 10 Oct 2022 10:00:48 -0700 [thread overview]
Message-ID: <0a53a6affe3d8f34ac08b95f307de3ac1c674635.camel@gmail.com> (raw)
In-Reply-To: <20221008075509.26252-1-xdavidwuph@gmail.com>
On Sat, 2022-10-08 at 15:55 +0800, Pinghao Wu wrote:
> Try to find out printing width of wide chars using current locale and
> its byte length before falling back to non-codepoint UTF-8 bytes
> method.
> ---
> client/display.c | 16 +++++++++++++++-
> client/main.c | 3 +++
> 2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/client/display.c b/client/display.c
> index b729ad4c..dcbe11f8 100644
> --- a/client/display.c
> +++ b/client/display.c
> @@ -26,10 +26,13 @@
>
> #define _GNU_SOURCE
> #include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> #include <signal.h>
> #include <sys/stat.h>
> #include <sys/ioctl.h>
> #include <unistd.h>
> +#include <wchar.h>
>
> #include <readline/history.h>
> #include <readline/readline.h>
> @@ -401,15 +404,26 @@ static char* next_line(char *s, unsigned int
> *max, char **color_out)
> unsigned int i;
> int last_space = -1;
> int last_color = -1;
> + int s_len = strlen(s);
>
> /* Find the last space before 'max', as well as any color */
> - for (i = 0; i <= *max && s[i] != '\0'; i++) {
> + for (i = 0; i <= *max && i != s_len; i++) {
> if (s[i] == ' ')
> last_space = i;
> else if (s[i] == 0x1b) {
> /* color escape won't count for column width
> */
> *max += color_end(s + i);
> last_color = i;
> + /* Non-ASCII, try wchar */
> + } else if (s[i] & 0x80) {
> + wchar_t w;
> + int w_mblen;
> + if ((w_mblen = mbtowc(&w, &s[i], s_len - i))
Instead of mbtowc() use l_utf8_get_codepoint() (an ELL utility). Since
we assume the input is going to be utf-8 always.
> > 0) {
> + /* Compensate max bytes for wide char
> */
> + *max += w_mblen - wcwidth(w);
> + /* Skip other bytes for this wchar */
> + i += w_mblen - 1;
> + }
> /* Add width for non-codepoint UTF-8 bytes */
> } else if (((uint8_t)s[i] >> 6) == 2)
> *max += 1;
And you can go ahead and remove this if-clause entirely since the above
case should now cover it. Plus the s[i] & 0x80 check above actually
prevents this branch from ever being taken.
> diff --git a/client/main.c b/client/main.c
> index df5c0a61..7e8dead4 100644
> --- a/client/main.c
> +++ b/client/main.c
> @@ -25,6 +25,7 @@
> #endif
>
> #include <errno.h>
> +#include <locale.h>
> #include <signal.h>
> #include <ell/ell.h>
>
> @@ -50,6 +51,8 @@ int main(int argc, char *argv[])
> {
> bool all_done;
>
> + setlocale(LC_CTYPE, "");
> +
> if (!l_main_init())
> return EXIT_FAILURE;
>
Thanks,
James
prev parent reply other threads:[~2022-10-10 17:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-08 7:55 [PATCH] client: handle wide chars for table rows Pinghao Wu
2022-10-10 15:57 ` James Prestwood
2022-10-10 16:09 ` Pinghao Wu
2022-10-10 16:55 ` James Prestwood
2022-10-10 17:00 ` James Prestwood [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0a53a6affe3d8f34ac08b95f307de3ac1c674635.camel@gmail.com \
--to=prestwoj@gmail.com \
--cc=iwd@lists.linux.dev \
--cc=xdavidwuph@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox