static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/********************************************************************/
/* <cllexfnc.c>                                                     */
/*      字句解析共通関数                                            */
/********************************************************************/

#include "colmn.h"          /* 定数定義 */

extern condList CLcList;  /* 情報リスト */
extern tableRoot CLtbl;   /* 解析するタグ及び文字が格納される領域*/
extern cmdTable  CLcmdTable[];   /* */

/*************************/
/* cl_get_str (文字列取得) */
/*************************/
int cl_get_str(buff)
char   buff[];
{
	tdtInfoParm *pInfoParm;
	SSP_S *ssp;
	int    len;
	char   *rc,*p,c;
	int    (*func)();
							/* ファイルが既にクローズされている */
	if (CLcList.fp == NULL) return(C_FEND);

	if (CLcList.option & D_SCRPT_MEMORY) {
		pInfoParm = (tdtInfoParm *)CLcList.fp;
		ssp = (SSP_S *)pInfoParm->pi_paux;
		len = akxtmgetline(pInfoParm->pi_data,pInfoParm->pi_dlen,ssp);
		if (len < 0) {
			CLcList.fp = NULL;
			return C_FEND;
		}
		if (ssp->sp >= 1) {
			p = pInfoParm->pi_data + ssp->sp - 1;
			if ((c=*p)=='\r') len++;
			else if (c=='\n') {
				len++;
				if (ssp->sp >= 2) {
					if (*(p-1)=='\r') len++;
				}
			}
		}
		if (len >= BUFLEN) {
			ssp->sp -= (len-(BUFLEN-1));
			len = BUFLEN -1;
		}
		memzcpy(buff,ssp->wd,len);
/*
printf("cl_get_str: len=%d buff=[%s]\n",len,buff);
*/
	}
	else if (CLcList.option & D_SCRPT_FUNC) {
		func = (int (*)())CLcList.fp;
		len = func(buff,(int)BUFLEN);
/*
printf("cl_get_str: len=%d buff=[%s]\n",len,buff);
*/
		if (len < 0) {
			return C_FEND;
		}
	}
	else {
		len = akxa_get_line(buff,(int)BUFLEN,CLcList.fp,0x01);
		if (len < 0) {
			fclose(CLcList.fp);
			CLcList.fp = NULL;
			return C_FEND;
		}
/*
printf("cl_get_str: buff=[%s]\n",buff);
*/
	}
	(CLcList.line)++;
	return 0;
}

/************************************/
/* cl_cmd_chk (コマンド種類チェック)	*/
/************************************/
cmdTable *cl_cmd_chk(buff)
char *buff;
{
	static XHASHB *xhp=NULL;
	static cmdTable *p_un=NULL;
	static int iTry=1;
	int i;
	cmdTable *p,**pp;

	if (!buff) buff = "";
	i = strlen(buff);
	if (i>=2 && buff[i-1]==':') {
		if (p = cl_cmd_chk("LABEL")) p->type = 9;
		return p;
	}
	if (iTry && !xhp) {
		if (xhp=akxs_xhash_new2(0,100,97,sizeof(cmdTable *))) {
			xhp->xha_id[0] = 'h';
			p = &CLcmdTable[0];
			for (;;p++) {
				if (!p->cmds) break;
				if ((i=akxs_xhash2(xhp,'S',p->cmds,&p)) <= 0) {
					akxs_xhash_free(xhp);
					xhp = NULL;
					break;
				}
				if (!p_un && p->cmdid==C_UNKNOWN) {
					p_un = p;
				/*	break;	*/
				}
			}
		}
		iTry = 0;
		if (!xhp || !p_un) ERROROUT2("cl_cmd_chk: xhp=%08x p_un=%08x",xhp,p_un);
	}
	if (xhp && p_un) {
		if ((i=akxs_xhash2(xhp,'R',buff,&pp)) > 0) p = *pp;
		else p = p_un;
/*
printf("cl_cmd_chk: buff=[%s] p->cmds=[%s]\n",buff,p->cmds);
*/
		return p;
	}
	p = &CLcmdTable[0];
	for (i=0;;i++,p++) {
		if (p->cmdid==C_UNKNOWN) break;
		else if(!stricmp(buff,p->cmds)) break;
	}
	return p;
}

/*****************************************/
/* cl_cmd_init (構造体 cmdInfo の初期設定) */
/*****************************************/
void cl_cmd_init(tp)
cmdInfo *tp;
{
	if (tp) {
		tp->rc      = 0;	/* 領域の初期設定 */
		tp->sub_cid = 0;
		tp->type    = 0;
		tp->pos     = 0;
		tp->prmnum  = 0;
		tp->cid     = C_UNKNOWN;
		tp->parnum  = 0;
	}
	return;
}

/***************************************/
/* cl_copy_cmd (構造体 cmdInfo のコピー) */
/*            tp1 <- tp2               */
/***************************************/
void cl_copy_cmd(tp1,tp2)

cmdInfo *tp1;
cmdInfo *tp2;
{
	if (tp1 && tp2) {
		tp1->rc      = tp2->rc;
		tp1->cid     = tp2->cid;
		tp1->sub_cid = tp2->sub_cid;
		tp1->type    = tp2->type;
		tp1->pos     = tp2->pos;
		tp1->prmnum  = tp2->prmnum;
		tp1->type    = tp2->type;
	}
	return;
}

/*******************************/
/* cl_cmd_chk_cid (コマンド種類チェック)*/
/*******************************/
int cl_cmd_chk_cid(buff)
char *buff;
{
	cmdTable *p;

	p = cl_cmd_chk(buff);
	return p->cmdid;
}

/************************************/
/*									*/
/************************************/
char *cl_gets_cmd_name(cid)
int cid;
{
	static HASHB *hp=NULL;
	static cmdTable *p_un=NULL;
	static int iTry=1;
	static char *argv[2]={NULL,NULL};
	int i;
	cmdTable *p;

/*
printf("cl_gets_cmd_name: cid=%08x\n",cid);
*/
	if (iTry && !hp) {
		if (hp=akxs_hasl_new2(sizeof(int),100,97,0)) {
			hp->ha_key = (char *)argv;
			p = &CLcmdTable[0];
			for (;;p++) {
				if (!p->cmds) break;
				if (akxshaslr(hp,(long)p->cmdid) > 0) continue;
				argv[1] = (char *)p;
				if ((i=akxshasls(hp,(long)p->cmdid)) <= 0) {
					akxs_hasl_free(hp);
					hp = NULL;
					break;
				}
				if (!p_un && p->cmdid==C_UNKNOWN) {
					p_un = p;
				/*	break;	*/
				}
			}
		}
		if (!hp || !p_un) ERROROUT2("cl_gets_cmd_name: hp=%08x p_un=%08x",hp,p_un);
	}
	if (hp && p_un) {
		if ((i=akxshaslr(hp,(long)cid)) > 0) p = (cmdTable *)argv[1];
		else p = p_un;
/*
printf("cl_gets_cmd_name: cid=%d p->cmdid=%d p->cmds=[%s]\n",cid,p->cmdid,p->cmds);
*/
		return p->cmds;
	}
	iTry = 0;
	p = &CLcmdTable[0];
	for (;p->cmds;p++) {
		if (p->cmdid == C_UNKNOWN) break;
		else if (p->cmdid == cid) break;
	}
	return p->cmds;
}

/************************************/
/*									*/
/************************************/
int cl_get_cmd_name(cid,buf)
int cid;
char *buf;
{
	int num;
/*
printf("cl_get_cmd_name: cid=%08x\n",cid);
*/
	strcpy(buf,cl_gets_cmd_name(cid));
	if (strcmp(buf,"UNKNOWN")) return 0;
	else return -1;
}

/************************************/
/*									*/
/************************************/
int cl_get_cmd_line(pcmd,ppCmdLine)
cmdInfo *pcmd;
char **ppCmdLine;
{
	parmList *pl;
	ParList  *pal;
	char buf[32],*p;
	int i,len,cmnd,scno,par_num;
	static MCAT mcat={'M','C',256,0,0,0,NULL,0};

	if (ppCmdLine) *ppCmdLine = NULL;
	if (!pcmd || !ppCmdLine) return -1;
	mcat.mc_ipos = 0;
	par_num = pcmd->parnum;
	cmnd = pcmd->cid;
	scno = pcmd->sub_cid;
/*
printf("cl_get_cmd_line: par_num=%d cmnd=%08x scno=%d \n",par_num,cmnd,scno);
*/
	/* コマンドライン出力時に、２重引用符が消えては困るコマンドは、パラメータ単位の出力にする */
/*	if (cmnd == C_LOOP) par_num = 0;
	else */if (cmnd == C_LET) {
		switch (scno) {
		case CS_OPTIONS:
		case CS_OPTION:
		case CS_SHIFT:
		case CS_CONTINUE:
		case CS_LPRINT:
		case CS_PRINT:
		case CS_ECHO:
		case CS_DUMP:
		case CS_LOGPARM:
			par_num = 0;
		}
	}
	pal = NULL;
	if (par_num>0 && pcmd->parl) {
		/* SET_CMD_NAME */
		if (pcmd->parl[2].par) {
/*
printf("cl_get_cmd_line: parl[2].par=[%s]\n",pcmd->parl[2].par);
*/
			pal = &pcmd->parl[2];
			if ((p=pal->par) && *p) {
				akxtmcats(&mcat, p);
				akxtmcats(&mcat, " ");
			}
			akxtmcats(&mcat, pcmd->parl[0].par);
			if (p = pcmd->parl[D_LEAF_LABEL].par) {
				akxtmcats(&mcat, " AS ");
				akxtmcats(&mcat, p);
			}
		}
	}
	if (!pal) {
		if (cl_get_cmd_name(pcmd->cid,buf)) return 0;
		if (pcmd->cid==C_LABEL && pcmd->type==9) {
			pl = pcmd->prmp[0];
			akxtmcats(&mcat,pl->prp);
			akxtmcats(&mcat,":");
		}
		else {
			akxtmcats(&mcat, buf);
			for (i=0;i<pcmd->prmnum;i++) {
				if (pl=pcmd->prmp[i]) {
					if ((p=pl->prp) && *p) {
						if (akxnskipto(p,len=pl->prmlen," \t")>=len) {
							akxtmcats(&mcat, " ");
							akxtmcats(&mcat, p);
						}
						else {
							akxtmcats(&mcat, " \"");
							akxtmcats(&mcat, p);
							akxtmcats(&mcat, "\"");
						}
					}
					else
						akxtmcats(&mcat, " \"\"");
				}
			}
		}
	}
	if (mcat.mc_ipos > 0) *ppCmdLine = mcat.mc_bufp;
	return 0;
}
