next up previous contents index
: put_byte の追加 : 例 一バイト書き出し関数の追加 : 関数名, 仕様を決める   目次   索引

open_file の改造

ファイルを 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;

と宣言されている. 第 $k$ 引数 ($k\ge 0$ )を取り出す場合, メンバ next$k$ 回たどる必要があるが, 組み込み関数の引数取り出し用に ARG0(arg), $\cdots$, ARG10(arg) が用意されている.

file_tab[] における引数の個数指定 $n$, 正の場合, $n$以外は不正, 負の場合, 0 以上 $n$ 以下の任意の個数を意味する. 上の変更の場合, 無引 数の場合をチェックしていないのでやや不備である.



Nobuki Takayama 平成15年9月12日