From e5542f1fc33e61f594876039c9eed24a92a2597d Mon Sep 17 00:00:00 2001 From: Craig Small Date: Tue, 1 Feb 2022 16:46:09 +1100 Subject: [PATCH] free: Use wstr width and not length The previous commit used the value from mbstowcs() to work out the spacing required, as printf() got it completely wrong. However, for alignment of text you don't use the string length but the string width. As the referenced website says: Use wcslen when allocating memory for wide characters, and use wcswidth to align text. Which is what free does now. Chinese is still off by one but I cannot see why this is so. It's close enough for now. If someone can work it out, I'd love to know what the fix is. As a side effect, #213 is fixed because we are putting the correct number of spaces in. French is still an issue (see #24 ) but this is because the string is too long! References: procps-ng/procps#24 procps-ng/procps#213 procps-ng/procps#229 commit 9f4db0fb5606e4872829bd44b29443d5707b1505 https://www.linux.com/news/programming-wide-characters/ Signed-off-by: Craig Small --- NEWS | 1 + free.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index d8417d3c..a487278a 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ procps-ng-NEXT * free: Add committed line option merge #25 * free: Fix -h --si combined options issue #133, #223 * free: Fix first column justification issue #229, #204, #206, Debian #1001689 + * free: Better spacing for Chinese language issue #213 * library: renamed to libproc-2 and reset to 0:0:0 * library: add support for accessing smaps_rollup issue #112, #201 * library: add support for accessing autogroups diff --git a/free.c b/free.c index 4e989af4..94943e88 100644 --- a/free.c +++ b/free.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "config.h" #include "c.h" @@ -185,13 +186,18 @@ static void print_head_col(const char *str) { int len; int spaces = 9; + wchar_t wstr[BUFSIZ]; - len = mbstowcs(NULL, str, 0); + len = mbstowcs(wstr, str, BUFSIZ); if (len < 0) spaces = 9; - else if (len < HC_WIDTH) - spaces = HC_WIDTH - len; - else + else if (len < HC_WIDTH) { + int width; + if ( (width = wcswidth(wstr, 99)) > 0) + spaces = HC_WIDTH - width; + else + spaces = HC_WIDTH - len; + } else spaces = 0; printf("%s%.*s", str, spaces, " "); -- 2.40.0