static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/****************************************************/
/*  <clTree>										*/
/*  文書管理										*/
/*	構文解析解析木作成ル−チン						*/
/****************************************************/
#include "colmn.h"

extern condList  CLcList;	/* 情報リスト */
extern int giOptions[];
extern GlobalCt  *pGlobTable;

static int _tr_end();
static int _tr_get_as_name();

/**************************************************/
/* cl_tree_main (select process as kind of tag)	 */
/**************************************************/
int cl_tree_main()
{
	int rc,inter_mode,cmnd;
	char *name,*p;
	ScrPrCT *scrptct;
/*
printf("cl_tree_main:Enter: cmd=%s\n",cl_gets_cmd_name(CLcList.cmd.cid));
*/
	if (scrptct = cl_search_src_ct())
		inter_mode = scrptct->pFlag & D_SCRPT_INTERACTIVE;
	else inter_mode = 0;

	switch (cmnd=CLcList.cmd.cid) {
		case C_PROC:
		case C_FUNCTION:
		case C_CLASS:
			if (pGlobTable->options[7] & 0x02) break;
		case C_IMPORT:
		case C_DEFINE:
		case C_ONN:
			if (inter_mode) {
				/* cl_tree_main: [%s]は使用できません。 */
				ERROROUT1(FORMAT(81),cl_gets_cmd_name(CLcList.cmd.cid));
				return ECL_TREE;
			}
			break;
		case C_DIM:
	/*	case C_TYPEDEF:	*/
		case C_FEND:
		case C_PRAGMA:
			break;
		default:
			if (!inter_mode) {
				if (cl_nest_tag(1) == SysError) {
					if (CLcList.cmd.cid == C_LET) {
						CLcList.cmd.cid = C_DEFINE;
					}
					else {
						/* cl_tree_main: [%s]はPROC/FUNC/CLASSの外側では使用できません。 */
						ERROROUT1(FORMAT(82),cl_gets_cmd_name(CLcList.cmd.cid));
						return ECL_TREE;
					}
				}
			}

	}
	switch (CLcList.cmd.cid) {
		case C_IMPORT:
		case C_DEFINE:
		case C_ONN:
			if (!inter_mode) {
				if (cl_nest_tag(1) != SysError) {
					/* cl_tree_main: [%s]はPROC/FUNC/CLASSの内側では使用できません。 */
					ERROROUT1(FORMAT(84),cl_gets_cmd_name(CLcList.cmd.cid));
					return ECL_TREE;
				}
			}
			break;
	}
	if (cmnd==C_LOOP || cmnd==C_FOR || cmnd==C_WHILE || cmnd==C_UNTIL
	 || cmnd==C_DO || cmnd==C_SWITCH) {
		if (rc=_tr_get_as_name(&CLcList.cmd)) return rc;
	}
	switch (CLcList.cmd.cid) {
		case C_CALL:
		case C_EXEC:		rc = col_mn_tr_exec();		break;
		case C_FUNCTION:
		case C_CLASS:
		case C_PROC:		rc = col_mn_tr_proc();		break;
		case C_ENDFUNC:
		case C_ENDCLASS:
		case C_ENDPROC:		rc = col_mn_tr_end_proc();	break;
		case C_MSG:			rc = col_mn_tr_msg();		break;
		case C_SQL:			rc = col_mn_tr_sql();		break;
		case C_FOR:
		case C_WHILE:
		case C_UNTIL:
		case C_DO:
		case C_LOOP:		rc = col_mn_tr_loop();		break;
		case C_ENDDO:
		case C_NEXT:
		case C_ENDFOR:
		case C_ENDWHILE:
		case C_ENDUNTIL:
		case C_ENDLOOP:		rc = col_mn_tr_end_loop();	break;
		case C_CONTINUE:	rc = col_mn_tr_continue();	break;
		case C_BREAK:		rc = col_mn_tr_break();		break;
		case C_READ:		rc = col_mn_tr_read();		break;
		case C_OUTPUT:		rc = col_mn_tr_output();	break;
		case C_IMPORT:
		case C_DIM:
	/*	case C_TYPEDEF:	*/
		case C_DEFINE:		rc = col_mn_tr_define();	break;
		case C_REDEFINE:	rc = col_mn_tr_re_define();	break;
		case C_UNDEFINE:	rc = col_mn_tr_un_define();	break;
		case C_ONN:			rc = col_mn_tr_on();		break;
		case C_TRY:			rc = col_mn_tr_try();		break;
		case C_EXCEPTION:	rc = col_mn_tr_exception();	break;
		case C_SWITCH:
		case C_IF:			rc = col_mn_tr_if();		break;
		case C_ELSEL:
		case C_ELSE:		rc = col_mn_tr_else();		break;
		case C_ELSEIF:		rc = col_mn_tr_else_if();	break;
		case C_ENDIF:		rc = col_mn_tr_end_if();	break;
		case C_CASE:		rc = col_mn_tr_case();		break;
		case C_DEFAULT:		rc = col_mn_tr_default();	break;
		case C_ENDSW:		rc = col_mn_tr_end_sw();	break;
		case C_CATCH:		rc = col_mn_tr_catch();		break;
		case C_FINALLY:		rc = col_mn_tr_finally();	break;
		case C_ENDTRY:		rc = col_mn_tr_end_try();	break;
		case C_THROW :		rc = col_mn_tr_throw();		break;
		case C_LET:
		case C_BEXP:		rc = col_mn_tr_bexp();		break;
		case C_SLEEP:
		case C_RETURN:		rc = col_mn_tr_return();	break;
		case C_FEND:		rc = col_mn_tr_file_end();	break;
		case C_LEAVE:		rc = col_mn_tr_leave();		break;
		case C_LABEL:		rc = col_mn_tr_label();		break;
		case C_END:			rc = _tr_end();				break;
	/*	case C_INTERACTIVE: rc = ColMnTrInteractive();	break;	*/
		default: rc = ECL_TREE;
	}
	return rc;
}

static int _tr_end()
{
	char *p;
	int  cnum,cnum1,i,num;

	p = CLcList.cmd.prmp[0]->prp;
	cnum = cl_cmd_chk_cid(p);
	if (CLcList.cmd.prmnum > 1) {
		if (!strnicmp(p,"WHILE",5) || !strnicmp(p,"UNTIL",5)) {
			cl_tr_split(0,"(");
			p = CLcList.cmd.prmp[0]->prp;
			cnum = cl_cmd_chk_cid(p);
		}
		if (cnum == C_DO) {
			cnum1 = cl_cmd_chk_cid(CLcList.cmd.prmp[1]->prp);
			if (cnum1==C_WHILE || cnum1 == C_UNTIL) {
				CLcList.cmd.cid = C_ENDDO;
				CLcList.cmd.sub_cid = cnum1;
				num = --CLcList.cmd.prmnum;
				for (i=0;i<num;i++) CLcList.cmd.prmp[i] = CLcList.cmd.prmp[i+1];
				return cl_tree_main();
			}
		}
		else if (cnum==C_WHILE || cnum==C_UNTIL) {
			if (cnum==C_WHILE) CLcList.cmd.cid = C_ENDWHILE;
			else CLcList.cmd.cid = C_ENDUNTIL;
			num = --CLcList.cmd.prmnum;
			for (i=0;i<num;i++) CLcList.cmd.prmp[i] = CLcList.cmd.prmp[i+1];
/*
for (i=0;i<CLcList.cmd.prmnum;i++) printf("end: prmp[%d]=[%s]\n",i,CLcList.cmd.prmp[i]->prp);
*/
			return cl_tree_main();
		}
	}
	if (CLcList.cmd.prmnum != 1) {
		ERROROUT(FORMAT(83));	/* _tr_end: パラメータが１つ必要です。 */
		return ECL_TREE;
	}
	switch (cnum) {
		case C_PROC:	cnum = C_ENDPROC;	break;
		case C_FUNCTION:cnum = C_ENDFUNC;	break;
		case C_CLASS:	cnum = C_ENDCLASS;	break;
		case C_LOOP:	cnum = C_ENDLOOP;	break;
		case C_DO:		cnum = C_ENDDO;		break;
		case C_IF:		cnum = C_ENDIF;		break;
		case C_SWITCH:	cnum = C_ENDSW;		break;
		case C_TRY	:	cnum = C_ENDTRY;	break;
		case C_WHILE:	cnum = C_ENDWHILE;	break;
		case C_UNTIL:	cnum = C_ENDUNTIL;	break;
		case C_FOR:		cnum = C_ENDFOR;	break;
		default:
			ERROROUT2(FORMAT(45),"_tr_end",p);	/* %s: パラメータ[%s]が誤っています。 */
			return ECL_TREE;
	}
	CLcList.cmd.cid = cnum;
	CLcList.cmd.prmnum = 0;
	return cl_tree_main();
}

/********************************************/
/*											*/
/********************************************/
static int _tr_get_as_name(pcmd)
cmdInfo *pcmd;
{
	static char *_NAME_="_tr_get_as_name";
	int cmnd,i,ret,nprm,len;
	char *name,*p;
	parmList **pprm,*prm;

	ret = 0;
	pprm = pcmd->prmp;
	nprm = pcmd->prmnum;
	if ((i=get_pos_as_name(pprm,nprm)) > 0) {
		if (i == nprm-1) {
			if (prm = pprm[i]) {
				name = prm->prp;
				len = prm->prmlen;
/*
printf("_tr_get_as_name: len=%d nam=[%s]\n",len,name);
*/
				if (cl_is_name(name,len) <= 0) {
					/*_%s: %s名[%s]が不正です。*/
					ERROROUT3(FORMAT(113),_NAME_,FORMAT(598),name);
					ret = ECL_SCRIPT_ERROR;
				}
				else if (len > 0) {
					pcmd->prmnum = i - 1;
					p = Malloc(len+1);
					memzcpy(p,name,len);
					pcmd->parl[D_LEAF_LABEL].par = p;
					pcmd->parl[D_LEAF_LABEL].parlen = len;
				}
			}
		}
		else {
			if (i == nprm)
				/* %s: パラメータが足りません。 */
				ERROROUT1(FORMAT(42),_NAME_);
			else
				/* %s: 余分なパラメータ[%s]があります。 */
				ERROROUT2(FORMAT(43),_NAME_,pprm[i+1]->prp);
			ret = ECL_SCRIPT_ERROR;
		}
	}
	return ret;
}
