static char sccsid[]="%Z% %M% %I% %E% %U%";
/*************************************************/
/*  Program name                                 */
/*       int       col_mn_tr_proc                */
/* --------------------------------------------- */
/*  (I/O)                                        */
/*       Out        0   :Normal                  */
/*                 -1   :AbNormal                */
/* --------------------------------------------- */
/*  Function :                                   */
/*     Justify no shori.                         */
/* --------------------------------------------- */
/*  Version                    1.00  2010/05/28  */
/*************************************************/
/* */

#include "colmn.h"

extern GlobalCt  *pGlobTable;
extern int giOptions[];
extern condList CLcList;	/* 情報リスト */
extern CLNCB    CLSTCB;		/* タグの構文解析を行うための領域 */

/*********************************************/
/*                                           */
/*********************************************/
static int _add_stack_zero()
{
	parmList *lp;
	char buf[12],*pp;
	int  rc,cid,num,len;

	lp  = CLcList.cmd.prmp[0];
	num = CLcList.cmd.prmnum;
	cid = CLcList.cmd.cid;

	sprintf(buf,"%d",ECL_DO_STACK_ZERO);
	len = strlen(buf);
	CLcList.cmd.prmnum  = 0;
	CLcList.cmd.cid     = C_SLEEP;
	pp = cl_const_ct_malloc(CLcList.ConstCt,len+1);
	if (pp) {
		memcpy(pp,buf,len+1);
		rc = clparmset(pp,len);
		rc = cl_tree_main();
	}
	else rc = ECL_MALLOC_ERROR;

	CLcList.cmd.prmp[0] = lp;
	CLcList.cmd.prmnum  = num;
	CLcList.cmd.cid     = cid;
	return rc;
}

/*********************************************/
/*                                           */
/*********************************************/
int col_mn_tr_proc()
{
	static char *_fn_="col_mn_tr_proc";
	static char sep[]={" \t\"'()<"};
	int rc,len,n,i,num,opt,line_len,iEXTENDS;
	char *name,*pnm,tag,*line,wrk[40];
	qSubCommand *sc;
	SSPL_S sspl;

	if (CLcList.cmd.cid == C_PROC) {
		name = FORMAT(114);	/* "手続き" */
		opt = 2;
		tag = CTAG_PROC;
	}
	else if (CLcList.cmd.cid == C_FUNCTION) {
		name = FORMAT(115);	/* "関数" */
		opt = 0;
		tag = CTAG_FUNC;
	}
	else {
		name = FORMAT(120);	/* "クラス" */
		opt = 0;
		tag = CTAG_CLASS;
		pGlobTable->options[7] |= 0x02;	/* 手続き／関数の入れ子をサポートする */
		CLcList.cmd.sub_cid = 0;
#if 1	/* 2017.6.17 */
		line = CLcList.cmd.parl[0].par;
		line_len = CLcList.cmd.parl[0].parlen;
		memset(&sspl,0,sizeof(SSPL_S));
		sspl.wd = wrk;
		sspl.wdmax = sizeof(wrk);
		/* skip class name */
		len = akxtgwnsl(line,line_len,&sspl,NULL,0x1);
		iEXTENDS = 0;
		rc = 0;
		while ((len=akxtgwnsl(line,line_len,&sspl,NULL,0x1)) > 0) {
			pnm = sspl.wd;
			if ((CLcList.cmd.sub_cid & (CS_STATIC | CS_EXTENDS)) == (CS_STATIC | CS_EXTENDS)) rc = -100; 
			else if (sspl.attr[0] == 1) {
				if (sc=cl_get_name_attr(pnm,len,1,0x110)) {
					if (sc->scid == CS_STATIC) CLcList.cmd.sub_cid |= CS_STATIC;
					else if (sc->scid == CS_EXTENDS) {
						iEXTENDS++;
					}
				}
				else rc = -200;
			}
			else if (*pnm == '<') {	/* Extends */
				iEXTENDS++;
			}
			else rc = -200;
			if (rc == -100) {
				/* %s: 余分なパラメータ[%s]があります。 */
				ERROROUT2(FORMAT(43),_fn_,pnm);
				return ECL_TR_PROC;
			}
			else if (rc == -200) {
				/* %s: パラメータ[%s]が誤っています。 */
				ERROROUT2(FORMAT(45),_fn_,pnm);
				return ECL_TR_PROC;
			}
			else if (iEXTENDS == 1) {
				if ((len=akxtgwnsl(line,line_len,&sspl,NULL,0x1)) > 0) {
					if (sspl.attr[0] == 1) {
						pnm = sspl.wd;
						if (rc=cl_tr_chk_proc_name(pnm,len,opt,_fn_,name)) return rc;
						strcpy(CLcList.cmd.parl[0].par,pnm);
						CLcList.cmd.parl[0].parlen = len;
						CLcList.cmd.sub_cid |= CS_EXTENDS;
						iEXTENDS++;
					}
					else rc = -200;
				}
				else {
					/* %s: スーパークラス名がありません。 */
					ERROROUT1(FORMAT(596),_fn_);
					return ECL_TR_PROC;
				}
			}
		}
#else
		if (CLcList.cmd.prmnum >= 2) {
			for (i=1;i<CLcList.cmd.prmnum;i++) {
				pnm = CLcList.cmd.prmp[i]->prp;
				len = CLcList.cmd.prmp[i]->prmlen;
				if (sc=cl_get_name_attr(pnm,len,1,0x110)) {
					if (sc->scid == CS_STATIC) CLcList.cmd.sub_cid |= CS_STATIC;
					else if (sc->scid == CS_EXTENDS) {
						if (i+1 < CLcList.cmd.prmnum) {
							i++;
							pnm = CLcList.cmd.prmp[i]->prp;
							len = CLcList.cmd.prmp[i]->prmlen;
							if (rc=cl_tr_chk_proc_name(pnm,len,opt,_fn_,name)) return rc;
							strcpy(CLcList.cmd.parl->par,pnm);
							CLcList.cmd.parl->parlen = len;
							CLcList.cmd.sub_cid |= CS_EXTENDS;
						}
						else {
							ERROROUT1("No super class name.",_fn_);
							return ECL_TR_PROC;
						}
					}
					else sc = NULL;
				}
				if (!sc) {
					/* %s: パラメータ[%s]が誤っています。 */
					ERROROUT2(FORMAT(45),_fn_,pnm);
					return ECL_TR_PROC;
				}
			}
		/*	CLcList.cmd.prmnum = 1;	*/
		}
#endif
	}
	rc = 0;
	if (CLcList.cmd.prmnum == 0) {
		ERROROUT2(FORMAT(111),_fn_,name);	/* %s: %s名が必要です。 */
		rc = ECL_TR_PROC;
	}
	else {
		cl_tr_split(0,"(");
		pnm = CLcList.cmd.prmp[0]->prp;
		len = CLcList.cmd.prmp[0]->prmlen;
#if 1	/* 2017.6.2 */
		rc = cl_tr_chk_proc_name(pnm,len,opt,_fn_,name);
#else
		if (len > PR_NM_DEF) {
			/* %s: %s名[%s]が長すぎます(len=%d > %d)。 */
			ERROROUT5(FORMAT(112),_fn_,name,pnm,len,PR_NM_DEF);
			rc = ECL_TR_PROC;
		}
		if (cl_chk_name_opt(pnm,len,opt)) {
			ERROROUT3(FORMAT(113),_fn_,name,pnm);	/* %s: %s名[%s]が不正です。 */
			rc = ECL_TR_PROC;
		}
#endif
		if (!rc && CLcList.cmd.cid!=C_CLASS) {
			if ((rc = cl_tr_gather(1)) > 0) rc = 0;
		}
	}
	if (!rc) {
		rc = cl_make_push_leaf();
		CLSTCB.TopStack->cmdtag = tag;
	}
	return rc;
}

/*********************************************/
/*                                           */
/*********************************************/
int cl_tr_split(ip,sep)
int ip;
char *sep;
{
	int rc,len,n,i,num;
	char *pnm;

	pnm = CLcList.cmd.prmp[0]->prp;
	len = CLcList.cmd.prmp[0]->prmlen;
	num = CLcList.cmd.prmnum;
	if (ip<num && num<CLcList.max_prmnum && (n=akxnskipto(pnm,len,sep))<len && n>=0) {
		for (i=num;i>ip+1;i--) CLcList.cmd.prmp[i] = CLcList.cmd.prmp[i-1];
		CLcList.cmd.prmnum = 1;
		if (rc=clparmset(pnm+n,len-n)) return rc;
		*(pnm+n) = '\0';
		CLcList.cmd.prmp[0]->prmlen = n;
		CLcList.cmd.prmnum = num + 1;
/*
for (i=0;i<CLcList.cmd.prmnum;i++) printf("split: prmp[%d]=[%s]\n",i,CLcList.cmd.prmp[i]->prp);
*/
	}
	else n = 0;
	return n;
}

/*********************************************/
/*                                           */
/*********************************************/
int col_mn_tr_exception()
{
	int rc,len,n,i,num;
	char *name,*pnm;

	rc = 0;

	if (CLSTCB.nestLev1 != (Leaf *)NULL) {		/* ENDPROCのチェック  */
		/* %s: ＥＮＤＰＲＯＣまたはＥＮＤＦＵＮＣが設定されませんでした。 */
		ERROROUT1(FORMAT(36),"col_mn_tr_exception");
		rc = ECL_TR_PROC;
	}
	else {
		rc = cl_make_push_leaf();
	}
	return rc;
}

/********************************************/
/*											*/
/********************************************/
int cl_tr_chk_proc_name(pnm, len, opt, _fn_, name)
char *pnm,*_fn_,*name;
int len,opt;
{
	char *p;
	int rc,ret,parm[5];

	rc = 0;
	if (len > PR_NM_DEF) {
		/* %s: %s名[%s]が長すぎます(len=%d > %d)。 */
		ERROROUT5(FORMAT(112),_fn_,name,pnm,len,PR_NM_DEF);
		rc = ECL_TR_PROC;
	}
	if (cl_chk_name_opt(pnm,len,opt)) {
		ERROROUT3(FORMAT(113),_fn_,name,pnm);	/* %s: %s名[%s]が不正です。 */
		rc = ECL_TR_PROC;
	}
	if (ret=cl_is_yoyakugo(pnm)) {
		if (ret!=2 || !cl_get_func_info(pnm,parm)) {
			ERROROUT2(FORMAT(121),_fn_,pnm);
			rc = ECL_TR_PROC;
		}
	}
	return rc;
}
