Barbarism begins at internet:2006年10月分

2006/10/01(Sun)

NetBSD

@vfprintf/vfwprintf positional order/wide character support

きのこ先生のお導きでバイク小屋^H^H^H^H^Hsrc/doc/ROADMAP 読んでたらコーヒー噴いた。

        (a) Support cond. printf fmt    tnozaki                         3.0
		Responsible: tnozaki
		ETA: 3.0

俺かYO!大昔bsd-localeだかtech-userlevelだかに投げたpatchのことか。
誰かがFreeBSDからvfwprintfをパチってきてたんで
じゃあvfprintも持ってくるだろから無駄だなと思って止めちゃったんだよな。
あのpatchはwide character対応だけだったんだけど
その後positional orderまで実装して放置状態だったんだよね。 ものは ココ。この実装だと

printf("%1$E %1$d", 0.12);

みたくformatでargumentに異なるサイズを指定した場合

printf("%E %d", 0.12, (int)0.12);

と解釈して表示するよーに実装してあるんだけど
FreeBSD/Linux/Solarisいずれの実装もそこまでの世話は焼かないし
gcc4はformat中で異なるサイズを指定した場合ちゃんと警告を出す。
削ってしまった方がいい鴨。

  • コードの整理。
  • NL_ARGMAXの大きさを増やした方がいいのかとか。
  • 性能
  • テストケース

をやるべか…。

@とりあえずprintfに関するsend-pr

を調べた。
lib/1862scanfは未着手。
lib/22019上で晒した実装では直ってます。
lib/18803
lib/32290__ldtoa/__hdtoa/__hldtoaに手を出さんといけないらしい。

@LC_NUMERIC

のdecimal_point/thousands_sepってlocaledef(1)の書式だけ見ると

CHARMAP
<UFF0E>	\xA1\xA5
...
LC_NUMERIC
decimal_point	"<UFF0E>"

のように書いても良さそうなんだけど、仕様にはしっかりとワイド文字指定した場合の動作は未定義と書いてあんのね。
まあstateful encodingでlocaleconvが困るし当然か。

2006/10/02(Mon)

NetBSD

@vfprintf/vfwprintf positional order support

仕様書読み直し。
%n$のpositional orderが指定されない場合、引数はNL_ARGMAXを超えても良さそうだな。
そもそもpositional orderが入る前のprintfの仕様にはNL_ARGMAXについての言及が無いから
互換性を考えるとそうでないと困る罠、つーわけで後で直す。

@mbstate_t

opaque objectであるmbstate_tの初期化は

  1. mbrtowcで初期化する
    mbstate_t st;
    mbrtowc(NULL, NULL, 0, &st);
    
  2. memsetで初期化する
    mbstate_t st;
    memset(&st, 0, sizeof(st));
    
  3. 初期化子を書く
    mbstate_t st = { 0 };
    

の3通りの方法があるんだけども、NetBSDの場合gcc4になってから
unionの初期化子チェックが厳しくなったせい?で、3.をcompileすると

test.c:6: warning: missing braces around initializer
test.c:6: warning: (near initialization for 'st.__mbstate8')

つー警告が出るようになった。
修正方法はmachine/ansi.hの

typedef union {
	char __mbstate8[128];
	__int64_t __mbstateL;   /* for alignment */
} __mbstate_t;

typedef union {
	__int64_t __mbstateL;   /* for alignment */
	char __mbstate8[128];
} __mbstate_t;

とすることで、指示子がない場合__mbstateLがdefaultになり回避可能。

@vfprintf/vfwprintf

/distfiles/citrus/NetBSD/vfprintf-20061002.tar.bz2
更新。

2006/10/03(Tue)

NetBSD

@mbstate_t

gcc -Werror -Wmissing-bracesで

mbstate_t st = { 0 };

がエラーになる件はgcc3でも同じだった。

2006/10/04(Wed)

NetBSD

@mbstate_t

ついでにmbstate_tネタ。
Citrusの場合、mbsrtowcs/wcsrtombsを使うよりも
mbstowcs/wcstombsを使う方が性能的に有利な可能性がある。
前者を使う場合、mbstate_tの初期化はユーザの責任なので

mbstate_t st;
char *s;
const wchar_t *ws = L"...";
memset(&st, 0, sizeof(st));
n = wcsrtombs(NULL, &ws, 0, &st);
if (n == (size_t)-1)
	abort();
_DIAGASSERT(n != 0);
s = malloc(++n);
if (s == NULL)
	abort();
_DIAGASSERT(mbsinit(&st));
wcsrtombs(s, &ws, n, &st);
...

のようにmemsetなりで初期化してやる必要がある。
しかしNetBSDの場合 sizeof(mbstate_t)が割と大きい(=128)実装なので
この部分が繰り返し呼ばれるとちょっとしたボトルネックになる。

char *s;
const wchar_t *ws = L"...";
n = wcstombs(NULL, ws, 0);
if (n == (size_t)-1)
	abort();
_DIAGASSERT(n != 0);
s = malloc(++n);
if (s == NULL)
	abort();
wcstombs(s, ws, n);
...

と書き換えると、mbstate_tの初期化には_citrus_${ENCODING}_init_stateが呼ばれ
各encoding moduleに最適化されほんのちょっとだけ早くなる。

2006/10/09(Mon)

OpenBSD + Citrus

@20061009版

4.0もそろそろらしいので、全くテストしてないけど。
/distfiles/citrus/OpenBSD/
いちお最近漏れがNetBSD-currentで弄った部分はmergeしてあります (ただし相変わらずwprintf/wsanf周りは未merge)。
いつもの通りの注意事項ですがMB_LEN_MAXが1→32になってる関係上 バイナリ互換性は失われています。
ユーザランドは全部作り直して下さい。

昔みたいに__RENAMEマクロ使った対策パッチ作ってもいいんだけど、 multibyte localeを使おうと思ったら
どっちみちユーザランドは作り直しだし、どーせlibcのmajorもすぐ上がるしで バイナリ互換維持するメリットが(以下略

NetBSD

@vfprintf/vfwprintf positional order

動かなくなてた、ちょと修正。
/distfiles/citrus/NetBSD/vfprintf-20061008.tar.bz2

テストケースは絶賛停滞中…めんどい。

2006/10/14(Sat)

今週

ロイホで会計中に突然レジが故障、EMP効果をマジ疑った。

NetBSD

@元祖天才バガソン

  • lib/18521
    まだ他にもprintfのPRあった。漏れの実装ではLC_NUMERIC対応してあるので直ってる。
  • lib/23460
    wcs*ネタ、あとで性能どれくらい上がるかとかバグ無いかとかチェックする。
  • lib/30809
    manネタ、今朝方commitした。
  • lib/11546 lib/25877
    LC_COLLATEはさておき、これlocale.aliasで片付けちゃっていいのかな。

@hpcboot(8) + dk(4)

root device指定のオプション文字列を渡せばいいだけっぽいので port-hpcarm/34814とでもしとけばいいんじゃないかな。
うちの MorJornada710はこれでおkだった。
そいやGNATにport-hpcって無いのね。

2006/10/18(Wed)

NetBSD

@iconv support S.Korean encoding `JOHAB'.

ファミレスで飯食いながらてきとーに実装、かつとじ鍋うまうま。家に帰ってからテスト。
EUC-KR等との変換時にISO-2022-JP-3-strictと 同じ問題が発生するので
iconvdataをKSC5601をハングルと漢字記号に分けたけど
やっぱりesdb側でqualityを制御できるようにしたいね。

BTS

@CVS commit mail

むかーし使ってたcvswebへのリンクを追加する改造を加えたFreeBSD版log_accume.pl他。
/distfiles/citrus/NetBSD/log_accum.tar.gz
使い方はこちら↓。
http://www.jp.freebsd.org/www.FreeBSD.org/doc/en_US.ISO8859-1/articles/cvs-freebsd/article.html
非常にいい加減な仕事ですが日本語メールも使えるようにしてあったり、cfg_local.pm参照。
そのうちRSS生成するようにしようとか思ってたんだけど、最近はSVN + Trac使ってるからやる気にならん。

2006/10/19(Thu)

pkgsrc

@devel/apr

pkgsrc/26056、これlibaptutilのapr-iconvに依存してるpackage(subversion-baseとか)も
pkg revision上げなきゃダメなんじゃないかな。mk.confに

PREFERE.iconv=	pkgsrc

をセットしてる場合(会社で使わされてるFC2のglibc builtin iconvだとsambaが困る)
make replaceでaprだけ入れ替えると

-bash-2.05b$ svn
svn: error while loading shared libraries: /usr/pkg/lib/libaprutil-0.so.0: undefined symbol: libiconv_open

となってしまうジャマイカ。

@つーわけで

バイナリ互換性ないならsubversion-baseをrebuildすんべと思ったら

=> Required installed package libtool-base>=1.5.18nb5: libtool-base-1.5.22nb3 found
=> Required installed package apr>=0.9.7.2.0.55nb2: apr-0.9.12.2.0.59nb1 found
=> Required installed package neon>=0.25.5nb2: neon-0.
(中略)
collect2: ld returned 1 exit status
*** Error code 1

Stop.

うーん、libiconvへの依存関係がマズイもより。
*.mk読んでる暇がないのでwork/.buildlink/libの下に
libiconvへのsymlink貼って逃げた。

NetBSD

@Citrus iconv vs GNU libiconv

pkgsrcのGNU libiconvがサポートしてCitrus iconvがサポートしないCESはあとこんだけかな?

C99			※1
JAVA			※1
MACHEBREW		※2
MACARABIC		※2
MULELAO-1
CP1133
TIS-620
VISCII
TCVN
CP51932			※4
CP50221			※4
ISO-2022-CN-EXT
HZ			※1
BIG5-HKSCS		※3
CP922
CP943
CP1046
CP1124
CP1129
CP1161
CP1162
CP1163
DEC-KANJI
DEC-HANYU
CP853
CP858
CP1125
EUC-JISX0213		※2
SHIFT_JISX0213		※2
ISO-2022-JP-3		※2
TDS565
RISCOS-LATIN1

※1 module/iconvdataは書いたけどまだcommitしてない
※2 iconvでm:n変換を実装する必要あり
※3 変換表は入手してある
※4 既存のmoduleの修正が必要かも
なかなか追いつかんね...いや追い付いてどうすんだという話もあるが。

Unicode.org

@小林克也のBestFit(以下略

これ何だろ。
ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/ WideCharToMultiByteはそのロケールにないワイド文字が渡された場合
強引に似た字に置き換えるらすいんだけど(んで時にセキュリティホールになる奴ねw)
そのルールを決めた変換表なのかな。

続NetBSD

@iconvdata

/usr/share/i18n以下が全部で8.8MB。
UCS%*が無駄に領域喰ってるのよね...

SRC_ZONE= 0x0000 - 0xFFFC
BEGIN_MAP
0x0000 = 0x00
0xFFFC = 0x1
END_MAP

みたいな極端なケースだと、0xFFFA*sizeof(uint32_t)の領域は
そのままディスクの無駄領域なんだよね。速度を優先してるんだろうけど
8bitに収まる文字集合くらいなら詰めこんでbinary searchで問題なさげ。
そのうちなんか考える。

2006/10/26(Thu)

NetBSD

@Citrus iconv

ISO-2022-CN-EXTのサポートを追加。
これ、ISO-IR-165では0x2A21-0x2A7Dにhalfwidth latinを割り当ててるけど
これをUCS変換時に0x21~に変換しちゃうと安全じゃないケースがあるので禁止しておいた。

ちなみにGNU libiconvは

^[$)E^N*/^O

をiconv -f ISO-2022-CN-EXT -t UTF-8 すると

/

に変換しちゃう。
まーこれでdirectory traversalが成功してもiconvのせいじゃなくてアプリが悪いんだけどね。

2006/10/27(Fri)

NetBSD

@Citrus iconv

UTF-32変換の際サロゲート領域0xD800-0DFFFをスルーしちゃうlibUTF1632のバグはけーん。
後でcommitしておくべ。

いちおう他の実装でテストした結果↓

Solaris8 iconv … OK
GNU libiconv … OK
glibc iconv(Fedora Core 2) … NG

2006/10/29(Sun)

GNU libiconv vs sun-JDK native2ascii

@``JAVA'' encoding

どうでもいい話なんだけど

$ native2ascii -encoding UTF-8
$ iconv -f UTF-8 -t JAVA

は同じ変換をするんだけど、逆のケース

$ native2ascii -reverse -encoding UTF-8
$ iconv -f JAVA -t UTF-8

は微妙に動作が異なるね。

前者に8bitな文字(つまりASCIIじゃない文字ね)を喰わせると\xEF\xBF\xBD(=U+FFFD)に置換するのだが
後者はU+0080~U+00FFと解釈して変換しちゃうみたい。
つまりGNU iconvはnative2ascii互換じゃなくてnative2iso8859-1だったんだよ!!(なんだってーAA略)

2006/10/30(Mon)

NetBSD

@vsnprintf_ss(signal-safe vsnprintf)

syslog_r(3)祭りでvfprintfもちょっと手が入った模様。
いつぞやのstrtonum(3)といい最近のOpenBSD由来のAPIは(以下自粛

SUSv3にあるasync-signal-safeなfunction一覧↓
http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
stdargのva_*マクロが呼んでるgccの__builtin_va_*は(調べたことないけど多分)セーフ。
localeconv、mbrtowcは例外ありMT-safe、__dtoaはmallocやmutex依存なんでアウト。
なのでstruct FILEに__SAFEフラグが立っている場合、これらを回避するkludgeを用意したってことらすい。

んでstrftime_ssはまだ作業中?

@安全なシグナル処理のために再入可能ファンクションを使う

そういやこんな記事があったなぁ。
http://www-06.ibm.com/jp/developerworks/linux/050210/j_l-reent.html

@つーわけでTODO追加

うちのpositional order対応vfprintfもそのうち直す。
つかテストケース書くモチベーションが無くて進んでないのよね…

@性能

今のNetBSDのvfprintfは%[doux]を指定した場合無条件でintmax_tを使うのでわりと遅い。
うちのやつでは直してある、gprofマンセー。

@vfscanf positional order対応

そろそろ手をつけるかな。

format stringから1文字読むごとにFILEからも1文字読んで比較する方が多分速いんだけど、
%sが指定された場合、orderが確定してない状態では直接va_argに書き込めない。
なもんでFILEから読み込んだ文字列を保存しておく必要があるのよね。

でもwidthが指定されない限り、長さが不定なのでmallocを使わざるを得ない。
メモリ使用量増えるしなによりvfscanf_ssが必要になった時「%s はダメ」制限はイクナイ。

format stringを最後までparseしてorderを確定した後、もう一度format stringを巻き戻して
FILEから読み込んだ文字との比較をするという作りじゃないとダメっぽいな、無駄だ…。

2006/10/31(Tue)

BTS

@trac-0.10

NetBSDのpkgsrcも0.10に更新されたのでインスコしてみた。

非UTF-8ロケール時でもTimelineの日付は文字化けしなくなったけど、Updateボタン押すとダメぽ。
ソース見てみたけどtrac/util/text.pyとかtrac/util/datefmt.pyがより一層グダグダ化してるもより。
というわけで0.10対応した不具合解消patch↓
/distfiles/trac/

以前作ったChangesetでのraw unified diff出力する時の文字コードと改行コードを指定できるようにするパッチは
今回廃止(理由:ダサいから)、patch(1)で扱えるdiff出力が欲しい場合はsvnやTortoiseSVNでどぞ。