static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/******************************************************************************
*                                                                             *
*      処理目的　　：  定数変換 ( 数値 )                                      *
*                                                                             *
*      関数名　　　：　int cl_conv_const_n( pparmList , pInfoParm )           *
*                      (I)prmList	*pparmList                                *
*                      (O)tdtInfoParm	*pInfoParm                            *
*                                                                             *
*      引き数      ：　なし                                                   *
*                                                                             *
*                                                                             *
*      戻り値　　　：　ERROR                                    　            *
*                      NORMAL                                                 *
*                                                                             *
*      処理概要　　：　                                                       *
*                                                                             *
******************************************************************************/
#include <colmn.h>
extern CLPRTBL *pCLprocTable;
extern GlobalCt  *pGlobTable;
extern int giOptions[];

int cl_conv_const_n(pparmList,pInfoParm)
parmList   *pparmList;
tdtInfoParm  *pInfoParm;
{
	int	len;
	char *prp;

	if (!pparmList) {
		ERROROUT(FORMAT(30));	/* システムエラー */
		return ERROR;
	}
	if (!pparmList->prp) {
		ERROROUT(FORMAT(30));	/* システムエラー */
		return ERROR;
	}
	prp = &(pparmList->prp[0]);
	len = pparmList->prmlen;
	return cl_conv_const_n_str(pInfoParm,prp,len);
}

int cl_conv_const_n_str(pInfoParm,prp,len)
tdtInfoParm *pInfoParm;
char *prp;
int	len;
{
	int	rc,opt,iAttr[4],iVal;
	double dValue;
	long   lValue,lValz[NMPA_LONG],*lVal;

	opt = pGlobTable->options[16];
	iAttr[0] = 0;
	lVal = cl_get_tmpMPA(lValz);
	if ((rc=cl_conv_const_nsub(prp,len,lVal,"cl_conv_const_n_str: ",iAttr,opt)) < 0) return rc;
	else if (rc > 0) return ECL_SCRIPT_ERROR;
	if (iAttr[0] == DEF_ZOK_FLOA) {
		memcpy(&dValue,lVal,sizeof(double));
		cl_set_parm_double(pInfoParm,dValue);
	}
	else if (iAttr[0] == DEF_ZOK_DECI) {
		cl_set_parm_mpa(pInfoParm,lVal);
		if (iAttr[1] < 0) pInfoParm->pi_alen = D_AULN_OVERFLOW;
	}
	else {
#if defined(_LP64)
		if (iAttr[1] == sizeof(long))
			cl_set_parm_long(pInfoParm,lVal[0]);
		else {
			iVal = lVal[0];
			cl_set_parm_int(pInfoParm,iVal);
		}
#else
		cl_set_parm_long(pInfoParm,lVal[0]);
#endif
		if (iAttr[2] & AKX_NUM_U) pInfoParm->pi_scale |= D_DATA_UNSIGNED;
	}
	pInfoParm->pi_aux[1] = D_AUX1_PROTECTED;

	return NORMAL;
}

int cl_conv_const_nsub(p0,len0,pValue,pMsg,iAttr,opt)
char *p0;
int  len0;
long *pValue;
char *pMsg;
int  iAttr[];
int  opt;
{
	int	i,rc,len;
	char *prp,*prp2,c,cValue[33];

	prp = p0;
	len = len0;
/*
printf("cl_conv_const_nsub: prp=[%s] len=%d opt=%d\n",prp,len,opt);
*/
	if (prp && len) {
		i = akxnskipin(prp,len," \t");
		prp += i;
		len = akxnrskipin(prp,len-i," \t");
/*
printf("cl_conv_const_nsub: i=%d len=%d\n",i,len);
*/
	}
	rc = cl_conv_const_mpasub(prp,len,pValue,pMsg,iAttr,opt & ~AKX_CNVN_OPT_DOUBLE);
	return rc;
}

int cl_set_parm_bin(pInfoParm,iValue)
tdtInfoParm *pInfoParm;
int iValue;
{
	cl_set_parm_long(pInfoParm,(long)iValue);
	return 0;
}

int cl_set_parm_int(pInfoParm,iValue)
tdtInfoParm *pInfoParm;
int iValue;
{
#if defined(_LP64)
	long lVal;
	int *p;

	lVal = 0;
	p = (int *)&lVal;
	*p = iValue;
	cl_set_parm_long(pInfoParm,lVal);
	pInfoParm->pi_dlen = sizeof(int);
#else
	cl_set_parm_long(pInfoParm,(long)iValue);
#endif
	return 0;
}

/**************************************************************
 D_DATA_LPOSDATA(0x40)を立てるときは、pi_posにlongで保持する。
**************************************************************/
int cl_set_parm_long(pInfoParm,lValue)
tdtInfoParm *pInfoParm;
long lValue;
{
	memset(pInfoParm,0,sizeof(tdtInfoParm));
	pInfoParm->pi_id = ' ';
	pInfoParm->pi_attr = DEF_ZOK_BINA;
	pInfoParm->pi_scale= D_DATA_LPOSDATA;
	pInfoParm->pi_pos  = lValue;
	pInfoParm->pi_dlen = sizeof(long);
	pInfoParm->pi_data = (char *)&(pInfoParm->pi_pos);
	return 0;
}

int cl_set_parm_double(pInfoParm,dValue)
tdtInfoParm *pInfoParm;
double dValue;
{
/*
printf("cl_set_parm_double: dValue=%f\n",dValue);
*/
	memset(pInfoParm,0,sizeof(tdtInfoParm));
	pInfoParm->pi_id = ' ';
	pInfoParm->pi_attr = DEF_ZOK_FLOA;
	pInfoParm->pi_scale= D_DATA_LPOSDATA;
	memcpy(&pInfoParm->pi_pos,&dValue,sizeof(double));
	pInfoParm->pi_dlen = sizeof(double);
	pInfoParm->pi_data = (char *)&(pInfoParm->pi_pos);
	return 0;
}

int cl_set_parm_mpa(pInfoParm,val)
tdtInfoParm *pInfoParm;
MPA *val;
{
	char *p;

	memset(pInfoParm,0,sizeof(tdtInfoParm));
	if (!(p=cl_tmp_const_malloc(sizeofMPA()))) return -1;
	if (!val) val = m_get_i(0);
	memcpy(p,val,sizeofMPA());
	pInfoParm->pi_id = ' ';
	pInfoParm->pi_attr = DEF_ZOK_DECI;
	pInfoParm->pi_scale= 0;
	pInfoParm->pi_dlen = sizeofMPA();
	pInfoParm->pi_data = p;
	return 0;
}

int cl_conv_const_mpasub(p,len,pValue,pMsg,iAttr,opt)
char *p;
int  len;
long *pValue;
char *pMsg;
int  iAttr[];
int  opt;	/* AKX_CNVN_OPT_DOUBLE = ON:double ２進浮動小数点数, OFF:decimal １０進浮動小数点数  */
{
	static char *_fn_="cl_conv_const_mpasub";
	int rc,attr,k,size,opt17,iUL,iU,iL,iVal,iOVER;
	long lValue;
	double dVal;
	char   buf[33],*pp;
	MPA ma,*pma;
/*
printf("cl_conv_const_mpasub: p=[%s] len=%d opt=%08x iAttr[0]=%d\n",p,len,opt,iAttr[0]);
*/
	iUL = iU = iL = rc = 0;
#if 1	/* 2022.6.17 */
	opt17 = cl_get_option(17,0);
	opt |= opt17;
	k = cl_chk_digit_fopt(10,p,len,opt | AKX_CNVN_OPT_DIGIT | AKX_CNVN_OPT_FU_MPA);
#else
	k = cl_chk_digit_fopt(10,p,len,opt | AKX_CNVN_OPT_DIGIT | AKX_CNVN_OPT_FU_MPA);
	opt17 = cl_get_option(17,0);
#endif
	if (k > 0) {
		iU = k & AKX_NUM_U;
		iL = k & AKX_NUM_L;
		iUL = iU | iL;
		k &= ~AKX_NUM_UL;
	}
/*
printf("cl_conv_const_mpasub: k=%08x iAttr[0]=%d opt17=%04x iUL=%04x\n",k,iAttr[0],opt17,iUL);
*/
	if (iU) len--;
	if (iL) len--;
	if (k==8) {
		if (iAttr[0]==3) k = 1;
#if 1	/* 2022.2.7 */
		else if (iAttr[0]==4) k = 2;
		else if (iAttr[0]==2 && !(opt17 & 0x80)) k = 2;
#else
		else if (iAttr[0]==4 || (opt17 & 0x80)) k = 2;
#endif
		else k = 0;
	}
	if (k==2 &&
	         ((opt & AKX_CNVN_OPT_DOUBLE) || (opt17 & 0x01))) k = 1;
/*
printf("cl_conv_const_mpasub: modified k=%d\n",k);
*/
	if (k == 2) {
		pma = (MPA *)pValue;
		if (rc=m_set_an_opt(pma,p,len,opt)) {
/*
printf("cl_conv_const_mpasub:m_set_an_opt: rc=%d\n",rc);
*/
			if (iU) {
				pma->sign = 0;
			}
			rc = cl_chk_error_mpa(rc,pMsg,p,len);
		}
		attr = DEF_ZOK_DECI;
		size = sizeofMPA();
	}
	else if (k == 1) {
#if 1	/* 2022.6.17 */
		if (opt & AKX_CNVN_OPT_COMMA) {
			pp = cl_tmp_const_malloc(len+1);
			len = akxcreplace_char2(pp,len,p,len,',','\0');
			*(pp+len) = '\0';
/*
printf("cl_conv_const_mpasub: len=%d pp=[%s]\n",len,pp);
*/
			p = pp;
		}
#endif
		if (rc=akxccvd(p,len,&dVal)) {
			if (rc>0 && (opt & 0x10)) 
				rc = 0;
			else {
				if (pMsg=cl_conv_msg_check(pMsg,rc)) {
					memnzcpy(buf,p,len,sizeof(buf));
							/* %s２進浮動小数点数[%s]の指定が誤っています(rc=%d)。 */
					ERROROUT3(FORMAT(307),pMsg,buf,rc);
				}
				if (rc < -10) rc = -rc/10;
			}
		}
		memcpy((char *)pValue,&dVal,sizeof(double));
		attr = DEF_ZOK_FLOA;
		size = sizeof(double);
	}
	else if (k == -6) {
		ERROROUT1(FORMAT(624),_fn_);	/* %s: 指数部が誤っています。*/
		rc = ECL_SCRIPT_ERROR;
	}
	else if (k == -7) {
		ERROROUT1(FORMAT(625),_fn_);	/* %s: 符号が重複しています。*/
		rc = ECL_SCRIPT_ERROR;
	}
	else {
		if (!(opt17 & 0x02)) {
			iUL |= AKX_NUM_L;
			iL = AKX_NUM_L;
		}
#if 1	/* 2022.6.17 */
		if (opt & AKX_CNVN_OPT_COMMA) {
			pp = cl_tmp_const_malloc(len+1);
			len = akxcreplace_char2(pp,len,p,len,',','\0');
			*(pp+len) = '\0';
/*
printf("cl_conv_const_mpasub: len=%d pp=[%s]\n",len,pp);
*/
			p = pp;
		}
#endif
		/*  2147483648 は、オーバーフローする
		   -2147483648 は、オーバーフローしない */
		rc = cl_cvn10(p,len,&lValue,iUL);
#if defined(_LP64)
		if (!iL) {
			if (iU) rc = akx_chk_uint_over(lValue,&iVal);
			else rc = akx_chk_int_over(lValue,&iVal);
			lValue = iVal;
/*
printf("cl_conv_const_mpasub: rc=%d lValue=%ld\n",rc,lValue);
*/
		}
#endif
		if (rc == -3) {	/* add 2021.9.24 */
			pma = (MPA *)pValue;
			m_set_an_opt(pma,p,len,opt);
			attr = DEF_ZOK_DECI;
			size = sizeofMPA();
			rc = 0;
#if 1	/* 2022.2.7 */
			/* 2147483648 は、decに変換し、オーバーフローさせないが
			   オーバーフローした印として -size とする。
			   (-(2147483648)を単項演算時に、intに戻すため) */
			iOVER = 1;
			if (!iU) {
				if ((iL && !m_cmp_a(pma,m_get_LONGMAX(-1))) ||	/* add 2021.9.26 */
				    (!iL && !m_cmp_a(pma,m_get_INTMAX(-1)))) {
						size = -size;	/* add 2022.2.12 */
					iOVER = 0;
				}
			}
/*
printf("cl_conv_const_mpasub: iOVER=%d size=%d\n",iOVER,size);
*/
			if (iOVER) {
/*
printf("cl_conv_const_mpasub:m_set_an_opt: opt17=%04x\n",opt17);
*/
				if (opt17 & 0x80) {
							/* (W)(%d)[%s]オーバフローしました。 */
					ERROROUT2(FORMAT(265),len,strtemp(p,len));
					rc = 0;
					if (iL) size = sizeof(long);
					else size = sizeof(int);
					attr = DEF_ZOK_BINA;
					*pValue = lValue;
				}
				else {
					if (iU) pma->sign = 0;
				}
			}
#else
			if (iU) pma->sign = 0;
			else if (!m_cmp_a(pma,m_get_INTMAX(-1))) size = -size;	/* add 2021.9.26 */
#if 0
			else {
				/* (W)(%d)[%s]オーバフローしました。 */
				ERROROUT2(FORMAT(265),len,buf);
				rc = 0;
			}
#endif
#endif
		}
		else {
			if (opt & 0x10) 
				rc = 0;
			else if (rc > 0) {
				if (pMsg=cl_conv_msg_check(pMsg,rc)) {
					/* %s数字以外の文字[%s]があります(pos=%d)。 */
					ERROROUT3(FORMAT(306),pMsg,strtemp(p,len),rc);
				}
				else rc = 0;
			}
			if (iL) size = sizeof(long);
			else size = sizeof(int);
			attr = DEF_ZOK_BINA;
			*pValue = lValue;
/*
printf("cl_conv_const_mpasub: size=%d lValue=%ld\n",size,lValue);
*/
		}
	}
	iAttr[0] = attr;
	iAttr[1] = size;
	iAttr[2] = iUL;
/*
printf("cl_conv_const_mpasub:Exit rc=%d attr=%d size=%d iUL=%04x\n",rc,attr,size,iUL);
*/
	return rc;
}

int cl_conv_const_double(p,len,pValue,pMsg,iAttr)
char *p;
int  len;
long *pValue;
char *pMsg;
int  iAttr[];
{
	return cl_conv_const_mpasub(p,len,pValue,pMsg,iAttr,AKX_CNVN_OPT_DOUBLE);
}

char *cl_conv_msg_check(pMsg,rc)
char *pMsg;
int rc;
{
	char c;

	if (pMsg) {
		if ((c=*pMsg)=='-') {
			if (rc >= 0) pMsg = NULL;
			else pMsg++;
		}
		else if (c=='+') {
			if (rc <= 0) pMsg = NULL;
			else pMsg++;
		}
	}
	return pMsg;
}

/****************************************/
/*										*/
/****************************************/
int cl_cvn10(p,len,pvalue,iUL)
char *p;
int  len,iUL;
long *pvalue;
{
	int rc;
	char buf[65];
	long lVal;

	if (len<0) {
		ERROROUT(FORMAT(262));	/* 文字列長が負です。 */
		rc = ECL_SYSTEM_ERROR;
	}
	else if (len == 0) {
		*pvalue = 0;
		rc = 0;
	}
	else {
	/*
		if (iUL & AKX_NUM_U) len--;
		if (iUL & AKX_NUM_L) len--;
	*/
		if (cl_get_option(17,0) & 0x100) iUL |= AKX_NUM_U;	/* add 2022.4.2 */
		rc = akxcgcvlu(p,len,&lVal,iUL & AKX_NUM_U);
		if (rc) {
			memnzcpy(buf,p,len,sizeof(buf));
				/* (%d)[%s]数字がありません。 */
			if      (rc == -1) ERROROUT2(FORMAT(263),len,buf);
				/* (%d)[%s]進数が不正です。 */
			else if (rc == -2) ERROROUT2(FORMAT(264),len,buf);
#if 0	/* 2021.9.24 */
			else if (rc == -3) {
				/* (W)(%d)[%s]オーバフローしました。 */
				ERROROUT2(FORMAT(265),len,buf);
				rc = 0;
			}
#endif
		}
/*
printf("cl_cvn10: iUL=%02x lVal=%d rc=%d\n",iUL,lVal,rc);
*/
		*pvalue = lVal;
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
long *cl_get_tmpMPA(long *az)
{
	return cl_get_tmpMPA2(az,1);
}

/****************************************/
/*										*/
/****************************************/
long *cl_get_tmpMPA2(long *az,int m)
{
	long *a;

	if (m_get_nmpa10() <= NMPA10) a = az;
	else {
		if (m <= 0) m = 1;
		a = (long *)cl_tmp_const_malloc(sizeofMPA()*m+sizeof(long));
	}
	return a;
}

/****************************************/
/*										*/
/****************************************/
long *cl_get_tmpMPA10W2(long *az,int m)
{
	long *a;

	if (m_get_nmpa10() <= NMPA10) a = az;
	else {
		if (m <= 0) m = 1;
		a = (long *)cl_tmp_const_malloc(sizeofMPA10W()*m+sizeof(long));
	}
	return a;
}
