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

#include "colmn.h"

extern condList CLcList;		/* 情報リスト */
extern CLPRTBL  *pCLprocTable;	/*  */
extern GlobalCt *pGlobTable;

ScrPrCT *cl_lru_scr_src();
extern FILE *gStdio[];

/****************************************/
/*										*/
/****************************************/
int cl_set_proc_nm(proc,name)
ProcCT *proc;
char *name;
{

	if (proc->ProcNM) Free(proc->ProcNM);
	proc->ProcNM = Strdup(name);
	return 0;
}

/**************************************************************/
/* cl_pr_exec_ip                                              */
/* function; Exec Internal Procedure.                         */
/**************************************************************/
int cl_pr_exec_ip(leaf,proc,nam_pos)
Leaf   *leaf;
ProcCT *proc;
int    nam_pos;
{
	ScrPrCT *scrprct;
	ProcCT  *procct,*procct_cr;
	Leaf    *wkleaf;
	char    *name,namebuf[Pr_NM_MAX+1];
	int     rc,len,namelen;
	ParList pr_nam,sc_nam;

	rc = 0;

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

	/* existence check of procedure name */
	if (leaf->cmd.prmnum < nam_pos+1) {
		ERROROUT("cl_pr_exec_ip: No procedure name for EXEC command");
		return ECL_SCRIPT_ERROR;
	}
#if 1	/* 2020.3.6 */
	/* get procedure & script name */
	rc = cl_ex_get_proc_scr_name(leaf->cmd.prmp[nam_pos],proc->Obj,&pr_nam,&sc_nam);
#else
	/* get procedure name */
	rc = cl_ex_get_proc_name(PR_NM_DEF,leaf->cmd.prmp[1],proc->Obj,&name,&namelen);
#endif
	if (rc) return(rc);
	if (sc_nam.par) {
		return cl_pr_exec_sc_sub(leaf,proc,&sc_nam,&pr_nam,nam_pos);
	}
	if (rc = cl_exe_proc_name_check(&pr_nam)) return rc;
/*	memnzcpy(namebuf,,namelen,sizeof(namebuf));	*/
	/*   */
#if 1	/* 2020.3.6 */
	nam_pos++;
	if (rc = cl_execute_proc(&leaf->cmd.prmp[nam_pos],leaf->cmd.prmnum-nam_pos,proc,pr_nam.par)) return rc;
#else
	if (rc = cl_execute_proc(leaf,proc,namebuf)) return rc;
#endif
	/* return information set process */
	proc->Curleaf = leaf;
	cl_ret_leaf_push(proc,leaf);
	cmn_set_stat(RTN_PR,&proc->ptype,L_ON);
	/* Need Parameter Set process */
	if (rc = cl_prparmset(/*leaf,*/proc,namebuf)) {
		rc = cl_er_lk_proc_ct();	/* Erase ProcCt */
		if(rc == -1) return ECL_SYSTEM_ERROR;
		return(ECL_EX_EXEC);
	}
	return rc;
}

/**************************************************************/
/* cl_pr_exec_ep                                              */
/* function; Exec External Procedure(function).               */
/**************************************************************/
int cl_pr_exec_ep(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	ProcCT *procct;
	Leaf   *wkleaf;
	char   *name,*parm,namebuf[Pr_NM_MAX+1];
	int    namelen,rc,len;
	tdtInfoParm InfoParm;
	ParList pr_nam;
	tdtREDIRECT *red0,*red;

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

	/* existence check of procedure name */
	if (leaf->cmd.prmnum < 2) {
		ERROROUT("No procedure name for EXEC command");
		return ECL_SCRIPT_ERROR;
	}

	/* get procedure name */
/*	pr_nam.par = name;	*/
	rc = cl_ex_get_proc_name(leaf->cmd.prmp[1],proc->Obj,&pr_nam);
	if (!rc) rc = cl_exe_proc_name_check(&pr_nam);
	if (rc) return(rc);
	name    = pr_nam.par;
	namelen = pr_nam.parlen;
	memnzcpy(namebuf,name,namelen,sizeof(namebuf));
	/* Check specified function has been registered & execute. */
	if (!strcmp(namebuf,D_EPNM_INPUT) || !strcmp(namebuf,D_EPNM_INPUTXML)) {
		if (leaf->cmd.prmp[2] == NULL) {
			ERROROUT("cl_pr_exec_ep: No parameter for external function(input)");
			return ECL_SCRIPT_ERROR;
		}
		procct = cl_mk_lk_proc_ct(); /* Make Linked Proc Control Table */
		if (!procct) return ECL_SYSTEM_ERROR;
		cmn_set_stat(FNC_PR,&procct->ptype,L_ON);
		/* Get start point */
		rc = cl_gx_exp_obj(leaf->cmd.prmnum-2,&leaf->cmd.prmp[2],proc->Obj,&InfoParm);
		if (rc) {
			if (cl_er_lk_proc_ct() == -1) return ECL_SYSTEM_ERROR;
			return ECL_SCRIPT_ERROR;
		}
		/* Need logic for input control table set process */
		cl_set_proc_nm(procct,namebuf);
#if 1	/* 2020.6.17 */
		red0 = proc->redirect;
		red  = procct->redirect;
		mem_cpy_addr(red->stdio,red0->stdio,4);
#endif
		rc = cl_input_prep(&InfoParm);
		if (rc) {
			if (cl_er_lk_proc_ct() == -1) return ECL_SYSTEM_ERROR;
			return ECL_SCRIPT_ERROR;
		}
		/* return information set process */
		proc->Curleaf = leaf;
		cl_ret_leaf_push(proc,leaf);
		cmn_set_stat(RTN_PR,&proc->ptype,L_ON);
		if (!strcmp(namebuf,D_EPNM_INPUT)) rc = input();
		else {
			cl_code_type(1,0);	/* reset code type */
			rc = input_xml(1);
		}
	}
	else if (!strcmp(namebuf,D_EPNM_SELMAIN)) {
		procct = cl_mk_lk_proc_ct();
		if (!procct) return ECL_SYSTEM_ERROR;
		cmn_set_stat(FNC_PR,&procct->ptype,L_ON);
		cl_set_proc_nm(procct,namebuf);
#if 1	/* 2020.6.17 */
		red0 = proc->redirect;
		red  = procct->redirect;
		mem_cpy_addr(red->stdio,red0->stdio,4);
#endif
		/* return information set process */
		proc->Curleaf = leaf;
		cl_ret_leaf_push(proc,leaf);
		cmn_set_stat(RTN_PR,&proc->ptype,L_ON);
		rc = cl_sel_main();
	}
	else if (!strcmp(namebuf,D_EPNM_USERFUNC)) {
		procct = cl_mk_lk_proc_ct();
		if (procct == NULL) return ECL_SYSTEM_ERROR;
		cmn_set_stat(FNC_PR,&procct->ptype,L_ON);
		cl_set_proc_nm(procct,namebuf);
#if 1	/* 2020.6.17 */
		red0 = proc->redirect;
		red  = procct->redirect;
		mem_cpy_addr(red->stdio,red0->stdio,4);
#endif
		/* return information set process */
		proc->Curleaf = leaf;
		cl_ret_leaf_push(proc,leaf);
		cmn_set_stat(RTN_PR,&proc->ptype,L_ON);
		rc=cl_user_func(leaf,proc,namebuf);
	}
	else {
		ERROROUT(FORMAT(471));	/* 未定義の外部関数です。 */
		return ECL_SCRIPT_ERROR;
	}
	if (rc && !cmn_chk_stat(RET_PR,&procct->ptype)) {
		if (cl_er_lk_proc_ct() == -1) return ECL_SYSTEM_ERROR;
	}
	if (rc) {
		if (!pGlobTable->error) pGlobTable->error = rc;
		if (!pGlobTable->exception)
			pGlobTable->exception = cl_mk_exception_code(ETC_EXCEPTION,rc);
	}
	return rc;
}

/**************************************************************/
/* cl_pr_exec_sc                                              */
/* function; Exec Another Script.                             */
/**************************************************************/
int cl_pr_exec_sc(leaf,proc,nam_pos)
Leaf   *leaf;
ProcCT *proc;
int    nam_pos;
{
	ScrPrCT *scrprct;
	ScrPrCT *scrprctlru;
	ProcCT  *procct;
	Leaf    *wkleaf;
	char    *name;
	int     namelen;
	char   namebuf[Pr_NM_MAX+1];
	int   rc;
	int   len;
	ParList pr_nam,sc_nam;

	rc = 0;

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

	/* existence check of procedure name */
	if (leaf->cmd.prmnum < nam_pos+1) {
		ERROROUT("cl_pr_exec_sc: No procedure name for EXEC command");
		return ECL_SCRIPT_ERROR;
	}
#if 1	/* 2020.3.1 */
	rc = cl_ex_get_proc_scr_name(leaf->cmd.prmp[nam_pos],proc->Obj,&pr_nam,&sc_nam);
#else
	/* get procedure name */
	rc = cl_ex_get_proc_name(0,leaf->cmd.prmp[1],proc->Obj,&name,&namelen);
#endif
	if (rc != NormalEnd) {
		ERROROUT("cl_pr_exec_sc: EXEC name get procedure error.");
		return rc;
	}
	if (!sc_nam.par || !sc_nam.parlen) {
		sc_nam = pr_nam;
		pr_nam.par = NULL;
		pr_nam.parlen = 0;
	}
	else {
		if (rc = cl_exe_proc_name_check(&pr_nam)) return rc;
	}
	return cl_pr_exec_sc_sub(leaf,proc,&sc_nam,&pr_nam,nam_pos);
}

int cl_pr_exec_sc_sub(leaf,proc,sc_nam,pr_nam,nam_pos)
Leaf    *leaf;
ProcCT  *proc;
ParList *pr_nam,*sc_nam;
int     nam_pos;
{
	int rc,len;
	char *nam;

DEBUGOUTL3(110,"cl_pr_exec_sc_sub:Enter leaf=%08x proc=%08x nam_pos=%d",leaf,proc,nam_pos);
	/* return information set process */
	proc->Curleaf = leaf;
	cl_ret_leaf_push(proc,leaf);
	cmn_set_stat(RTN_PR,&proc->ptype,L_ON);

	/* execute another procedure */ 
	CLcList.option = 0;
	nam = sc_nam->par;
	len = sc_nam->parlen;
	if (*nam=='{' && nam[len-1]=='}') {
		CLcList.fname = "MEM:";
		rc = cl_exe_scr_mem_init(sc_nam,pr_nam,leaf,proc,nam_pos);
	}
	else {
		rc = cl_exe_scr_init(sc_nam,pr_nam,leaf,proc,nam_pos);
	}
	if (!rc) cmn_set_stat(NEW_SC,&pCLprocTable->ScrSt,L_ON);

DEBUGOUTL1(110,"cl_pr_exec_sc_sub:Exit rc=%d",rc);
	return rc;
}

/**************************************************************/
/* cl_pr_exec_sm                                              */
/* function; Exec Script In Memory.                           */
/**************************************************************/
int cl_pr_exec_sm(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	tdtInfoParm InfoParm;
	ParList pr_nam,sc_nam;
	int rc;

	rc = 0;

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

	/* existence check of procedure name */
	if (leaf->cmd.prmnum < 2) {
		ERROROUT("cl_pr_exec_sm: No script source for EXEC command");
		return ECL_SCRIPT_ERROR;
	}

	/* get script source */
#if 1	/* 2020.3.25 */
	rc = cl_ex_get_proc_scr_name(leaf->cmd.prmp[1],proc->Obj,&pr_nam,&sc_nam);
	if (rc) {
		ERROROUT("cl_pr_exec_sm: EXEC name get procedure error.");
		return rc;
	}
	if (!sc_nam.par) {
		sc_nam = pr_nam;
		pr_nam.par = NULL;
		pr_nam.parlen = 0;
	}
	else {
		if (rc = cl_exe_proc_name_check(&pr_nam)) return rc;
	}
#else
	if (rc=cl_gx_exp_obj_opt(1,&leaf->cmd.prmp[1],proc->Obj,&InfoParm,0)) return rc;
	if (rc) {
		ERROROUT1("cl_pr_exec_sm: get script source error. ret=%d",rc);
		return rc;
	}
	else if (InfoParm.pi_attr != DEF_ZOK_CHAR) {
		ERROROUT1("cl_pr_exec_sm: not text. attr=%d",InfoParm.pi_attr);
		return ECL_SCRIPT_ERROR;
	}
#endif

	/* return information set process */
	proc->Curleaf = leaf;
	cl_ret_leaf_push(proc,leaf);
	cmn_set_stat(RTN_PR,&proc->ptype,L_ON);

	/* execute another procedure */
	CLcList.fname = "MEM:";
	CLcList.option = 0;
#if 1	/* 2020.3.25 */
	if (rc=cl_exe_scr_mem_init(&sc_nam,&pr_nam,leaf,proc,1)) return rc;
#else
	if (rc=cl_exe_scr_mem_init(InfoParm.pi_data,InfoParm.pi_dlen,leaf,proc)) return rc;
#endif

	cmn_set_stat(NEW_SC,&pCLprocTable->ScrSt,L_ON);

	return rc;
}

/**************************************************************/
/* cl_process_exec                                            */
/* function; Exec command Process                             */
/**************************************************************/
int cl_process_exec(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	ScrPrCT *scrprct;
	ProcCT  *procct;
	int rc,scno;
	char *p;

	rc = 0;

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

	/* specify exec procedure */
#if 1
	rc = ECL_SYSTEM_ERROR;
	if (scno=leaf->cmd.sub_cid) {
		switch (scno) {
		case CS_IP:
				rc = cl_pr_exec_ip(leaf,proc,1);
				break;
		case CS_EP:
				rc = cl_pr_exec_ep(leaf,proc);
				break;
		case CS_SC:
				rc = cl_pr_exec_sc(leaf,proc,1);
				break;
		case CS_SM:
				rc = cl_pr_exec_sm(leaf,proc);
				break;
#if 1	/* 2022.3.5 */
		case CS_REDIRECT:
				rc = cl_pr_exec_redirect(leaf,proc);
#endif
		}
	}
#else
	if (leaf->cmd.prmnum < 2) return ECL_SYSTEM_ERROR;

	if (stricmp(p=leaf->cmd.prmp[0]->prp,"IP") == 0) {
		rc = cl_pr_exec_ip(leaf,proc);
	}
	else if (stricmp(p,"SC") == 0) {
		rc = cl_pr_exec_sc(leaf,proc);
	}
	else if (stricmp(p,"EP") == 0) {
		rc = cl_pr_exec_ep(leaf,proc);
	}
	else if (stricmp(p,"SM") == 0) {
		rc = cl_pr_exec_sm(leaf,proc);
	}
	else {
		rc = ECL_SCRIPT_ERROR;
	}
#endif
	if (!rc) {
		pGlobTable->exception = pGlobTable->error = 0;
	}
	return rc;
}

/**************************************************************/
/* cl_process_exec_return                                     */
/**************************************************************/
int cl_process_exec_return(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	int rc=0;

	if (leaf) {
		if (pCLprocTable->WaitPacketp) Free(pCLprocTable->WaitPacketp);
		pCLprocTable->WaitPacketp = NULL;
		cmn_set_stat(RTN_PR,&proc->ptype,L_OFF);
		cmn_set_stat(RTN_PR,&pCLprocTable->PrSt,L_OFF);
		if (cmn_chk_stat(TRY_EXIT,&pCLprocTable->ScrSt)) {
			rc = cl_ex_exit_finally();
		}
	}
	else rc = ECL_SYSTEM_ERROR;

	return rc;
}

/************************************************************/
/*	cl_process_call											*/
/************************************************************/
int cl_process_call(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	int rc;

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

	if (leaf->cmd.sub_cid == CS_REDIRECT)
		rc = cl_pr_exec_redirect(leaf,proc);
	else
		rc = cl_pr_exec_ip(leaf,proc,0);
	return rc;
}

/* 2022.3.5 */
/************************************************************/
/* cl_process_exec_redirect									*/
/************************************************************/
int cl_pr_exec_redirect(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	int rc,reset;
	FILE *stdiow[4];
	ParList2 parl;
	tdtREDIRECT *red;

	mem_set_addr(stdiow,NULL,4);
	memset(&parl,0,sizeof(ParList2));
	if ((rc=_set_redirect_by_parmList(leaf->cmd.prmp,leaf->cmd.prmnum,leaf->cmd.rc,stdiow,&parl)) > 0) {
		/* 2020.4.6 */
		reset = rc & ECL_RESET_REDIRECT;
		rc = 0;
		red = proc->redirect;
		/* 2022.5.22 */
		if (reset) {
			rc = cl_reset_stdio_redirect(red,reset>>16,proc);
		}
		if (!rc) rc = cl_set_stdio_redirect(red,NULL,stdiow,&parl);
	}
	return rc;
}
