Re: /bin/ls formatting broken for non-C(?) locales

From: Andrey Chernov <ache_at_freebsd.org>
Date: Wed, 25 Nov 2015 17:06:17 +0300
On 25.11.2015 16:51, Baptiste Daroussin wrote:
> wcslcat works like strlcat:
> to quote the manpage:
> "It will append at most dstsize - strlen(dst) - 1 characters."
> So here with your version it will be n - wcslen(wab_months[i]) -1
> which won't fit what we want to do.
> 
> btw that makes me figure out that what I want is wcsncat because we do care to
> make sure we have appended the right number of spaces at the end of the
> abbreviated month based on character width, not the on the len of the wide
> string
> 
> so I changed it
> 
> if ((n = max_month_width - wab_months_width[i]) > 0)
>     wcsncat(wab_months[i], L"     "/* MAX_ABMON_WIDTH */, n);

Sorry, I initially mean wcsncat() functionality here, wcslcat() is
sneaked in due to wrong memorizing.

About width counting and fallback...
Without attempt to nicely truncate data damaged by unknown way the code
will be simpler. Instead all that loop adding width one by one wchar, just:

width = wcswidth(wab_months[i], MAX_ABMON_WIDTH);
if (width == -1) {
    max_month_width = -1;
    return;
}
wab_months_width[i] = width;

About
/* NULL terminate to simplify padding later */
wab_months[i][j] = L'\0';
You don't need it, mbstowcs() null-terminates result, if there is a room.
BTW, array size looks suspicious:
static wchar_t wab_months[12][MAX_ABMON_WIDTH * 2 * MB_LEN_MAX];
what MB_LEN_MAX doing here? This constant is for multiple-bytes encoded,
not for wide chars.

-- 
http://ache.vniz.net/


Received on Wed Nov 25 2015 - 13:06:23 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:01 UTC