/*---------------------------------------------------------------------------*/
/* コマンドテーブル処理（切り放し不可）*/

#include "stk.h"

/*---------------------------------------------------------------------------*/

// 実際にリンクされる最初のコマンドテーブルのアドレス
static STKCOM	*FirstTbl=NULL;
// リンクされたテーブル数
static short	ComTbls=0;

/*---------------------------------------------------------------------------*/

STKCOM *FirstComLink()
// 実際にリンクされる最初のコマンドテーブルのアドレスを返す
{
	return(FirstTbl);
}

/*---------------------------------------------------------------------------*/

void SetComLink(STKCOM add[])
// コマンドテーブルをリンクさせる
{
	// リンクしたテーブルの数+1
	if ((ComTbls++)==0) { // 一番最初
		// 実際にリンクされる最初のコマンドテーブルを記録
		FirstTbl=add;
	} else { // ２つ目以降
	    STKCOM *tbl;
		// リンクテーブル最後を探す
		tbl=FirstTbl;
		while (tbl[0].name!=NULL) tbl=(STKCOM *)tbl[0].name; // 次へ
		// そこにテーブルをリンクさせる
		(STKCOM *)tbl[0].name=add;
	}
}

/*---------------------------------------------------------------------------*/

static int ComExec(int i,STKCOM *(*tbl))
/* 初期化・終了関数があれば呼び出す */
{
int (*func)();
	func=(*tbl)[i].func;
	if (func!=NULL) {
	    int ret;
		if ((ret=func())) return(ret);
	}
	/* 次のテーブルアドレスを返す */
	*tbl=(STKCOM *)(*tbl)[0].name;
	return(OK);
}

/*---------------------------------------------------------------------------*/

int ComInit()
/* 各外部コマンドファイルの初期化ルーチンを呼び出す */
/* 各テーブルの最初のfuncに処理ルーチンを定義しておくと自動的に呼び出す。NULLならなし */
/* １回のプログラム実行中に１回以上呼び出さないこと */
/* エラー処理は、初期化関数内で、メッセージ表示を含めて行い、０以外を返す */
{
STKCOM *tbl,*tbl0;
int ret=OK;
	tbl=FirstTbl;
	do {
		// 初期化関数があれば呼び出す
		tbl0=tbl;
		if ((ret=ComExec(0,&tbl))) break;
	} while (tbl0[0].name!=NULL);
	return(ret);
}

/*---------------------------------------------------------------------------*/

int ComEnd()
/* 各外部コマンドファイルの終了処理ルーチンを呼び出す */
/* 各テーブルの最後のfuncに処理ルーチンを定義しておくと自動的に呼び出す。NULLならなし */
/* １回のプログラム実行中に１回以上呼び出さないこと */
/* エラー処理は、終了関数内で、メッセージ表示を含めて行い、０以外を返す */
{
int i,ret;
STKCOM *tbl;
	tbl=FirstTbl;
	do {
		/* 各テーブル最後を探す */
		i=1;
		while (tbl[i].name!=NULL) i++;
		/* 終了関数があれば呼び出す */
		if ((ret=ComExec(i,&tbl))) break;
	} while (tbl!=NULL);
	return(ret);
}

/*---------------------------------------------------------------------------*/
