static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/*******************************************************/
/* <clnode.c>                                          */
/*      NODE process   　　　                          */
/*******************************************************/

#include "colmn.h"
#undef DEBUG

extern int giProgram[];	/* [0] =0:coal, =1:ColMnMain */
						/* [1] = iCmd */
extern int giOptions[];
extern CLPRTBL  *pGLprocTable;
extern CLPRTBL  *pCLprocTable;
extern GlobalCt *pGlobTable;
extern CLCOMMON  CLcommon;
extern tdtIterate_ctl gtIter_ctl[];

int Errprflg;

static int _list();
static int _list_node();

/************************************/
/*									*/
/************************************/
static void _close_try_with_resources(pTryCB)
BlockCB *pTryCB;
{
	int i,ret;
	FILE **p,*fp;
	char *pw,*p1;

	if (pTryCB) {
		if (pTryCB->iUsed && (pTryCB->cid == C_TRY)) {
			p = (FILE **)pTryCB->pSwParm + pTryCB->iLoopMax - 1;
			for (i=0;i<pTryCB->iLoopMax;i++) {
				fp = *p--;
				if ((ret=_check_fp('D',fp,&p1,NULL)) > 0) {
					if (!(pw = p1)) pw = " ";
					pw++;
					ret= cl_close_fp(fp,pw,NULL,0);
					if (ret >= 0) {
						PRINTOUT2("_close_try_with_resources: close fp=%08x file=[%s].",fp,pw);
					}
					if (p1) Free(p1);
				}
			}
			pTryCB->iLoopMax = 0;
		}
	}
}

/************************************/
/*									*/
/************************************/
static int _change_thread(org_leaf)
Leaf *org_leaf;
{
	static parmList wprmlist,*wprm[2];
	Leaf *leaf;
	int  rc,iCh,iCon,iCid;

	if (!org_leaf) return -1;
/*
printf("_change_thread: org_leaf->pFlag=%d giProgram[1]=%d\n",
org_leaf->pFlag,giProgram[1]);
*/
	if (/* org_leaf->pFlag || */(iCid=org_leaf->cmd.cid) == C_SLEEP ||
	    iCid == C_PROC || iCid == C_FUNCTION ) {
	/*	org_leaf->pFlag = 0; */
		return 1;
	}

	if (giProgram[1] & 0x08) {
		iCon = 0;
	}
	else return 2;

	leaf = (Leaf *)Malloc(sizeof(Leaf));
	if (!leaf) return SysError;

/*	org_leaf->pFlag = 1;	*/

	memset(leaf,0,sizeof(Leaf));
	wprmlist.prmlen = 1;
	wprmlist.prp    = "0";
	wprm[0] = &wprmlist;
	leaf->cmd.cid    = C_SLEEP;
	leaf->cmd.prmnum = 1;
	leaf->cmd.prmp   = wprm;
	leaf->rightleaf = org_leaf;
	org_leaf->preleaf->rightleaf = leaf;
DEBUGOUTL1(100,"_change_thread: [ %s ]",cl_get_pcmd_line(leaf));
/*	rc = clProcessSleepSend(leaf);	*/
	rc = cl_process_msg_pre_send(leaf);
	return rc;
}

/************************************/
/*									*/
/************************************/
char *cl_get_pcmdc_line(cmd)
cmdInfo *cmd;
{
	char *buf = NULL;

	if (cmd) cl_get_cmd_line(cmd,&buf);
	if (!buf) buf = AKX_NULL_PRINT;
	return buf;
}

/************************************/
/*									*/
/************************************/
char *cl_get_pcmd_line(leaf)
Leaf *leaf;
{
	char *p;

	if (leaf) p = cl_get_pcmdc_line(&leaf->cmd);
	else p = "no leaf";
	return p;
}

/************************************/
/*									*/
/************************************/
static int _pr_ret(rc,leaf,proc,opt)
int    rc,opt;
Leaf   *leaf;
ProcCT *proc;
{
	Leaf	*retleaf;
	parmList *retprmlist,**wprmp;
#if 0
	char	*retprm;

	retleaf = (Leaf *)cl_scr_malloc(sizeof(Leaf));
	retprm  = cl_scr_malloc(16);
	retprmlist = (parmList *)cl_scr_malloc(sizeof(parmList));
	wprmp = (parmList **)cl_scr_malloc(sizeof(parmList *)*2);
#else
	Leaf	Retleaf;
	char	retprm[16];
	parmList Retprmlist,*Wprmp[2];

	retleaf = &Retleaf;
	retprmlist = &Retprmlist;
	wprmp = Wprmp;
#endif
	memcpy(retleaf,leaf,sizeof(Leaf));
	retleaf->cmd.parnum = 0;
	retleaf->cmd.parl  = NULL;
	retleaf->rightleaf = NULL;
	retleaf->leftleaf  = NULL;
	cl_copy_cmd(&(retleaf->cmd),&(leaf->cmd));
	retleaf->cmd.prmp = wprmp;
/*	retleaf->cmd.bxobj = NULL;	*/
	sprintf(retprm,"%d",rc);
	retleaf->cmd.cid    = C_RETURN;
	retleaf->cmd.prmnum = opt;
	retleaf->cmd.prmp[0]= retprmlist;
	retprmlist->prmlen  = strlen(retprm);
	retprmlist->prp     = retprm;
	retprmlist->opt     = D_GX_OPT_NO_USE_OBJ;
DEBUGOUTL1(100,"[ %s ]",cl_get_pcmd_line(retleaf));
	if (cl_process_return(retleaf,proc)) cmn_set_stat(RET_PR,&proc->ptype,L_ON);
	return 0;
}

/*************************************/
/* cl_node_process                   */
/* function; check command of this   */
/*          leaf then call functions */
/*************************************/
int cl_node_process(leaf, proc)
Leaf    *leaf;
ProcCT  *proc;
{
	return cl_node_process_opt(leaf,proc,0);
}

int cl_node_process_opt(leaf,proc,opt)
Leaf    *leaf;
ProcCT  *proc;
int opt;	/* add 2021.4.28 */
{
	int   rc,iRTN_PR,cmd_cid,*option;
	Leaf	retleaf;
	char	retprm[16];
	parmList retprmlist,*wprmp[2];
	char buf[64],*fmt,*cmd;
	ScrPrCT *scrptct;
	BlockCB *pTryCB;

	if (leaf == NULL) return(ECL_SYSTEM_ERROR);
	if (proc == NULL) return(ECL_SYSTEM_ERROR);

	gtIter_ctl[0].itc_circ_ref = NULL;
	gtIter_ctl[1].itc_circ_ref = NULL;
/*
printf("cl_node_process.enter: iStackDepth = %d\n",pCLprocTable->iStackDepth);
*/
	option = pGlobTable->options;
	if (!(opt & 0x01)) {
		rc = cl_tmp_const_clear(0);
DEBUGOUTL2(105,"cl_node_process:cl_tmp_const_clear(0) rc=%d proc->ptype=%02x",rc,proc->ptype);
	}
	rc = 0;
	errno = 0;
	Errprflg = 0;
	pGlobTable->Quot[2] = 1;	/* pGlobTable->err_msg 先頭追加フラグ */
	if (iRTN_PR = cmn_chk_stat(RTN_PR,&proc->ptype)) fmt = "[(return from %s)]";
	else fmt = "[ %s ]";
/*cmd=cl_get_pcmd_line(leaf);*/
DEBUGOUTL1(100,fmt,cl_get_pcmd_line(leaf));
	proc->Curleaf = leaf;
	cmd_cid = leaf->cmd.cid;
	pGlobTable->script_line = leaf->cmd.rc;
#if 0
	if (!(scrptct=cl_search_src_ct())) return ECL_SYSTEM_ERROR;
	if ((scrptct->pFlag & D_SCRPT_INTERACTIVE) &&
#else
	if (!leaf->rightleaf &&
#endif
	    (/*cmd_cid==C_LOOP ||*/ cmd_cid==C_IF || cmd_cid==C_SWITCH || cmd_cid==C_TRY
	  || cmd_cid==C_INTERACTIVE
	  || cmd_cid==C_ONN || cmd_cid==C_DEFINE || cmd_cid==C_IMPORT)) {
		/* cl_node_process: このコマンド[%s]は実行できません。 */
		ERROROUT1(FORMAT(406),cl_gets_cmd_name(cmd_cid));
		rc = -1;
	}
	else {
	switch(cmd_cid) {
	case C_PROC:
	case C_FUNCTION:
	case C_CLASS:
		rc = cl_process_proc(leaf,proc);
		break;
	case C_ENDPROC:
	case C_ENDFUNC:
	case C_ENDCLASS:
		rc = cl_process_end_proc(leaf,proc);
		break;
	case C_EXEC:
	case C_CALL:
		if (iRTN_PR) rc = cl_process_exec_return(leaf,proc);
		else if (cmd_cid == C_EXEC) rc = cl_process_exec(leaf,proc);
		else rc = cl_process_call(leaf,proc);
		break;
	case C_SQL:
	/*	if (iRTN_PR) rc = clProcessSqlpreReturn(leaf,proc);
		else rc = clProcessSqlpreSend(leaf,proc);
		break;	*/
	case C_SLEEP:
	/*	if (iRTN_PR) rc = clProcessSleepReturn(leaf);
		else rc = clProcessSleepSend(leaf);
		break;	*/
	case C_MSG:
		if (iRTN_PR) rc = cl_process_msg_pre_return(leaf,proc);
		else rc = cl_process_msg_pre_send(leaf,proc);
		break;
	case C_LOOP:
	case C_FOR:
	case C_DO:
		rc = cl_process_loop(leaf,proc);
		break;
	case C_ENDWHILE:
	case C_ENDUNTIL:
		rc = cl_process_do_while(leaf,proc);
		break;
	case C_CONTINUE:
		rc = cl_process_continue(leaf,proc);
		break;
	case C_BREAK:
		rc = cl_process_break(leaf,proc);
		break;
	case C_READ:
		rc = cl_process_read(leaf,proc);
		break;
	case C_OUTPUT:
		rc = cl_process_output(leaf,proc);
		break;
	case C_IF:
		rc = cl_process_if(leaf,proc);
		break;
	case C_ENDIF:
	case C_ENDSW:
	case C_ENDTRY:
		rc = cl_process_end_if(leaf,proc);
		break;
	case C_ELSEIF:
		rc = cl_process_else_if(leaf,proc);
		break;
	case C_ELSE:
	case C_DEFAULT:
	case C_FINALLY:
		rc = cl_process_else(leaf,proc);
		break;
	case C_BEXP:
	case C_LET:
		if (iRTN_PR) rc = let_compute_return(leaf,proc);
		else rc = cl_process_bexp(cmd_cid,leaf,proc);
		break;
	case C_RETURN:
		rc = cl_process_return(leaf,proc);
		break;
/*	case C_ONN:
		rc = cl_process_on(leaf,proc);
		break; */
	case C_LEAVE:	/* LEAVE 処理 */
		rc = cl_process_leave(leaf,proc);
		break;
	case C_SWITCH:
		rc = cl_process_switch(leaf,proc);
		break;
	case C_TRY:
		rc = cl_process_try(leaf,proc);
		break;
	case C_CASE:
		rc = cl_process_case(leaf,proc);
		break;
	case C_CATCH:
		rc = cl_process_catch(leaf,proc);
		break;
	case C_THROW:
		rc = cl_process_throw(leaf,proc);
		break;
	case C_REDEFINE:
		rc = cl_pr_ex_re_define(leaf,proc);
		break;
/*
	case C_INTERACTIVE:
		rc = cl_process_interactive(leaf,proc);
		break;
*/
	case C_UNDEFINE:
		rc = cl_pr_ex_un_define(leaf,proc);
		break;
	case C_DIM:
		if (!(scrptct=cl_search_src_ct())) return ECL_SYSTEM_ERROR;
		rc = cl_pr_ex_dim(leaf,scrptct,proc,0);
		break;
/*
	case C_TYPEDEF:
		if (!(scrptct=cl_search_src_ct())) return ECL_SYSTEM_ERROR;
		rc = cl_pr_ex_typedef(leaf,scrptct,proc,0);
		break;
*/
	case C_LABEL:
		return 0;
	default:
		ERROROUT(FORMAT(407));	/* cl_node_process: コマンドではありません */
		rc = -1;
	}
	}
/*
printf("cl_node_process.ret: iStackDepth = %d\n",pCLprocTable->iStackDepth);
*/
	if (opt & 0x01) return rc;	/* add 2021.4.28 */

DEBUGOUTL4(110,"cl_node_process: rc=%d try_level=%d ucExcept=%d exception=%08x",
rc,pGlobTable->try_level,proc->ucExcept,pGlobTable->exception);

	if ((pGlobTable->try_level>0 && !proc->ucExcept) || proc->ucExcept) {
		if (rc || pGlobTable->exception) {
			if (!pGlobTable->exception)
				pGlobTable->exception = cl_mk_exception_code(ETC_EXCEPTION,rc);
			if (!(option[6] & 0x01) &&
			    !(pGlobTable->exception && (iRTN_PR || cmd_cid==C_ENDTRY))) {
				if (clerrdisp(pGlobTable->exception,leaf)) return ECL_SYSTEM_ERROR;
			}
			if (proc->ucExcept==D_EXCEPT_TRY) {
				proc->ucExcept = D_EXCEPT_CATCH;
				proc->exception = pGlobTable->exception;
				if (pTryCB = cl_search_block_cb(proc,C_TRY,0x03)) {
					pTryCB->TureFlag = L_OFF;
					proc->pcrBlockCB = pTryCB;
					_close_try_with_resources(pTryCB);
				}
				else return -11921;
				rc = pGlobTable->exception = 0;
				pGlobTable->error = 0;
			}
			else if (proc->ucExcept>D_EXCEPT_TRY) {	/* CATCH or FINALLYの中で例外が発生したとき */
				proc->pFlag |= D_PFLAG_EXCEPTION;
				if (pTryCB = cl_search_block_cb(proc,C_TRY,0x03)) {
					pTryCB->EndFlag = pGlobTable->exception;
					proc->pcrBlockCB = pTryCB;
					/* break/return/exitはキャンセルする */
					cmn_set_stat(BRK_PR|RET_PR,&proc->ptype,L_OFF);
					cmn_set_stat(TRY_EXIT,&pCLprocTable->ScrSt,L_OFF);
				}
				else return -11922;
				rc = pGlobTable->exception = 0;
				pGlobTable->error = 0;
			}
			else {
				cmn_set_stat(UFN_PR,&proc->ptype,L_OFF);
				_pr_ret(0,leaf,proc,0);
			}
		}
		rc = 0;
	}
	else if (rc != 0) {
/*
printf("cl_node_process: rc=%d option[6]=%08x\n",rc,option[6]);
*/
		if (!(option[6] & 0x01)) {
			if (clerrdisp(rc,leaf)) return ECL_SYSTEM_ERROR;
		}
		if (option[6] & 0x04) {
			pGlobTable->error = rc;
			pGlobTable->exception = cl_mk_exception_code(ETC_EXCEPTION,rc);
			cmn_set_stat(SCR_ED,&pCLprocTable->ScrSt,L_ON);
		}
		else if (!(option[6] & 0x02)) {
			cmn_set_stat(UFN_PR,&proc->ptype,L_OFF);
			rc = _pr_ret(rc,leaf,proc,1);
		}
		rc = 0;
	}
/*
printf("cl_node_process:Exit: rc=%d exception=%08x\n",rc,pGlobTable->exception);
*/
	return rc;
}

/************************************/
/*									*/
/************************************/
int clerrdispcmd(rc,cmd)
int  rc;
cmdInfo *cmd;
{
	ScrPrCT *scrprct;
	char *pCmdLine,*name;

	Errprflg++;
#if 1
DEBUGOUTL1(110,"clerrdisp: cmd.parl[1].par=[%s]",cmd->parl[1].par);
	name = akxt_get_last_name("\\/",cmd->parl[1].par);
	ERROROUT4("clerrdisp:rc=%6d(%08x) at script=[%s] line=%d",rc,rc,name,cmd->rc);
#else
	/* これでは、importしたスクリプトの名前が表示できない */
	if (!(scrprct = cl_search_src_ct())) return ECL_SYSTEM_ERROR;
	ERROROUT4("clerrdisp:rc=%6d(%08x) at script=[%s] line=%d",rc,rc,scrprct->pId,cmd->rc);
#endif
	if (!cl_get_cmd_line(cmd,&pCmdLine)) ERROROUT1(" ---> [%s]",pCmdLine);
	return 0;
}

/************************************/
/*									*/
/************************************/
int clerrdisp(rc,leaf)
int  rc;
Leaf *leaf;
{
	clerrdispcmd(rc,&leaf->cmd);
	return 0;
}

/************************************/
/*									*/
/************************************/
static int _fshut_exit(exit_ret)
int exit_ret;
{
	int val;
	tdtInfoParm InfoParm,*pInfoParm;

	pInfoParm = &InfoParm;
	cl_set_parm_bin(pInfoParm,exit_ret);
	return cl_ex_exit(&val,1,&pInfoParm);
}

/************************************/
/* cl_node_control                  */
/************************************/
int cl_node_control(leaf, proc)
Leaf    *leaf;
ProcCT  *proc;
{
	static int try_cida[]={C_CATCH,C_FINALLY,C_ENDTRY,0};
	int rc,cmd_cid,debug_mode_ret;
	ProcCT *procct;
	Leaf   *next;

	if (!leaf || !proc) return ECL_SYSTEM_ERROR;

	procct = proc;
DEBUGOUTL1(110,"cl_node_control: enter procct=%08x",procct);
	if (cmn_chk_stat(RTN_PR,&procct->ptype) != L_OFF) {
		leaf = cl_ret_leaf_pop(procct);
DEBUGOUTL1(110,"cl_node_control: RTN [ %s ]",cl_get_pcmd_line(leaf));
	}

	rc = 0;
	while (leaf && !rc) {
		if (CLcommon.dbgopt[0]) {
			debug_mode_ret = cl_debug_mode(leaf,procct,0);
		}
#if 1
		if (aka_shut_control(AKA_SHUT_GET,NULL)) {	/* FSHUT or サスペンド中でないSHUT mode */
			if (rc = _fshut_exit(AKB_CMD_FSHUT)) break;
		}
		else {
/*
DEBUGOUTL1(110,"cl_node_control: [ %s ]",cl_get_pcmd_line(leaf));
*/
			procct->Nextleaf = leaf->rightleaf;
			if (rc = cl_node_process(leaf, procct)) break;
		}
#else
		if (aka_shut_control(AKA_SHUT_GET,NULL) == 2) {	/* FSHUT mode */
			cmn_set_stat(SCR_ED,&pCLprocTable->ScrSt,L_ON);
			return 0;
		}
DEBUGOUTL1(110,"cl_node_control: [ %s ]",cl_get_pcmd_line(leaf));
		procct->Nextleaf = leaf->rightleaf;
		if (rc = cl_node_process(leaf, procct)) break;
#endif
		if (CLcommon.dbgopt[0] && debug_mode_ret) {
			cl_debug_mode(leaf,procct,debug_mode_ret);
		}
		if (cmn_chk_stat(SCR_ED,&pCLprocTable->ScrSt) != L_OFF) return 0;
#if 1
		procct = cl_search_proc_ct();
		if (!procct) return ECL_SYSTEM_ERROR;
DEBUGOUTL1(110,"cl_node_control: procct=%08x",procct);
#endif
#if 1
		if (cmn_chk_stat(TRY_EXIT,&pCLprocTable->ScrSt)) {
			cmn_set_stat(RET_PR,&procct->ptype,L_ON);
		}
#endif
		if (cmn_chk_stat(SCR_LV,&pCLprocTable->ScrSt) != L_OFF) return 0;
		if (cmn_chk_stat(NEW_SC,&pCLprocTable->ScrSt) != L_OFF) {
			cmn_set_stat(NEW_SC,&pCLprocTable->ScrSt,L_OFF);
			return 0;
		}
#if 0
		procct = cl_search_proc_ct();
DEBUGOUTL1(110,"cl_node_control: procct=%08x",procct);
#endif
#if 0
		if (cmn_chk_stat(RTN_PR | RET_PR,&procct->ptype) != L_OFF) break;
#else
		if (cmn_chk_stat(RTN_PR,&procct->ptype) != L_OFF) break;
		else if (cmn_chk_stat(RET_PR,&procct->ptype) && !procct->ucExcept) break;
#endif
		if (procct->ucExcept == D_EXCEPT_CATCH) {
			procct->ucExcept = D_EXCEPT_RUN;
			if (!(procct->Nextleaf=cl_ret_leaf_pop_search(procct,try_cida,3))) return -1;
		}
		else if (procct->pFlag & D_PFLAG_EXCEPTION) {
			procct->pFlag &= ~D_PFLAG_EXCEPTION;
			procct->Nextleaf = NULL;
		}

		if (leaf = procct->Nextleaf) {
		/*	pCLprocTable->iStackDepth++;	*/
		}
		else {
			_close_try_with_resources(proc->pcrBlockCB);
			leaf = cl_ret_leaf_pop(procct);
DEBUGOUTL1(110,"cl_node_control: Jump [ %s ]",cl_get_pcmd_line(leaf));
		}
/*
printf("cl_node_control: next leaf=%08x\n",leaf);
*/
		pCLprocTable->iStackDepth++;
		if (leaf && pCLprocTable->iStackDepth>MAX_DO_STACK_DEPTH) {
			pCLprocTable->iStackDepth = 0;
			if (!_change_thread(leaf)) break;
		}
	}
	if (!rc && !cmn_chk_stat(RTN_PR | RET_PR,&procct->ptype)) {
			/* cl_node_control: ＲＥＴＵＲＮ文がありません。" */
		ERROROUT(FORMAT(408));
		rc = -1;
	}
/*
printf("cl_node_control:Exit rc=%d\n",rc);
*/
	return rc;
}

/************************************/
/*									*/
/************************************/
Leaf *cl_ret_leaf_pop(proc)
ProcCT  *proc;
{
	Leaf    *leaf;
	int cid;

	leaf=(Leaf *)akxs_rb_get_n(proc->pRetStack);
DEBUGOUTL1(110,"cl_ret_leaf_pop: leaf=%08x",leaf);
	if (leaf) {
		cid=leaf->cmd.cid;
DEBUGOUTL2(110,"cl_ret_leaf_pop: cid=%08x %s",cid,cl_gets_cmd_name(cid));
	}
	return leaf;
}

/************************************/
/*									*/
/************************************/
int cl_ret_leaf_push(proc,leaf)
Leaf    *leaf;
ProcCT  *proc;
{
	int cid;

DEBUGOUTL2(110,"cl_ret_leaf_push: proc=%08x leaf=%08x",proc,leaf);
	if (!proc || !leaf) return -1;
	cid=leaf->cmd.cid;
DEBUGOUTL2(110,"cl_ret_leaf_push: cid=%08x %s",cid,cl_gets_cmd_name(cid));
	if (akxs_rb_set_t(proc->pRetStack,leaf)) return 0;
	return -1;
}

/************************************/
/*									*/
/************************************/
Leaf *cl_ret_leaf_peek(proc)
ProcCT  *proc;
{
	return (Leaf *)akxs_rb_get(proc->pRetStack);
}

/************************************/
/*									*/
/************************************/
Leaf *cl_ret_leaf_pop_search(proc,cida,nn)
ProcCT  *proc;
int cida[],nn;
{
	Leaf *leaf;
	int i;

	while (leaf=cl_ret_leaf_pop(proc)) {
		for (i=0;i<nn;i++) {
			if (!cida[i]) break;
			if (leaf->cmd.cid == cida[i]) return leaf;
		}
	}
	return NULL;
}

/************************************/
/*									*/
/************************************/
int cl_debug_mode(leaf0,proc,mode)
Leaf    *leaf0;
ProcCT  *proc;
int      mode;
{
	static Leaf *ret_leaf=NULL,*right_leaf=NULL;
	static int step_count=0;
	static int until_lno=0;
	static char his[256]={'\0'};
	char buf[256],*argv[128],parm[256],*p;
	int n,i,v,len,rc,ihelp,argl;
	int cno,lno,ln;
	Leaf leaf,*wleaf;
	parmList *ppL[128],pL[128];
	ScrPrCT *scrprct;
	char *pCmdLine,cmd;

	if (mode) {
		if (proc) {
			if (ret_leaf=cl_ret_leaf_peek(proc)) {
				if (ret_leaf == leaf0) right_leaf = ret_leaf->rightleaf;
			}
		}
		return 0;
	}

	if (ret_leaf || right_leaf) {
		if (leaf0!=ret_leaf && leaf0!=right_leaf) return 0;
		ret_leaf = right_leaf = NULL;
	}
	if (step_count > 0) {
		if (--step_count > 0) return 0;
	}
	if (until_lno > 0) {
		if (leaf0->cmd.rc != until_lno) return 0;
		until_lno = 0;
	}

	if (!(scrprct = cl_search_src_ct())) return 0;

	if (!(CLcommon.dbgopt[0] & 0x02)) {
		if (rc=cl_get_cmd_line(&leaf0->cmd,&pCmdLine)) printf("error rc=%d\n",rc);
		else printf("%s\n",pCmdLine);
	}

	leaf.cmd.prmp = ppL;
	for (;;) {
		ihelp = 1;
		printf("%s(%d)> ",scrprct->pId,leaf0->cmd.rc);
		gets(buf);
		if (!strcmp(buf,"/")) {
			if (*his) strnzcpy(buf,his,sizeof(buf)-1);
		}
		else strnzcpy(his,buf,sizeof(his)-1);
		n = akxtgetargv2(buf,argv,128,parm,sizeof(parm),4);	/* , */
		if (n >= 1) {
			argl = strlen(argv[0]);
			cmd = toupper(*argv[0]);
			if (!stricmp(argv[0],"STEP") || (argl==1 && cmd=='S')) {
				if (n >= 2) step_count = atoi(argv[1]);
				break;
			}
			else if (cmd=='N' || !stricmp(argv[0],"NEXT")) {
				return 1;
			}
			else if (cmd=='U' || !stricmp(argv[0],"UNTIL")) {
				if (n >= 2) until_lno = atoi(argv[1]);
				else if ((cno=leaf0->cmd.cid)==C_LOOP || cno==C_FOR ||
					    cno==C_WHILE || cno==C_UNTIL) {
					if (wleaf = leaf0->rightleaf) until_lno = wleaf->cmd.rc;
					else if (wleaf = cl_ret_leaf_peek(proc)) until_lno = wleaf->cmd.rc;
				}
				break;
			}
			else if (cmd=='Q' || !stricmp(argv[0],"QUIT")) exit(100);
			else if (cmd=='T' || !stricmp(argv[0],"THRU")) {
				CLcommon.dbgopt[0] = 0;
				break;
			}
			if (n >= 2) {
				leaf.cmd.prmnum = n - 1;
				memset(pL,0,sizeof(parmList)*leaf.cmd.prmnum);
				for (i=0;i<leaf.cmd.prmnum;i++) {
					leaf.cmd.prmp[i] = &pL[i];
					len = strlen(p=argv[i+1]);
					pL[i].prmlen = len;
					pL[i].prp = p;
				}
			}
			ihelp = 0;
			if (!stricmp(argv[0],"LIST") || (argl==1 && cmd=='L')) {
				_list(scrprct,leaf0,proc,n-1,argv+1);
			}
			else if (cmd=='P' || !stricmp(argv[0],"PRINT")) {
				cl_echo_text(&leaf.cmd.prmp[0],NULL,leaf.cmd.prmnum,1);
			}
			else if (!stricmp(argv[0],"LET") || !stricmp(argv[0],"SET")) {
				cl_process_let(&leaf,proc);
			}
			else ihelp = 1;
		}
		if (ihelp) {
			printf("Enter quit/thru/next/step/until/list/print/let/set\n");
		}
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
static void _list_line(leaf,level)
Leaf *leaf;
int   level;
{
	char *p;
	int cno,lno,i;

	cno = leaf->cmd.cid;
	lno = leaf->cmd.rc;
	printf("%05d:",lno);
	if (leaf->pFlag & D_LEAF_INEFFECTIVE) printf("*");
	else printf(" ");
	if (cno==C_ENDPROC || cno==C_ENDFUNC) level--;
	for (i=0;i<level;i++) printf("    ");
	p = cl_get_pcmd_line(leaf);
	if (p) printf("%s\n",p);
	else printf("cannot list command line!!\n");
}

/********************************************/
/*											*/
/********************************************/
static int _list(scrprCT,leaf,proc,n,argv)
ScrPrCT *scrprCT;
Leaf    *leaf;
ProcCT  *proc;
int      n;
char    *argv[];
{
	Leaf *wleaf,*wkl;
	int lno,l1,l2,nl,i;
	char *p,c;

	if (!scrprCT) return -1;
	lno = leaf->cmd.rc;
	if (n >= 1) {
		if ((c=toupper(*(p=argv[0])))=='_' || (c>='A' && c<='Z')) {
			for (i=0;i<2;i++) {
				if (wleaf=cl_search_proc(scrprCT->TreeTop,p)) ;
				else if (wleaf=cl_search_func(scrprCT->TreeTop,p)) ;
				else if (wleaf=cl_search_class(scrprCT->TreeTop,p)) ;
				if (wleaf) break;
				scrprCT = pGLprocTable->CurScr;
			}
			if (!wleaf) {
				ERROROUT1("_list: not found [%s]",p);
				return 0;
			}
			_list_line(wleaf,0);
			if (wleaf=wleaf->leftleaf) {
				_list_node(wleaf,0,INT_MAX,1);
			}
			return 0;
		}
		else if (akxccvn(10,p,strlen(p),&lno)) {
			ERROROUT1("_list: invalid number[%s]",p);
			return 0;
		}
	}
	l1 = lno - 5;
	l2 = lno + 5;
	if (n >= 2) {
		l1 = lno;
		p = argv[1];
		if (akxccvn(10,p,strlen(p),&nl)) {
			ERROROUT1("_list: invalid number[%s]",p);
			return 0;
		}
		l2 = l1 + nl - 1;
	}
printf("_list: l1=%d l2=%d\n",l1,l2);
#if 1	/* 2021.2.20 */
	wleaf = leaf;
	while (wkl=wleaf->preleaf) wleaf = wkl;
	_list_node(wleaf,l1,l2,0);
#else
	_list_node(scrprCT->TreeTop,l1,l2,0);
#endif
	return 0;
}

/********************************************/
/*											*/
/********************************************/
static int _list_node(leaf,from_line,to_line,level)
Leaf *leaf;
int   from_line,to_line,level;
{
	char *p;
	int cno,rc,lno,i;
 
	if (!leaf) return -1;

	rc = 0;
/*	if (!(leaf->pFlag & D_LEAF_INEFFECTIVE)) {	*/
		cno = leaf->cmd.cid;
		lno = leaf->cmd.rc;
/*
printf("_list_node: cno=%08x lno=%d\n",cno,lno);
*/
		if (lno>=from_line && lno<=to_line) {
			_list_line(leaf,level);
		}
		if (lno >= to_line) return -1;
/*
		if ((cno=leaf->cmd.cid)==C_NODE_SCRIPT || cno==C_NODE_IMPORT)
			printf(" pFlag=0x%02x",leaf->pFlag);
*/
		if (leaf->leftleaf) {
			if (rc=_list_node(leaf->leftleaf,from_line,to_line,level+1)) return rc;
		}
/*	}	*/
	if (leaf->rightleaf) {
		rc = _list_node(leaf->rightleaf,from_line,to_line,level);
	}
 
	return rc;
}
