/*****************************************************************************/
/* ＳＴＫ外部コマンド：エラー/CTRL-C発生時処理（切り放し可能）*/
/*****************************************************************************/

#include "stk.h"

extern STKSYS *stksys;

/*****************************************************************************/

static int Sbrkerr(NSTACK nstk[],int mode,unchar *text,unchar *(*jump),unchar *(*go))
/* エラー／CTRL-C発生時処理 */
{
int ret;
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	switch (mode) {
	    case 0:// label ONERROR → なし : エラー発生時ｼﾞｬﾝﾌﾟ先設定
	    case 1:// label ONBREAK → なし : CTRL-C発生時ｼﾞｬﾝﾌﾟ先設定
		/* 重複設定は後が有効になる */
		{ unchar atrb,*adrs;
		if ((ret=PopLStack(&adrs,&atrb,0))) break;
		if (atrb!=LLBL) ret=LBLERR;
		else {
			if (((int)adrs)&1) adrs--; // LNEXTはアドレス補正する
			sys->onact[mode*2]=adrs;
			// label==LNULLのときは特別処理が解除される
		}
		}
		break;
	    case 2:// ERRNO → エラーコード(0)
		// エラーコードを返す：ONERROR時用
		NN0=(long)sys->errno;
		ret=NOK;
		break;
	    case 3:// エラーメッセージを返す
		// work(1:NADRS) errno(0) ERRMES → なし
		ret=ARYStoreB(&NS1,STKError((int)NN0),0);
		break;
	    case 4:// エラーを発生させる
		// error(0) ERROR → なし
		ret=NN0;
		break;
	
	    // RESUME処理
	    case 5: // label ERESUME → なし : エラー
	    case 6: // label BRESUME → なし : CTRL-C
		{ unchar atrb,*(*adrs);
		adrs=&sys->onact[mode==5? 1:3]; // resume point = 発生したコマンドアドレス
		if (*adrs==NULL) return(NORESUME); // resume出来ない
		
		if ((ret=PopLStack(go,&atrb,0))) break;
		if (atrb!=LLBL) return(LBLERR);
		
		if (*go==NULL) { // LNULL ?RESUME : 発生したコマンドそのものへ戻る
			*go=*adrs;  // ジャンプ先
		}
		else
		if (((int)(*go))&1) { // LNEXT ?RESUME : 発生した次のコマンドへ戻る
		    unchar *ad;
			ad=(*adrs)+1; // ジャンプ先(skip code)
			ad+=EvenLen(*ad++); // 偶数バイト化付き
			*go=ad;
		}
		// その他は指定したラベルに戻る
		*adrs=NULL; // 臨時処理の終了を宣言する
		ret=LOK;
		}
	}
	return(ret);
}

/*****************************************************************************/

// ここの中だけで特有なエラー
static ERRMES ERRbrk[]={
	 {NORESUME	,"resume出来ない"}
	,{0,NULL}
};
static ERLINK erlist={ERRbrk,NULL};

static int BrkInit()
/* 初期化 */
{
	return(STKErrLink(&erlist));
}

/*****************************************************************************/
/* コマンドテーブル */

STKCOM ebtbl[]={
	 {NULL		,BrkInit,TNONE,0,0}
	,{"ONERROR"	,Sbrkerr,TNONE,0,0}	// error  jump 設定
	,{"ONBREAK"	,Sbrkerr,TNONE,0,1}	// CTRL-C jump 設定
	,{"ERRNO"	,Sbrkerr,TNONE,1,2}	// エラー番号
	,{"ERRMES"	,Sbrkerr,TNUM TADRS,0,3}// エラーメッセージ
	,{"ERROR"	,Sbrkerr,TNUM ,0,4}	// エラー発生
	,{"ERESUME"	,Sbrkerr,TNONE,0,5}	// error  resume
	,{"BRESUME"	,Sbrkerr,TNONE,0,6}	// CTRL-C resume
	,{NULL		,NULL	,TNONE,0,0}
};

/*****************************************************************************/
