static    char    sccsid[]="%Z% %M% %I% %E% %U%";
/*************************************************/
/*  Program name                                 */
/*       int       col_mn_tr_loop                */
/* --------------------------------------------- */
/*  (I/O)                                        */
/*       Out        0   :Normal                  */
/*                 -1   :AbNormal                */
/* --------------------------------------------- */
/*  Function :                                   */
/*     Justify no shori.                         */
/* --------------------------------------------- */
/*************************************************/
#include "colmn.h"

extern condList  CLcList;  /* 情報リスト */
extern tableRoot CLtbl;   /* 解析するタグ及び文字が格納される領域*/
extern CLNCB     CLSTCB;  /* タグの構文解析を行うための領域 */

/********************************************/
/*											*/
/********************************************/
static int _change_from_for()
{
	static char *_func_="_change_from_for";
	static char sep[]={" \t\"'();"};
	SSP_S ssp;
	int rc,len,i,num,pnm_len,st_pos,nbun;
	int kk_level;	/* ()のネストレベル */
	char *pnm,buf[33];
	GWPRM_S gwprm;
	SSPL_S sspl;

	if (CLcList.cmd.prmnum <= 1) return 0;
	memset(&sspl,0,sizeof(SSPL_S));
	gwprm.nparam = CLcList.cmd.prmnum - 1;
	gwprm.maxlen = 0;
	gwprm.parmLp = &CLcList.cmd.prmp[1];
	gwprm.iparam = 0;
	if (cl_gp_gwse(&gwprm,&sspl,sep,0x21) <= 0) return 0;
	if (*sspl.wd == '(') {
		nbun = 0;
		while (cl_gp_gwse(&gwprm,&sspl,sep,0x21) > 0) {
			if (*sspl.wd == ';') {
				nbun++;
				break;
			}
		}
		if (!nbun) return 0;
	}
	else return 0;
/*
printf("%s: nbun=%d\n",_func_,nbun);
*/
	if ((rc=cl_tr_gather(1)) < 0) return rc;
	pnm = CLcList.cmd.prmp[1]->prp;
	pnm_len = CLcList.cmd.prmp[1]->prmlen;
	num = CLcList.cmd.prmnum;
/*
printf("%s: num=%d pnm_len=%d pnm=[%s]\n",_func_,num,pnm_len,pnm);
printf("%s: st_pos=%d\n",_func_,st_pos);
*/
	st_pos = 1;
	ssp.sp = st_pos;
	kk_level = 1;
	rc = nbun = 0;
	while ((len=akxtgwns(pnm,pnm_len,&ssp,sep,0x21)) > 0) {
		switch (*ssp.wd) {
		case '(':
			kk_level++;
			break;
		case ')':
			if (--kk_level <= 0) {
				if ((len=akxtpkns(pnm,pnm_len,&ssp," \t",0x21)) > 0) {
					memnzcpy(buf,ssp.wd,len,sizeof(buf));
				/*	if (stricmp(buf,"AS")) {	*/
						/* %s: 右括弧')'の後ろに余分な語句[%s]があります。(sp=%d) */
						ERROROUT3(FORMAT(96),_func_,buf,ssp.sp);
					 	rc = ECL_SCRIPT_ERROR;
						goto Err;
				/*	}	*/
				}
/*
printf("%s: st_pos=%d ssp.sp=%d\n",_func_,st_pos,ssp.sp);
*/
				if (rc=clparmset(pnm+st_pos,ssp.sp-st_pos-1)) goto Err;
			}
			break;
		case ';':
			rc = ECL_SCRIPT_ERROR;
			if (kk_level > 1) {
				/* %s: 区切り';'の位置が不正です。(sp=%d) */
				ERROROUT2(FORMAT(97),_func_,ssp.sp);
				goto Err;
			}
			else if (++nbun > 2) {
				/* %s: 区切り';'が多すぎます。(sp=%d) */
				ERROROUT2(FORMAT(98),_func_,ssp.sp);
				goto Err;
			}
			if (rc=clparmset(pnm+st_pos,ssp.sp-st_pos-1))  goto Err;
			st_pos = ssp.sp;
			break;
		}
	}
 	rc = ECL_SCRIPT_ERROR;
	if (kk_level > 0) {
		ERROROUT1(FORMAT(99),_func_);	/* %s: 括弧が閉じていません。 */
		goto Err;
	}
	else if (nbun < 2) {
		ERROROUT1(FORMAT(100),_func_);	/* %s: 区切り';'が足りません。 */
		goto Err;
	}
	num = --CLcList.cmd.prmnum;
	for (i=1;i<num;i++) CLcList.cmd.prmp[i] = CLcList.cmd.prmp[i+1];
	return num;
 Err:
	CLcList.cmd.prmnum = num;
 	return rc;
}

/********************************************/
/*											*/
/********************************************/
static int _change_from_to_step()
{
	static char *_fn_="_change_from_to_step";
	static char *p0=NULL;
	int ret,i,len,k,s,num,pos,len2,len3,f,len4;
	char *p1,*p2,*p3,*p,c,*argv[5];
	parmList **prmL;

	num = CLcList.cmd.prmnum;
	prmL = CLcList.cmd.prmp;
	ret = 0;
	if (num>=3) {
		if (!stricmp(prmL[2]->prp,"TO")) {
			if (num == 3) {
				ERROROUT1(FORMAT(42),_fn_);	/* %s: パラメータが足りません。 */
				return ECL_SCRIPT_ERROR;
			}
			p1 = prmL[1]->prp;
			len = prmL[1]->prmlen;
			if ((pos=akxnskipto(p1,len,"=")) >= len) {
				/* %s: 初期値式[%s]に'='がありません。 */
				ERROROUT2(FORMAT(485),_fn_,p1);
				return ECL_SCRIPT_ERROR;
			}
			p2 = p3 = NULL;
			f = 0;
			for (i=3;i<num;i++) {
				if (!cl_is_not_space(prmL[i])) {
					ERROROUT1(FORMAT(486),_fn_);	/* %s: パラメータがNULLです。 */
					ret = ECL_SCRIPT_ERROR;
				}
				else {
					p = prmL[i]->prp;
					if (i!=4 && !stricmp(p,"STEP")) {
						ERROROUT1(FORMAT(487),_fn_);	/* %s: STEPの位置が不正です。 */
						ret = ECL_SCRIPT_ERROR;
						f = 1;
					}
					else if (i == 3) p2 = p;
					else if (i == 5) p3 = p;
				}
			}
			if (num >= 5) {
				if (!f && stricmp(prmL[4]->prp,"STEP")) {
					ERROROUT1(FORMAT(488),_fn_);	/* %s: STEPがありません。  */
					ret = ECL_SCRIPT_ERROR;
				}
				if (num == 5) {
					ERROROUT1(FORMAT(42),_fn_);	/* %s: パラメータが足りません。 */
					ret = ECL_SCRIPT_ERROR;
				}
				else if (num > 6) {
				/*	if (stricmp((p=prmL[6]->prp),"AS")) {	*/
						/* %s: 余分なパラメータ[%s]があります。 */
						ERROROUT2(FORMAT(43),_fn_,prmL[6]->prp);
						ret = ECL_SCRIPT_ERROR;
				/*	}	*/
				}
				if (ret) return ret;
			}
			len4 = 0;
			s = 1;
			if (p3) {
				if (!strcmp(p3,"1") || !strcmp(p3,"+1")) s = 1;
				else if (!strcmp(p3,"-1")) s = -1;
				else {
					s = 0;
					len4 = strlen(p3) + 9;
				}
			}
			len2 = len3 = pos + 5;
			len2 += strlen(p2);
			len = len2 + len3;
			if (len4) {
				len3 += len4;
				len += len4 + len2 + len3;
			}
			if (!(p=MRealloc(p0,len))) return -1;
			argv[1] = p;
			memcpy(p,p1,pos);
			if (p3) {
				if (s < 0) {
					strcpy(p+pos,"--");
/*
printf("%s: wrk2=[%s]\n",_fn_,p);
*/
					p += len3;
					argv[0] = p;
					memcpy(p,p1,pos);
					sprintf(p+pos,">=(%s)",p2);
/*
printf("%s: wrk1=[%s]\n",_fn_,p);
*/
				}
				else if (s == 0) {
					sprintf(p+pos,"+=(%s)",p3);
/*
printf("%s: wrk2=[%s]\n",_fn_,p);
*/
					p += len3;
					argv[0] = p;
					memcpy(p,p1,pos);
					sprintf(p+pos,"<=(%s)",p2);
/*
printf("%s: wrk1=[%s]\n",_fn_,p);
*/
					p += len2;
					argv[2] = p;
					sprintf(p,"%s>=0?1:-1",p3);
/*
printf("%s: wrk3=[%s]\n",_fn_,p);
*/
					p += len4 + 1;
					argv[3] = p;
					memcpy(p,p1,pos);
					sprintf(p+pos,">=(%s)",p2);
/*
printf("%s: wrk4=[%s]\n",_fn_,p);
*/
				}
			}
			if (s > 0) {
				strcpy(p+pos,"++");
/*
printf("%s: wrk2=[%s]\n",_fn_,p);
*/
				p += len3;
				argv[0] = p;
				memcpy(p,p1,pos);
				sprintf(p+pos,"<=(%s)",p2);
/*
printf("%s: wrk1=[%s]\n",_fn_,p);
*/
			}
			CLcList.cmd.prmnum = 2;
			if (ret=clparmset(argv[0],strlen(argv[0]))) return ret;
			if (ret=clparmset(argv[1],strlen(argv[1]))) return ret;
			if (len4) {
				if (ret=clparmset(argv[2],strlen(argv[2]))) return ret;
				if (ret=clparmset(argv[3],strlen(argv[3]))) return ret;
			}
		}
	}
	return 0;
}

/********************************************/
/*											*/
/********************************************/
int col_mn_tr_loop()
{
	int rc,len,n,i,pnum,cid,scno;
	char *name,*pnm;
#if 0
	if (cl_nest_tag(1) == SysError) {
		ERROROUT(FORMAT(101));
		return ( ECL_TR_LOOP );
	}
	rc = cl_search_active_loop();
	if ( rc ) {
		if (rc == -1) ERROROUT(FORMAT(101);
	/*	if (rc == -2) ERROROUT(FORMAT(102);	*/
		return ( ECL_TR_LOOP );
	}
#endif
/*
	if ((cid=CLcList.cmd.cid)!=C_DO && !CLcList.cmd.prmnum) {
		ERROROUT(FORMAT(103);
		return ( ECL_TR_LOOP );
	}
*/
	cid = CLcList.cmd.cid;
	if (cid==C_FOR && !strnicmp(CLcList.cmd.prmp[0]->prp,"EACH",4)) ;
	else if (cid==C_FOR || cid==C_WHILE || cid==C_UNTIL) {
		cl_tr_insert(0,cl_gets_cmd_name(cid));
		CLcList.cmd.cid = C_LOOP;
	}

	if (CLcList.cmd.prmnum > 0)
		pnm = CLcList.cmd.prmp[0]->prp;
	else pnm = "";

	scno = 0;
	if (!strnicmp(pnm,"WHILE",5) || !strnicmp(pnm,"UNTIL",5) ||
	    !strnicmp(pnm,"EACH",4)) {
		cl_tr_split(0,"(");
		pnum = CLcList.cmd.prmnum;
		pnm = CLcList.cmd.prmp[0]->prp;
		if (pnum>=2 && !stricmp(pnm,"WHILE")) scno = D_LOOP_WHILE;
		else if (pnum>=2 && !stricmp(pnm,"UNTIL")) scno = D_LOOP_UNTIL;
		else if (pnum>=4) scno = D_LOOP_EACH;
		else scno = -1;
	}
	else if (!strnicmp(pnm,"FOR",3)) {
		cl_tr_split(0,"(");
		if ((rc=_change_from_for()) < 0) return rc;
		else if (!rc) {
			if (rc=_change_from_to_step()) return rc;
		}
		pnum = CLcList.cmd.prmnum;
		if (pnum>=2) scno = D_LOOP_FOR;
		else scno = -1;
	}
/*
	else if (cid==C_DO && CLcList.cmd.prmnum>0) {
		ERROROUT1(FORMAT(41),"ColMnTrDo");
		return  ECL_TR_LOOP;
	}
*/
	if (scno < 0) {
		ERROROUT1(FORMAT(42),"col_mn_tr_loop");
		return  ECL_TR_LOOP;
	}
	CLcList.cmd.sub_cid |= scno;

	if (!(rc=cl_make_leaf())) {
		cl_pre_nest();
		if (!(rc=cl_push())) rc= cl_change_stcb();
	}
	return rc;
}

/********************************************/
/*											*/
/********************************************/
int cl_tr_insert(ip,name)
int ip;
char *name;
{
	int rc,len,n,i,num;

	num = CLcList.cmd.prmnum;
	if (ip<num && num<CLcList.max_prmnum) {
		for (i=num;i>ip;i--) CLcList.cmd.prmp[i] = CLcList.cmd.prmp[i-1];
		CLcList.cmd.prmnum = ip;
		if (rc=clparmset(name,strlen(name))) return rc;
		n = CLcList.cmd.prmnum = num + 1;
	}
	else n = 0;
	return n;
}

int cl_search_active_loop()
{
	Leaf  *Dummy;

	if (!(Dummy = CLSTCB.nestLev2)) return 0;
	while (Dummy) {

		if ( Dummy == CLSTCB.nestLev1 ||
		    (Dummy->cmd.type == 0 && Dummy->cmd.cid == C_LOOP) )
			return ( 0 );
	/*
		else if ( Dummy->cmd.cid == C_LOOP ) return ( -2 );
	*/
		Dummy = Dummy->preleaf;
	}
	return -1;
}
