Gauche:内部エンコーディング
yaegashiさんのところから引越し。
内部エンコーディングを実行時に切替えるには?
WiLiKi の Debian パッケージで苦労したので、 Gauche が実行時に(コマンドラインオプションなどで) 内部エンコーディングを指定できるようにできないかと思いソースコードを眺めています。 char_euc_jp.h などの中で定義されているマクロ類を グローバル変数や関数ポインタに定義しなおせば実現できるような気がしますが、 SCM_CHAR_NBYTES() とか繰り返し読んでいるところではえらく速度が落ちそうです。
関連する話題
方法の検討
- コンパイル時の選択でマクロ埋め込み(現在のバージョン)
- pros
- 実行効率が良い
- cons
- バイナリから何もかもエンコーディング依存になってしまう
- 簡単に他のエンコーディングを試せない
- 外部モジュールもエンコーディング依存になってしまう
- pros
- コンパイル時選択、複数エンコーディングインストール可
別々のエンコーディング用にコンパイルされたバイナリやライラリファイルを (ディレクトリを分ける等で)同時にインストールできるようにする。
- pros
- 少なくとも起動時にエンコーディングを選択するくらいのことはできるようになる
- cons
- 外部モジュールは依然としてエンコーディング別にコンパイルする必要あり。
- 全てを重複して持つのは無駄が多い。
- pros
- エンコーディング依存のマクロをポインタ経由の関数呼び出しに置き換える
- pros
- 実行中にも切替えられる
- 外部モジュールやライブラリはエンコーディング非依存にできる
- cons
- 速度低下が心配
- そもそも、内部文字列が作られてしまっている状態で内部エンコーディングを 切替えることが必要か
- pros
- エンコーディングに依存するモジュールのみ別のdsoとしてコンパイルする
マクロを関数に置き換えるよりも粒度の大きい方法。
- pros
- inner loopではマクロ展開が効くので、速度低下はあまりないだろう。
- 外部モジュールは(エンコーディング依存マクロを直接呼ぶ必要がある ものでない限り)一回のコンパイルで済む
- cons
- 必ずいずれかのエンコーディング依存モジュールをdlopen()でロードしなければ ならないとなると、dlopenが動かない環境で全く使えなくなる。
- 起動時にスクリプト等でdsoのサーチパスをいじる等の方法でも 機種依存性が高くなる。
- pros
エンコーディングマクロに依存している部分
yaegashi(2002/12/22 01:46:39 PST): エンコーディングにかかわる部分だけ別の .so に分離することは簡単かと考え、 手始めに SCM_CHAR_* マクロの呼び出され具合を src/*.o について調べてみたところ、 以下のファイルで使われていることがわかりました。 これらを libgauche から分離して、 エンコーディング毎に別ディレクトリに格納とかできるといいかな?
char.o: U SCM_CHAR_ENCODING_NAME U SCM_CHAR_MAX_BYTES U SCM_CHAR_NBYTES U SCM_CHAR_PUT main.o: U SCM_CHAR_ENCODING_NAME port.o: U SCM_CHAR_GET U SCM_CHAR_MAX_BYTES U SCM_CHAR_NBYTES U SCM_CHAR_NFOLLOWS U SCM_CHAR_PUT read.o: U SCM_CHAR_MAX_BYTES U SCM_CHAR_NBYTES U SCM_CHAR_PUT regexp.o: U SCM_CHAR_GET U SCM_CHAR_MAX_BYTES U SCM_CHAR_NBYTES U SCM_CHAR_NFOLLOWS U SCM_CHAR_PUT string.o: U SCM_CHAR_BACKWARD U SCM_CHAR_GET U SCM_CHAR_MAX_BYTES U SCM_CHAR_NBYTES U SCM_CHAR_NFOLLOWS U SCM_CHAR_PUT symbol.o: U SCM_CHAR_GET U SCM_CHAR_NBYTES
あと SCM_CHAR_MAX_BYTES が 構造体や配列の宣言で使われているところがありましたが、 これについてはサポートするエンコーディング中で最大のもの(6?)とかにしてしまえば よいでしょうか。