print関数のフラグを追加する方法

print(f)関数を使っていてフラグ(%につづく文字列)を自由に定義できたらと思ったことはないだろうか?例えば、URLエンコーディングが必要なときに、

    encoded = smprint("%s", urlencode(s));

じゃなくて、

    encoded = smprint("%R", s);

みたいな感じに書くと、print関数の中でURLエンコードしてくれるとか。

Plan 9ではfmtinstall関数を使うと、上記のようなことが実現できる。#pragmaはprint関数でワーニングが出ないようにするためのおまじないだ。

    #pragma varargck type 'R' char *
    int urlencode(Fmt *);

    fmtinstall('R', urlencode);

先日のPlan 9勉強会でこっそり#plan9greeのtweetを監視するtwitter clientをでっち上げて動かしながらプレゼンしていたんだけど、「#」を「%23」に変換するためにこの仕掛けを使っていた。コードは例によってgithubに上げた。urlencode.cが該当する処理。

ちなみに動かし方は、

% mk nuke
% mk all
% mk install
% ticker '#plan9gree'