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();

/****************************************/
/*										*/
/****************************************/
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)

Leaf    *leaf;
ProcCT  *proc;
{
	ScrPrCT *scrprct;
	ProcCT  *procct,*procct_cr;
	Leaf    *wkleaf;
	char    *name,namebuf[Pr_NM_MAX+1];
	int     rc,len,namelen; 

	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 < 2) {
		ERROROUT("No procedure name for EXEC command");
		return(ECL_SCRIPT_ERROR);
	}
	/* get procedure name */
	rc = cl_ex_get_proc_name(PR_NM_DEF,leaf->cmd.prmp[1],proc->Obj,&name,&namelen);
	if (rc) return(rc);
	memnzcpy(namebuf,name,namelen,sizeof(namebuf));
	/*   */
	if (rc = cl_execute_proc(leaf,proc,namebuf)) return rc;
	/* 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;

	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 */
	rc = cl_ex_get_proc_name(PR_NM_DEF,leaf->cmd.prmp[1],proc->Obj,&name,&namelen);
	if (rc) return(rc);
	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("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);
		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);
		/* 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);
		/* 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)
Leaf    *leaf;
ProcCT  *proc;
{
	ScrPrCT *scrprct;
	ScrPrCT *scrprctlru;
	ProcCT  *procct;
	Leaf    *wkleaf;
	char    *name;
	int     namelen;
	char   namebuf[Pr_NM_MAX+1];
	int   rc;
	int   len;

	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 < 2) {
		ERROROUT("No procedure name for EXEC command");
		return ECL_SCRIPT_ERROR;
	}

	/* get procedure name */
	rc = cl_ex_get_proc_name(0,leaf->cmd.prmp[1],proc->Obj,&name,&namelen);
	if (rc != NormalEnd) {
		ERROROUT("EXEC name get procedure error.");
		return rc;
	}

	/* 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;
	if (rc=cl_exe_scr_init(name,leaf,proc)) return rc;

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

	return rc;
}

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

	rc = 0;

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

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

	/* get script source */
	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;
	}

	/* return information set process */
	proc->Curleaf = leaf;
	cl_ret_leaf_push(proc,leaf);

	/* execute another procedure */
	CLcList.fname = "MEM:";
	CLcList.option = 0;
	if (rc=cl_exe_scr_mem_init(InfoParm.pi_data,InfoParm.pi_dlen,leaf,proc)) return rc;

	cmn_set_stat(RTN_PR,&proc->ptype,L_ON);
	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);
				break;
		case CS_EP:
				rc = cl_pr_exec_ep(leaf,proc);
				break;
		case CS_SC:
				rc = cl_pr_exec_sc(leaf,proc);
				break;
		case CS_SM:
				rc = cl_pr_exec_sm(leaf,proc);
				break;
		}
	}
#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;
}
