2008/03/03(Mon)
○ 週末
Hi-Maticのピント調整がイマイチだったのでバラして組み直したり。
最近買ったもの
- Core Memory ― ヴィンテージコンピュータの美
ここ2年くらいコンピュータ書籍コーナーには近寄らんのだけども、これは久しぶりのオライリー本。 - マグナム―報道写真半世紀の証言 / ラッセル・ミラー
- 宇宙飛行士が答えた500の質問/マイク・ミュレイン
○[NetBSD] Citrus iconv
すっかり忘れてたのだが、 この問題も直さないとな。
前回の ISO-2022-JP問題の対応がいまいちいちイケてないわけですな。
もうちょいコード整理しないとアレだけどこんな感じ?
Index: citrus_iconv_std.c
===================================================================
RCS file: /cvs/cvsroot/src/lib/libc/citrus/modules/citrus_iconv_std.c,v
retrieving revision 1.15
diff -u -r1.15 citrus_iconv_std.c
--- citrus_iconv_std.c 13 Nov 2006 19:08:19 -0000 1.15
+++ citrus_iconv_std.c 3 Mar 2008 09:30:48 -0000
@@ -477,6 +477,57 @@
if (in==NULL || *in==NULL) {
/* special cases */
if (out!=NULL && *out!=NULL) {
+ for (;;) {
+ ret = get_state_desc_gen(
+ &sc->sc_src_encoding, &state);
+ if (ret)
+ goto err;
+ if (state == _STDENC_SDGEN_INITIAL ||
+ state == _STDENC_SDGEN_STABLE)
+ break;
+ save_encoding_state(&sc->sc_src_encoding);
+ save_encoding_state(&sc->sc_dst_encoding);
+
+ /* XXX FIXME, need to heavily rework. */
+ tmpin = "";
+ szrin = 0;
+ ret = mbtocsx(&sc->sc_src_encoding,
+ &csid, &idx, &tmpin, 1, &szrin);
+
+ if (ret)
+ goto err;
+ if (szrin == (size_t)-2) {
+ ret = EINVAL;
+ goto err;
+ }
+ /* convert the character */
+ ret = do_conv(is, sc, &csid, &idx);
+ if (ret) {
+ if (ret != E_NO_CORRESPONDING_CHAR)
+ goto err;
+ ++inval;
+ szrout = 0;
+ if ((flags & _CITRUS_ICONV_F_HIDE_INVALID) == 0 &&
+ is->is_use_invalid) {
+ ret = wctombx(
+ &sc->sc_dst_encoding,
+ *out, *outbytes,
+ is->is_invalid,
+ &szrout);
+ if (ret)
+ goto err;
+ }
+ } else {
+ ret = cstombx(&sc->sc_dst_encoding,
+ *out, *outbytes,
+ csid, idx, &szrout);
+ if (ret)
+ goto err;
+ }
+ *outbytes -= szrout;
+ *out += szrout;
+ }
+
/* init output state and store the shift sequence */
save_encoding_state(&sc->sc_src_encoding);
save_encoding_state(&sc->sc_dst_encoding);
@@ -505,12 +556,8 @@
/* normal case */
for (;;) {
- if (*inbytes==0) {
- ret = get_state_desc_gen(&sc->sc_src_encoding, &state);
- if (state == _STDENC_SDGEN_INITIAL ||
- state == _STDENC_SDGEN_STABLE)
- break;
- }
+ if (*inbytes == 0)
+ break;
/* save the encoding states for the error recovery */
save_encoding_state(&sc->sc_src_encoding);
@@ -524,22 +571,8 @@
if (ret)
goto err;
- if (szrin == (size_t)-2) {
- /* incompleted character */
- ret = get_state_desc_gen(&sc->sc_src_encoding, &state);
- if (ret) {
- ret = EINVAL;
- goto err;
- }
- switch (state) {
- case _STDENC_SDGEN_INITIAL:
- case _STDENC_SDGEN_STABLE:
- /* fetch shift sequences only. */
- goto next;
- }
- ret = EINVAL;
- goto err;
- }
+ if (szrin == (size_t)-2)
+ goto next;
/* convert the character */
ret = do_conv(is, sc, &csid, &idx);
if (ret) {
以前のエントリではdst(cs/idx -> wc -> mb)側のstate objectを初期化するput_state_reset()と同様に
src(mb -> wc -> cs/idx)側のstate objectも初期化する必要があるよね、と書いたのだけども
ここではmbtocsx()で代用してる(XXX FIXMEの部分)。
この部分どうしようかね、mbtocs()が内部で呼ぶmbrtowc_priv()は
mb = NULL;
mbrtowc_priv(ei, &wc, &mb, 0, ps, &nr);
という呼出をした場合、mbrtowc(3)の仕様である
If s is a null pointer, the mbrtowc() function shall be equivalent to the call: mbrtowc(NULL, "", 1, ps)
通りの動作をするので、wcを無視してpsを初期化しちまうのだが
DR#288のケースをうまく扱おうとするとここは
「psの中にまだ変換可能なwchar_tがある場合、それを吐き出す」
という動作をして貰いたいよな。
今は緊急避難で"", 1を喰わせて回避してるのだが、ちとkludge過ぎる。
というのも、VIQRならこれでも解決するんだが、UTF-5のバヤイそもそも""はillegal byte sequenceだ罠。