ファイルを open し, そのファイル記述子を返す組み込み関数 open_file の本体は次のようになっている.
void Popen_file(), Pclose_file(), Pget_line(), Pget_byte(); void Ppurge_stdin();
struct ftab file_tab[] = { {"purge_stdin",Ppurge_stdin,0}, /* 関数本体は Popen_file, 引数は 1 */ {"open_file",Popen_file,1}, {"close_file",Pclose_file,1}, {"get_byte",Pget_byte,1}, ...
void Popen_file(arg,rp) NODE arg; Q *rp; { char *name; FILE *fp; char errbuf[BUFSIZ]; int i; /* 引数(ファイル名) のチェック */ asir_assert(ARG0(arg),O_STR,"open_file"); /* ファイルポインタ配列の空きを探す */ for ( i = 0; i < BUFSIZ && file_ptrs[i]; i++ ); if ( i == BUFSIZ ) error("open_file : too many open files"); name = BDY((STRING)ARG0(arg)); /* 読み込みモードで open */ fp = fopen(name,"r"); if ( !fp ) { sprintf(errbuf,"open_file : \"%s\" not found",name); error(errbuf); } /* ファイルポインタを格納 */ file_ptrs[i] = fp; /* index をファイル記述子として返す */ STOQ(i,*rp); }
この状態では, ファイルは常に読み込みモードで open されるが, 書き出しモードが指定された場合に, 対応するモードでファイルが open されるように変更する.
struct ftab file_tab[] = { {"purge_stdin",Ppurge_stdin,0}, /* 関数本体は Popen_file, 引数は最大で 2 */ {"open_file",Popen_file,-2}, ...
void Popen_file(arg,rp) ... name = BDY((STRING)ARG0(arg)); /* 2 番目の引数が指定されたらそのモードで open */ /* そうでなければ読み込みモードで open */ if ( argc(arg) == 2 ) { asir_assert(ARG1(arg),O_STR,"open_file"); fp = fopen(name,BDY((STRING)ARG1(arg))); } else fp = fopen(name,"r"); if ( !fp ) { sprintf(errbuf,"open_file : \"%s\" not found",name); error(errbuf); } ...
関数の引数は NODE という, リストを表す構造体により渡される. NODE は
typedef struct oNODE { pointer body; struct oNODE *next; } *NODE;
と宣言されている. 第 引数 (
)を取り出す場合, メンバ next を
回たどる必要があるが, 組み込み関数の引数取り出し用に
ARG0(arg),
, ARG10(arg) が用意されている.
file_tab[] における引数の個数指定 , 正の場合,
以外は不正,
負の場合, 0 以上
以下の任意の個数を意味する. 上の変更の場合, 無引
数の場合をチェックしていないのでやや不備である.