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

#include "colmn.h"

extern condList  CLcList;		/* 情報リスト */
extern CLPRTBL   *pGLprocTable;
extern CLPRTBL   *pCLprocTable;
extern CLNCB     CLSTCB;
extern GlobalCt  *pGlobTable;
extern CLCOMMON  CLcommon;
extern int giOptions[];
extern tdtLruScrHead *tpLruScrHeadImp;
extern tdtLruScrHead *tpLruScrHead;
/*extern FILE *gStdio[];*/
extern FILE *stdios[];

static MCAT CLcList_mcat={'M','C',512,0,0,0,NULL,0};

typedef struct {
	FILE **stdiow;
	FILE *fpi;
	FILE *fpo;
	int nparm;
	int here_doc;
	int pflag2_opt;
	ParList2 *parl;		/* heredocのEOF文字列格納 */
	char *mode;
} tdtREDIRECT_CTL;

/****************************************************/
/*	01 _print_script_start							*/
/****************************************************/
static void _print_script_start(scrname)
char *scrname;
{
	static char *fmt="***** Script Name ( %s ) *****";

/*	PRINTOUT1(fmt,scrname);
	DEBUGOUTL1(1,fmt,scrname);	*/
	PRDBGOUTL1(1,fmt,scrname);
}

/****************************************************/
/*	02 _print_end_script							*/
/****************************************************/
static void _print_end_script(scrname,errcode)
char *scrname;
int errcode;
{
	static char *fmt="----- End Script ( %s )  nofree no=%d ret=%d -----";

	PRDBGOUTL3(1,fmt,scrname,Nofree(0),errcode);	/* Nofree(0)はcrprctを開放後に取得する */
}
/*
static FILE *fpi,*fpo;
static int disp,nparm,here_doc,pflag2_opt;
static char *mode;
*/
/****************************************************/
/*	03 _set_redirect								*/
/****************************************************/
static int _set_redirect(p,len,i,parmnum,exec_line,red)
char *p;
int  i,len,parmnum,exec_line;
tdtREDIRECT_CTL *red;
{
	tdtInfoParm pParm[2],*ppParm[2];
	FILE *fp,**gStdio;
	int rc,iParm[5],std_err,pos,i_sta;
	char c,*pWork,*pp;
	parmList prmList;
	ProcCT *proc;
	ScrPrCT *scrprct;
	ParList2 *parl;
/*
printf("_set_redirect:Enter i=%d parmnum=%d exec_line=%d mode=[%s] len=%d p=[%s]\n",
i,parmnum,exec_line,red->mode,len,p);
*/
	rc = std_err = i_sta = 0;
	if (!(gStdio = red->stdiow)) return -1;
	if (!(parl = red->parl)) return -1;
	c = *p;
	if (!red->mode) {
		if (c=='<' || c=='>') {
			if (len > 1) {
				p++;
				len--;
			}
			else if (i >= parmnum) rc = -210140301;
			else p = NULL;
			if (!rc) {
				if (c == '<') {
					red->mode = "r";
					if (red->fpi) rc = -210140302;
					else if (p) {
						if (*p == '<') {
							p++;
							len--;
							if (len <= 0) p = NULL;
							else {
								pos = akxnskipin(p,len,"-=!");
								if (pos) {
									if (inmemchars(p,pos,"-")) red->pflag2_opt |= D_PFLAG2_DEL_TAB;
									if (inmemchars(p,pos,"=")) red->pflag2_opt |= (D_PFLAG2_DEL_SPACE | D_PFLAG2_DEL_TAB);
									if (inmemchars(p,pos,"!")) red->pflag2_opt |= D_PFLAG2_NOT_CLOSE;
									p += pos;
									len-= pos;
									if (len <= 0) p = NULL;
								}
							}
							red->here_doc = 1;
						}
					}
				}
				else {
					red->mode = "w";
					if (red->fpo) rc = -210140303;
					else if (p) {
						if (*p == '>') {
							p++;
							len--;
							red->mode = "a";
							if (len <= 0) p = NULL;
						}
						if (p) {
							if (*p == '&') {
								p++;
								len--;
								std_err = 1;
								if (len <= 0) p = NULL;
							}
						}
					}
				}
				if (p) {
					p = akxttrim2(0,p,&len);
					if (len <= 0) p = NULL;
				}
				if (red->nparm < 0) red->nparm = i - 1;	/* 最初に設定された位置(先頭がi=1)の一つ前が入る。 */
			}
		}
		else if (red->fpi || red->fpo) rc = -210140304;
	}
	else if (c=='<' || c=='>') rc = -210140305;
	if (rc) {
		ERROROUT4(FORMAT(515),"_set_derirect",i,p,rc);	/* %s: 第%dパラメータ[%s]が誤っています。rc=%d */
	}
	else if (red->mode && p) {
		/* '.'、'/'から始まるファイル名は、cl_arg_to_char_num()で数値、式と見なされエラーになる */
		if (!memcmp(p,"/dev/tty",len)) {
			rc = 0;
			if (*red->mode == 'r') rc++;
			else {
				rc += 2;
				if (std_err) rc += 4;
			}
			return rc<<16;
		}
		else if ((c=*p)=='.' || c=='/') cl_set_parm_char(pParm,p,len);
		else {
			if (red->here_doc) {
#if 0
				i_sta = exec_line;
#else
				pos = akxs_in_str_opt(p," ",2);
				if (pos > 0) {
				/*	*(p+pos-1) = '\0';	*/
					len = pos - 1;
					i_sta = atoi(p+pos);
				/*	p = akxttrim2(0,p,&len);	*/
				}
				else {
					return -1;
				}
#endif
/*
printf("_set_redirect: i_sta=%d\n",i_sta);
*/
			}
/*
printf("_set_redirect: len=%d p=[%s]\n",len,p);
*/
			prmList.prp = p;
			prmList.prmlen = len;
			prmList.opt = 0;
			prmList.bxobj = 0;
			proc = cl_search_proc_ct();
			if ((rc=cl_arg_to_char_num(&prmList,proc->Obj,pParm,"_set_redirect",0,0)) < 0) return 0;
		}
		if (red->here_doc) {
			scrprct = cl_search_src_ct();
			if (!scrprct) return ECL_SYSTEM_ERROR;
			parl->par = pParm[0].pi_data;
			parl->parlen = pParm[0].pi_dlen;
			parl->option = red->pflag2_opt | (cl_get_option(25,0) & D_PFLAG2_HEREDOC_OPT);
/*
printf("_set_redirect: heredoc parlen=%d option=%02x par=[%s]\n",parl->parlen,parl->option,parl->par);
*/
			pParm[0].pi_data = scrprct->fullname;
			pParm[0].pi_dlen = strlen(scrprct->fullname);
		}
/*
		else {
			parl->par = NULL;
			parl->parlen = 0;
			parl->option = 0;
		}
*/
		cl_set_parm_char(pParm+1,red->mode,1);
		pWork = (char *)&fp;
		ppParm[0] = &pParm[0];
		ppParm[1] = &pParm[1];
		if ((rc=func_file(&pWork,"fopen",2,ppParm,D_FUC_FOPEN,iParm)) >= 0) {
			if (pGlobTable->error < 0) {
				rc = pGlobTable->exception;
				if (rc >= 0) rc |= 0x80000000;
			}
			else {
				if ((c=*red->mode) == 'r') {
/*
printf("_set_redirect: fp=%08x\n",fp);
*/
					gStdio[0] = red->fpi = fp;
					if (red->here_doc) {
						cl_skip_line(fp,i_sta);
					}
				}
				else {
					gStdio[1] = red->fpo = fp;
					if (std_err) gStdio[2] = fp;
					std_err = 0;
				}
				red->mode = NULL;
				red->here_doc = rc = 0;
			}
		}
	}
	return rc;
}

/****************************************************/
/*	04 _set_redirect_by_parmList					*/
/****************************************************/
int _set_redirect_by_parmList(pprmp,parmnum,exec_line,stdiow,parl)
parmList **pprmp;
int  parmnum,exec_line;
FILE *stdiow[];
ParList2 *parl;
{
	parmList *parm;
	int rc,i,reset;
	tdtREDIRECT_CTL red;

	memset(&red,0,sizeof(tdtREDIRECT_CTL));
	red.stdiow = stdiow;
	red.parl = parl;
	red.nparm = -1;
	rc = reset = 0;
	for (i=0;i<parmnum;i++)  {
		parm = pprmp[i];
		if ((rc=_set_redirect(parm->prp,parm->prmlen,i+1,parmnum,exec_line,&red)) < 0) break;
		reset |= rc & ECL_RESET_REDIRECT;
		rc = 0;
	}
	if (reset || (!rc && (red.fpi || red.fpo))) {
		rc |= red.nparm + 1;	/*  redirectがあるときは、最初に設定された位置(先頭が1)が入る */
		rc |= reset;
	}
	return rc;	/* rc>0:redirect設定あり */
}

/****************************************************/
/*	05 _set_redirect_by_pasento						*/
/****************************************************/
static int _set_redirect_by_pasento(pScCT,stdiow,parl)
ScrPrCT *pScCT;
FILE *stdiow[];
ParList2 *parl;
{
	tdtInfoParm ***pTBL,*pInfoParm;
	VarTBL *VaryW;
	int rc,i,varmax,*pSize;
	tdtREDIRECT_CTL red;

	memset(&red,0,sizeof(tdtREDIRECT_CTL));
	red.stdiow = stdiow;
	red.parl = parl;
	red.nparm = -1;

	VaryW = pScCT->Vary;
	pTBL   = VaryW->pTBL_pasento;
	varmax = VaryW->varnam_pasento;
	rc = 0;
	for (i=1;i<=varmax;i++) {
		pInfoParm = cl_get_var_ent_opt(pTBL,i,'r');
		if (rc = _set_redirect(pInfoParm->pi_data,pInfoParm->pi_dlen,i,varmax,0,&red)) break;
	}
	if (!rc && (red.fpi || red.fpo)) {
		VaryW->varnam_pasento = red.nparm;
		pSize = (int *)VaryW->pTBL_pasento[0];
		cl_set_parm_bin(cl_var_size_parm(pSize),red.nparm);
	}
	return 0;
}

/* 2022.5.22 */
/********************************************************/
/*	06 cl_set_stdio_redirect							*/
/*	 (1)red  : pStdio[]を設定するプロセスのredirect		*/
/*	exec リダイレクト		 : red0=NULL				*/
/*	exec ip xxx リダイレクト : red0=呼び出し元プロセス	*/
/*	exec sc xxx リダイレクト : red0=redと異なる値		*/
/*										(何でも良い)	*/
/*	 (2)red  : pStdio[]を設定するスクリプトのredirect	*/
/*							 : red0=NULL				*/
/********************************************************/
int cl_set_stdio_redirect(red,red0,pStdio,parl)
tdtREDIRECT *red,*red0;
FILE *pStdio[];
ParList2 *parl;
{
	int i,rc,f;
	FILE *fp,*fps,*fp0;
	char *p;
/*
printf("cl_set_stdio_redirect:Enter red=%08x red0=%08x parlen=%d option=%02x par=[%s]\n",
red,red0,parl->parlen,parl->option,parl->par);
*/
	if (!red0) red0 = red;
	fp0 =  red->stdio[0];
	f = D_PFLAG2_SET_STDIN;
	for (i=0;i<3;i++) {
		if (fp=pStdio[i]) {
/*
printf("cl_set_stdio_redirect: i=%d fp=%08x\n",i,fp);
*/
			if (red==red0 && (red->pFlag2 & f)) {
				if ((fps=red->stdio[i])!=stdios[i]) {
					rc = 0;
					if (i) {
/*
printf("cl_set_stdio_redirect: i=%d close fps=%08x\n",i,fps);
*/
						rc = cl_check_close_fp(fps);
					}
					else if (red->HereDoc_nm)
						rc = cl_heredoc_skip_to_eof_close(red);
					if (rc < 0) return rc;
				}
			}
			red->stdio[i] = fp;
			red->pFlag2 |= f;
			pStdio[i] = NULL;
/*
printf("cl_set_stdio_redirect: red->stdio[%d]=%08x\n",i,fp);
*/
		}
		f += f;
	}
	if (parl->parlen) {
		red->stdio[3] = fp0;
		p = Malloc(parl->parlen+1);
		memzcpy(p,parl->par,parl->parlen);
		red->HereDoc_nm = p;
		red->pFlag2 |= parl->option;
	}
/*
printf("cl_set_stdio_redirect:Exit red->pFlag2=%08x\n",red->pFlag2);
*/
	return 0;
}

/****************************************************/
/* 07 cl_reset_stdio_redirect						*/
/*	(1)red : procのredirectのとき					*/
/*		proc : 設定するproc							*/
/*	(2)red : scrのredirectのとき					*/
/*		proc : NULL									*/
/****************************************************/
int cl_reset_stdio_redirect(red,reset,proc)
tdtREDIRECT *red;
int reset;
ProcCT *proc;
{
	FILE *fps;
	int rc,i,k,f;
/*
printf("cl_reset_stdio_redirect: red=%08x reset=%02x proc=%08x\n",red,reset,proc);
*/
	rc = 0;
	k = 1;
	f = D_PFLAG2_SET_STDIN;
	for (i=0;i<3;i++) {
		if (reset & k) {
			/* 2022.4.23 */
			if (red->pFlag2 & f) {
				if ((fps=red->stdio[i]) != stdios[i]) {
/*
printf("cl_reset_stdio_redirect: i=%d reset stdio from=%08x to=%08x\n",i,fps,stdios[i]);
*/
					rc = 0;
					if (i) {
/*
printf("cl_reset_stdio_redirect: i=%d close fps=%08x\n",i,fps);
*/
						rc = cl_check_close_fp(fps);
					}
					else if (red->HereDoc_nm) {
/*
printf("cl_resetr_stdio_redirect: i=%d clear heredoc\n",i);
*/
						if (proc) rc = cl_heredoc_end(NULL,proc,1);
						else {
							red->stdio[3] = NULL;
							red->HereDoc_nm = NULL;
						}
					}
					if (rc < 0) break;
					rc = 0;
					red->stdio[i] = stdios[i];
				}
				red->pFlag2 &= ~f;
			}
		}
		k += k;
		f += f;
	}
	return rc;
}

/**************************************************************/
/* cl_execute_script                                          */
/* function; Execute specified Script                         */
/**************************************************************/
int cl_execute_script()
{
	ScrPrCT *scrprct = ( ScrPrCT *)NULL;
	ProcCT  *procct  = ( ProcCT *)NULL ;
	int rc,ret,i;
	char wrk[Pr_NM_MAX+1];
	Leaf *nodeleaf;
	FILE *fp;

DEBUGOUTL(110,"cl_execute_script: enter");

	scrprct = cl_search_src_ct(); /* Search current script control table */
	if (!scrprct) return ECL_SYSTEM_ERROR;
DEBUGOUTL1(110,"cl_execute_script: enter scrprct=%08x",scrprct);

	procct = cl_search_proc_ct(); /* Search current proc control table */
	if (procct == NULL) return ECL_SYSTEM_ERROR;
DEBUGOUTL1(110,"cl_execute_script: enter procct=%08x",procct);

	if (cmn_chk_stat(SCR_PR,&procct->ptype)) {
		ret = cl_node_control(procct->ProcTop,procct);
		procct = cl_search_proc_ct();
		if (!procct) return ECL_SYSTEM_ERROR;
DEBUGOUTL3(110,"cl_execute_script: ret=%d exception=%08x ret node procct=%08x",ret,pGlobTable->exception,procct);
		if (cmn_chk_stat(RET_PR,&procct->ptype)){
		/*	if (procct->ptype & D_PFLAG_NO_FREE) return ret;	*/
#if 1
/*
if (procct->Nodeleaf) printf("cl_execute_script:End scrprct=%08x procct=%08x\n",scrprct,procct);
*/
			cl_set_scr_const_ct(scrprct,procct->Nodeleaf,NULL);
#endif
#if 0	/* 2021.8.26 */
/*
printf("cl_execute_script: procct->try_level=%d\n",procct->try_level);
*/
			pGlobTable->try_level = procct->try_level;
#endif
#if 1	/* 2022.4.15 */
			cl_heredoc_skip_to_eof(procct->redirect);	/* この処理はprocctを開放前に行う必要がある */
#endif
			rc = cl_er_lk_proc_ct();	/* Erase ProcCt */
			if(rc == -1) {
				return ECL_SYSTEM_ERROR;
			}
			else if(rc == -2) {
				strnzcpy(wrk,scrprct->pId,sizeof(wrk)-1);	/* scrprctを開放するとスクリプト名が取れないのでここで保存する */
#if 1	/* 2022.4.26 */
			cl_heredoc_skip_to_eof(scrprct->redirect);	/* この処理はscrprctを開放前に行う必要がある */
#endif
#if 1	/* 2021.8.25 */
			/*	if (scrprct->try_level_save > 0) {	*/
/*
printf("cl_execute_script: try_level_save=%d\n",scrprct->try_level_save);
*/
					pGlobTable->try_level = scrprct->try_level_save;
			/*	}	*/
#endif
				rc = cl_er_lk_scr_pr_ct();
				if (rc == -1)
					return ECL_SYSTEM_ERROR;
				else if (rc == -2) {
					cmn_set_stat(SCR_ED,&pCLprocTable->ScrSt,L_ON);
				}
				else {
					_print_end_script(wrk,pGlobTable->error);
				}
			}
			if (scrprct = cl_search_src_ct()) {
#if 1
				procct = cl_search_proc_ct();
#else
				if (procct = cl_search_proc_ct())
					cl_set_scr_const_ct(scrprct,procct->Nodeleaf);
#endif
			}
			rc = 0;
		}
	}
	else {
#if 1	/* 2021.7.22 */
		if (pGlobTable->try_level>0 && pGlobTable->exception) {
			rc = cl_er_lk_proc_ct();	/* Erase ProcCt */
			return 0;
		}
#endif
		ret = cl_func_process(procct);
		if (ret) {
/*
printf("clexescr.c:clfunc ret = %d\n",ret);
*/
			pGlobTable->error = ret;
			if (!pGlobTable->exception)
				pGlobTable->exception = cl_mk_exception_code(ETC_EXCEPTION,ret);
			ret = 0;
		}
	}
	return ret;
}

/**************************************************************/
/* cl_exe_scr_name_check                                      */
/**************************************************************/
int cl_exe_scr_name_check(sc_nam,pr_nam)
ParList *pr_nam,*sc_nam;
{
	static char *_fname_="cl_exe_scr_name_check";
	int  len,n;
	char *name,*pn;

	/* parameter check */
	if (!(name=sc_nam->par)) {
		ERROROUT1("%s: script name is NULL!",_fname_);
		return ECL_SYSTEM_ERROR;
	}
	if (cl_chk_file_name(sc_nam->par,sc_nam->parlen)) {
		/* %s: スクリプト名[%s]が不正です。 */
		ERROROUT3(FORMAT(113),_fname_,FORMAT(119),sc_nam->par);
		return ECL_SCRIPT_ERROR;
	}
	return 0;
}

/****************************************************************/
/* cl_exe_scr_init												*/
/* function; Read specified Script From DB						*/
/* 引数 : proc	: EXECコマンドを実行しているproc				*/
/****************************************************************/
int cl_exe_scr_init(sc_nam,pr_nam,leaf,proc,nam_pos)
ParList *pr_nam,*sc_nam;
Leaf   *leaf;
ProcCT *proc;
int    nam_pos;
{
	int rc,len,n,l;
	char *name,*p,*scrname;

DEBUGOUTL3(110,"cl_exe_scr_init:Enter leaf=%08x proc=%08x nam_pos=%d",leaf,proc,nam_pos);

	if (!(rc = cl_exe_scr_name_check(sc_nam,pr_nam))) {
		rc = cl_exe_scr_file_init(sc_nam->par,pr_nam->par,leaf,proc,nam_pos);
		if (rc == ECL_NOT_FOUND_PROC) {
			if (!pr_nam->par || !pr_nam->parlen) rc = 0;
		}
	}
DEBUGOUTL1(110,"cl_exe_scr_init:Exit rc=%d",rc);
	return rc;
}

/****************************************************/
/*	cl_exe_scr_file_init							*/
/* 引数 : proc	: EXECコマンドを実行しているproc	*/
/****************************************************/
int cl_exe_scr_file_init(name,procname,leaf0,proc,nam_pos)
char   *name;
char   *procname;
Leaf   *leaf0;
ProcCT *proc;
int    nam_pos;
{
	ScrPrCT *scrprct;
	ScrPrCT *scrprctlru;
	parmList *prmp,**pprmp;
	ParList2 parl;
	FILE *stdiow[4];
	char *scrname,*sckind;
	int rc,pos,sk_len,iOPT_TRYPASS,parmnum,reset;

	if (!(scrname = cl_set_script_name_extension(name,strlen(name)))) return -1;
	_print_script_start(scrname);

#if 1	/* 2022.5.8 */
	mem_set_addr(stdiow,NULL,4);
	memset(&parl,0,sizeof(ParList2));
	reset = 0;
#endif
	/* 2021.8.18 */
	if (leaf0 && proc) {
		pprmp = &leaf0->cmd.prmp[nam_pos+1];
		parmnum = leaf0->cmd.prmnum - (nam_pos+1);
		/* 2021.12.13 */
		if ((rc=_set_redirect_by_parmList(pprmp,parmnum,leaf0->cmd.rc,stdiow,&parl)) < 0) return rc;
		else if (rc > 0) {
			reset = rc & ECL_RESET_REDIRECT;
			rc &= ~ECL_RESET_REDIRECT;
			parmnum = rc - 1;
			leaf0->cmd.prmnum = rc + nam_pos;
		}
		if ((rc=cl_set_exec_parm(pprmp,parmnum,proc)) < 0) return rc;
	}

	if (scrprctlru=cl_lru_scr_src(tpLruScrHead,scrname)) {	/* キャッシュにあるか調べる */
DEBUGOUTL1(110,"cl_exe_scr_file_init: %s is found in cache",name);
		if (!(scrprct=cl_mk_lk_scr_pr_ct(NULL))) {
			return ECL_SYSTEM_ERROR;
		}
/*
printf("cl_exe_scr_file_init: cache hit\n");
*/
DEBUGOUTL2(110,"cl_exe_scr_file_init: scrprct=%08x leaf0=%08x",scrprct,leaf0);
		scrprct->ConstCt = NULL;
		scrprct->TreeTop = scrprctlru->TreeTop;
		scrprct->LeafConstCt = scrprctlru->LeafConstCt;
		scrprct->pId = scrprctlru->pId;
#if 1
		scrprct->fullname = scrprctlru->fullname;
#endif
		scrprct->pFlag = scrprctlru->pFlag;
	}
	else {
		scrprct = cl_mk_scr_and_reg(tpLruScrHead,NULL,scrname);
		if (!scrprct) return ECL_SYSTEM_ERROR;
		if (!cl_mk_lk_scr_pr_ct(scrprct)) { /* Make Linked Script Control Table */
			const_ct_clear(CLcList.ConstCt);
			CLcList.ConstCt = NULL;
			cl_scr_clear(scrprct);
			return ECL_SYSTEM_ERROR;
		}
DEBUGOUTL2(110,"cl_exe_scr_file_init: scrprct=%08x leaf0=%08x",scrprct,leaf0);
	}

#if 1	/* 2021.8.18 */
#if 1	/* 2022.5.8 */
	rc = cl_exe_scr_set_up(procname,leaf0,proc,scrprct,stdiow,&parl,reset);
#else
	rc = cl_exe_scr_set_up(procname,proc,scrprct);
#endif
#else
	rc = cl_exe_scr_set_up(procname,leaf0,proc,scrprct,nam_pos);
#endif
#if 1	/* 2021.8.25 */
/*
printf("cl_exe_scr_file_init: rc=%d try_level=%d\n",rc,pGlobTable->try_level);
*/
	scrprct->try_level_save = pGlobTable->try_level;
	if (!rc && leaf0 && pGlobTable->try_level>0) {
		iOPT_TRYPASS = cl_get_option(7,0) & 0x08;
		prmp = leaf0->cmd.prmp[nam_pos-1];
		sckind = prmp->prp;
		sk_len = prmp->prmlen;
		pos = akxnskipto(sckind,sk_len,":") + 1;
/*
printf("cl_exe_scr_file_init: pos=%d sk_len=%d sckind=[%s]\n",pos,sk_len,sckind);
*/
		if (pos < sk_len) {
			sckind += pos;
/*
printf("cl_exe_scr_file_init: try_level=%d option=[%s]\n",pGlobTable->try_level,sckind);
*/
			if (!stricmp(sckind,D_EX_OPT_NOTRYPASS)) iOPT_TRYPASS = 0;
			else if (!stricmp(sckind,D_EX_OPT_TRYPASS)) iOPT_TRYPASS = 1;
		}
/*
printf("cl_exe_scr_file_init: iOPT_TRYPASS=%d\n",iOPT_TRYPASS);
*/
		if (!iOPT_TRYPASS) pGlobTable->try_level = 0;
	}
#endif
	return rc;
}

/********************************************/
/*	cl_mk_scr_and_reg						*/
/********************************************/
ScrPrCT *cl_mk_scr_and_reg(tpLSH,scrct,scrname)
tdtLruScrHead *tpLSH;
ScrPrCT *scrct;
char *scrname;
{
	ScrPrCT *scrprct=NULL;
	ProcCT  *procct;
	Leaf    *leaf,*leafTop;
	int     rc;
	char    *p;

	if (!(CLcList.ConstCt=cl_const_ct_new())) {
		ERROROUT("Malloc ConstCt");
		return NULL;
	}

	CLcList.mcat = &CLcList_mcat;

	rc = cl_lex_syn(scrname); /* Execute Lexial Analysis & Syntax Analysis */
	if ((rc != NormalEnd) || !(leafTop = search_top_leaf())) {
		goto Err;
	}
	if (scrct) {
		scrprct = scrct;
		memset(scrprct,0,sizeof(ScrPrCT));
	}
	else {
		scrprct = cl_mk_scr_pr_ct(); /* Make Script Control Table */
		if (!scrprct) goto Err;
	}
	scrprct->TreeTop = leafTop;
	scrprct->ConstCt = CLcList.ConstCt;
	scrprct->pFlag |= (CLcList.option & D_SCRPT_NEW_LEX);

	CLcList.ConstCt = NULL;
	CLSTCB.TopStack = NULL;	/* Ao */
	if (!(scrprct->pId=cl_const_ct_malloc(scrprct->ConstCt,strlen(scrname)+1))) {
		goto Err;
	}
	strcpy(scrprct->pId,scrname);
#if 1
	p = CLcList.fullname;
	if (!(scrprct->fullname=cl_const_ct_malloc(scrprct->ConstCt,strlen(p)+1))) {
		goto Err;
	}
	strcpy(scrprct->fullname,p);
#endif
	PRINTOUTL1(10,"***** Path = %s",CLcList.fullname);
	scrprct->LeafConstCt = scrprct->ConstCt;
	rc = cl_lru_scr_reg(tpLSH,scrprct,CLcList.fullname);	/* キャッシュに登録する */
	if (rc < 0) goto Err;
	else if (rc != C_NO_ENTRY)  {
		scrprct->ConstCt = NULL;
DEBUGOUTL1(110,"cl_mk_scr_and_reg : %s is cached now.",scrname);
	}
	return scrprct;
 Err:
	if (!scrct && scrprct) Free(scrprct);
 	const_ct_clear(CLcList.ConstCt);
	CLcList.ConstCt = NULL;
	CLSTCB.TopStack = NULL;
	return NULL;
}

/********************************************/
/*	_set_node_path							*/
/********************************************/
int _set_node_path(scrct,leaf,argv0,nodeleaf)
ScrPrCT *scrct;
Leaf  *leaf;
char  *argv0[];
Leaf  *nodeleaf;
{
	int id,len,flg,n0,n,len0,pos,ln;
	char name[128],*np,buf[256],*path0,*path,*p,*argv[2];
	uchar *up0,*up;
	parmList *parmp;
	GXObject *pbxObj;
	Leaf *la[2];
	XHASHB *ProcIndex;

	id = leaf->cmd.cid;
/*
DEBUGOUTL1(130,"_set_node_path:Enter: node=[%s]",cl_gets_cmd_name(id));
*/
	if (leaf) {
		path = path0 = argv0[0];
		argv[1] = up0 = argv0[1];
		if ((id==C_NODE_SCRIPT || id==C_NODE_IMPORT) && leaf->leftleaf) {
			nodeleaf = leaf;
		}
		else if (id==C_PROC || id==C_FUNCTION || id==C_CLASS) {
			parmp = leaf->cmd.prmp[0];
			if (id == C_PROC) np = "P:";
			else if (id == C_FUNCTION) np = "F:";
			else np = "C:";
			strcpy(name,np);
			strcat(name,parmp->prp);
			if (path && *path) {
				ln = strlen(name);
				len = strlen(path) + ln + 2;
				if (len >= sizeof(buf)) return -1;
				sprintf(buf,"%s.%s",path,name);
				path = buf;
				len0 = up0[0];
				n0 = up0[len0+1];
				n = n0 + 1;
				if (!(up=(uchar *)cl_scr_malloc(len+2*n+3))) return ECL_MALLOC_ERROR;
				up[0] = len;
				memcpy(up+1,buf,len);
				up[len] = '.';
				up[len+1] = n;
				memcpy(up+len+2,up0+len0+2,2*n0);
				up[len+2+2*n0] = len0 + 1;
				up[len+2+2*n0+1] = ln;
				up[len+2+2*n0+2] = '\0';
				argv[1] = (char *)up;
			}
			else {
				ln = strlen(name);
				len = ln + 1;
				path = name;
				n0 = 0;
				n = 1;
				if (!(up=(uchar *)cl_scr_malloc(len+2+3))) return ECL_MALLOC_ERROR;
				up[0] = len;
				memcpy(up+1,name,ln);
				up[len] = '.';
				up[len+1] = n;
				up[len+2] = 1;
				up[len+2+1] = ln;
				up[len+2+2] = '\0';
				argv[1] = (char *)up;
/*
DEBUGOUTL5(130,"_set_node_path: up=%d [%s] %d %d %d",up[0],strname(up+1,ln+1),up[len+1],up[len+2],up[len+3]);
*/
			}

DEBUGOUTL4(130,"_set_node_path: nodeleaf=%08x leaf=%08x path0=[%s] path=[%s]",nodeleaf,leaf,path0,path);

			flg = 0;
			if (!strcmp(parmp->prp,"main")) {
				if (nodeleaf) flg = nodeleaf->pFlag & D_LEAF_INEFFECTIVE;
			}
			if (!flg) {
				if (akxs_xhash2(scrct->ProcIndex,'R',up,la) <= 0) {
					la[0] = leaf;
					la[1] = nodeleaf;
					pos = akxs_xhash2(scrct->ProcIndex,'S',up,la);

DEBUGOUTL1(130,"_set_node_path: set nodeleaf & cur.leaf i=%d",pos);

				}
			}
/*
DEBUGOUTL1(130,"_set_node_path: parmp->bxob=%08x\n",parmp->bxobj);
*/
			if (!(pbxObj=parmp->bxobj)) {
				len = sizeof(GXObject) + sizeof(char **) + strlen(path) + 1;
				if (!(p=cl_leaf_malloc(len))) return ECL_MALLOC_ERROR;
				pbxObj = (GXObject *)p;
				memset(pbxObj,0,sizeof(GXObject));
				parmp->bxobj = pbxObj;
				p += sizeof(GXObject);
				pbxObj->da = (char **)p;
				pbxObj->da[0] = p + sizeof(char **);
				strcpy(pbxObj->da[0],path);
			}
		}
		argv[0] = path;
		if (leaf->leftleaf) {
			_set_node_path(scrct,leaf->leftleaf,argv,nodeleaf);
		}
 		if (leaf->rightleaf) {
			_set_node_path(scrct,leaf->rightleaf,argv0,nodeleaf);
		}
	}
/*
DEBUGOUTL1(130,"_set_node_path:Return: node=[%s]",cl_gets_cmd_name(id));
*/
	return 0;
}

/********************************************************/
/*	cl_exe_scr_set_up									*/
/* 引数 : proc		: EXECコマンドを実行しているproc	*/
/*		  scrprct	: 実行するSCRIPTのScrCt				*/
/********************************************************/
/* 2022.5.8 */
int cl_exe_scr_set_up(procname,leaf0,proc,scrprct,stdiow,parl,reset)
char *procname;
Leaf    *leaf0;
ProcCT  *proc;
ScrPrCT *scrprct;
FILE *stdiow[];
ParList2 *parl;
int reset;
{
	int  rc,i,f,parmnum,pflag2;
	char *exprocname,*argv[2],*p;
	Leaf*leaf;
	ScrPrCT	*pre;
	FILE *fp;
	parmList **pprmp;
	tdtREDIRECT *red,*redscr;

DEBUGOUTL3(110,"cl_exe_scr_set_up:Enter proc=%08x scrprct=%08x reset=%08x",proc,scrprct,reset);

	if (!(scrprct->Obj=cl_mk_obj0(cl_get_obj0_used(NULL,scrprct),0))) {
		ERROROUT("cl_exe_scr_set_up: Error occured set scrprct->Objj");
		goto ErLkScr;
	}
#if 0	/* 2021.7.26 */
	if (leaf=scrprct->TreeTop) {
		return cl_gx_clear_var_obj2(leaf,NULL,NULL,scrprct->Obj,D_AUX1_PRIVATE_VAR);
	}
#endif
#if 1	/* 2021.8.7 */
	redscr = scrprct->redirect;
	if (proc) {
		red = proc->redirect;
		mem_cpy_addr(redscr->stdio,red->stdio,4);
		redscr->HereDoc_nm = red->HereDoc_nm;
		redscr->pFlag2 = red->pFlag2 & D_PFLAG2_HEREDOC_OPT;
#if 1	/* 2022.5.8 */
		rc = 0;
#if 1	/* 2022.5.22 */
		if (reset) {
			rc = cl_reset_stdio_redirect(redscr,reset>>16,NULL);
		}
		if (!rc) rc = cl_set_stdio_redirect(redscr,NULL,stdiow,parl);
#else
		if (reset) {
			rc = cl_reset_scr_stdio_redirect(scrprct,reset>>16);
		}
		if (!rc) rc = cl_set_scr_stdio_redirect(scrprct,stdiow,parl);
#endif
		if (rc < 0) return rc;
#endif
/*
for (i=0;i<4;i++) {
printf("cl_exe_scr_set_up:1 redscr->stdio[%d]=%08x\n",i,redscr->stdio[i]);
}
printf("cl_exe_scr_set_up:1 HereDoc_nm=[%s]\n",redscr->HereDoc_nm);
*/
	}
	else {
		redscr->stdio[0] = stdin;
		redscr->stdio[1] = stdout;
		redscr->stdio[2] = stderr;
		redscr->stdio[3] = NULL;
		redscr->HereDoc_nm = NULL;
	}
#endif
	mem_set_addr(stdiow,NULL,4);
	parl->par = NULL;
	parl->parlen = 0;
	if (leaf0) {
		/* 2021.8.18 */
		rc = cl_scparmset(proc,scrprct,stdiow,parl);
		/* 2022.5.20 */
#if 1	/* 2022.5.22 */
		if ((rc=cl_set_stdio_redirect(redscr,NULL,stdiow,parl)) < 0) return rc;
#else
		if ((rc=cl_set_scr_stdio_redirect(scrprct,stdiow,parl)) < 0) return rc;
#endif
/*
for (i=0;i<4;i++) {
printf("cl_exe_scr_set_up:2 redscr->stdio[%d]=%08x\n",i,redscr->stdio[i]);
}
printf("cl_exe_scr_set_up:2 HereDoc_nm=[%s]\n",redscr->HereDoc_nm);
*/
	}
	else {
		rc = cl_parameter_set();
#if 0	/* 2021.12.13 */
		if (!rc) rc = _set_redirect_by_pasento(scrprct);
#endif
	}
	if (rc) goto ErLkScr;

	pGLprocTable->CurScr->pId = scrprct->pId;
	if (rc = cl_process_import(scrprct,NULL)) {
		ERROROUT("cl_exe_scr_set_up: Error occured Import Process");
		goto ErLkScr;
	}
	if (CLcommon.dbgopt[1] & 0x01) {
		col_leaf(scrprct);
		if (!(CLcommon.dbgopt[1] & 0x02)) {
			rc = ECL_EX_EXEC_TREE;
			goto ErLkScr;
		}
	}
	rc = ECL_MALLOC_ERROR;
	if (!(scrprct->ProcIndex = akxs_xhash_new2(0,10,7,sizeof(Leaf *)*2))) goto ErLkScr;
#if 0
	if (!(scrprct->pListExport = akxs_list_new(0,0))) goto ErLkScr;	/* add 2021.8.7 */
#endif
	rc = 0;
	argv[0] = "";
	argv[1] = NULL;
	_set_node_path(scrprct,scrprct->TreeTop,argv,NULL);
	if (rc = cl_process_on(scrprct)) {
		ERROROUT("cl_exe_scr_set_up: Error occured ON condition Process");
		goto ErLkScr;
	}
	if (leaf=pGLprocTable->CurScr->TreeTop) {
#if 1	/* 2021.2.20 */
		_set_node_path(pGLprocTable->CurScr,leaf,argv,NULL);
#endif
#if 0	/* 2021.11.14 *//* importされたスクリプトのスクリプト変数は、実行中のスクリプト */
		/* 固有のスクリプト変数になるようにscrprctを指定する */
		if (rc = cl_mk_lk_push(pGLprocTable->CurScr)) {
			goto ErLkScr;
		}
		pCLprocTable->CurScr = pGLprocTable->CurScr;
		rc = cl_process_define(pGLprocTable->CurScr,leaf);
		if (cl_er_lk_scr_pr_ct_opt(1) == -1) rc = ECL_SYSTEM_ERROR;
		if (rc) {
#else
		if (rc = cl_process_define(scrprct,leaf)) {
#endif
			ERROROUT("cl_exe_scr_set_up: Error occured GLOBAL Define Process");
			goto ErLkScr;
		}
	}
	if (rc = cl_process_define(scrprct,scrprct->TreeTop)) {
		ERROROUT("cl_exe_scr_set_up: Error occured Define Process");
		goto ErLkScr;
	}
	if (procname && *procname) exprocname = procname;
	else exprocname = "main";
	rc = cl_execute_scr_proc(NULL,0,NULL,scrprct,exprocname);
	if (rc < 0) goto ErLkScr;
	if (leaf0 && proc) {
		/* Need Parameter Set process */
		if (rc = cl_prparmset(/*leaf0,*/proc,exprocname)) {
			if (cl_er_lk_proc_ct() == -1) return ECL_SYSTEM_ERROR;
			else if(rc == -2) {
				if (cl_er_lk_scr_pr_ct() == -1) return ECL_SYSTEM_ERROR;
			}
			return ECL_EX_EXEC;
		}
	}
DEBUGOUTL1(110,"cl_exe_scr_set_up:Exit rc=%d",rc);
	return rc;

  ErLkScr:
	if (cl_er_lk_scr_pr_ct() == -1) rc = ECL_SYSTEM_ERROR;
DEBUGOUTL1(110,"cl_exe_scr_set_up:Exit rc=%d",rc);
	return rc;
}

/********************************************/
/*	cl_mk_scr_mem_and_reg					*/
/********************************************/
ScrPrCT *cl_mk_scr_mem_and_reg(mem,len)
char *mem;
int  len;
{
	tdtInfoParm InfoParm;
	SSP_S ssp;
	ScrPrCT *scrprct;
	Leaf    *leafTop;
	int     rc,pos;

	if (!(CLcList.ConstCt=(ConstantCt *)cl_const_ct_new())) {
		ERROROUT("Malloc ConstCt");
		return NULL;
	}
	CLcList.ConstCt->cct_top = NULL;
	CLcList.ConstCt->cct_cur = NULL;

	CLcList.mcat = &CLcList_mcat;
	if (*mem == '{') {
		mem++;
		len--;
	}
	if (mem[len-1] == '}') {
		len--;
		mem[len] = '\0';
	}
	ssp.sp = 0;
	InfoParm.pi_paux = (char *)&ssp;
	InfoParm.pi_dlen = len;
	InfoParm.pi_data = mem;
	InfoParm.pi_scale = 0;
	CLcList.fp = (FILE *)&InfoParm;
	CLcList.line = 0;
	CLcList.fullname = CLcList.fname;
	CLcList.option |= D_SCRPT_MEMORY;
	CLSTCB.TopStack = NULL;
	rc = cl_lex();
	if ((rc != NormalEnd) || !(leafTop = search_top_leaf())) {
		goto Err;
	}
	scrprct = cl_mk_scr_pr_ct(); /* Make Script Control Table */
	if (!scrprct) goto Err;
	scrprct->TreeTop = leafTop;
	scrprct->ConstCt = CLcList.ConstCt;
	scrprct->pFlag |= (CLcList.option & D_SCRPT_NEW_LEX);

	CLcList.ConstCt = NULL;
	CLSTCB.TopStack = NULL;
	scrprct->pId = CLcList.fname;

	scrprct->LeafConstCt = scrprct->ConstCt;
	scrprct->ConstCt = NULL;
	return scrprct;
 Err:
 	const_ct_clear(CLcList.ConstCt);
	CLcList.ConstCt = NULL;
	CLSTCB.TopStack = NULL;
	return NULL;
}

/********************************************/
/*	cl_exe_scr_mem_init						*/
/********************************************/
int cl_exe_scr_mem_init(sc_nam,pr_nam,leaf0,proc,nam_pos)
ParList *pr_nam,*sc_nam;
int  nam_pos;
Leaf    *leaf0;
ProcCT  *proc;
{
	ScrPrCT *scrprct;
	char *mem,*proc_name;
	int  len,parmnum,rc;
	parmList **pprmp;
	ParList2 parl;
	FILE *stdiow[4];

DEBUGOUTL3(110,"cl_exe_scr_mem_init:Enter leaf0=%08x proc=%08x nam_pos=%d",leaf0,proc,nam_pos);

	_print_script_start(CLcList.fname);

	proc_name = pr_nam->par;
	scrprct = cl_mk_scr_mem_and_reg(sc_nam->par,sc_nam->parlen);
	if (!scrprct) return ECL_SYSTEM_ERROR;
	if (!cl_mk_lk_scr_pr_ct(scrprct)) { /* Make Linked Script Control Table */
		const_ct_clear(CLcList.ConstCt);
		CLcList.ConstCt = NULL;
		cl_scr_clear(scrprct);
		return ECL_SYSTEM_ERROR;
	}
	if (proc_name) mem = proc_name;
	else mem = "";
DEBUGOUTL2(110,"cl_exe_scr_mem_init: scrprct=%08x proc_name=[%s]",scrprct,mem);

#if 1	/* 2022.6.16 */
	if (leaf0 && proc) {
		pprmp = &leaf0->cmd.prmp[nam_pos+1];
		parmnum = leaf0->cmd.prmnum - (nam_pos+1);
		if ((rc=cl_set_exec_parm(pprmp,parmnum,proc)) < 0) return rc;
	}
	mem_set_addr(stdiow,NULL,4);
	memset(&parl,0,sizeof(ParList2));
	return cl_exe_scr_set_up(proc_name,leaf0,proc,scrprct,stdiow,&parl,0);
#else
	return cl_exe_scr_set_up(proc_name,leaf0,proc,scrprct,nam_pos);
#endif
}

/**************************************************************/
/* cl_search_src_ct                                           */
/* function; Search current Script Control Table              */
/**************************************************************/
ScrPrCT *cl_search_src_ct()
{
	ScrPrCT *scrprct;

#if 1	/* 2021.2.5 */
	if (!(scrprct=pCLprocTable->CurScr)) {
		if (scrprct=pCLprocTable->PrCTp) {
			while (scrprct->nextScCT) scrprct = scrprct->nextScCT;
			pCLprocTable->CurScr = scrprct;
		}
	}
	return scrprct;
#else
	if (!(scrprct=pCLprocTable->CurScr)) {
		pCLprocTable->CurScr = NULL;
		if (!(scrprct=pCLprocTable->PrCTp)) return NULL;
		while (scrprct->nextScCT) scrprct = scrprct->nextScCT;
	}
	return pCLprocTable->CurScr = scrprct;
#endif
}

/**************************************************************/
/* cl_search_proc_ct                                          */
/* function; Search current Proc Control Table                */
/**************************************************************/
ProcCT *cl_search_proc_ct()
{
	ScrPrCT *scrprct;
	ProcCT *proc;

	if (scrprct = cl_search_src_ct()) proc = scrprct->CurProc;
	else proc = NULL;
	pCLprocTable->CurProc = proc;
	return proc;
}

/**************************************************************/
/* cl_search_method_leaf                                      */
/* function; Search Method keyed by procname                  */
/**************************************************************/
Leaf *cl_search_method_leaf(leaf,procname,ppTopleaf,tag)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
int  tag;
{
	Leaf    *wkleaf;
	Leaf    *retleaf,*topleaf;
	int cno,flg,cno_OK,pFlg,opt;

	if (!procname || !leaf) return NULL;
/*
printf("cl_search_method_leaf: proc=[%s] called. leaf=%08x ppTopleaf=%08x\n",
procname,leaf,ppTopleaf);
if (ppTopleaf) {
printf("cl_search_method_leaf: proc=[%s] nodeleaf=%08x\n",procname,*ppTopleaf);
}
*/
	retleaf  = NULL;
	wkleaf = leaf;
	opt = pFlg = flg = 0;
	if (pGlobTable->options[7] & 0x04) opt = AKX_ARGV_USE_ICMP;
	cno = wkleaf->cmd.cid;

	cno_OK = wkleaf->cmdtag & tag;

DEBUGOUTL5(151,"cl_search_method_leaf: proc=[%s] tag=%02x cno_OK=%02x cno=%08x [%s]",
procname,tag,cno_OK,cno,cl_gets_cmd_name(cno));

/*
printf("                  proc=[%s] cno_OK=%d\n",procname,cno_OK);
*/
/*
printf("proc=[%s]\n",wkleaf->cmd.prmp[0]->prp);
*/
	if (cno_OK && !akxs_opt_strcmp(wkleaf->cmd.prmp[0]->prp,procname,opt)) {
		if (ppTopleaf) {
			if (topleaf = *ppTopleaf) {
				pFlg = topleaf->pFlag;
				flg = pFlg & D_LEAF_INEFFECTIVE;
			}
		}

DEBUGOUTL2(151,"cl_search_method_leaf: proc=[%s] found. pFlag=%02x",procname,pFlg);

		if (!flg || akxs_opt_strcmp(procname,"main",opt)) return wkleaf;
	}
		if ((cno==C_NODE_SCRIPT || cno==C_NODE_IMPORT) && wkleaf->leftleaf) {
			if (ppTopleaf) *ppTopleaf = wkleaf;
/*{
Leaf *nodeleaf;
if (ppTopleaf) nodeleaf = *ppTopleaf;
else nodeleaf = NULL;
printf("cl_search_method_leaf: proc=[%s] cno=%08x\n",procname,cno);
printf("                       leaf=%08x ppTopleaf=%08x nodeleaf=%08x\n",
wkleaf,ppTopleaf,nodeleaf);
}*/
			retleaf = cl_search_method_leaf(wkleaf->leftleaf,procname,ppTopleaf,tag);
			if (retleaf) return retleaf;
			if (ppTopleaf) *ppTopleaf = NULL;
		}
		if (wkleaf->rightleaf) {
			retleaf = cl_search_method_leaf(wkleaf->rightleaf,procname,ppTopleaf,tag);
			if (retleaf) return retleaf;
		}
		return NULL;
}
#if 0	/* 2021.2.20 */
/********************************************/
/*	cl_search_proc_leaf						*/
/********************************************/
Leaf *cl_search_proc_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return cl_search_method_leaf(leaf,procname,ppTopleaf,CTAG_PROC);
}
#endif
/********************************************/
/*	cl_search_func_leaf						*/
/********************************************/
Leaf *cl_search_func_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return cl_search_method_leaf(leaf,procname,ppTopleaf,CTAG_FUNC);
}
#if 0	/* 2021.2.20 */
/********************************************/
/*	cl_search_class_leaf					*/
/********************************************/
Leaf *cl_search_class_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return cl_search_method_leaf(leaf,procname,ppTopleaf,CTAG_CLASS);
}
#endif
/********************************************/
/*	cl_search_proc							*/
/********************************************/
Leaf *cl_search_proc(leaf,procname)
Leaf *leaf;
char *procname;
{
	return cl_search_method_leaf(leaf,procname,NULL,CTAG_PROC);
}

/********************************************/
/*	cl_search_func							*/
/********************************************/
Leaf *cl_search_func(leaf,procname)
Leaf *leaf;
char *procname;
{
	return cl_search_method_leaf(leaf,procname,NULL,CTAG_FUNC);
}

/********************************************/
/*	cl_search_class							*/
/********************************************/
Leaf *cl_search_class(leaf,procname)
Leaf *leaf;
char *procname;
{
	return cl_search_method_leaf(leaf,procname,NULL,CTAG_CLASS);
}
#if 0	/* 2021.2.20 */
/********************************************/
/*	_search_proc_leaf_inner					*/
/********************************************/
static Leaf *_search_proc_leaf_inner(proc,procname,ppTopleaf,kind)
ProcCT *proc;
char *procname;
Leaf **ppTopleaf;
int  kind;
{
	Leaf *leaf;

	if (!proc) return NULL;
	if (!(leaf=proc->ProcTop)) return NULL;
	if (ppTopleaf) *ppTopleaf = NULL;
	return cl_search_method_leaf(leaf->leftleaf,procname,ppTopleaf,kind);
}

/********************************************/
/*	cl_search_proc_leaf_inner				*/
/********************************************/
Leaf *cl_search_proc_leaf_inner(proc,procname,ppTopleaf)
ProcCT *proc;
char *procname;
Leaf **ppTopleaf;
{
	return _search_proc_leaf_inner(proc,procname,ppTopleaf,CTAG_PROC);
}

/********************************************/
/*	cl_search_func_leaf_inner				*/
/********************************************/
Leaf *cl_search_func_leaf_inner(proc,procname,ppTopleaf)
ProcCT *proc;
char *procname;
Leaf **ppTopleaf;
{
	return _search_proc_leaf_inner(proc,procname,ppTopleaf,CTAG_FUNC);
}
#endif
/********************************************/
/*											*/
/********************************************/
int col_leaf(scrprCT)
ScrPrCT *scrprCT;
{
	Leaf *leaf;

	if (!scrprCT) return -1;
	if (leaf=pGLprocTable->CurScr->TreeTop) {
		printf("### Global Source Area.\n");
		col_leaf_print(leaf);
		printf("\n");
	}
	if (leaf=scrprCT->TreeTop) {
		printf("### Source Area.\n");
		col_leaf_print(leaf);
		printf("\n");
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int col_leaf_print(leaf)
Leaf *leaf;
{
	static char s_node[2]={'A','\0'};
	char buf[10],*p,node[2],*pp;
	int cno;
 
	if (!leaf) return -1;
	node[0] = '\0';
	node[1] = '\0';
	p = cl_get_pcmd_line(leaf);
	if (!(leaf->leftleaf)) printf("*");
	if (CLcommon.dbgopt[1] & 0x04) printf("(%d)",leaf->type);
	cl_str_conv_put(&pp,p,strlen(p));
	printf("[%s]",pp);
	if (p != pp) Free(pp);
	if ((cno=leaf->cmd.cid)==C_NODE_SCRIPT || cno==C_NODE_IMPORT)
		printf(" pFlag=0x%02x",leaf->pFlag);
	if (!(leaf->rightleaf)) {
		printf(".");
		if (!(leaf->leftleaf)) printf("\n");
	}
	else if (leaf->leftleaf) {
		node[0] = s_node[0];
		printf("->%s",node);
		s_node[0]++;
	}
	if (leaf->leftleaf) {
		printf("\n|\n");
		col_leaf_print(leaf->leftleaf);
	}

	if (leaf->rightleaf) {
		printf("\n%s-",node);
		col_leaf_print(leaf->rightleaf);
	}

	return (0);
}

/********************************************/
/*											*/
/********************************************/
tdtLruScrHead *cl_lru_scr_new(max)
int max;
{
	tdtLruScrHead *tpLSH;
	qLruScr *pLruScr;

	if (max < LRU_SCR_MIN) max = LRU_SCR_MIN;
PRINTOUT1("cl_lru_scr_new:max=%d",max);
	if (!(tpLSH=(tdtLruScrHead *)Malloc(sizeof(tdtLruScrHead)))) {
		ERROROUT("cl_lru_scr_new:Malloc error!!");
		return NULL;
	}
	memset(tpLSH,0,sizeof(tdtLruScrHead));
	if (!(pLruScr = (qLruScr *)Malloc(max*sizeof(qLruScr)))) {
		ERROROUT("cl_lru_scr_new:Malloc error!!");
		Free(tpLSH);
		return NULL;
	}
	memset(pLruScr,0,max*sizeof(qLruScr));
	tpLSH->LruOption = 0;
	tpLSH->LruScrMax = max;
	tpLSH->LruCount = 0;
	tpLSH->tpLruScr = pLruScr;
	return tpLSH;
}

/********************************************/
/*											*/
/********************************************/
static int cl_lru_scr_expand(tpLSH,max)
tdtLruScrHead *tpLSH;
int max;
{
	qLruScr *pLruScr;

	if (max < LRU_SCR_MIN) max = LRU_SCR_MIN;
PRINTOUT1("cl_lru_scr_expand:max=%d",max);
	max +=tpLSH->LruScrMax;
	if (!(pLruScr = (qLruScr *)Realloc(tpLSH->tpLruScr,max*sizeof(qLruScr)))) {
		ERROROUT("cl_lru_scr_expand:Malloc error!!");
		return -1;
	}
	tpLSH->LruScrMax = max;
	tpLSH->tpLruScr = pLruScr;
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int cl_lru_scr_init(max)
int max;
{
	if (max < LRU_SCR_MIN) max = LRU_SCR_MIN;
PRINTOUT1("cl_lru_scr_init:max=%d",max);
	if (!(tpLruScrHead = cl_lru_scr_new(max))) {
		ERROROUT("cl_lru_scr_new:Malloc error!!");
		return -1;
	}
	if (!(tpLruScrHeadImp = cl_lru_scr_new(max))) {
		ERROROUT("cl_lru_scr_new:Imp:Malloc error!!");
		return -1;
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int cl_lru_scr_free(tpLSH)
tdtLruScrHead *tpLSH;
{
	if (tpLSH) {
		cl_lru_scr_all_clear(tpLSH);
		Free(tpLSH);
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
static int cl_lru_scr_srci(tpLSH,fullname)
tdtLruScrHead *tpLSH;
char *fullname;
{
	int i;
	qLruScr *pLruScr;

	if (!tpLSH) return -1;
	if (fullname) {
		if (!(pLruScr = tpLSH->tpLruScr)) return -1;
		for (i=0;i<tpLSH->LruCount;i++,pLruScr++) {
			if (!strcmp(pLruScr->cpfullname,fullname)) {
/*
printf("cl_lru_scr_srci:found %s i=%d\n",fullname,i);
*/
				return i;
			}
		}
	}
	return -1;
}

/********************************************/
/*											*/
/********************************************/
static int cl_lru_scr_reg_new(scrprct,fullname,pLruScr)
ScrPrCT *scrprct;
char *fullname;
qLruScr *pLruScr;
{
	struct stat tStat;

	if (!scrprct || !fullname || !pLruScr) return -1;
	if (stat(fullname,&tStat)) return -1;

	if (!(pLruScr->cpfullname =
		cl_const_ct_malloc(scrprct->ConstCt,strlen(fullname)+1))) return -1;
	strcpy(pLruScr->cpfullname,fullname);
	pLruScr->mtime = tStat.st_mtime;
	pLruScr->ltime = time(0);
	akxe_get_msec(NULL,&pLruScr->rtime);
	pLruScr->refc  = 1;
	scrprct->pFlag |= D_LEAF_CACHED;
	memcpy(&pLruScr->scrct,scrprct,sizeof(ScrPrCT));
/*
printf("cl_lru_scr_reg_new:mtime=%d ltime=%d\n",pLruScr->mtime,pLruScr->ltime);
*/
	return 0;
}

/********************************************/
/*											*/
/********************************************/
static int cl_lru_scr_reg_rep(scrprct,fullname,pLruScr)
ScrPrCT *scrprct;
char *fullname;
qLruScr *pLruScr;
{
	ScrPrCT *scrlruct;

	if (!scrprct || !fullname || !pLruScr) return -1;

	scrlruct = &pLruScr->scrct;
/*
printf("cl_lru_scr_reg_rep:fullname=[%s] pFlag=%02x\n",fullname,scrlruct->pFlag);
*/
	if (!(scrlruct->pFlag & D_LEAF_IMPORTMODE)) {
		cl_leaf_clear(scrlruct->TreeTop);
		const_ct_clear(scrlruct->ConstCt);
	}
	return cl_lru_scr_reg_new(scrprct,fullname,pLruScr);
}

/********************************************/
/*											*/
/********************************************/
ScrPrCT *cl_lru_scr_src_opt(tpLSH,scrname,opt)
tdtLruScrHead *tpLSH;
char *scrname;
int  opt;
{
	int i;
	struct stat tStat;
	char dir[256];
	FILE *fp;
	qLruScr *pLruScr;

	if (!scrname) return NULL;
	if (!(fp=cl_file_open(scrname,dir))) return NULL;
/*
printf("cl_lru_scr_src:dir = %s\n",dir);
*/
	fclose(fp);
	if ((i=cl_lru_scr_srci(tpLSH,dir))>=0) {
		pLruScr = &tpLSH->tpLruScr[i];
		pLruScr->ltime = time(0);
		akxe_get_msec(NULL,&pLruScr->rtime);
		if (!stat(akb_akb_home_add(dir),&tStat)) {
/*
printf("cl_lru_scr_src:i = %d, mtime=%d st_mtime=%d\n",i,
pLruScr->mtime,tStat.st_mtime);
*/
			if (pLruScr->mtime == tStat.st_mtime) {
				if (opt & 0x01) pLruScr->refc++;
/*
printf("cl_lru_scr_src:after.refc=%d\n",pLruScr->refc);
*/
				return &pLruScr->scrct;
			}
		}
	}
	return NULL;
}

/********************************************/
/*											*/
/********************************************/
ScrPrCT *cl_lru_scr_src(tpLSH,scrname)
tdtLruScrHead *tpLSH;
char *scrname;
{
	return cl_lru_scr_src_opt(tpLSH,scrname,1);
}

/********************************************/
/*											*/
/********************************************/
int	cl_lru_scr_reg(tpLSH,scrprct,fullname)
tdtLruScrHead *tpLSH;
ScrPrCT *scrprct;
char *fullname;
{
	qLruScr *pLruScr;
	int i,i_min,t_min,rc=0,refc;
	struct timeval tv_min;

	if (!tpLSH || !scrprct || !fullname) return -1;
/*
printf("cl_lru_scr_reg: fulname=[%s]\n",fullname);
*/
	if ((i=cl_lru_scr_srci(tpLSH,fullname))>=0) {
		pLruScr = &tpLSH->tpLruScr[i];
		refc = pLruScr->refc;
/*
printf("cl_lru_scr_reg:found [%s], refc = %d\n",fullname,refc);
*/
		rc = cl_lru_scr_reg_rep(scrprct,fullname,pLruScr);
		if (!rc) pLruScr->refc = refc + 1;
	}
	else if (tpLSH->LruCount<tpLSH->LruScrMax || (tpLSH->LruOption & 0x01)) {
/*
printf("cl_lru_scr_reg:LruCount = %d\n",tpLSH->LruCount);
*/
		if (tpLSH->LruOption & 0x01) {
			if ((rc=cl_lru_scr_expand(tpLSH,LRU_SCR_MIN)) < 0) return rc;
		}
		if (!(rc = cl_lru_scr_reg_new(scrprct,fullname,&tpLSH->tpLruScr[tpLSH->LruCount])))
			tpLSH->LruCount++;
	}
	else {
#if 1
		i_min = -1;
		tv_min.tv_sec = LONG_MAX;
		tv_min.tv_usec = LONG_MAX;
		pLruScr = &tpLSH->tpLruScr[0];
		for (i=0;i<tpLSH->LruCount;i++,pLruScr++) {
/*
printf("cl_lru_scr_reg:i=%d refc=%d rtime=%d %d tv_min=%d %d\n",
i,pLruScr->refc,pLruScr->rtime.tv_sec,pLruScr->rtime.tv_usec,tv_min.tv_sec,tv_min.tv_usec);
*/
			if (!pLruScr->refc && akxe_timer_cmp(&pLruScr->rtime,&tv_min)<0) {
				i_min = i;
				tv_min = pLruScr->rtime;
			}
		}
		if (i_min >= 0) {
/*
printf("cl_lru_scr_reg:i_min = %d refc = %d\n",i_min,pLruScr->refc);
*/
			pLruScr = &tpLSH->tpLruScr[i_min];
			rc = cl_lru_scr_reg_rep(scrprct,fullname,pLruScr);
		}
		else rc = C_NO_ENTRY;
#else
		i_min = 0;
		t_min = tpLSH->tpLruScr[i_min].ltime;
		pLruScr = &tpLSH->tpLruScr[1];
		for (i=1;i<tpLSH->LruCount;i++,pLruScr++) {
			if (!pLruScr->refc && pLruScr->ltime<t_min) {
				i_min = i;
				t_min = pLruScr->ltime;
			}
		}
		pLruScr = &tpLSH->tpLruScr[i_min];
/*
printf("cl_lru_scr_reg:i_min = %d refc = %d\n",i_min,pLruScr->refc);
*/
		if (!pLruScr->refc)
			rc = cl_lru_scr_reg_rep(scrprct,fullname,pLruScr);
		else rc = C_NO_ENTRY;
#endif
	}
	return rc;
}

/********************************************/
/*											*/
/********************************************/
int cl_lru_scr_era(tpLSH,scrname)
tdtLruScrHead *tpLSH;
char *scrname;
{
	qLruScr *pLruScr;
	int i, refc;
	char dir[256];
	FILE *fp;

	if (!tpLSH || !scrname) return -1;
/*
printf("cl_lru_scr_era: scrname=[%s]\n",scrname);
*/
	if (!(fp=cl_file_open(scrname,dir))) return -1;
/*
printf("cl_lru_scr_era:dir = %s\n",dir);
*/
	fclose(fp);
	if ((i=cl_lru_scr_srci(tpLSH,dir))>=0) {
		pLruScr = &tpLSH->tpLruScr[i];
/*
printf("cl_lru_scr_era:i = %d, before.refc=%d\n",i,pLruScr->refc);
*/
		if (pLruScr->refc>0) pLruScr->refc--;
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int cl_lru_scr_all_clear(tpLSH)
tdtLruScrHead *tpLSH;
{
	int i;
	qLruScr *pLruScr;
/*
printf("cl_lru_scr_all_clear: tpLSH=%08x\n",tpLSH);
*/
	if (!tpLSH) return -1;
	if (!(pLruScr = tpLSH->tpLruScr)) return -1;

	for (i=0;i<tpLSH->LruCount;i++,pLruScr++) {
		cl_leaf_clear(pLruScr->scrct.TreeTop);
		const_ct_clear(pLruScr->scrct.ConstCt);
		pLruScr->scrct.TreeTop = NULL;
		pLruScr->scrct.ConstCt = NULL;
		pLruScr->scrct.LeafConstCt = NULL;
	}
	Free(tpLSH->tpLruScr);
	tpLSH->tpLruScr = NULL;
	return 0;
}
