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

#include "colmn.h"

extern CLPRTBL *pGLprocTable;
extern CLPRTBL *pCLprocTable;

/************************************/
/*									*/
/************************************/
int cl_is_loop_exec(leaf,proc)
Leaf    *leaf;
ProcCT  *proc;
{
	BlockCB *next;

	if (next=proc->pcrBlockCB) {
		if (next->iUsed && leaf==next->Blockleaf) {
DEBUGOUTL2(190,"_is_loop_exec: match leaf=%08x in LoopCB=%08x",leaf,next);
			return 1;
		}
	}
	return 0;
}

/************************************/
/*									*/
/************************************/
static int _get_loop_max()
{
	tdtInfoParm *pInfoParm;
	int ret,loop_max;

	if (pInfoParm = cl_get_public_var(D_NAM_MAX_LOOP_WHILE)) {
		if ((ret = cl_get_parm_bin(pInfoParm,&loop_max,"_get_loop_max:")) < 0)
			loop_max = ret;

DEBUGOUTL1(190,"_get_loop_max: loop_max=%d",loop_max);

	}
	else loop_max = MAX_LOOP_WHILE;
	return loop_max;
}

static parmList _PrmL[2]={{5,"Index",0,NULL},{5,"Value",0,NULL}};
static parmList *_pPrmL[2]={&_PrmL[0],&_PrmL[1]};

/************************************/
/*									*/
/************************************/
static int _get_loop_max_each(cmd,Obj,pInfoParm)
cmdInfo *cmd;
int     *Obj;
tdtInfoParm *pInfoParm;
{
	static char *_fn_="_get_loop_max_each";
	parmList **prmL,*prmL3,*prmL1;
	int ret,count,len,iRANGE,i,n,attr,alen;
	XHASHB *xhp;
	char c,*name,*p;
	tdtRbCtl *pCt;
	tdtDefType *pDeftype;
	tdtInfoParm *pInfoParmT,*pInfoParm1,*pInfoS,*pInfoD,tInfoParm;
	ScrPrCT   *pScCT;
	uchar uc;

	prmL = cmd->prmp;
	name = prmL[1]->prp;
	len  = prmL[1]->prmlen;
	if ((c=*name)=='$') {
		name++;
		len--;
	}
														/* 要素用変数名 */
	if (ret=cl_def_chk_name(name,len,"_get_loop_max_each",FORMAT(481))) return ret;
	if (stricmp(prmL[2]->prp,"IN")) {
		ERROROUT1(FORMAT(482),_fn_);	/* %s: IN がありません。 */
		return ECL_SCRIPT_ERROR;
	}
	ret = cl_gx_exp_obj_opt(cmd->prmnum-3,&prmL[3],Obj,pInfoParm,D_GX_OPT_PARMINFO2);
DEBUGOUT_InfoParm(190,"_get_loop_max_each: ret=%d",pInfoParm,ret,0);
	if (!ret) {
		iRANGE = 0;
		uc = pInfoParm->pi_aux[0];
		if (pInfoParm->pi_id==' ' && (pInfoParm->pi_alen & D_AULN_RANGE_DATA)) {
			iRANGE = 1;
			pInfoParm->pi_aux[0] |= DEF_ZOK_DATA;
		}
		ret = cl_func_count(&count,1,&pInfoParm,1/* | D_GX_OPT_PARMINFO2*/);
		pInfoParm->pi_aux[0] = uc;
		if (ret) return ret;
DEBUGOUTL1(110,"_get_loop_max_each: count=%d",count);
		if (!count) return 0;
	}
	else if (ret > 0) ret = ECL_SCRIPT_ERROR;
	if (ret < 0) {
		ERROROUT1(FORMAT(483),_fn_);	/* %s: 対象データの式が誤っています。 */
		return ECL_SCRIPT_ERROR;
	}

	prmL1 = prmL[1];
		ret = cl_anal_parm(prmL1);
		if (ret!=PARAMETER && ret!=NAME_CONST) {
			ret = ECL_SCRIPT_ERROR;
		}
		else {
			pScCT = cl_search_src_ct();
			ret=cl_gx_get_info_parm_opt(pScCT,'s',prmL1,&pInfoParmT,D_GX_OPT_SET_LOCAL|D_GX_OPT_DEFINE);
DEBUGOUT_InfoParm(190,"_get_loop_max_each: ret=%d",pInfoParmT,ret,0);
			if (!ret) {
				if (pInfoParmT->pi_aux[1] & D_AUX1_PROTECTED) ret = ECL_SCRIPT_ERROR;
#if 1	/* 2021.12.30 */
				else cl_free_info_parm(pInfoParmT);
#endif
			}
		}
		if (ret) {
			ERROROUT2(FORMAT(318),_fn_,prmL1->prp);	/* %s: %s は使用できません。 */
			return ret;
		}
		pInfoParmT->pi_id = 'T';
		pInfoParmT->pi_attr = DEF_ZOK_BULK;
		if (!(p=Malloc(prmL1->prmlen+1))) {
			ERROROUT("_set_each: struct name area malloc");
			return ECL_MALLOC_ERROR;
		}
		memzcpy(p,prmL1->prp,prmL1->prmlen);
		pInfoParmT->pi_pos = (long)p;
		pInfoParmT->pi_alen = D_AULN_IGN_CASE;
		pInfoParmT->pi_aux[1] = D_AUX1_PROTECTED;
		pInfoParmT->pi_scale |= D_DATA_MALLOC | D_DATA_INDEX_FREE;
		pInfoParmT->pi_aux[0] = D_AUX0_TYPE_STRUCT;

		if (!(pDeftype=(tdtDefType *)Malloc(sizeof(tdtDefType)))) return -1;
		memset(pDeftype,0,sizeof(tdtDefType));
		pDeftype->size = 0;
		pDeftype->ntype = 2;
		pInfoParmT->pi_data = (char *)pDeftype;
		pInfoParmT->pi_dlen = sizeof(tdtDefType);
		pDeftype->vname = _pPrmL;
		if (!pDeftype->pType) {
			if (!(pDeftype->pType=(tdtInfoParm **)Malloc(2*sizeof(tdtInfoParm *)))) return -1;
			if (!(pDeftype->pType[0]=(tdtInfoParm *)Malloc(sizeof(tdtInfoParm)))) return -1;
			if (!(pDeftype->pType[1]=(tdtInfoParm *)Malloc(sizeof(tdtInfoParm)))) return -1;
			memset(pDeftype->pType[0],0,sizeof(tdtInfoParm));
			memset(pDeftype->pType[1],0,sizeof(tdtInfoParm));
		}
		cl_set_parm_long(pInfoParm+2,pInfoParmT);

	if (pInfoParm->pi_alen & D_AULN_PARMINFO2) {
		pInfoParm1 = pInfoParm + 1;
		len = pInfoParm1->pi_dlen;
		if (!(p=Malloc(len))) return ECL_MALLOC_ERROR;
		memset(p,0,len);
		pInfoD = (tdtInfoParm *)p;
		pInfoS = (tdtInfoParm *)pInfoParm1->pi_data;
		pInfoParm1->pi_data = p;
		pInfoParm1->pi_scale = D_DATA_MALLOC;
		n = len/sizeof(tdtInfoParm);
		for (i=0;i<n;i++,pInfoS++,pInfoD++) {
			if (pInfoS->pi_id=='R' || pInfoS->pi_id=='A')
				pInfoS->pi_aux[0] &= ~DEF_ZOK_DATA;
DEBUGOUTL4(120,"_get_loop_max_each: n=%d i=%d pInfoS=%08x pInfoD=%08x",n,i,pInfoS,pInfoD);
			if (ret=cl_gx_rep_info_set_ign(pInfoD,pInfoS,1)) break;
		}
	}
	else if ((c=pInfoParm->pi_id)==D_DATA_ID_LIST || c==D_DATA_ID_NARABI) {
		pInfoParm1 = pInfoParm + 1;
		if (!(ret=cl_gx_rep_info_set_ign(pInfoParm1,pInfoParm,1))) {
			cl_gx_copy_info(pInfoParm,pInfoParm1);
			akxs_rb_read(pInfoParm->pi_data,0);
		}
	}
	else if (iRANGE) {
		pInfoParm1 = pInfoParm + 3;
		cl_gx_copy_info(pInfoParm1,pInfoParm);
		pInfoParm1->pi_scale &= ~D_DATA_MALLOC;		/* 2021.7.13 add */
		alen = len = pInfoParm1->pi_dlen;
		if ((attr=pInfoParm1->pi_attr) != DEF_ZOK_BINA) {
			len *= 2;
			alen = len;
			if (!(p=cl_opt_malloc(D_OPT_ALC_LEAF,alen))) return -1;
			pInfoParm1->pi_data = p;
			memcpy(p,pInfoParm->pi_data,len);
			if (attr==DEF_ZOK_CHAR) *(p+1) = '\0';
		}
		pInfoParm1->pi_aux[0] = pInfoParm1->pi_alen = 0;
		pInfoParm1->pi_paux = NULL;
	}
#if 1	/* 2021.9.7 */
	/* ここでは、全てのpInfoParm->pi_scale の D_DATA_MALLOC は、0になっている */
	/* とりあえず、配列の集合演算の結果は、Indexをtmpに取っているので、 */
	/* D_DATA_INDEX_FREE が 0 になっている */
	else if ((c=pInfoParm->pi_id)=='R' && (pInfoParm->pi_scale & D_DATA_INDEX_TMP)) {
#if 1	/* 2021.9.9 */
	/*	pInfoParm->pi_aux[0] |= DEF_ZOK_DATA;	*/
		if ((ret=cl_gx_rep_info_set_ign(&tInfoParm,pInfoParm,1)) < 0) return ret;
DEBUGOUT_InfoParm(190,"_get_loop_max_each:tInfoParm: ret=%d",&tInfoParm,ret,0);
	/*	tInfoParm.pi_aux[0] &= ~DEF_ZOK_DATA;	*/
		cl_gx_copy_info(pInfoParm,&tInfoParm);
#else
		if (!(p=Malloc(sizeof(tdtArrayIndex)))) return ECL_MALLOC_ERROR;
		memcpy(p,pInfoParm->pi_data,pInfoParm->pi_dlen);
		pInfoParm->pi_data = p;
		pInfoParm->pi_scale |= D_DATA_MALLOC/* | D_DATA_INDEX_FREE*/;
		pInfoParm->pi_alen |= D_AULN_NO_AL_LPOS;
#endif
	}
	else if ((c=='L' || c=='N') && (pInfoParm->pi_scale & D_DATA_DATA_FREE)) {
		pInfoParm->pi_scale |= D_DATA_MALLOC;
	}
#endif
	else if ((c=pInfoParm->pi_id)=='A' || c=='R' || c=='P' || c=='T') {
		pInfoParm->pi_scale &= ~(D_DATA_MALLOC | D_DATA_INDEX_FREE);
		pInfoParm->pi_alen |= D_AULN_NO_AL_LPOS;
	}
	if (ret > 0) ret = ECL_SCRIPT_ERROR;
	else if (!ret) ret = count;
	return ret;
}

/************************************/
/*									*/
/************************************/
int cl_loop_set_each(pcrLCB,ppInfoParmW,cppKey)
BlockCB *pcrLCB;
tdtInfoParm **ppInfoParmW;
char **cppKey;
{
	static tdtInfoParm tInfoParmList;
	tdtArrayIndex *pIndex,tIndex;
	XHASHB *xhp;
	int ix,i,ret,len,opt;
	char *cpKey,*cpDat,c,*buf,*p,*name;
	tdtInfoParm *pInfoParmW,*pInfoParm,**pvParm,*pInfoParm1,tInfoParm;
	ScrPrCT   *pScCT;
	int *index;

	if ((ix=pcrLCB->iLoopCounter) >= pcrLCB->iLoopMax) return 100;
	if (cppKey) {
		*cppKey = cpKey = NULL;
	}
	pInfoParm = pcrLCB->pEachParm;
DEBUGOUT_InfoParm(190,"cl_loop_set_each:pInfoParm: ",pInfoParm,0,0);
	if ((pInfoParm->pi_alen & D_AULN_PARMINFO2) && pInfoParm[1].pi_pos) {
		pInfoParmW = (tdtInfoParm *)pInfoParm[1].pi_data;
		pInfoParmW += ix;
	}
	else if ((c=pInfoParm->pi_id)=='R' || c=='A') {
		memcpy(&tIndex,pInfoParm->pi_data,sizeof(tdtArrayIndex));
		if (c=='R') {
			if (xhp = tIndex.xhp) {
				for (ix=pcrLCB->iLoopCounter+1;ix<=pcrLCB->iLoopMax;ix++) {
					xhp->xha_xhix = ix;
					if (akxs_xhash2(xhp,'p',&cpKey,&cpDat)) {
DEBUGOUTL2(190,"cl_loop_set_each:H: ix=%d key=[%s]",ix,cpKey);
						memcpy(&pInfoParmW,cpDat,sizeof(tdtInfoParm *));
						if (!cl_is_undef_parm(pInfoParmW)) break;
					}
				}
				xhp->xha_xhix = 0;
DEBUGOUTL1(190,"cl_loop_set_each:H: ix=%d",ix);
				pcrLCB->iLoopCounter = ix - 1;
				if (ix>pcrLCB->iLoopMax) return 100;
DEBUGOUT_InfoParm(190,"cl_loop_set_each:H:ArrayW: ix=%d key=[%s]",pInfoParmW,ix,cpKey);
			}
			else {
				if (tIndex.uAttr[0] == DEF_ZOK_VARI) {
					if (pvParm=tIndex.pVarIndex) {
						for (ix=pcrLCB->iLoopCounter;ix<pcrLCB->iLoopMax;ix++) {
							if (!cl_is_null_parm(pInfoParmW=pvParm[ix])) break;
						}
						pcrLCB->iLoopCounter = ix;
						if (ix>=pcrLCB->iLoopMax) return 100;
					}
					else return -1;
DEBUGOUT_InfoParm(190,"cl_loop_set_each:BULK:ArrayW: ix=%d",pInfoParmW,ix,0);
				}
				else {
					pInfoParmW = &tInfoParmList;
					if (ret=cl_get_array_val_opt(pInfoParmW,&tIndex,ix+1,'r')) return ret;
				}
			}
		}
		else {	/* MAPPEDARRAY のときの処理 */
			if (!(pScCT = (ScrPrCT *)pInfoParm->pi_len)) {
				if (!(pScCT = cl_search_src_ct())) {
					ERROROUT1(FORMAT(27),"cl_loop_set_each");	/* %s:システムエラー */
					return ECL_SYSTEM_ERROR;
				}
			}
			opt = 0;
			if (pInfoParm->pi_aux[1] & D_AUX1_LOCAL_VAR) opt |= D_GX_OPT_SET_LOCAL;
			name = (char *)pInfoParm->pi_pos;
			index = tIndex.index;
			if ((c=name[0])=='%' || c=='#') {
				if (ret=cl_gx_get_all_var_ent(pScCT,'R',name,&pInfoParmW,ix+index[3],"",opt))
					return ret;
			}
			else {	/* $ */
				for (ix=pcrLCB->iLoopCounter;ix<pcrLCB->iLoopMax;ix++) {
					if (!cl_gx_get_all_var_ent(pScCT,'R',name,&pInfoParmW,ix+index[3],"",opt))
						break;
				}
				pcrLCB->iLoopCounter = ix;
				if (ix>=pcrLCB->iLoopMax) return 100;
			}

DEBUGOUT_InfoParm(190,"cl_loop_set_each:MAPPED:ArrayW: ix=%d name=[%s]",pInfoParmW,ix,name);

		}
	}
	else if (c==' ') {
		if (pInfoParm->pi_alen & D_AULN_RANGE_DATA) {
DEBUGOUT_InfoParm(190,"cl_loop_set_each: RANGE: ",pInfoParm,0,0);
			pInfoParm1 = pInfoParm + 3;
			if (ix > 0) {
				if (pInfoParm1->pi_attr == DEF_ZOK_CHAR) {
					*(uchar *)(pInfoParm1->pi_data) = *(uchar *)(pInfoParm1->pi_data) + 1;
				}
				else if ((ret=_gx_ppmm(14,pInfoParm1)) < 0) return ret;
			}
			pInfoParmW = pInfoParm1;
		}
		else pInfoParmW = pInfoParm;
	}
	else if (c==D_DATA_ID_LIST || c==D_DATA_ID_NARABI) {
		pInfoParmW = (tdtInfoParm *)akxs_rb_read(pInfoParm->pi_data,1);
		if (!pInfoParmW) return 100;
	}
	else
		return -1;
DEBUGOUT_InfoParm(190,"cl_loop_set_each:return:c=%c",pInfoParmW,c,0);
	*ppInfoParmW = pInfoParmW;
	if (cppKey) *cppKey = cpKey;
	return 0;
}

/************************************/
/*									*/
/************************************/
static int _set_each(proc,cmd,pcrLCB)
ProcCT  *proc;
cmdInfo *cmd;
BlockCB *pcrLCB;
{
	int ix,i,ret;
	char *cpKey;
	tdtInfoParm *pInfoParmW,*pInfoParm,tInfoParm,*pInfoParmWIX;
	tdtDefType *pDeftype;

	ret = cl_loop_set_each(pcrLCB,&pInfoParmW,&cpKey);
	if (ret) {
		if (ret == 100) ret = 0;
		return ret;
	}
	ix = pcrLCB->iLoopCounter;

	pInfoParm = (tdtInfoParm *)pcrLCB->pEachParm[2].pi_pos;
	pDeftype = (tdtDefType *)pInfoParm->pi_data;
#if 1	/* 2021.10.27 */
	if (ret=cl_gx_rep_info_als(pDeftype->pType[1],pInfoParmW,1)) {
#else
	if (ret=cl_gx_rep_info_set(pDeftype->pType[1],pInfoParmW,1)) {
#endif
		return ret>0 ? -ret : ret;
	}
	pInfoParmWIX = &tInfoParm;
	if (cpKey)
		cl_set_parm_char(pInfoParmWIX,cpKey,strlen(cpKey));
	else
		cl_set_parm_bin(pInfoParmWIX,ix);
	if (ret=cl_gx_rep_info_set_ign(pDeftype->pType[0],pInfoParmWIX,1)) {
		return ret>0 ? -ret : ret;
	}
	pInfoParm->pi_len = ++pGLprocTable->gid;
	i = akxs_xhasl(pGLprocTable->pha_gid,'S',pInfoParm->pi_len,0);
/*
printf("_set_each: store gid=%d ix=%d\n",pInfoParm->pi_len,i);
*/
	ret = 1;
DEBUGOUT_InfoParm(190,"_set_each:return: ret=%d",pInfoParm,ret,0);
	return ret;
}

/************************************/
/*									*/
/************************************/
static int _end_each(proc,cmd,pcrLCB)
ProcCT  *proc;
cmdInfo *cmd;
BlockCB *pcrLCB;
{
	tdtInfoParm *pInfoParm;
	XHASHB *pha_vname;
	int  rc,vnlen;
	char *varnam;

	if (pInfoParm = (tdtInfoParm *)pcrLCB->pEachParm[2].pi_pos) {
		if (pha_vname = proc->pha_vnam) {
			varnam = (char *)pInfoParm->pi_pos;
			vnlen = strlen(varnam);
			rc = cl_gx_chk_vnam('d',pha_vname,varnam,vnlen);
/*
printf("_end_each: delete name=[%s] ix=%d\n",varnam,rc);
*/
		}
		rc = akxs_xhasl(pGLprocTable->pha_gid,'D',pInfoParm->pi_len,0);
/*
printf("_end_each: delete gid=%d ix=%d\n",pInfoParm->pi_len,rc);
*/
		cl_free_info_parm(pInfoParm);
	}
	if (pInfoParm = &pcrLCB->pEachParm[0]) {
		cl_free_info_parm(pInfoParm);
	}
	return 0;
}

/************************************/
/*									*/
/************************************/
int cl_is_not_space(prmL)
parmList *prmL;
{
	int  len,ret;
	char *p;
	
	if ((len=prmL->prmlen)>0 && (p=prmL->prp)
		                     && akxnskipin(p,len," \t")<len) ret=1;
	else ret=0;
	return ret;
}

/************************************/
/*									*/
/************************************/
static int _set_for(cmd,Obj,ipOpt,pargv)
cmdInfo *cmd;
int *Obj;
int *ipOpt;
char ***pargv;
{
	static char *_fn_="_set_for";
	int ret,iOpt,i,len,k,s,num,pos,len2,len3;
	char *p1,*p2,*p3,*p,c,**argv;
	parmList **prmL,PrmL;

	argv = NULL;
	iOpt = ret = 0;
	num = cmd->prmnum;
	prmL = cmd->prmp;
	if (num >= 2) {
		if (cl_is_not_space(prmL[1])) {
			ret = let_compute_sub(1,&prmL[1],Obj);
			iOpt = 0x01;
		}
		if (num>=3) {
			if (cl_is_not_space(prmL[2])) iOpt |= 0x02;
			if (cmd->prmnum>=4 && cl_is_not_space(prmL[3])) iOpt |= 0x04;
			if (cmd->prmnum>=5) iOpt |= 0x10;	/* TO STEP */
		}
	}
	*ipOpt = iOpt;
	*pargv = NULL;
	return ret;
}

/************************************/
/*									*/
/************************************/
static int _exec_for(cmd,Obj,pcrLCB)
cmdInfo *cmd;
int *Obj;
BlockCB *pcrLCB;
{
	int ret,count,opt,sig,i0,nparm;
	parmList *prmL[2],PrmL,*prmLi;
	char **argv;
	tdtInfoParm tInfoParm;

	ret = 1;
	count = pcrLCB->iLoopCounter;
	opt   = pcrLCB->iOpt;
	if (opt & 0x08) {
		argv = (char **)pcrLCB->pSwParm;
		prmL[0] = &PrmL;
		if (count>0 && (opt & 0x04)) {
			prmLi = cmd->prmp[3];
			PrmL.opt    = prmLi->opt;
			PrmL.bxobj  = prmLi->bxobj;
			PrmL.prp    = argv[1];
			PrmL.prmlen = strlen(PrmL.prp);
			if ((ret = let_compute_sub(1,prmL,Obj)) < 0) return ret;
			prmLi->opt   = PrmL.opt;
			prmLi->bxobj = PrmL.bxobj;
		}
		if (opt & 0x02) {
			prmLi = cmd->prmp[2];
			PrmL.opt    = prmLi->opt;
			PrmL.bxobj  = prmLi->bxobj;
			PrmL.prp = argv[0];
			PrmL.prmlen = strlen(PrmL.prp);
			if ((ret=cl_if_compare_sub(1,prmL,Obj)) >= 0) {
				prmLi->opt   = PrmL.opt;
				prmLi->bxobj = PrmL.bxobj;
			}
		}
	}
	else {
		if (opt & 0x10) {
			if ((ret = cl_gx_exp_obj(1,&cmd->prmp[4],Obj,&tInfoParm)) < 0) return ret;
			if ((ret = cl_get_parm_bin(&tInfoParm,&sig,"_exec_for:")) < 0) return ret;
			if (sig >= 0) i0 = 0;
			else i0 = 3;
			nparm = 1;
		}
		else {
			i0 = 0;
			nparm = cmd->prmnum-3;
		}
		if (count>0 && (opt & 0x04)) {
			if ((ret = let_compute_sub(nparm,&cmd->prmp[3],Obj)) < 0) return ret;
		}
		if (opt & 0x02) {
			ret = cl_if_compare_sub(1,&cmd->prmp[i0+2],Obj);
		}
	}
	return ret;
}

/************************************/
/* clPrcessLoop						*/
/************************************/
int cl_process_loop(leaf, proc)
Leaf    *leaf;
ProcCT  *proc;
{
	int rc,loop_max,lb_used,pnum,iOpt,count;
	BlockCB *pcrLCB;
	tdtInfoParm tInfoParm[4];
	char **argv,*p;
	cmdInfo *pcmd;

	if (!leaf) return -1;
	if (!proc) return -2;

	rc = 0;
	cmn_set_stat(BRK_PR,&proc->ptype,L_OFF);
	pcrLCB = proc->pcrBlockCB;
	if (cl_is_loop_exec(leaf,proc)) {
		pcrLCB->iLoopCounter++;
	}
	else {
		memset(&tInfoParm,0,sizeof(tdtInfoParm));
		iOpt = 0;
		/* Loop max value set process */
		/* 最初に、暫定で、最大値に設定する */
		loop_max = INT_MAX;
		lb_used = leaf->cmd.sub_cid & ~C_CMD_FLAGS;
		if (lb_used ==  D_LOOP_WHILE) {
		}
		else if (lb_used == D_LOOP_UNTIL) {
		}
		else if (lb_used == D_LOOP_EACH) {
			if ((loop_max = _get_loop_max_each(&leaf->cmd,proc->Obj,tInfoParm)) < 0)
				return ECL_EX_LOOP;
		}
		else if (lb_used == D_LOOP_FOR) {
			if ((rc = _set_for(&leaf->cmd,proc->Obj,&iOpt,&argv)) < 0) return rc;
			if (!(iOpt & 0x02)) {
				PRINTOUT1("_set_for:no exit check.loop_max=%d",loop_max);
			}
		}
		else {
			if (leaf->cmd.cid == C_LOOP) {
				if (leaf->cmd.prmnum > 0) {
					if ((rc = cl_loop_max(leaf,proc,&loop_max)) != NORMAL)
						return ECL_EX_LOOP;
				}
			}
			else loop_max = 1;	/* C_DO */
			lb_used = D_LOOP_NORMAL;
		}

DEBUGOUTL2(190,"cl_process_loop: proc = %s, loop_max = %d",proc->ProcNM,loop_max);

		if (loop_max > 0) {
			if (rc = loop_pre_proc(leaf,proc)) return rc;
			cmn_set_stat(LOP_PR,&proc->ptype,L_ON);
			pcrLCB = proc->pcrBlockCB;
			pcrLCB->iLoopMax = loop_max;
			pcrLCB->Blockleaf = leaf; /* set Loop first leaf */
			pcrLCB->iUsed = lb_used;
			pcrLCB->iOpt = iOpt;
			pcrLCB->pSwParm = (char *)argv;
			pcmd = &(leaf->cmd);
			pcrLCB->BlockName = Strdup(pcmd->parl[D_LEAF_LABEL].par);
			proc->Nextleaf = leaf->leftleaf;
			if (tInfoParm[0].pi_id) {
				if (pcrLCB->pEachParm) {
				    memcpy(pcrLCB->pEachParm,tInfoParm,sizeof(tdtInfoParm)*4);
				}
				else if (!(pcrLCB->pEachParm=
				    (tdtInfoParm *)Memdup(tInfoParm,sizeof(tdtInfoParm)*4)))
					return ECL_EX_LOOP;
			}
		}
		else {
			proc->Nextleaf = leaf->rightleaf;
			return 0;
		}
	}

DEBUGOUTL2(190,"cl_process_loop: proc = %s, loop_count = %d",
proc->ProcNM,pcrLCB->iLoopCounter);

	/* この時点でのMAX_LOOP_WHILEを求める */
	if ((loop_max = _get_loop_max()) < 0) return ECL_EX_LOOP;
	count = pcrLCB->iLoopCounter;
	if (count<loop_max && count < pcrLCB->iLoopMax) {
		/* それぞれのコマンドでのループ条件を判定する */
		rc = 1;
		lb_used = pcrLCB->iUsed;
		if (lb_used==D_LOOP_WHILE || lb_used==D_LOOP_UNTIL) {
			rc = cl_if_compare_sub(leaf->cmd.prmnum-1,&leaf->cmd.prmp[1],proc->Obj);
			if (rc < 0) return rc;
			if (lb_used == D_LOOP_UNTIL) {
				rc = rc ? 0 : 1;
			}
		}
		else if (lb_used == D_LOOP_EACH) {
			if ((rc=_set_each(proc,&leaf->cmd,pcrLCB)) < 0)
				return rc;
		}
		else if (lb_used == D_LOOP_FOR) {
			if ((rc=_exec_for(&leaf->cmd,proc->Obj,pcrLCB)) < 0) return rc;
		}
	}
	else rc = 0;

	if (rc) {
		proc->Nextleaf = leaf->leftleaf;
DEBUGOUTL1(200,"cl_process_loop: push [ %s ]",cl_get_pcmd_line(leaf));
		cl_ret_leaf_push(proc,leaf);
		rc = 0;
	}
	else {	/* end loop */
		if (pcrLCB->iUsed == D_LOOP_EACH) _end_each(proc,&leaf->cmd,pcrLCB);
		proc->Nextleaf = leaf->rightleaf;
		pcrLCB->iLoopCounter = 0;
		pcrLCB->iLoopMax = 0;
		pcrLCB->iUsed = 0;
		if (!cl_search_block_cb(proc,C_LOOP,1) &&
		    !cl_search_block_cb(proc,C_FOR,1) &&
		    !cl_search_block_cb(proc,C_DO,1)) {
			cmn_set_stat( LOP_PR , &proc->ptype , L_OFF );
			cmn_set_stat( BRK_PR , &proc->ptype , L_OFF );
		}
		proc->pcrBlockCB = pcrLCB->preBlockCB;

DEBUGOUTL2(190,"cl_process_loop: proc = %s, end pcrLoopCB = %08x",
proc->ProcNM,proc->pcrBlockCB);

	}
	return rc;
}

/************************************/
/* loop_pre_proc					*/
/************************************/
int loop_pre_proc(pLeaf,pProc)
Leaf    *pLeaf;
ProcCT  *pProc;
{
	int  	rc;
	BlockCB	*pLoopCB;

	if (!pLeaf || !pProc) return ERROR;
	/* BlockCB生成 */
	if (rc = cl_add_block_cb(pProc)) return rc;
	pLoopCB = pProc->pcrBlockCB;
	pLoopCB->cid = pLeaf->cmd.cid;

DEBUGOUTL1(190,"loop_pre_proc: set pcrLoopCB = %08x",pLoopCB);

	return 0;
}

/****************************************/
/*	cl_func_times						*/
/****************************************/
int cl_func_times(pInfoParmW,nparm,ppParm)
tdtInfoParm *pInfoParmW;
int  nparm;
tdtInfoParm **ppParm;
{
	int rc,loop_max,i,m;
	tdtInfoParm *pInfoParmM,tInfoParm;
	char id;

	cl_null_data(pInfoParmW);
	if ((i=nparm) > 0) {
		if (cl_is_null_parm(ppParm[0])) i = 0;
		else {
			if (rc = cl_get_parm_bin(ppParm[0],&loop_max,"func_times: "))
				return ECL_EX_LOOP;
		}
	}
	if ((m = _get_loop_max()) < 0) return ECL_EX_LOOP;
	if (i && loop_max>m) i = 0;
	if (!i) loop_max = m;
	rc = 0;
	if (nparm > 1) {
		pInfoParmM = ppParm[1];
		id = pInfoParmM->pi_id;
		for (i=0;i<loop_max;i++) {
			if (id == 'F') {
				pInfoParmW->pi_paux = pInfoParmM->pi_paux;
				if (rc=cl_gx_func_method(pInfoParmW,pInfoParmM,nparm-2,&ppParm[2],0,ppParm[2])) break;
			}
			else if (id == 'M')
				rc = cl_ex_class_method(pInfoParmW,pInfoParmM,nparm-2,&ppParm[2],0);
			else rc = cl_ex_eval(pInfoParmW,nparm-1,&ppParm[1]);
			if (rc) break;
		}
	}
	return rc;
}

/************************************/
/* clPrcessDoWhile					*/
/************************************/
int cl_process_do_while(leaf, proc)
Leaf    *leaf;
ProcCT  *proc;
{
	int rc,loop_max,pnum;
	BlockCB *pcrLCB;

	if (!leaf) return(-1);
	if (!proc) return(-2);

	rc = 0;
	pcrLCB = proc->pcrBlockCB;

	if (cl_is_loop_exec(leaf->cmd.parl[D_DOWHILE_TOP_LEAF].par,proc)) {

DEBUGOUTL2(190,"cl_process_do_while: proc = %s, loop_count = %d",
proc->ProcNM,pcrLCB->iLoopCounter);
/*
printf("cl_process_do_while: proc=[%s] loop_count=%d loop_max=%d\n",
proc->ProcNM,pcrLCB->iLoopCounter,pcrLCB->iLoopMax);
*/
		if (pcrLCB->iLoopMax == 1) {
			if ((loop_max = _get_loop_max()) < 0) return ECL_EX_LOOP;
			pcrLCB->iLoopMax = loop_max;
		}
		rc = 1;
		rc = cl_if_compare_sub(leaf->cmd.prmnum,&leaf->cmd.prmp[0],proc->Obj);
		if (rc < 0) return rc;
		if (leaf->cmd.cid == C_ENDUNTIL) {
			rc = rc ? 0 : 1;
		}
		if (!rc) pcrLCB->iLoopCounter = 0x7ffffffe;
		rc = 0;
	}
	else {
		ERROROUT1("%s: ループ実行中ではありません。","cl_process_do_while");
		rc = ECL_EX_LOOP;
	}

	return rc;
}
