デバッグのためのデバッグのためのデバッグ
MinGW版はBufferdFileBinaryInputPort.cpp:179 でASSERT
Consoleに直接アクセスしてるとCygwinの端末やシェルスクリプトから使えない(= gdbが使えない)ので回避ルーチンを書く(要するに元に戻す)
(そもそも自前のターミナルエミュレータを前提に作ってあるskymoshに関してはこの部分のパッチを常に行っている)
しかし、それらが上手く働いているのかを確かめる術がない
アナリストのデザイン
コンソールのcodepageをUTF-8(65001)に設定するのってなんでダメなんだっけ*1?
もっとも :
- Win32コンソールやそれを使うアプリケーションは多言語の扱いが圧倒的に間違っている
- Win32コンソールを使うとアトリビュートの設定が比較的面倒
- Win32コンソールはコピペが面倒
- Write/ReadConsoleはコンソールにしか使えないのでstdout/in/errがコンソールかどうかを判別するコードが必要
emacs必須とかで一つ。。
異文化
まぁ、要するに諸悪の根源はUNIXとWin32で多言語周りに関するデザインチョイスがかなり違うことだとは思う。
まず、Cの標準でwchar枠を作って、Cの標準ライブラリのうち文字列の処理とかは共通化され、fopenとかはそのままになったという前提を考える。
- UNIXの場合
プログラムは明示的にwcharに対応する必要が生じ、かつ、標準的なwchar対応のopenやstatは準備されなかった(なぜならそれらはシステムコールだから)
今でも多くのアプリケーションはwcharではなくcharを使い、メッセージなどの必要に応じてはgettextなど別の方法論を使っている。
- Windowsの場合
WinNTはそもそもwcharを前提にデザインされているので*2、すべてのAPIはwcharを受け入れるようにデザインされている。
同時にWin9xのようなcharを前提にデザインされたシステムとソースコードを共通化したいという需要も有るわけで、ほぼ全ての必要なAPIと構造体にはwchar版とchar版の両方が用意され、コンパイル時にUNICODEが定義されているかどうかで切り替えられるようになった。
つまりCreateFileとだけソースコードに書かれていても、実際に呼ばれるのはCreateFileA(char版)とかCreateFileW(wchar版)と別々の関数になる*3。実際にはWinNTの内部はUnicodeで処理しているので、〜Aの関数はwrapperであり実際の処理を行うのは〜Wになる(Win9xは逆)。WindowsCEではそもそも〜Aが存在しない(常に/DUNICODEされる)。
選択肢
どう対処するのかは様々な選択肢があるし、これはどれが望ましいとも一概には言えない。
- 1. Win32を全面的に使い、OS抽象化ライブラリを作る(現在のチョイス)
- 2. Cライブラリをshift-jisで使う(個人的なおすすめ - VCのランタイムよりもCランタイムを上手く作れる自信が無いなら)
- 2a. wchar版のCライブラリも混ぜる(printfにおける%lsとか)
- 3. skymoshのように必要最低限の入出力だけを言語実装に持ち、残りをSchemeに移行する
- 4. Win32側に揃えて、Cライブラリの方をwrapする
- 5. GlibとGtkを使う
追記 : そもそも、プログラムのコードページをUTF-8に変えたら、Cライブラリをそのまま使うだけでよくなったりしないだろうか。。
追記 : わざわざ断ってあった
ANSI、OEM、またはオペレーティング システムがサポートする他のコード ページ値に関係なく、その他の有効なコード ページ値 (サポートされていない UTF-7 および UTF-8 を除く)