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*****