蝉は、やがて死ぬる午後に気づいた。ああ、私たち、もっと仕合せになってよかったのだ。:2006年11月27日分

2006/11/27(Mon)

NetBSD

@Citrus iconv

先日commitする気ナッシングと書いたUTF-5の件について。

仕様については これ参照のこと、ちなみにstateless encodingね。
国際化ドメイン名にPunycodeが採用され死んだはずなので無視しよかと思ってたら
なんとemacs風エディタのxyzzyがUTF-5の読み書きサポートしてるのを発見…ようやるわ。

Citrus iconvでUTF-5を実装する場合、実はちょっと問題がある。iconv(3)の中で動くのがmbrtowc(3)なので
バイト列 "J04A"をワイド文字 L'お' 変換しようとすると

const char *s = "J04A";
size_t n = 4;
int ch, state;
wchar_t wc;

wc = (wchar_t)0;
for (;;) {
	if (n-- < 1)
		goto restart;
	ch = (unsigned char)*s++;
	if (ch > 'F' && wc != 0)
		break;
	wc << 4;
	wc |= char_to_nibble(ch);
}
...
---------------------------------------------
n	= 3
ch	= 'J'
s	= "04A"
wc	= 0x3;
---------------------------------------------
n	= 2
ch	= '0'
s	= "4A"
wc	= 0x30
---------------------------------------------
n	= 1
ch	= '4'
s	= "A"
wc	= 0x304
---------------------------------------------
n	= 0
ch	= 'A'
s	= ""
wc	= 0x304A
---------------------------------------------

と、4byte目まで変換したところでinput byteの長さが残り0になり
mbrtowc的には(size_t)-2を返すrestartの状態になってしまうんだよね。
次の文字の先頭バイトが見つからない限り文字の長さが判らないCESって実はこないだのVIQRも同じ。

$ echo "A." | iconv -f VIQR -t JAVA
\u1ea0

$ echo -n "A." | iconv -f VIQR -t C99
iconv: iconv(): Invalid argument

とまぁ、直さないとちとまずそうなんだな。
wc -> mbの変換時だとmbstate_tにまだ吐き出せる文字がある場合、喉の奥に
_citrus_${ENCODING}_put_state_reset()を突っ込んで無理矢理mbを吐かせるのに習い
mb -> wcの変換時にも同様にmbstate_tに浣w腸wしてwcを吐かせないとあかんな。

@GB12345

こないだcommitしたGB12345。 元々EUC-CN(GB2312)を無理矢理フォントを置き換えて簡体→繁体表示にしたものらすい。
こういうのってiconvでサポートすべきかちょっと悩むよね。
他にもShift_JIS?のフォントを無理矢理GB2312にしたSHIFTGBというものも存在するらしい。

@CP50220

legacy-encoding.sourceforge.jpの記述通りに実装するとなるとUnicodeからCP50220に変換する時には
半角カナは全角カナにしないとダメなんだが絶賛放置中。ハ゜ → パの変換にM:N変換モジュール書かないとダメだし。
個人的には〓にすべきだと思うけど、暫く様子見。
CP50221がESC)IだけでなくSI/SOでもJISX0201-KANAを扱えるのもあれは単にMicrosoftの実装上の都合な希ガス。
多分mb -> wcのコンバータがCP50221もCP50222も同じもの使ってるだけじゃないかな。