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;

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

/****************************************************/
/*	_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);
}

/**************************************************************/
/* cl_execute_script                                          */
/* function; Execute specified Script                         */
/**************************************************************/
int cl_execute_script()
{
	ScrPrCT *scrprct = ( ScrPrCT *)NULL;
	ProcCT  *procct  = ( ProcCT *)NULL ;
	int rc;

	scrprct = cl_search_src_ct(); /* Search current script control table */
	if (!scrprct) return(ECL_SYSTEM_ERROR);

	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 )) {
 		rc = cl_node_control(procct->ProcTop,procct);
		procct = cl_search_proc_ct();
DEBUGOUTL1(110,"cl_execute_script: ret node procct=%08x",procct);
		if (cmn_chk_stat(RET_PR,&procct->ptype)){
		/*	if (procct->ptype & D_PFLAG_NO_FREE) return rc;	*/
			rc = cl_er_lk_proc_ct();	/* Erase ProcCt */
			if(rc == -1) {
				return(ECL_SYSTEM_ERROR);
			}
			else if(rc == -2) {
				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);
				}
			}
			if (scrprct = cl_search_src_ct()) {
				if (procct = cl_search_proc_ct())
					cl_set_scr_const_ct(scrprct,procct->Nodeleaf);
			}
			rc = 0;
		}
	}
	else {
		rc = cl_func_process(procct);
		if (rc) {
/*
printf("clexescr.c:clfunc ret = %d\n",rc);
*/
			pGlobTable->error = rc;
			if (!pGlobTable->exception)
				pGlobTable->exception = cl_mk_exception_code(ETC_EXCEPTION,rc);
			rc = 0;
		}
	}
	return rc;
}

/**************************************************************/
/* cl_exe_scr_name_check                                      */
/**************************************************************/
int cl_exe_scr_name_check(scrname,scrlen)
char *scrname;
int   scrlen;
{
	static char *_fname_="cl_exe_scr_name_check";
	int  len,n;
	char *name,*pn;

	/* parameter check */
	if (!(name=scrname)) {
		ERROROUT1("%s: script name is NULL!",_fname_);
		return ECL_SYSTEM_ERROR;
	}
	len = scrlen;
	n = akxnskipto(name,len,":");
	if (n < len) {
		pn = FORMAT(114);	/* "手続き" */
		if (n > PR_NM_DEF) {
			/* %s: 手続き名[%s]が長すぎます(len=%d > %d)。 */
			ERROROUT5(FORMAT(112),_fname_,pn,strtemp(name,n),n,PR_NM_DEF);
			return ECL_SCRIPT_ERROR;
		}
		if (cl_chk_proc_name(name,n)) {
			/* %s: 手続き名[%s]が不正です。 */
			ERROROUT3(FORMAT(113),_fname_,pn,strtemp(name,n));
			return ECL_SCRIPT_ERROR;
		}
		n++;
		name += n;	/* script name */
		len  -= n;
	}
	if (cl_chk_file_name(scrname,len)) {
		/* %s: スクリプト名[%s]が不正です。 */
		ERROROUT3(FORMAT(113),_fname_,FORMAT(119),strtemp(name,n));
		return ECL_SCRIPT_ERROR;
	}
	return 0;
}

/**************************************************************/
/* cl_exe_scr_init                                            */
/* function; Read specified Script From DB                    */
/**************************************************************/
int cl_exe_scr_init(scrname,leaf,proc)
char    *scrname;
Leaf    *leaf;
ProcCT  *proc;
{
	int rc,len,n,l;
	char *name,*p;

	len=strlen(scrname);
	if (!(rc = cl_exe_scr_name_check(scrname,len))) {
		n = akxnskipto(scrname,len,":");
/*
printf("cl_exe_scr_init len=%d n=%d\n",len,n);
*/
		if (n >= len) {
			name = scrname;
			p = NULL;
		}
		else {
			if (p = cl_tmp_const_malloc(n+1)) {
				memzcpy(p,scrname,n);
			}
			else {
				ERROROUT("cl_exe_scr_init: script name area malloc error");
				return -1;
			}
			name = scrname + n + 1;
		}
		rc = cl_exe_scr_file_init(name,p,leaf,proc);
		if (rc == ECL_NOT_FOUND_PROC) {
			if (!p || (p && !*p)) rc = 0;
		}
	}
	return rc;
}

/********************************************/
/*	cl_exe_scr_file_init					*/
/********************************************/
int cl_exe_scr_file_init(name,procname,leaf0,proc)
char *name;
char *procname;
Leaf    *leaf0;
ProcCT  *proc;
{
	ScrPrCT *scrprct;
	ScrPrCT *scrprctlru;
/*	ProcCT  *procct;
	Leaf    *leaf,*leafTop,*nodeleaf;	*/
	char    *scrname;

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

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

	return cl_exe_scr_set_up(procname,leaf0,proc,scrprct);
}

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

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

	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;
	/*	leaf->pFlag |= D_LEAF_CACHED;	*/
	/*	scrprct->pFlag |= D_LEAF_CACHED;	*/
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						*/
/********************************************/
int cl_exe_scr_set_up(procname,leaf0,proc,scrprct)
char *procname;
Leaf    *leaf0;
ProcCT  *proc;
ScrPrCT *scrprct;
{
	int  rc;
	char *exprocname,*argv[2];
	Leaf*leaf;

#if 1
	if (!(scrprct->Obj=cl_mk_obj0(cl_get_obj0_used(NULL,scrprct),0))) {
		ERROROUT("Error occured set scrprct->Objj");
		goto ErLkScr;
	}
#endif
	if (leaf0) rc = cl_scparmset(leaf0,proc);
	else rc = cl_parameter_set();
	if (rc) {
		goto ErLkScr;
	}
	pGLprocTable->CurScr->pId = scrprct->pId;
	if (rc = cl_process_import(scrprct,NULL)) {
		ERROROUT("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;
		}
	}
#if 1
	scrprct->ProcIndex = akxs_xhash_new2(0,10,7,sizeof(Leaf *)*2);
	argv[0] = "";
	argv[1] = NULL;
	_set_node_path(scrprct,scrprct->TreeTop,argv,NULL);
#endif
	if (rc = cl_process_on(scrprct)) {
		ERROROUT("Error occured ON condition Process");
		goto ErLkScr;
	}
	if (leaf=pGLprocTable->CurScr->TreeTop) {
		if (rc = cl_process_define(scrprct,leaf)) {
			ERROROUT("Error occured GLOBAL Define Process");
			goto ErLkScr;
		}
	}
	if (rc = cl_process_define(scrprct,scrprct->TreeTop)) {
		ERROROUT("Error occured Define Process");
		goto ErLkScr;
	}
/*
	if (rc = cl_process_dim(scrprct)) {
		ERROROUT("Error occured Dim Process");
		goto ErLkScr;
	}
*/
	if (procname && *procname) exprocname = procname;
	else exprocname = "main";
/*	rc = cl_execute_scr_proc(leaf0,proc,scrprct,exprocname);	*/
	rc = cl_execute_scr_proc(NULL,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;
		}
	}
	return rc;

  ErLkScr:
	if (cl_er_lk_scr_pr_ct() == -1) rc = ECL_SYSTEM_ERROR;
	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;

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

	CLcList.mcat = &CLcList_mcat;

	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.fname = "MEM:";	*/
	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 = "MEM:";	*/
	scrprct->pId = CLcList.fname;

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

/********************************************/
/*	cl_exe_scr_mem_init						*/
/********************************************/
int cl_exe_scr_mem_init(mem,len,leaf0,proc)
char *mem;
int  len;
Leaf    *leaf0;
ProcCT  *proc;
{
	ScrPrCT *scrprct;

	_print_script_start(CLcList.fname);

	scrprct = cl_mk_scr_mem_and_reg(mem,len);
	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_mem_init: scrprct=%08x leaf0=%08x",scrprct,leaf0);

	return cl_exe_scr_set_up(NULL,leaf0,proc,scrprct);
}

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

	if (!(scrprct=pCLprocTable->CurScr)) {
		pCLprocTable->CurScr = NULL;
		if (!(scrprct=pCLprocTable->PrCTp)) return NULL;
		while (scrprct->nextScCT) scrprct = scrprct->nextScCT;
	}
	return pCLprocTable->CurScr = scrprct;
}

/**************************************************************/
/* cl_search_proc_ct                                          */
/* function; Search current Proc Control Table                */
/**************************************************************/
ProcCT *cl_search_proc_ct()
{
#if 1
	return pCLprocTable->CurProc;
#else
	ScrPrCT *scrprct;
	ProcCT  *procct;
#if 1
	if (!(scrprct=cl_search_src_ct())) return NULL;
	if (!(procct=scrprct->CurProc)) {
		if (!(procct=scrprct->ProCT)) return NULL;
		while (procct->nextPCT) procct = procct->nextPCT;
	}
	return pCLprocTable->CurProc = procct;
#else
	pCLprocTable->CurProc = NULL;
	if (!(scrprct=cl_search_src_ct())) return NULL;
	if (!(procct=scrprct->ProCT)) return NULL;
	while (procct->nextPCT) procct = procct->nextPCT;
	return pCLprocTable->CurProc = procct;
#endif
#endif
}

/**************************************************************/
/* cl_search_proc                                             */
/* function; Search Proc keyed by procname                    */
/**************************************************************/
#if 1
static Leaf *_search_proc_leaf(leaf,procname,ppTopleaf,tag)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
int  tag;
#else
static Leaf *_search_proc_leaf(leaf,procname,ppTopleaf,kind)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
int  kind;
#endif
{
	Leaf    *wkleaf;
	Leaf    *retleaf,*topleaf;
	int cno,flg,cno_OK,pFlg,opt;

	if (!procname || !leaf) return NULL;
/*
printf("cl_search_proc_leaf: proc=[%s] called. leaf=%08x ppTopleaf=%08x\n",
procname,leaf,ppTopleaf);
if (ppTopleaf) {
printf("cl_search_proc_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;

#if 1
	cno_OK = wkleaf->cmdtag & tag;

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

#else
	cno_OK = cno==C_PROC || cno==C_FUNCTION || cno==C_CLASS;

DEBUGOUTL5(151,"cl_search_proc_leaf: proc=[%s] kind=%08x cno_OK=%d cno=%08x [%s]",
procname,kind,cno_OK,cno,cl_gets_cmd_name(cno));

	if (kind) cno_OK = (cno==kind) && cno_OK;
#endif
/*
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_proc_leaf: proc=[%s] found. pFlag=%02x",procname,pFlg);

		if (!flg || akxs_opt_strcmp(procname,"main",opt)) return wkleaf;
	}
/*	else { */
		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_proc_leaf: proc=[%s] cno=%08x\n",procname,cno);
printf("                  leaf=%08x ppTopleaf=%08x nodeleaf=%08x\n",
wkleaf,ppTopleaf,nodeleaf);
}*/
			retleaf = _search_proc_leaf(wkleaf->leftleaf,procname,ppTopleaf,tag);
			if (retleaf) return retleaf;
		/*	*ppTopleaf = NULL;	*/
			if (ppTopleaf) *ppTopleaf = NULL;
		}
		if (wkleaf->rightleaf) {
			retleaf = _search_proc_leaf(wkleaf->rightleaf,procname,ppTopleaf,tag);
			if (retleaf) return retleaf;
		}
		return NULL;
/*	} */
}

Leaf *cl_search_proc_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return _search_proc_leaf(leaf,procname,ppTopleaf,CTAG_PROC);
}

Leaf *cl_search_proc(leaf,procname)
Leaf *leaf;
char *procname;    
{
	return _search_proc_leaf(leaf,procname,NULL,CTAG_PROC);
}

Leaf *cl_search_func_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return _search_proc_leaf(leaf,procname,ppTopleaf,CTAG_FUNC);
}

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

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 _search_proc_leaf(leaf->leftleaf,procname,ppTopleaf,kind);
}

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

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

Leaf *cl_search_class_leaf(leaf,procname,ppTopleaf)
Leaf *leaf;
char *procname;
Leaf **ppTopleaf;
{
	if (ppTopleaf) *ppTopleaf = NULL;
	return _search_proc_leaf(leaf,procname,ppTopleaf,CTAG_CLASS);
}

/********************************************/
/*											*/
/********************************************/
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];
	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);
	printf("[%s]",p);
	if ((cno=leaf->cmd.cid)==C_NODE_SCRIPT || cno==C_NODE_IMPORT)
		printf(" pFlag=0x%02x",leaf->pFlag);
/*	if (leaf->pFlag & D_LEAF_INEFFECTIVE) printf("@");	*/
	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);
}

/********************************************/
/*											*/
/********************************************/
/*
typedef struct {
	long    mtime;
	long    ltime;
	int     refc;
	ScrPrCT scrct;
	char   *cpfullname;
} qLruScr;
static int LruCount = 0;

static int giLRU_SCR_MAX;
static qLruScr *LruScr=NULL;
static tdtLruScrHead *tpLruScrHead=NULL;
*/

/********************************************/
/*											*/
/********************************************/
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));
/*	giLRU_SCR_MAX = max;	*/
	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;
	}
/*	giLRU_SCR_MAX = max;	*/
	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);
	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;
{
	if (!scrprct || !fullname || !pLruScr) return -1;
/*
printf("cl_lru_scr_reg_rep:fullname=%s\n",fullname);
*/
	cl_leaf_clear(pLruScr->scrct.TreeTop);
	const_ct_clear(pLruScr->scrct.ConstCt);
/*	const_ct_clear(pLruScr->scrct.LeafConstCt);	*/
	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);
		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;

	if (!tpLSH || !scrprct || !fullname) return -1;
/*
printf("cl_lru_scr_reg: fulname=[%s]\n",fullname);
*/
#if 0
	if (!*fullname || !stricmp(fullname,"NULL")) return 0;
#endif
	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 {
		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;
	}
	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);
	/*	const_ct_clear(pLruScr->scrct.LeafConstCt);	*/
		pLruScr->scrct.TreeTop = NULL;
		pLruScr->scrct.ConstCt = NULL;
		pLruScr->scrct.LeafConstCt = NULL;
	}
	Free(tpLSH->tpLruScr);
	tpLSH->tpLruScr = NULL;
	return 0;
}
