[Anthy-dev 2508] Re: r5rs: portの抽象化

アーカイブの一覧に戻る

Jun Inoue jun.l****@gmail*****
2005年 10月 9日 (日) 09:57:25 JST


On Sat, 08 Oct 2005 10:15:45 +0900
YamaKen <yamak****@bp*****> wrote:

> > > struct ScmCPortVTbl {
> > >     ScmObj (*type)(ScmCPort cport);  /* returns a symbol */
> > 
> > 変数にした方がいいでしょう。途中でコロコロ変わる必要は無いし、変わられて
> > も困る。
> 
> これは変数にしようか迷ったんですが、constなグローバル変数として
> テーブルを初期化するにはstorageの初期化が必要なScmObjは都合が悪
> いので関数にしました。動的にIDを変える目的ではないです。

あ、変える「目的がある」と誤解したわけではなくて、「変わってしまうバグが
恐い」という話です。どっちでもいいですが。


> ついでに突っ込まれそうなんで説明しておきますが、手動でシンボル
> ('ScmStrPortとか)を割り当てるとユーザ定義のportと衝突する可能性
> があるので、cons cellを割り当ててそれをIDとした方がよいです。

Macro 用の hygienic な symbol を用意することになりそうな予感。


> > >     int (*finalize)(ScmCPort cport);
> > >     int (*close_input)(ScmCPort cport);
> > >     int (*close_output)(ScmCPort cport);
> > 
> > 全部 close 一つでまとめたらいいのでは? 入出力 port の一方向だけ塞がなく
> > てはいけない場面というのを思いつかないんですが。
> 
> まずfinalizeとcloseは区別する必要があります。closeはコードの指示
> で明示的に閉じる場合、finalizeはsweep時のScmCPort解放です。単な
> るfree(3)では済まないような構造を持っている場合に必要です。
> 
> それからin/outを区別してのcloseですが、pipe(2)で得たfdを
> fdopen(3)経由でScmFilePortに保持するような場合に必要です。

そんなもんなんですか。Pipe なんか使ったこと無いのでよくわかりませんが。
あ、shell から使ったことがある(笑)
でも man した限りではどういうことかよくわからなかったので質問。使いかたは

int fd[2];
FILE *in, *out;
pipe(fd);
in = fdopen(fd[0], "r");
out = fdopen(fd[1], "w");

のようですが、これだと
close_in() == fclose(in)
close_out() == fclose(out)
ですよね? ということはどっちの access を閉じるかという情報は閉じる
object に含まれてるので、やっぱり close 一つで足りそうです。
close_in()/close_out() の pair が close() にできない仕事をするのは
read/write で開いた stream の一方の access だけを切るときだけですが、
そんな操作はclose(2) からして用意されてなさそうです (当然 stdio にも)。
もし fd[0] と fd[1] を multiplex した FILE* を作る方法があったとしても、
そんなことしたら deadlock さんいらっしゃいな気が…?


> > >     /* input */
> > >     int (*getc)(ScmCPort cport);
> > >     int (*peek_char)(ScmCPort cport);
> > >     int (*char_readyp)(ScmCPort cport);

これは get_byte(), peek_byte(), byte_readyp() or number_of_bytes_ready
() にしましょう。Multibyte port を読むとき次の文字が何 bytes 含むかの判
定は SigScheme 側で書きたいところです。あるいは port 側でそれを用意しな
くてはならない場面があるでしょうか。

> > >     /* output */
> > >     int (*vprintf)(ScmCPort cport, const char *str, va_list args);
> > >     int (*display)(ScmCPort cport, const char *str);
> > >     size_t (*ndisplay)(ScmCPort cport, size_t size, const char *str);
> > 
> > ndisplay は要らないと思う。Port の許容量は無制限が普通 (ですよね?)。
> 
> これはnull-terminatedでない文字列を渡すために入れました。port側
> の都合ではなくcaller側の都合です。

ああそうか。了解。display() は strlen() する wrapper 関数にしてもいいか
もしれませんね。

-- 
Jun Inoue
jun.l****@gmail*****



Anthy-dev メーリングリストの案内
アーカイブの一覧に戻る