Barbarism begins at internet:2006年11月分

2006/11/04(Sat)

NetBSD

@legacy encoding

CP51932,CP5022[0-2]を追加、ついでにISO-2022-JP-1も。
CP5022[1-2]はG0とG1に同時にJISX0201カナ(ESC(I)があるという珍妙な仕様なので
libISO2022に手を加えないとフツーにだめー★かと思ったら大丈夫ですた。

2006/11/09(Thu)

NetBSD

@mapper_zone

Citrus iconvはesdbで指定されているDEFCSIDがfromとtoが一致したらピボット変換しない(必要ないので)。
先日対応したCP51932/CP50220だけど、CP932とは収録文字数に差がある(前者にはユーザ定義文字とか
IBM拡張文字が含まれないのよー)。その為に異なるDEFCSIDを振らざるを得なかったので
両者の変換は必ずUnicodeを経由しての変換になってしまう。
ダサダサ。

もっとスマートなやり方ならばshare/i18n/csmapper/mapper.dir で

CP932/CP51932	mapper_zone	0x2121 - 0x7426, 0x7921 - 0x7C7E
CP51932/CP932	mapper_zone
...

とか書ければ一番いいんだけど(それならCP932EXT%UCS.srcを3分割する必要もなかった)
mapper_zoneは細かいZONE指定に対応していないんだよなー。
直すのはそんなに手間じゃないはずなので、TODOに追加しておこう(いれときっぱなしー)。

これ対応すればこないだJOHAB対応時にKS5601のテーブルを2分割したのも元に戻せる。

...ってdistrib/sets/lists/base/miで一度obsoleteにマークしたものって戻して良いんだっけ?

@VIQR(RFC1456)

それがVIPクオリティ、じゃなくてヴェトナムの7bitコード、メールやニュースグループで使用されてたらすい。
文字集合はVISCII、符号化手法はISO-2022のような状態遷移を使うのではなく、RFC1345のようなニーモニックを使う。

A	-> 0x41
A(	-> 0xC5
A('	-> 0x81
A(.	-> 0x83
A(`	-> 0x82
...

ニーモニックではなくリテラルで

A(`

を表現したい場合、エスケープ文字として0x5cを使い

A\(`

と書く、符号化手法というより換字ですな。

というわけで(どういうわけで)、これもまた DR#288のケースだね。
mbrtowc(&wc, ...)がwc != L'\0'の場合でも(size_t)0を返す可能性がある。
またwc->mb に戻す時、前の文字がニーモニックの1バイト目と被るASCIIの文字である場合
エスケープが必要なのでその情報をmbstate_tで保持する必要がある。
つまり mb -> wc はstatelessだけれども wc -> mb はstatefulなパターン。

実装自体はニーモニックを1文字づつバラしたツリーを辿る方法で簡単にできるっぽ。
テストしたらcommitするよん。

2006/11/13(Mon)

NetBSD

@Citrus iconv

libVIQRと長らく放置してたlibUES(UnicodeEscape)をcommit。
後者はC99変換でUniversal Characterとして使ってはフツーにだめーな文字
(U+009f以下かつU+0024,U+0040,U+0060でないものとサロゲート領域)
の扱いが間違ってたので修正、つーか全部書き直したwwwwww

libVIQRについてはsoc.culture.vietnameseあたりのニュースグループでは
RFC1456で定義されてるよりも多くのニーモニックがありそうなんだが
詳細不明なんで、とりあえず拡張可能にだけしておいてお茶を濁した。

2006/11/14(Tue)

Unicode

@UTF-8N

塩崎さんとこより。

BOMをZWNBSPと見抜けない人には(UTF-8を使うのは)難しい(AA略 ネタ。

UTF-8Nという言葉を使い出したのは日本の(ピー)じゃなくてあのMark Davisみたいですね。
http://web.archive.org/web/20050506211548/http://www-128.ibm.com/developerworks/library/utfencodingforms/index.html
http://www2.xml.gr.jp/log.html?MLID=xmlmoji&N=827
使ってるのが日本人ばかりってのは厳密に区別したがる国民性なんだろか。

2006/11/19(Sun)

NetBSD

@Citrus iconv

libHZの書き直しオワタ、もうちょいテストして今週中にはcommitすると思われ。
HZ+やEHZでBig5を3面に分けて94*2に振り直してる部分をwctocs/cstowcで
面倒を見ようとするとVARIABLEでの指定が繁雑になるんでヤメ。
そんなのは新しくmapper_shift(仮)とか作って

HZP-BIG5-1/BIG5-ETEN  mapper_shift 0x21-0x7F/0x21-0x7F/8 : 0xA1-0xC8/0x40-0x7E,0xA1-FE/8

とか書いてiconv mapperにお任せした方がすっきりしそうだし。
LC_CTYPEにしてもmklocale(1)だとwchar_tがBig5のコードポイント
であるほうがいい(必須じゃないが)んだけど、localedef(1)化したら関係ないしな。
つーわけでmapper_shiftはまだ書いてないのでとりあえずはHZとHZ8のサポートのみ先行。

2006/11/21(Tue)

NetBSD

@Citrus iconv

太古の昔に書いたlibZWのコード整理してwc -> mbに大問題があることに気付いた。
HZの文字列

1|	12345
2|	ABCD~{!!!!~}

をzWに変換するとき

1|	12345
2|	ABCD
3|	zW!!!!

と出力してたんだけど、ASCIIな行(2行目)では最後の改行コードはよく考えると有効な文字なんだよね。
GB2312の行(zWで始まる3行目)のように改行コードの有効/無効を"#"で切替出来ないから。
だから再度zW -> HZに戻すと

1|	12345
2|	ABCD
3|	~{!!!!~}

と、ひとつの行が2行目と3行目に分かれてしまいマズー。 正しくは

1|	12345
2|	zW A B C D!!!!

のようにASCIIとGB2312の文字の両方が存在する行は
GB2312の行とし、ASCIIの文字は' 'によるシングルシフトで表現しなければならないっつーことね。

Citrusの場合、iconvの中身がmbrtowc/wcrtombなので
改行コードまで読み込んでASCII or GB2312をチェックするのは無理。
よってもの凄いダサい回避策

1|	zW 1 2 3 4 5#
2|	zW A B C D!!!!

みたいに全ての行をGB2312で扱うようにせんとダメぽ。
ちなみに私の知る限りzWの読み書きの可能な唯一のエディタ(RFC1842でも紹介されてる)
NJStar v3.1 WordProcessor for MS-DOSもzWで保存時にはこうやってた。

根本的な解決はmbstate_tを使わずともrestartableなiconv moduleを用意するしかないよなぁ。
wc -> mb ならメモリ喰うだけでstdin問題もないし、UTF-6の圧縮率決定問題も解決するし。
なんかそのうち考えるかぁ。

2006/11/23(Thu)

NetBSD

@Citrus iconv

HZとzWサポートをcommitしたよん。

2006/11/24(Fri)

NetBSD

@encoding module

ネタ切れ気味、実用的なのって何かないかな。
流石にこんなの↓は触手^H^H食指が動かん。

  • SCSU http://www.unicode.org/unicode/reports/tr6/
  • BOCU http://www-06.ibm.com/jp/developerworks/unicode/010921/j_u-binary.html
  • BOCU-1 http://www.unicode.org/notes/tn6/
  • IDN系、PunycodeとかRACE他。UTF-5/6は昔書いたけどcommitする気ナッシング。
  • UTF-1 ちょwwwwww http://czyborra.com/utf/#UTF-1
  • 幻のDIS10646:1991 1.0 Draft ちょwwwww
  • TRONコード ちょwwwww
  • NWSOS(NEWS-OSじゃないよ)方面でUTFCP/UTFCP2/UTFJPというのも2chで見かけたな。


ヴェトナム語(クォックグー)のVIQRみたいなASCII換字ネタだと、チベット文字のワイリー法は
InputMethodとしてGTK2なんかが使ってるし、MacOS方面にはconverterがある。
しかし7bitコードとして情報交換に使ってる例を見たことが無い(ってもGoogleの届く範囲だけだけど)。
それにスペースが文字境界/単語境界なのか文字通りのスペースなのか曖昧に思えるし
ローマ字と同じでA(あ)と文字通りのA(エー)の区別がつかなそうなんだよな、ちゃんと仕様読んでませんが。
VIQRはスペースは文字通りのスペースだしdiacritical markと\(エスケープ)で明確に区別できるから
ASCII換字ではあってもCharacter Encoding Schemeとして成り立ってるとオモ。

そのへんを考えないず無分別にiconvで対応してしまうと

$ iconv -f ヘボン式 -t 訓令式

も変換しなければならんことになってしまう悪寒、んなわけない。

@iconvのiって

Internetだっけ?(いやInternationalかな、自信無いけど以下前者の前提で)
"Internet"をどこで線引きするのかが曖昧なのが困りもんだよね。
情報交換にexposeされてもいいコードと内部でのみ使うべきコードったって
これまで王様の耳の噂程に守られなかったわけだし。
本来ならIANA charset registryがその役を果たすべきだったんだろうけど、現実的には足りないよなあれじゃぁ。
もう新しい登録はしないと聞いたような気もする(そいやJISX0213がMLで放置プレイ中ですな)。

GNU libiconvやglibc iconvなんてのはUCS4-INTERNALやWCHAR_Tといった8bit符号化を行わない
生変換やopaque object(彼らにとってwchar_tはopaqueじゃないのか)への変換までやっちゃうし。
あの機能に依存したアプリが増えないことを祈りまくりんぐ。

@legacy converter

日本ではnkfに比べてiconv(1)は

  • メンドクサイ
  • 使い物にならない

という主張がかつては多かった気がするけど最近はどうなんだろ。
nkfのメンテもいまだに続いているし、skfみたいに100徳ナイフ化(なんかサニタイズまでするらすい) してるのもある。意識は変わってないのかな。

文字コードの自動判定はiconvでも

$ iconv -f JISAUTODETECT -t UTF-8

みたいな方法で可能だとは思うけど(mbstate_tじゃ足りないからバッファリングしないとなぁ)

  • 壊れたISO-2022-JPを直す
  • MIME変換して60文字で折り返し

なんてのはソフトウェア作法的にiconv(1)の仕事ではない罠、あと

  • EILSEQで止まるのがウザイ>>iconv

つー不満もあんのかな。

まあnkf他が今後どうなるか知らんけど、お互いが勝手に変換表をメンテし続けるってのは不幸だよねぇ。
iconv(3)を呼ぶnkfってのはダメなのかな、ちょwwwww

2006/11/25(Sat)

NetBSD

@Citrus iconv

ラオスの文字コードCP1133とMULELAO-1追加、変換表はX-TTから。
タイの文字コードTIS620-0(ISO-IR-166)はISO-8859-11のaliasとして入れた。
GNU libiconvは別モノとして扱っているのはなぜだろ。

@CP5022x/CP51932/CP932

それぞれ別々のDEFCSIDになってる為にUnicodeを経由してのPivot変換になる無駄を
mapper_zoneを使って解消してみた。
Unicode経由だと例えば2chのモナーフォント スレの >>261をCP932 -> CP50221変換しようとすると
途中"\x88\x68"でEILSEQになっちゃってたんだよね。

あとはCP932とShift_JIS他との変換は相変わらずUnicode経由なので
これもmapper_serial使うことでなんとかならんか検討しよか。

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も同じもの使ってるだけじゃないかな。

2006/11/28(Tue)

Unicode

@WindowsVistaのJISX0213:2004対応

http://itpro.nikkeibp.co.jp/99/vista/index.html
こんな↑ページまでできて世の中はUnicode化待ったなしらしい。
帳票レイアウト上全角20文字だからデータベースはVARCHAR(40)で定義して容量計算、みたいな
非プロポーショナルフォント + Shift_JIS前提でしか設計ノウハウがない会社は大丈夫なんだろか。

2006/11/29(Wed)

NetBSD

@Citrus iconv

CP942/CP943関係を追加、IBMのDB2でおなじみですな。
Java方面のドキュメントによるといずれもCP932のスーパーセットとあるけど
CP942は旧JIS(JIS78)、CP943は新JIS(JIS83)なので
JISX0208ってもWindows31JなCP932のスーパーセットいっていいのか微妙だな。
後ろにCがつく場合、0x0-0x7FがJISX0201-ROMANではなくASCIIになる。