static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/******************************************************************************
*                                                                             *
*      処理目的　　：  TO  演算処理                          　　　           *
*                                                                             *
*      関数名　    ：　int cl_cmpt_to(pAns , pOprtr , pInfoParm1 , pInfoParm2)*
*					   (O)int		*pAns									  *
*				       (I)char  	*pOprtr								      *
*					   (I)tdtInfoParm *pInfoParm1							  *
*					   (I)tdtInfoParm *pInfoParm2							  *
*                                                                             *
*      戻り値　　　：　ERROR                                    　            *
*                      NORMAL                                                 *
*                                                                             *
*      処理概要　　：　                                                       *
*                                                                             *
******************************************************************************/
#include <colmn.h>
extern CLPRTBL *pCLprocTable;
extern GlobalCt  *pGlobTable;
extern CLCOMMON  CLcommon;
extern int giOptions[];

static int _to_number(pAns,pInfoParm1,cAttr,pTo,len)
char		**pAns;
tdtInfoParm	*pInfoParm1;
char		cAttr,*pTo;
int			len;
{
	tdtInfoParm qParm[5],*ppParm[5];
	int iParm[4],attr,rc,nparm,opt,i;
	long Val1z[NMPA_LONG],*Val1;
	qSubCommand *sc;
	long *pWork;

	pWork = (long *)*pAns;
	if (len >= 3) {
		if (sc=cl_get_name_attr(pTo,len,0x01,0x20)) {
			attr = sc->attr;
			if (attr!=DEF_ZOK_BINA && attr!=DEF_ZOK_FLOA
			 && attr!=DEF_ZOK_DECI && attr!=DEF_ZOK_LONG) sc = NULL;
		}
		if (!sc){
			ERROROUT(FORMAT(291));	/* 変換子に誤りがあります。 */
			*pWork = 0;
		 	return ECL_SCRIPT_ERROR;
		}
	}
	else if (cAttr == 'I') {
		attr = DEF_ZOK_BINA;
		if (cl_get_option(17,0) & 0x100) attr |= DEF_ZOK_USMASK;
	}
	else if (cAttr == 'U') attr = DEF_ZOK_BINA | DEF_ZOK_USMASK;
	else if (cAttr == 'F') attr = DEF_ZOK_FLOA;
	else {
		attr = DEF_ZOK_DECI;
	}

	ppParm[0] = pInfoParm1;
	for (i=1;i<5;i++) ppParm[i] = &qParm[i];

	cl_set_parm_long(ppParm[1],(long)attr);

	opt = (pGlobTable->options[16] >> 4) & 0x0f;
	if (opt) {
		cl_null_data(ppParm[2]);
		cl_null_data(ppParm[3]);
		cl_set_parm_long(ppParm[4],(long)opt);
		nparm = 5;
	}
	else nparm = 2;

	Val1 = cl_get_tmpMPA(Val1z);
	if ((attr = cl_cmpt_to_number(Val1,nparm,ppParm,iParm)) > 0) {
		if (attr==DEF_ZOK_BINA || attr==DEF_ZOK_FLOA)
			memcpy(pWork,Val1,iParm[1]);
		else if (attr == DEF_ZOK_DECI) {
			if (!(*pAns=clmemdup(Val1,sizeofMPA(),D_OPT_ALC_TMP))) attr = ECL_MALLOC_ERROR;
		}
	}
	return attr;
}

int cl_cmpt_to(pAns,pOprtr,nparm,ppParm,ope,opt)
char **pAns;
char *pOprtr;
int nparm,ope,opt;
tdtInfoParm	*ppParm[];
{
	tdtInfoParm	*pInfoParm1,tInfoParm;
	tdtInfoParm	*pInfoParm2;
	int  rc,len1,len2,i,attr,val[2],m,sw,i2,m2;
	long lValue;
	char *p1,*p2,*p,c1,c2,c,cc;
	uchar  uc;
	ushort us,usw;
	char    w1[16];
	MPA *ma;
/*
printf("cl_cmpt_to: pOprtr=[%s] nparm=%d\n",pOprtr,nparm);
*/
	rc = NORMAL;
	pInfoParm1 = ppParm[0];
	pInfoParm2 = ppParm[1];
	if (nparm > 2) {
		if (pInfoParm2->pi_id==' ' && pInfoParm2->pi_attr==DEF_ZOK_BINA) {
			pInfoParm2=ppParm[2];
			if (nparm > 3) {
				if (pInfoParm2->pi_id==' ' && pInfoParm2->pi_attr==DEF_ZOK_BINA) {
					pInfoParm2 = ppParm[3];
				}
			}
		}
	}
	len2 = pInfoParm2->pi_dlen;
/*
printf("cl_cmpt_to: len2=%d pi_attr=%d\n",len2,pInfoParm2->pi_attr);
*/
	if (pInfoParm2->pi_attr != DEF_ZOK_CHAR || len2==0) {
		/* パラメータ２の型があっていません。 */
		ERROROUT1(FORMAT(251),"cl_cmpt_to");
		return ECL_SCRIPT_ERROR;
	}
	p1 = pInfoParm1->pi_data;
	len1 = pInfoParm1->pi_dlen;
	p2 = pInfoParm2->pi_data;
	c2 = toupper(c=*p2);
/*
printf("cl_cmpt_to: p2=[%s]\n",p2);
*/
	if (c2=='I' || c2=='F' || c2=='D') {
		if (nparm>2 && pInfoParm1->pi_attr==DEF_ZOK_CHAR) {
			if ((rc=cl_get_str_pos(nparm,ppParm,0,&p1,&len1,NULL,NULL,"")) < 0) return rc;
			pInfoParm1 = &tInfoParm;
			cl_set_parm_char(pInfoParm1,p1,len1);
		}
		if (c1=='I' && toupper(*(p2+1))=='U') c2 = 'U';
		return _to_number(pAns,pInfoParm1,c2,p2,len2);
	}
	else if (c2 == 'X') {
		m = len1*3 + 1;
		if (!(*pAns = p = cl_tmp_const_malloc(m))) {
			ERROROUT("to: malloc error");
			return -1;
		}
		if ((attr=pInfoParm1->pi_attr) == DEF_ZOK_BINA) {
			cc = toupper(*(p2+1));
			if (cc == 'S') p2 = "%x";
			else p2 = "%08x";
			lValue = cl_get_data_long(pInfoParm1);
			sprintf(p,p2,lValue);
		}
		else if (attr==DEF_ZOK_FLOA && CLcommon.ucByteOrder) {
			memcpy(val,p1,sizeof(double));
			sprintf(p,"%08x",val[1]);
			sprintf(p+sizeof(int)*2,"%08x",val[0]);
		}
		else {
		/*	akxcxtoc(p1,len1,p);
			*(p+len1*2) = '\0';	*/
			m2 = atoi(p2+1);
			if (attr == DEF_ZOK_DECI) {
				ma = (MPA *)p1;
				len1 = ma->len + 12;
				m2 = 0;
			}
			else if (attr == DEF_ZOK_DATE) {
				ma = (MPA *)p1;
				len1 = ma->len;
				p1 = ma->num;
				m2 = 0;
			}
			else if (attr==DEF_ZOK_FLOA) m2 = 0;
			akxcxtocn(p1,len1,p,m,m2);
		}
		if (c == 'X') akxcuppern(p,NULL,strlen(p));
		return 0;
	}
	if (nparm > 2) {
		if ((rc=cl_get_str_pos(nparm,ppParm,0,&p1,&len1,NULL,NULL,"")) < 0) return rc;
	}
	if (strchr("HZULCP",c2)) {
		m = len1 + 1;
		if (c2=='H' || c2=='Z') m += len1*3;
		if (!(*pAns = p = cl_tmp_const_malloc(m))) {
			ERROROUT("to: malloc error");
			return -1;
		}
	}
	switch (c2) {
		case 'H':	/*** Hankaku ***/
				akxctohan(len1,p1,p);
				break;
		case 'Z':	/*** Zenkaku ***/
				akxctozen(len1,p1,p);
				break;
		case 'U':	/*** Upper ***/
				akxcuppern(p,p1,len1);
				break;
		case 'L':
				akxclowern(p,p1,len1);
				break;
		case 'C':	/*** Caption ***/
		case 'P':	/*** Proper ***/
				sw = 1;
				i = 0;
				while (i < len1) {
					c1 = *p1;
					m = akxqkanjilen(p1);
					if (m > 1) {
						akxctohan(m,p1,w1);
						cc = w1[0];
/*
printf("cl_cmpt_to: cc=[%c]\n",cc);
*/
					}
					else cc = c1;
					m2 = 0;
					if (sw) {
						if (isalpha(cc) || cc=='_') {
							m2 = akxcuplw(p,p1,0);
							sw = 0;
						}
						else if (c2 == 'P') {
							m2 = akxcuplw(p,p1,1);
						}
					}
					else {
						if (!isalpha(cc) && cc!='_') {
							sw = 1;
						}
						if (c2 == 'P') {
							m2 = akxcuplw(p,p1,1);
						}
					}
					if (!m2) {
						memcpy(p,p1,m);
						m2 = m;
					}
					if (m > 1) {
						p  += m2;
						p1 += m;
						i  += m;
					}
					else {
						p++;
						p1++;
						i++;
					}
				}
				*p = '\0';
				break;
		default:
			ERROROUT(FORMAT(291));	/* 変換子に誤りがあります。 */
			*pAns = 0;
		 	return ECL_SCRIPT_ERROR;
	}

	return NORMAL;
}

int cl_cmpt_to_number(pWork,nparm,ppParm,iParm)
long *pWork;
tdtInfoParm *ppParm[];
int nparm,iParm[];
{
	tdtInfoParm *pInfoParm;
	int  dtatr,iRc,ret,i,size,attr,scale,opt,val[2],iAttr[4],pre,iUNSIG;
	long lVal,Val1z[NMPA_LONG],*Val1;
	double dVal;
	char   *pMsg,wrk[30];
	MPA    *mpa;
/*
printf("cl_cmpt_to_number: Enter: nparm=%d\n",nparm);
*/
	iRc = 0;
	pre = attr = scale = 0;
	opt = pGlobTable->options[16];
	for (i=1;i<nparm && i<5;i++) {
		pInfoParm = ppParm[i];
		if (pInfoParm->pi_dlen > 0) {
			if (iRc=cl_get_parm_bin(pInfoParm,val,"cl_cmpt_to_number:")) return iRc;
			if (i == 1) attr = val[0];
			else if (i == 2) pre = val[0];
			else if (i == 3) scale = val[0];
			else opt = val[0] << 4;
		}
	}
/*
printf("cl_cmpt_to_number: iRc=%d attr=%d pre=%d scale=%d opt=%08x\n",iRc,attr,pre,scale,opt);
*/
	iUNSIG = attr & DEF_ZOK_USMASK;
	attr &= ~DEF_ZOK_USMASK;
	iAttr[0] = attr;
	strcpy(wrk,"-cl_cmpt_to_number.");
	pMsg = wrk;
	if (!(opt & AKX_CNVN_OPT_NOT_NUM)) pMsg++;
	Val1 = cl_get_tmpMPA(Val1z);
#if 1	/* 2021.11.5 */
	if (attr) {
		if (attr == DEF_ZOK_BINA) {
			strcat(pMsg,"BINA");
			if ((ret=cl_get_parm_ulong_opt(ppParm[0],Val1,pMsg,iUNSIG,opt)) < 0) return ret;
			else if (ret > 0) return ECL_SCRIPT_ERROR;
			size = sizeof(long);
			memcpy(pWork,Val1,size);
			scale = iUNSIG;
		}
		else if (attr == DEF_ZOK_FLOA) {
			strcat(pMsg,"FLOA");
			if ((ret=cl_get_parm_double_opt(ppParm[0],Val1,pMsg,iAttr,opt)) < 0)
				 return ret;
			else if (ret > 0) return ECL_SCRIPT_ERROR;
			size = sizeof(double);
			memcpy(pWork,Val1,size);
		}
		else if (attr == DEF_ZOK_DECI) {
			strcat(pMsg,"DECI");
			if ((ret=cl_get_parm_dec_opt(ppParm[0],Val1,pMsg,iAttr,opt)) < 0)
				 return ret;
			else if (ret > 0) return ECL_SCRIPT_ERROR;
			mpa = (MPA *)Val1;
			if (pre) {
				if ((ret=cl_mpa_scale(mpa,pre,scale)) < 0) return ret;
			}
			size = sizeofMPA();
			memcpy(pWork,mpa,size);
		}
		else return ECL_SCRIPT_ERROR;
		dtatr = attr;
	}
	else {
		if ((ret=cl_get_parm_mpa_opt(ppParm[0],Val1,pMsg,iAttr,opt)) < 0) return ret;
		else if (ret>0 && !(opt & AKX_CNVN_OPT_NOT_NUM)) {
			return ECL_SCRIPT_ERROR;
		}
/*
printf("cl_cmpt_to_number: dattr=%d\n",iAttr[0]);
*/
		dtatr = iAttr[0];
		size  = iAttr[1];
		scale = iAttr[2];
		if (size < 0) size = -size;
		if (dtatr==DEF_ZOK_BINA || dtatr==DEF_ZOK_FLOA || dtatr==DEF_ZOK_DECI) {
			memcpy(pWork,Val1,size);
			if (dtatr==DEF_ZOK_BINA && (scale & AKX_NUM_U)) scale = DEF_ZOK_USMASK;
		}
/*
		if (dtatr == DEF_ZOK_BINA) {
			lVal = Val1[0];
			memcpy(pWork,&lVal,size);
		}
		else if (dtatr == DEF_ZOK_FLOA) {
			memcpy(&dVal,Val1,size);
			memcpy(pWork,&dVal,size);
		}
		else if (dtatr == DEF_ZOK_DECI) {
			mpa = (MPA *)Val1;
			memcpy(pWork,mpa,size);
		}
*/
		else return ECL_SCRIPT_ERROR;
		size  = iAttr[1];
/*
printf("cl_cmpt_to_number: iVal=%d dVal=%f\n",iVal,dVal);
*/
	}
#else
	if (attr) {
		if (attr == DEF_ZOK_BINA) {
			if (dtatr == DEF_ZOK_FLOA) lVal = cl_chk_over_flow_d2_l(dVal,"cl_cmpt_to_number");
			else if (dtatr == DEF_ZOK_DECI) m_mpa2l(mpa,&lVal);
		}
		else if (attr == DEF_ZOK_FLOA) {
			if (dtatr == DEF_ZOK_BINA) dVal = lVal;
			else if (dtatr == DEF_ZOK_DECI) m_mpa2d(mpa,&dVal);
		}
		else if (attr == DEF_ZOK_DECI) {
			mpa = (MPA *)Val1;
			if (dtatr == DEF_ZOK_BINA) m_l2mpa(lVal,mpa);
			else if (dtatr == DEF_ZOK_FLOA) m_d2mpa(dVal,mpa);
			if (pre) {
				if ((ret=cl_mpa_scale(mpa,pre,scale)) < 0) return ret;
			}
		}
		else return ECL_SCRIPT_ERROR;
		dtatr = attr;
		if (dtatr == DEF_ZOK_BINA) {
			size = sizeof(long);
			memcpy(pWork,&lVal,size);
		}
		else if (dtatr == DEF_ZOK_FLOA) {
			size = sizeof(double);
			memcpy(pWork,&dVal,size);
		}
		else if (dtatr == DEF_ZOK_DECI) {
			size = sizeofMPA();
			memcpy(pWork,mpa,size);
		}
	}
#endif
	iParm[0] = dtatr;
	iParm[1] = size;
	iParm[2] = pre;
	iParm[3] = scale;
/*
printf("cl_cmpt_to_number:Exit dtatr=%d size=%d pre=%d scale=%04x\n",dtatr,size,pre,scale);
*/
	return dtatr;
}

/****************************************/
/*										*/
/****************************************/
char *_to_bulk(pInfoParm,iParm,opt)
tdtInfoParm *pInfoParm;
int iParm[],opt;
{
	int  ret,len,attr,val[2];
	short s,*sw;
	char *pdat,*p;
	MPA *ma;

	pdat = NULL;
	len = pInfoParm->pi_dlen;
	iParm[1] = len;
	iParm[0] = 0;
	if (len > 0) {
		if (ret=cl_check_data_id(pInfoParm,0)) {
			iParm[0] = ret+ECL_CHK_VAR_ERROR;
			return NULL;
		}
		attr = pInfoParm->pi_attr;
		pdat = pInfoParm->pi_data;
		if (attr == DEF_ZOK_BINA) {
			if (len == 2) {
				memcpy(&s,pdat,len);
				sw = (short *)&iParm[2];
				*sw = opt ? s : htons(s);
				pdat = (char *)sw;
			}
			else if (len == 4) {
				memcpy(val,pdat,len);
				iParm[2] = opt ? val[0] : htonl(val[0]);
				pdat = (char *)&iParm[2];
			}
		}
		else if (attr == DEF_ZOK_FLOA) {
			if (CLcommon.ucByteOrder) {
				memcpy(val,pdat,sizeof(double));
				if (opt) {
					iParm[2] = val[0];
					iParm[3] = val[1];
				}
				else {
					iParm[2] = htonl(val[1]);
					iParm[3] = htonl(val[0]);
				}
				pdat = (char *)&iParm[2];
			}
		}
		else if (attr == DEF_ZOK_CHAR) {
			if (opt) {
				if (p = cl_tmp_const_malloc(len/2+1)) {
					iParm[1] = akxcctox(pdat,len,p);
					pdat = p;
				}
				else {
					ERROROUT("_to_bulk: malloc error.");
					iParm[0] = -1;
					return NULL;
				}
			}
		}
		else if (attr == DEF_ZOK_DATE) {
			ma = (MPA *)pInfoParm->pi_data;
			pdat = ma->num;
			iParm[1] = ma->len;
		}
		else if (attr == DEF_ZOK_BULK) ;
		else if (attr == DEF_ZOK_DECI) ;
		else {
			/* _to_bulk: パラメータの型(%d)があっていません。 */
			ERROROUT2(FORMAT(285),"_to_bulk",attr);
			iParm[0] = -1;
			return NULL;
		}
	}
	return pdat;
}

/****************************************/
/*										*/
/****************************************/
int cl_cmpt_to_bulks(pAns,nparm,ppParm,iParm)
char **pAns;
tdtInfoParm *ppParm[];
int nparm,iParm[];
{
	static MCAT mcat={'M','C',256,0,0,0,NULL,0};
	int  i,len,opt;
	char *pdat,*p;

	*pAns = NULL;
	mcat.mc_ipos = 0;
	iParm[0] = 0;
	for (i=0;i<nparm;i++) {
		pdat = _to_bulk(ppParm[i],iParm,0);
		if (iParm[0] < 0) return iParm[0];
		if ((len = iParm[1]) > 0) {
			if (pdat) akxtmcat(&mcat,pdat,len);
			else return -1;
		}
	}
	if (mcat.mc_ipos > 0) {
		if (p = cl_tmp_const_malloc(mcat.mc_ipos+1)) {
			memzcpy(p,mcat.mc_bufp,mcat.mc_ipos);
			*pAns = p;
			iParm[0] = DEF_ZOK_BULK;
			iParm[1] = mcat.mc_ipos;
		}
		else {
			return -1;
		}
	}
	return iParm[0];
}

/****************************************/
/*										*/
/****************************************/
int cl_cmpt_to_bulk(pWork,nparm,ppParm,iParm)
char **pWork;
tdtInfoParm *ppParm[];
int nparm,iParm[];
{
	tdtInfoParm tParm,*pInfoParm;
	int len,ret,opt,val[2];
	char *pdat,*p;
	parmList tList;

	iParm[0] = 0;
	iParm[1] = ret = opt = 0;
	*pWork = NULL;
	if (nparm >= 4) {
		pInfoParm = ppParm[3];
		if (pInfoParm->pi_dlen > 0) {
			if (ret=cl_get_parm_bin(pInfoParm,val,"cl_cmpt_to_bulk:")) return ret;
			opt = val[0];
		}
	}
	pdat = _to_bulk(ppParm[0],iParm,opt);
	*pWork = pdat;
	if ((len=iParm[1]) > 0) {
		if (pdat) {
			if (nparm > 1) {
				cl_set_parm_char(&tParm,pdat,len);
				if (nparm >= 3) pInfoParm = ppParm[2];
				else pInfoParm = NULL;
				ret = substr_len(0,&tList,&tParm,ppParm[1],pInfoParm);
				if (!ret) {
					*pWork = tList.prp;
					iParm[1] = tList.prmlen;
				}
			}
			else {
				if (p = cl_tmp_const_malloc(len+1)) {
					memzcpy(p,pdat,len);
					*pWork = p;
				}
				else return -1;
			}
			iParm[0] = DEF_ZOK_BULK;
		}
		else ret = iParm[0];
	}
	return ret;
}

/****************************************/
/*										*/
/*	option = 0x00 :	四捨五入			*/
/*			 0x01 : 切捨て				*/
/*			 0x02 : 切上げ				*/
/*		0x10 : オーバーフロー時、数値はそのままとする。*/
/****************************************/
int cl_mpa_scale_opt(mpa,precision,scale,option)
MPA *mpa;
int precision,scale,option;
{
	static char *name="cl_mpa_scale";
	int ret,opt;
	char work[NMPA10+10],*fmt;
	MPA wz,*w;

	if ((opt=pGlobTable->options[10]) & 0x80) return 0;

	if (scale<MIN_DEC_SCALE || scale>MAX_DEC_SCALE) {
		/* cl_mpa_scale: 位取り(%d)が不正です。 */
		ERROROUT2(FORMAT(292),name,scale);
		return -1005;
	}
	w = (MPA *)cl_get_tmpMPA(&wz);
	m_cpy(w,mpa,0);
	ret = m_scale(mpa,precision,scale,option);
	if (ret == -1002) {
		/* cl_mpa_scale: 精度(%d)が不正です。 */
		ERROROUT2(FORMAT(293),name,precision);
		return ret;
	}
	else if (ret == 11) {
		m_mpa2an_exp(w,work,sizeof(work),0,0,0);
		if (option & 0x10) fmt = FORMAT(295);
		/* (W)cl_mpa_scale: MPA(%s) オーバフロー! */
		else fmt = FORMAT(294);
		/* (W)cl_mpa_scale: MPA(%s) オーバフロー! set to MAX. */
		ERROROUT2(fmt,name,work);
		return ECL_DEC_OVERFLOW;
	}
	else if (ret==-1003 || ret==1004) {
		/* cl_mpa_scale: 位取り(%d)が不正です。 */
		ERROROUT2(FORMAT(292),name,scale);
	}
	return ret;
}

/****************************************/
/*										*/
/****************************************/
int cl_mpa_scale(mpa,precision,scale)
MPA *mpa;
int precision,scale;
{
	int option;

	option = (pGlobTable->options[15] & 0x10) | pGlobTable->options[11];
	return cl_mpa_scale_opt(mpa,precision,scale,option);
}
