glibc の wcwidth の話の続き
glibc の wcwidth() の「曖昧な文字幅」についての動作の話の続き。
やっぱり、UTF-8 の charmap を全部書き換えてしまうのは良くないと思い、以下のようにしてみた。
まず、/usr/share/i18n/charmaps/UTF-8.gz を改造して ambiguous width な文字の幅を 2 にしたものを /usr/share/i18n/charmaps/UTF8-8-CJK.gz として設置。*1
次に UTF-8-CJK を使って locale を再作成
$ sudo localedef -i ja_JP -c -f UTF-8-CJK ja_JP.UTF-8
あるいは、/etc/locale.gen を以下のように書き換えて locale-gen コマンドを実行しても同じ。(Debian 特有?)
en_US.UTF-8 UTF-8 ja_JP.EUC-JP EUC-JP ja_JP.UTF-8 UTF-8-CJK
この状態で、前回作成したプログラムを実行した結果は以下のとおり。
$ LC_CTYPE=ja_JP.utf8 ./a.out wcwidth('A') == 1 wcwidth('α') == 2 wcwidth('あ') == 2 $ LC_CTYPE=en_US.utf8 ./a.out wcwidth('A') == 1 wcwidth('α') == 1 wcwidth('あ') == 2
これなら、CJK な人も non-CJK な人もそれなりに幸せになれるのではなかろうか。
もっとも、何かの拍子に(locales パッケージをアップグレードした時とか) locale-archive が更新されて元に戻ってしまいそうだけど、その時はその時で。
なお、UTF-8-CJK な charmap を作るにあたっては、以下のバグ報告(glibc 本家と Debian の glibc パッケージ)を参考にした。
- Bug 4335 (glibc 本家)
- Debian Bug #471021 (Debian glibc パッケージ)
*1:文字幅の情報は EastAsianWidth.txt (unicode.org) を参照。