The Man Who Fell From The Wrong Side Of The Sky:2008年4月17日分

[最新版] [一覧] [前月] [今月] [翌月]

2008/4/17(Thu)

[NetBSD] pkgsrc/wip/scim

obacheさんとこ、FreeBSDらしいなぁ。

というのは確かなので、手っ取り早く動かそうと思うとこうなるのだろう。

こんな patchでイケそうなのだけど、何故かGTK2+への入力で落ちるな。
うーむCSI xtermには *inputMethod:scim で問題なく入力できてるのだけど。
上のpatchでは修正してないけど、compare()がlength=0の場合を考慮してないバグあるので
そういうのが影響してるのかもしれない。

あとscim-chewingのL''問題については、ucs4_tをuint32_tではなくclassにして
そいでucs4_t& operator=(const wchar_t)を書いて代入を許可する
(overloadでwchar_tとucs4への変換ロジックを書く)とかやるしかないのでしょうが
芋蔓で他の演算子も…になるので、めんどくさいですやね。
wchar_t -> ucs4_tの変換を実装するにはiconv(3)が使えます。
ただしwchar_t -> multibyte -> utf-32{LE,BE}と手順が面倒なので
L'x' = 'x'の場合のみ許可するでもいいのかも。

まあこういう問題にぶち当たった時

と人それぞれ。

んで、突然気づいたのだが、先日やった BOM吐く対応
これやるとUCS-{4,2}はUTF-{32,16}のaliasのままだとマズいことに気づいた。
そのうち直すけど、そもそもiconvの引数にUCS-{2,4}が指定できるのこと自体好きじゃない。

[文字コード] 続 \(←なぜかYEN SIGNに見える)

0x5c問題、日銀総裁とバーターで「日本の通貨記号をバックスラッシュに変更する」案を民主 *1(以下略

UTF-8=File System Safe UCS Transformation Formatではあるけど
文字コード変換にまつわるトラブルが絡むと、まあいろいろ出ますやね。

なぜMS932の0x5cがYEN SIGNのグリフを持ったREVERSE SOLIDUSという
ぱっと見では開き直りに見える解決方法をとったのかを考察してみるテスト。

US-ASCIIとの互換性を考慮して、0x5cは文字もグリフもREVERSE SOLIDUSだと改めるとどうなるか。
これは簡単なはなししで、請求書にレストランのメニューにありとあらゆるドキュメントの
¥が\に化けてしまいますので、これらを全て修正する必要があります。

この修正作業は単純な置換ではダメです。
ディレクトリ区切り文字であれば\、通貨記号なら¥と文脈でどちらかを判断しなければなりません。
ツールを作るにしても結構複雑なものになりますし、完全に自動化は不可能でしょう。

それ以前に、この無理をする為にはCP932の変換テーブルに¥を追加しないことにははじまりません。
しかもバイト幅=文字幅という 呪術を信じる世のSIer(ソレナンテうちの現場?)の為に、残り少ない1バイト領域へ。
さて どこの空きにつっこみますか *2

では逆にJISX0208のShift_JIS仕様を守り、0x5cは文字もグリフもYEN SIGNだと定めるとどうなるか。
これだと日本語版Windowsと英語版Windowsでディレクトリ区切り文字が違うという事態に陥ります。

短絡的にi18n脳を発動させると「じゃあディレクトリ区切り文字もロケールデータベースに *3」ですが、これも無理。

HANDLE h = CreateFileA("C:\hoge.txt", ...);

と直書きされたプログラムは全てアウトになるので、これらはみーんなコード修正と再コンパイル *4です。
例え直書きせずレジストリやiniファイルに追い出してたとしても、さすがにロケール毎で
キーやファイルを切り替えるとこまでは想定してないでしょう。
# この悪夢から逃れられるアプリってどんだけ作者パラノイアなのよ。

なにかの奇跡が起きて、ファイル操作APIを一新できたとしても
今度はファイル名として使用が禁止される文字に互換性が失われてしまいます。

#include <windows.h>
int
main(void)
{
        HANDLE h;
        WCHAR dir[] = { 0x00A5, 0 };
        h = CreateFileW(&dir[0], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL, NULL);
}

を実行すると「¥」というファイルが作成可能であることから判る通り、U+00A5はファイル名として有効です *5

すでにこの名前で作成されたファイルがある可能性を勘案すると、後付けで禁止する為には
新たに禁止された文字を使用してるファイルをピックアップして、リネームする為の移行ツールが必要になります。

このツールはsambaのconvmvのよに、ファイル名を変更してコピーするだけでは機能不足です。
例えばAdobe LightroomやPhotoshop Albumは画像ファイルの検索性を高める為に
データベースにサムネイル他の情報と実際の画像ファイルへのパス情報を持ってますが
ファイル名が上記の移行ツールで変わってしまうとリンク切れが発生してしまいます。

同様の機能を持っているアプリは、画像ファイル管理ソフトだけに留まりません。
これらについてもあまねく移行ツールを書く必要がありますが、誰がそのコストを(以下略
# フォーマットを公開しないまま潰れた会社もあるだろうし。

これらの困難を考えると、YEN SIGNのグリフを持ったREVERSE SOLIDUSが
Cカップ並の最も正解に思えてくる不思議。

このごろ「失敗学」なんてのが流行ってて
こういうひどい本*6なんかも関連で売れてるようだけども
「互換性学」をでっちageるのはどうだろう>>ネタ切れでお困りの新書屋さん。
いまならVista叩くだけで一冊楽に書けるちゃーんすwwwww


*1:与党は日本の通貨記号を$に(中略)、一方で
太陽神ラーは日本と中国の通貨記号が同じ事に満足した。

*2:んで思い出したけど、MS936(≒GBK)は0x80にユーロ記号を無理矢理突っ込んだのだが
これCitrus iconvは対応してないのよな、そのうち直す。

*3:念のため、java.io.File.separatorCharはロケールでは無いですお
*4:creat(3)にeを足すちゃーんす。
*5:VCやmingwが手元に無い人は、プログラム>アクセサリ>システムツール>文字コード表より
U+00A5を選択/コピーし、ファイル/ディレクトリ名にペーストしてもこのことが確認できます。
ちなみにこのU+00A5、メモ帳に貼って保存すると0x5Cに変換されるというwwwww

*6:ハードカバーな部分以外は講○社α文庫や○いわ文庫レベルですな。

[C言語] iconv_open(3) argument

うに板より
みんな想像力豊かだなぁ、おりゃこんな使い方思いつかんぞ。

iconv_open("char", "wchar_t");

おお、mbsrtowcs(3)という妻がありながら、iconv(3)という愛人を…って映画「Control」の見過ぎー。

実際問題 GNU libiconvは

iconv_open("", "WCHAR_T");

で上と同様の変換が可能なのが困る罠、どーせwchar_tったってUCS4期待してんだろうに。

mbsrtowcs(3)使わずにiconv(3)を使いたがるのは
Unicode正規化問題とmbrtowcの食い合わせが悪い *1からなんだろうかにゃ。
でもGNU libiconvだって転写(//TRANSLIT)はあっても
//NFDとか//NFCなどは実装されていないのだけども。

個人的にはiconv(3)は使ったら負けだと思っている(言い過ぎ)。

ついでに書いておくと、TR 19769(char16_t/char32_t)を好きになれんのは
あれ結局MSVCの16bit wchar_t問題対策くらいの役にしかたたんからなのよね。
wchar_tを乗っ取らずにchar16_t/char32_tとして分離した点においてはむしろ好感。
Unicode正規化まで考慮し、is*とかto*、printf formatまで設計して
なおかつcode then spec, not spec then codeなら賛成する。
あ、あとMT-safeでないsetlocale()とはもう切り離してくれよってのもあるか。

まあそこまでいくとソレナンテ ICUになるわけですが。


*1:input bytesがMB_CUR_MAXに縛られるからね。


[ホームへ] [ページトップへ]