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

2008/04/01(Tue)

今日

結論としてwchar_t = UCS4前提でプログラムを書くのが正しい、 ソース。

ロシア的倒置法ではUCS4がwchar_tを 乗っ取る!!

kbkさんとこ経由で 面倒事に巻き込まれないための文字列処理指針

BSDのmbstowcsなんかはこの目的に特化していて、SJISロケー
ルで実行すると、SJIS一文字分をコード変換無しにひとつのwchar_tにパックしてくれます。

重箱の隅ですが、mbstowcs(3)はC90の頃から標準で、BSDといわれるととーっても違和感が。

 STANDARDS
     The mbstowcs() function conforms to ANSI X3.159-1989 (``ANSI C89'').  The
     restrict qualifier is added at ISO/IEC 9899:1999 (``ISO C99'').

それと「ひとつのwchar_tにパック」するのはmbstowcs(3)を挙げるより、mbtowc(3)かな。
#C99からは再スタート可能なmbsrtowcs(3)とmbrtowc(3)がそれぞれ追加されています。
他にもモ(略)な方々ならきっと(略)なのだけども、最初に

面倒事に巻き込まれたくないので

とあるので以下略。

「文字コード=面倒事」の起源ってどこだろう(自明です) *1

やっぱり「なぜ(内部文字コードを決めずに)wchar_tを使うのか?」とか書いた方がいいのかね。
ちゅうか最初に I18N本買え *2と一行書いて終わりな気もするけども。
こういう良本に誘導せず、ここに駄文書くのは 文豪 vs 携帯小説作家スイーツ(笑)

アラビア語サポート、ISO8859-6で勘弁してもらうとか。
基本的には対応してるToolkit使え&それのマニュアル嫁なのよね。

ウニクス方面では、Xの入力の国際化はXIM(=X Input Method)なんて呼ぶけど
反対側には、Xの出力を国際化するXOM(=X Output Method)というのもあるのよね。
#いまのXFree86/xorgにはこれがゴッソリ欠けてるので非常にマイナーですが。

このうち結合文字やbidiを扱うComplex Text Layoutの実装部分は
XomCTLと呼ばれ、Solarisなんかではliblayout + LO_LTYPE locale
及びMotif/CDEの拡張APIとしてとっくの昔に実装済だったりする。

んでXutf8*のゴタゴタの際に、li18nux/openi18nでのCVSで
Xlib-I18Nとliblayoutのソースを権利関係面で整理して 公開*3に踏み切った記憶があるんだけど
いつの間にか pango 使えとなってて、ポルナレフの気分を(以下略
今だと OpenSolarisの一部として見れますが *4

CSI/XOM xterm *5で遊びたかったんだけどねぇ、ってuxtermの方はbidi patchって結局入ったんだっけ?
例の人まだ早いといってた記憶が *6

liblayoutについては sys/layouts.hを見るとprefixが"m_"なので、 Distributed I18N Frameworkと同じグループが仕様策定したの鴨ね。

あとフォント管理に STSFってのもあったなぁ、もうOOoですらfontconfig/Xft2らしいけど。

そいや Fonts & Encodingはまだ日本語訳でないのかな。

*1:fj.kanjiですって? いえいえ創世記ですよ。
*2:そろそろ第2版改定キボンヌ
*3:XIM側の htt = 樋浦さんが 徹夜で 作ったIIIMFも動きないなぁ。
*4:CDDLになっちゃったけど。
*5:itermって結局XomCTLまで対応したのか記憶にないな。
*6:Unicodeのbidi(U+202A~U+202F)による偽造拡張子を踏んで
つこうた(AA略、なんてのがはやる前にちゃんと問題を認識してる訳だ。

2008/04/03(Thu)

[C言語] CERT Managed String

「勘弁な」な理由、theo氏の 今北産業まとめをお借りすると

Cの文字列(char *)ほどに簡単なものをマトモに扱えない香具師の喉に
その10倍複雑なもの(string_m)突っ込んだって、飲み下せるわけがないっしょJK

だから俺らはこの手の問題の解決法は、可能な限り簡単なものを用意するようにしてんだ。

ここでtheo氏がいう「簡単なもの」とは より安全な関数への置換Propoliceですな。

Managed Stringみたいなのをコピペ指向プログラマに使わせようもんなら

string_m ( ゜д゜)  char*
    ヽ/| y |ヽ/
          °。o

     ( ゜д゜) 。o°o。
     (ヽ/ヽ/

    <⌒/ヽ-、__
  /<_/____/ ← コードレビュアー

ということです(不謹慎AAすいません)

char *a;
string_m b;
...
a = (char *)b;

なんてコードが実装によってはなんとなーくうまく動いちゃったりしてというのを
想像するだけで胃が痛くなりますやね。
#Delphiだと文法的にはPChar/String変換はキャストで書けてコンパイラが頑張りますな。

なぜか上野恩賜公園に真昼間からいるわけですが(花見じゃないよ)。

満開の桜に青いビニールシートってどう考えても美的感覚が壊れてるよな。
つかそこいらで売ってるビニールシートはなぜ青いのか?
新書(笑)のタイトル一発勝負か、Web2.0企業(笑)の入社試験問題みたいだな。

ダーウィン展@国立科学博物館。

間接照明が照らす骨格標本の精緻さすてき、ちょとインテリアに(略)。
骨から見る生物の進化
はモノクロ写真なのが惜しいねぇ、骨のベージュってとっても美しいのに。

全長30cm以上あると、明らかにそれがカエルの骨格と見てとれても
脳が勝手にエラー判定、それと軽自動車くらいあるアルマジロはヤバイ。

鳥類標本から漂う死のイメージがなんとも、この写真集↓ちょっと欲しい。
BIOSOPHIA of BIRDS
剥製とはまるで違う、眠るような姿の標本は棺の中を覗いたような感覚。

シーラカンス標本の隣でその解剖ビデオを流してたんだけど、外科医の格好なので結構エグい。
魚屋さんの格好ならふつーに美味しそうと感じるのかもしれない。
だから捕鯨もg11n化してエイハブ船長とか、カウボーイとかフィッシャーマンズセーター(以下略

カブトガニの裏側いいわー癒される、ぬこたんのお腹のモフモフみたい。
小学校以来プラモなんか作ったこと無いけど、タミヤ1/1カブトガニとか出たら買う。
錆色入ったガンメタ仕上げで。
タイだとカブトガニ食べるのな、シガテラ毒あるけど美味いらしい。

ダーウィン自身が収集した標本というものはほとんど展示なしで
原稿メモ類もレプリカが多い、いろんなとこの自然博物館の収蔵品を
彼の研究に即して並べてみたという感じなので、この入場料はとってもお高め。
これではネット(ウィキペとかウィキペとかウィキペなど)に勝てないぞ。
んで文章展示にはフリガナ無いし内容も難しめ、子供連れてくのも微妙やね。

「種の起源」はマルサス「人口論」に影響を受けたとか、マルクス「資本論」に影響を与えたよに
IT分野も新しい血として学問の枠を超えたクロスオーバーにミクスチャーが必要だな。
元々数学方面とは親和性高いんだろうけど、哲学に文学に政治に何でも混ぜてみよう!

あんまり思いつかないもんだにゃー。

アメ横のあたりに安くて美味いsushi(8)屋があるとのことだったのだけど
あまりの人手の多さに歩くのが嫌になって発見できず、天麩羅喰って帰った。

2008/04/04(Fri)

今日

Austin GroupでwithdrawnされたThread-Aware Locale Extensionっておそらく
これかこいつの改訂版のような気がする。
muiltibyte <-> wchar_t変換の部分でmulti localeをどう扱うかゴッソリ抜けてる気がするのだが。
TOGのDistributed I18N Frameworkだとmbstate_tのコンストラクタ(m_creatembstate)を新設し
こいつがmbstate_tにlocale情報を埋めこむことで、mbrtowc(3)他はインタフェースを変えることなく
multi locale対応できるんじゃね? という腹づもりだったと記憶してるのだけども
それ相当の処理とか、直接locale_tを引数に渡すmbrtowc_lのようなものが見当たらないのだが。
なんか俺勘違いしてる?

Unicode5.1.0って今日リリースじゃなかったっけ?

Unihan.txtに未反映だったHKSCS-2004の文字がUnicode5.1.0で追加されてるっぽい。
ちと調べっか。

ふむ。

2008/04/05(Sat)

[C言語] wchar_t != WCHAR && UCS2 != UTF16

ytqwertyさんとこより

ただC標準とはいえWindowsですとUTF-16になる(からパックとも言い切れない)関数なんですよmbなんたらは。

あーMSVCだとtypedef unsigned short wchar_tですからねぇ。
んでもMSVCのmbstowcs/wcstombsってサロゲートペア喰わせてもEILSEQにはならないんでしたっけ?
# 手元のWin2k + VC++6だとBMP外の文字のあるロケール動かんので試せないのだけど
GB18030サポートキットとか入れるとsetlocaleでGB18030ロケールって使えるのだろーか。
でないとwchar_t1文字でその文字集合のすべての文字を表せないので、明らかに規格違反だ(汗。
http://www.opengroup.org/onlinepubs/009695399/basedefs/stddef.h.html

Integer type whose range of values can represent distinct wide-character codes
for all members of the largest character set specified among the locales supported by
the compilation environment:

規格ではwchar_tは最低charのサイズあればいいのですが
16bit wchar_tじゃUCS2=BMPまでしか扱えませんゴメンなさい、だから
32bit wchar_tにしてUCS4まで扱えるようとっとと移行します、となかなかならんもですね。
# っても互換性の問題もあるしなあ。

まあ今 ISO/IEC TR19769New character type in Cみたいな話があるので、そのうち

#if defined(WCHAR_T_AS_UCS2)
#define wchar_t char16_t
#else
#define wchar_t char32_t
#endif

というソレナンテTCHARなやり方で移行を考えてるのかもしれませんが。
いやよう知らんけど。
# ってもmbrtoc{16,32}は戻り値(size_t)-3なんてあるし
# すんなりマクロによる置換は無理だと思いますけどね、 参考コード

結局MSVCのwchar_tは内部UCS2、Win32APIのWCHARはUTF-16で
同じtypedef unsigned shortとはいえ両者は似て非なるもの
(wchar_t != WCHAR && UCS2 != UTF16)だと思うのですよ。
決して混ぜないよう気をつけてコード書くべきなんですが、もう無理かもな。

やぱしwchar_tを使うってことは、ISO-Cにのっとって移植性のあるコードを書くということだと思います。
そもそもwchar_tがUCS4であることを仮定して書いたコードには移植性はありません。
仮にwchar_t=UCS4を__STDC_ISO10646__を盾に認めさせたとしても
wchar_t=UCS2(これはUCS4はUCS2のスーパーセットなのでOK)ならばwchar_t=UTF16でもいいだろうと
サロゲートペア処理するなんてのはwchar_t=1文字という規格すらぶち壊すことになりますやね *1

wchar_t=UTF16が都合がいい、という理由ってのはどうせWin32APIの要求なわけですし
それなら移植性もへったくれもないのでwchart_t/mbrtowc/wcrtombなんぞ使わず
WCHAR/MultiByteToWideChar/WideCharToMultiByteを必ず使えってことですな。

 I18N本はやっぱり買う必要があるのかなあ……高い。

あと kbkさんとこ

 I18N本って「いちまんえん」もする本じゃないですか。

高価な本って不幸の手紙みたいなもんで、他の人に薦めたく(以下略

I18N本は第I章+第II章は国際化プログラミングとは何ぞや? って人には
プログラムを書くときに何を意識すれば良いのかを知るためには優れた内容だと思います。

でもやっぱり第III章実践編はちょっと内容が古くなってますかね。
Unix Cはそもそも化石なので問題ないのですが、X Motif/CDEは今となっては
GTK+/Gnome, QT/KDEあたりの話に触れておく必要があるでしょう。
んでWindowsの話はほんとに僅かなので、そっち系プログラマは肩透かしになると思います。
Javaの話もJSR-204にあわせて書き換えられる必要がありますな。
あとこんだけ若い人の興味がLL方面に向いてる今、そっち系のネタが無いのも辛いかも。

まあ国際化プログラミングとは何ぞがわかっているなら無理して買う必要は無いですね。
国際化関数の使い方なんてそれこそマニュアル読めばいいわけですし。

*1:Javaの場合、java.lang.Characterも16bitだからUCS2=BMPしか扱えないはずのものだったのに
JSR-204でjava.lang.Character=1文字であることを諦めて
UTF-16だからサロゲートしますが、何か? java.lang.Integer=1文字で扱えとなっちゃったけども。

2008/04/07(Mon)

今日

白熱灯は全廃、写真引伸機って蛍光灯で代用可能なのかね?
それよかネオンと自販機とコンビニと参(以下略

今の現場のオヒスって結構古いビルで、蛍光灯の本数が少ない上に
白色管なので昼でも薄暗いのよな、日当たり悪いので太陽の光もこないし。
んで夜自宅に帰ると昼白色なので、明るさが 夜 > 昼 になってしまい
睡眠障害になりそで困る、自宅は温白色に変えようかな。

ちゅーわけでUnicode5.1.0に基づいたHKSCSテーブルの差分 patchfor Citrus iconv。
ついでにUnihan.txtでは欠けてる0x8840 ~ 0x88AAのマッピングもドサクサに紛れて追加。

Big5-HKSCS

Unicode5.1.0のUnihan.txt、HKSCSの0x9EE5がU+47B6とU+27F2Eに重複登録されてんのな。
あとさっきのpatchだと0xC6A1~0xC8FE、0xF9DD~0xF9E4も足りてなかったので追加。

2008/04/10(Thu)

[Windows] mbrtowc(3) sim by MultiByteToWideChar

kbkさんとこより。

glibc側が呼び出している mbrtowcやmbrlen などを自前で実装するのが
一番早そうだという結論に達しました。

昔Cygwin developerのfujiedaさんが、MultiByteToWideCharをwrapして
mbrtowc(3)を実装なんてのをやってましたね、っても記憶では
wchar_tはunsigned shortのままで、サロゲートはダメぽでしたが。

しかーしMultiByteToWideCharをwrapしてmbrtowc(3) simを完全に実装するのは無理だったり。

とゆーのも、mbrtowc(3)では

この2つのケースは明確に区別されていてます。
んで再スタートの場合は変換途中のpartial charsはmbstate_t中に保持しますので

	char c;
	size_t len;
	wchar_t wc;
	mbstate_t *ps;
	do {
		c = ...
		len = mbrtowc(pwc, &c, 1, ps);
	} while (len == (size_t)-2);

ちゅーコードが動作しないとダメ(最近は直ったけど、昔のFreeBSDはダメでしたな)なのです。

しかーしMultiByteToWideCharにMB_ERR_INVALID_CHARSをセットしてる場合
この例のよに1byteづつ喰わせていくと

 DBCS 文字列の有効な後続バイトがない場合、その先行バイトを無効な文字と見なします。

というトンチキ仕様によりERROR_NO_UNICODE_TRANSLATIONが返ってくるので
本当に不正なバイト列だった場合と区別できないのです。

まあこれは無理矢理partial charsと解釈してしまえばある程度は誤魔化せます。
不正なバイト列の発見がMB_CUR_MAX読み込み時点まで遅延しますが
それで問題が起きることは少ないでしょう。

あとは現在のロケールのエンコーディングの

とかもありますな。

つーわけで、そこいらへんの問題を適当に誤魔化しつつ 実装してみた
全くテストしてないのでどこまでマトモに動くかは一切不明。

まあでもL''とL""だけはどうにもならんですな。

同様のものをiconv(3)使って書くと、今度はiconv_tのデストラクタ問題があるのよな。

2008/04/11(Fri)

今日

昨日の POSIX locale sim by Win32API、wctype(3)の実装もつっこんだ。

これ、WIN32APIを呼んでる*_priv()を差し替えれば 以前ちょっと考えてた
sysinst(8)/libhack向けのちんまいlocale実装に使える鴨ね。
# まあi18n wsconsが先なんだろけど。

[Windows] MB_CUR_MAX代わりに

Win32APIにGetCPInfo()というものがあるのだね、知らんかった。

2008/04/13(Sun)

週末

Big5-HKSCSの差分はcommit済み。

DragonFlyBSD、こっちからpatch送らんでも
hasso氏が最新のCitrusに追従してくれたみたいっすな。
なぜかlibc/locale以下は手付かずなのはアレだが。

OpenBSDもそろそろ4.3用のpatch作らんとな。
せめてMB_LEN_MAX 1を32にしてくれりゃ
libcのみの入れ替えで済むのにな。

ふーんMirBSDってC/POSIXロケール = UTF-8で
なおかつBMP=UCS2の範囲までに制限するという
とてもアレな実装だ、えんがちょ。

2008/04/14(Mon)

[Windows][Cygwin] POSIX locale sim by Win32API その3

wctrans回りも 実装してコードも整理したけど完全に飽きた。
残るはwc(s)widthとfgetwc/fputwcとかwprintf family他だけんど、続きを書くかは未定。

うーむシンクロニシティ(not ポリス)。
ちょうどcygwin-developersでfujiedaさんが mbrtowcの実装をMultiByteToWideCharでって話が再燃してたのね。

まあ 前回書いた通りの問題があるので、私の実装のように誤魔化すしかないだろけど。
ちゅうか知らん間にnewlibには BSDL iconvがimportされてたりするので、こっちを使う手もあるな。
MultiByteToWideChar()はワンショットな変換関数で、stateful encodingの場合
変換状態は失われてしまうけど、iconv(3)はpartial charは捨てるけどシフト状態は持ってるし。

iconv(3)を使う実装だとiconv_tをiconv_close(3)するタイミングがL'\0'まで変換した時くらいしかないので
どうしてもメモリリークの可能性がつきまとうのだが、newlib内にiconvあるのなら
iconv_tの内部実装に好きに触れるし問題ないやね。

まあどっちみちwchar_t = UCS4になってしまうので、激しく私の趣味じゃないんだけども。

ちなみに今のCygwinの実装だとnewlibの_mbtowc_r()が呼ばれてるはずなので
wchar_t != UCS4なCSI実装なのよな、Citrus以外では(私の知る限り)唯一
ISO-2022-JPをサポートしてたりする(CitrusのようなISO-2022のほぼ完全実装ではないけど)。

しかしnewlibの_mbtowc_r()ってなぜmbstate_tを要求するのかさぱーり意味不明。
あれ絶対_mbrtowc_r()とごっちゃになってワケワカメでやってしまったちゅー状態だよな。

最大の問題はcygwin1.dllはMB_LEN_MAX=1でビルドされてるので
multibyte localeをサポートしようとするとバイナリ後方互換が壊れることだろう。
あとmingwの方がwchar_t=16bitのままにせざるをえなさげなので
Cygwin側だけwchar_t=32bitにするとなんとなく嫌な問題が起きそうな希ガス。

2008/04/15(Tue)

最近

レイトショーで映画「Control」2回目観てきた、前回眼鏡忘れてたし。
Alexandra Maria Lara萌え。
ついでに24hour Party Peopleの ノベライズげと。

4/26からはBob Dylanをモチーフにした映画「 I'm not there」日本公開っすか。
この監督の Velvet Goldmineって未だ観てないんだよな、買ってくるか。

そいやグラムといえば昔引越しのドサクサでいろいろ無くしてしまったうちの1枚
Ziggy Stardust/David BowieのRykodisk盤が近所の古本屋で\500で売ってたので、これもゲット。
30周年記念盤は拝啓EMI殿のCCCDにお布施するほどの魅力はなさげだし。

2008/04/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に縛られるからね。

2008/04/18(Fri)

perl iconv

piconv -l するとRFC2047 MIMEとかまで出てきてワロタ。
やっぱり人によって文字符号化手法とそれ以外の線引きって違うモンタナ。

よーし俺も

iconv -f AES -t bzip2

とか実装しちゃうぞ、src/lib/libcにopensslにbzip2つっこんじゃうからな(やめなさい

2008/04/20(Sun)

今日

元気だった頃の 相棒

ここ数日の荒れた空から一転晴天となった昨日
ベランダで最後の日向ぼっこをしばし楽しんだ後
深夜にお別れとなりました。

ありがとな。

2008/04/21(Mon)

[NetBSD] std::locale loc("")

freebsd-i18nより。

$ LC_ALL=de_DE.UTF-8 ./test
C setlocale()
result=C/de_DE.UTF-8/C/C/C/de_DE.UTF-8

C++ std::locale
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
Abort (core dumped)
$

ふむNetBSDでも同じだなーと思って、該当個所のソース読んで笑った。

  void
  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
                                    __c_locale)
  {
    // Currently, the generic model only supports the "C" locale.
    // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
    __cloc = NULL;
    if (strcmp(__s, "C"))
      __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
                            "name not valid"));
  }

要はmulti-localeが実装されてるのはglibc2だけ、ちゅーことっすね。

まあlibc側でsetlocale(3)のreentrant版を用意して
(FreeBSDはアレだが、Citrusは対応してるので難しいことではない)
libstdc++で使うNetBSD用のfacet書けばmulti-localeもOKちゅうこと。
いちおTODO入れとく、が今精神的にダメ。

ksh: cat: not found

[NetBSD] locale_tのようなもの

setlocale(3)をreentrantにするならlocale_tのようなものをどっかに定義しないとならん。
まあ順当に考えるとsys/localedef.h(OSF/1由来、でも移植性は無い)なのだが
src/lib/libc/locale/runetype.hの内容もこっちに持ってくるのはかなり嫌っすな。
localedef(1)の為であればファイルフォーマット(_FileRuneLocale)だけ定義あればいいからね。
その意味では今のlocaledef.hに定義されてるstruct _TimeLocale他も
ファイルフォーマット用とlibc内部用とで分割しなければならないのだけど。

そもそもCitrus(mbrtowc/wcrtomb/iconv) + RUNE(wctype,wtrans,wcwidth)の
コードってsrc/distあたりに置きつつlibc/locale以下はインタフェースだけにして
locale実装をいつでも変更可能なように(例えばそうlibhack向けなんかにね)しとくのが
理想ちゃー理想なんだよな。
Citrusはsrc/distじゃないけど現状別ディレクトリ(src/lib/libc/citrus)にはなってるけど
RUNEはsrc/lib/libc/locale以下から分離できてないのだよな。

んでsrc/distに移したCitrus/RUNEはGNU libiconvとかIBM ICUのように
他のOSでも使える実装として単体配布できるようにしとくといいのだろね。
(GNU autotoolとかよー知らんのでやりたい人に任せますが)

ってもcollationとかregex次第ではAPIガンガン変わるだろうし
今はその時期ではないやな。

2008/04/22(Tue)

昨日

ストレスで随分胃をヤられてたよで、ここ2晩ほど猛烈な吐き気で目が覚めた。
ちゅーわけでしばらくAFK。

連休はヤツの故郷、諏訪の祭神様んとこに宜しくお願いしにいくべ。
捨てられっ子だったので、ヤツはカーチャンJ( 'ー`)しの顔を知らないのだ。

2008/04/27(Sun)

[C言語] iconv(3) buffer size problem

kbkさんよこより Cygwin + pax(1)ネタ
CygwinではMB_LEN_MAX=1であることはmbrtowc(3)等に影響はありますが
iconv(3)にはそもそも無関係、変換後バッファのサイズ計算に
MB_LEN_MAXを使うこと自体が間違いなのです、 ここ参照。

あとGNU系でよく使われるxmalloc(outlen)ってoutlen + 1で
malloc(3)してた記憶があります(zero length malloc及びstring nul terminate対策)
なのでout of index boundsにはならないかと。

[NetBSD] source-changes

うーむ、weってこれcommitしたの自分でしょが(笑)。
backout食らって悩んだ俺、とりあえずお疲れ。

関連で思い出したのだが、放置プレイ中の lib/33262
なんだけど、このへんwork areaのkleink氏って最近見ないな。

あとstrto*系全般の バグもfix入れると
えらい性能落ちるので、書き直そうと思いつつ放置中。

2008/04/29(Tue)

[NetBSD] multi-locale

お筆先にまかせて書き散らかしてみると こんな感じっすかね。
あんまり真面目にインタフェース設計してないのでツッコミ歓迎。

ja_JP.ISO2022-JPと性能の事を考えると、vfprintf(3)なんかも
ロケール毎に実装を切替可能だといいよね、という話が 以前でたのだが
同様の問題がstrto*とかstrf*にもあるのだよな。

[NetBSD] printtf(3)

あとどーでもいいけど

printf("%s\n", NULL);

は*BSD系は伝統的に

(null)

が出力されるのだけど、chiristos氏がpositional orderなprintfつっこんだあと
セグポるようになったね、実装依存なので別にセグポでもいいのだけど

printf(" %s\n", NULL);

のように前にスペースとか入れると

 (null)

と出力されよるので、おそらくバグでんな。

2008/04/30(Wed)

[NetBSD] multi-locale その2

sodaさんからご指摘を頂きまして

_isalnum_r(_locale_t, int);

をglibc2やMacOS X, VC++などに合わせて

_isalnum_l(int, _locale_t);

改めました、つかMacOS XとVC++も最近はmulti-locale実装してたのね。
完全に時代に取り残されてるわ。

メモ。

あとTOGのDistributed I18N Frameworkでは

という仕様に倣っていた部分を改め、_locale_tを引数にとるmbtowc_l、mbrtowc_lを追加する予定。
#これ、個人的には_locale_tとmbstate_tの組み合わせを意識しなければならなくなるのが嫌 *1なのだけど
#今のCitrusのコードはDistributed I18N Framework風にmbstate_tに_RuneLocaleを埋め込んでます。

まあfgetwc(3)なんかだと、FILEの中のmbstate_tにどーやってlocaleオブジェクト埋め込むか
# fopen(3)のmodeを拡張するとかしかないよな…
を悩まずに済みますやね。

あと全然関係ないんだけど、4.99.61に入れ換えたらpthread絡みで
perlからなにからみーんなmemory faultでコケるじゃあーりませんか orz

*1:あとnewlocale(3)だけってのもちょっと嫌なのよね、setlocale(LC_ALL, NULL)のmulti-locale版が無いから。

週末

No fun to be alone(by Iggy Pop & The Stooges)

近所の諏訪神社にお参り、子連れの狛犬さんだったのでカーチャン探してくれるだろ。
3日は下諏訪の大社にお参りに行く予定、 8時ちょうどのあずさ乗るのも久々でんな。

某所で期限切れ2008/07のフジ センシア(RAIII)20本入りが50%なのにグラッときたのだけども
今はディスコンが近いEPNで一枚でも多く撮る予定なので使い切れんからスルーかな。
EPNが店頭から消えたら、コダEPP or E100G、フジRAIIIのどれに移行するかは未定。
アスティア(RAP)もあるのだけどちと高いよな。

Hi-Matic Fの黒とシルバーの2台をジャンクで入手。
黒は全く問題なしで、かなりお得な買い物だったのだが
シルバーの方は巻き上げレバーがつっかかるのと
シャッターと露出計が不動だ、断線 or コンデンサ不良かな。