* Stefan Sperling <[email protected]> [110104 23:12]:
> On Tue, Jan 04, 2011 at 09:14:51PM +0300, Alexander Polakov wrote:
> > Hi,
> >
> > I wonder if there any plans on adding multibyte support for ls(1)?
> > Or maybe there's a reason why it's not a great idea (which I am not
> > aware of)?
> > Anyway, here's a patch I have. It's based on DragonFlyBSD's ls.
> >
>
> Any locale stuff added to applications that are used on the ramdisk
> (bsd.rd) must be inside #ifndef SMALL.
> The ls binary is linked statically so we need to prevent it from wasting
> space by pulling citrus stuff onto the ramdisk.
Sure.
> More importantly, there is an alleged bug in our wcwidth() implementation.
> I haven't had time to investigate, but it has been pointed out on separate
> occasions, by Jordi Beltran Creix and by n...@.
> Test program (from Jordi):
>
> #include <stdio.h>
> #include <locale.h>
>
> main ()
> {
> setlocale(LC_ALL, "");
> printf("%d %d %d %d\n", wcwidth(0x53DA), wcwidth('A'),
> wcwidth(0x200B), wcwidth(0x1F));
> return 0;
> }
>
> Output is 2, 1, 1, 0, should be 2, 1, 0, -1 (according to Jordi).
>
> We should make sure that wcwidth() is working properly before changing
> applications to use it. We also need a wcwidth() man page.
I think there're 2 separate bugs and I have 2 fixes (neither one
tested).
1) wcwidth(0x200B)
This if from http://unicode.org/Public/UNIDATA/ :
200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;;
200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
--- share/locale/ctype/en_US.UTF-8.src.orig Tue Jan 4 22:49:22 2011
+++ share/locale/ctype/en_US.UTF-8.src Tue Jan 4 22:50:55 2011
@@ -1672,7 +1672,8 @@
BLANK 0x2000 - 0x200b 0x202f 0x205f
PRINT 0x2000 - 0x200b 0x2010 - 0x2029 0x202f - 0x2052 0x2057
PRINT 0x205f
-SWIDTH1 0x2000 - 0x200b 0x2010 - 0x2029 0x202f - 0x2052 0x2057
+SWIDTH1 0x2000 - 0x200c 0x2010 - 0x2029 0x202f - 0x2052 0x2057
+SWIDTH0 0x200b - 0x200d
SWIDTH1 0x205f
2) wcwidth(0x1f)
DragonFly's man page for wcwidth(3) says that function returns -1 if
character is not printable. _RUNETYPE_R is the flag to check.
--- lib/libc/locale/iswctype.c.orig Tue Jan 4 23:12:23 2011
+++ lib/libc/locale/iswctype.c Tue Jan 4 23:02:37 2011
@@ -170,7 +170,11 @@
int
wcwidth(wchar_t c)
{
- return (((unsigned)__runetype_w(c) & _CTYPE_SWM) >> _CTYPE_SWS);
+ _RuneType r;
+ r = __runetype_w(c);
+ if (r & _RUNETYPE_R)
+ return (((unsigned)r & _CTYPE_SWM) >> _CTYPE_SWS);
+ return -1;
}
wctrans_t
Again, I don't have hardware at hand to build libc so this is completely
untested.