static	char	sccsid[]="%Z% %M% %I% %E% %U%";
/******************************************************************************
*                                                                             *
*      処理目的　　：  配列処理                                               *
*                                                                             *
*                                                                             *
*      処理概要　　：　                                                       *
*                                                                             *
******************************************************************************/
#include <colmn.h>

extern CLPRTBL  *pGLprocTable;
extern CLPRTBL  *pCLprocTable;
extern GlobalCt *pGlobTable;
extern CLCOMMON CLcommon;
extern int giOptions[];

/****************************************/
/*										*/
/****************************************/
int cl_get_array_index(pInfoParm,ppIndex)
tdtInfoParm *pInfoParm;
tdtArrayIndex **ppIndex;
{
	char c;
	int  rc;

	if (!pInfoParm || !ppIndex) return -1;
	*ppIndex = NULL;
	if (((c=pInfoParm->pi_id)=='A' || c=='R') &&
		pInfoParm->pi_dlen == sizeof(tdtArrayIndex)) {
		*ppIndex = (tdtArrayIndex *)pInfoParm->pi_data;

DEBUGOUT_InfoParm(194,"cl_get_array_index: ",pInfoParm,0,0);

		rc = 0;
	}
	else rc = ECL_SYSTEM_ERROR;
	return rc;
}

/************************************/
/*									*/
/************************************/
int cl_get_array_psize(pInfoParm,pcn,ppSize,ppTBL)
tdtInfoParm *pInfoParm;
char *pcn;
int **ppSize;
tdtInfoParm ****ppTBL;
{
	int opt;
	char cn,*name;

	cn = '\0';
	opt = 0;
	if (pInfoParm->pi_aux[1] & D_AUX1_LOCAL_VAR) opt = D_GX_OPT_SET_LOCAL;
	if (pInfoParm->pi_id == 'A') {
		name = (char *)pInfoParm->pi_pos;
/*
printf("cl_get_array_psize: name=[%s]\n",name);
*/
		cn = *name;
		if (cn!='%' && cn!='#') cn = '$';
	}
	if (pcn) *pcn = cn;
	return cl_def_get_psize(cn,NULL,NULL,opt,ppSize,ppTBL);
}

/****************************************/
/*										*/
/****************************************/
int cl_update_map_array_max(pInfoParm)
tdtInfoParm *pInfoParm;
{
	int rc,*pSize,*index,m;
	char cn;
	tdtArrayIndex *pIndex;

	rc = 0;
	if (pInfoParm->pi_id == 'A') {
		if ((rc=cl_get_array_psize(pInfoParm,&cn,&pSize,NULL)) >= 0) {
			rc = 0;
			if (cn=='$' || cn=='%') {
				pIndex = (tdtArrayIndex *)pInfoParm->pi_data;
				index = pIndex->index;
				if ((m=pSize[7]-index[3]+1) > index[2]) index[2] = m;
/*
printf("cl_update_map_array_max: index[2]=%d\n",index[2]);
*/
				if (index[2] < 0) index[2] = 0;
			}
		}
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
int cl_get_array_index_tbl(pInfoParm,pIndex,ppTBL,pMsg)
tdtInfoParm *pInfoParm;
tdtArrayIndex *pIndex;
tdtInfoParm ****ppTBL;
char *pMsg;
{
	int iRc;
#if 1	/* 2021.6.14 */
	tdtArrayIndex *pIndexW,**ppIndex;

	if (pIndex) {
		pIndexW = pIndex;
		ppIndex = &pIndexW;
	}
	else ppIndex = NULL;
	if (!(iRc=cl_get_array_index_tbl_ref(pInfoParm,ppIndex,ppTBL,pMsg))) {
		if (pIndex && pIndexW!=pIndex) memcpy(pIndex,pIndexW,sizeof(tdtArrayIndex));
	}
#else
	tdtArrayIndex *pIndexW;

	pIndexW = pIndex;
	if (!(iRc=cl_get_array_index_tbl_ref(pInfoParm,&pIndexW,ppTBL,pMsg))) {
		if (pIndexW != pIndex) memcpy(pIndex,pIndexW,sizeof(tdtArrayIndex));
	}
#endif
	return iRc;
}

/********1*********2*********3*********4*********5*********6*********7*/
/*	引数：	pInfoParm : 配列情報 or Mapp Index						  */
/*						Aのときは、index[2]を更新する。				  */
/*			ppIndex : = NULLのとき、pInfoは返さない。				  */
/*					  <>NULLのとき、*ppIndex には、&tIndex が、		  */
/*					    設定されていること							  */
/*					  *ppIndex には、A or R のとき、				  */
/*						配列のpIndexが返される。					  */
/*					  A,R 以外のときは、以下が入る					  */
/*						index[1]:Mapp Indexから配列の最大要素までの数 */
/*						index[3]:Mapp Index							  */
/*			ppTBL	: <>NULLのとき、								  */
/*						Mapp Index時の配列域へのポインタが返る		  */
/*			pMsg	: 呼び元等のコメント							  */
/*					  = NULLのときは、下位で呼ばれる関数名になる	  */
/**********************************************************************/
int cl_get_array_index_tbl_ref(pInfoParm,ppIndex,ppTBL,pMsg)
tdtInfoParm *pInfoParm;
tdtArrayIndex **ppIndex;
tdtInfoParm ****ppTBL;
char *pMsg;
{
	static char *_fn_ = "cl_get_array_index_tbl_ref";
	ScrPrCT	*pScCT;
	ProcCT  *proc;
	int *index;
	tdtInfoParm ***pTBL,*pInfo;
	tdtArrayIndex *pIndex,tIndex;
	int iRc,*pSize,m,tSize[4],opt;
	char c,*name,cn;

DEBUGOUT_InfoParm(191,"cl_get_array_index_tbl_ref:Enter: ",pInfoParm,0,0);
DEBUGOUTL4(191,"%s:Enter: ppIndex=%08x ppTBL=%08x pMsg=[%s]",_fn_,ppIndex,ppTBL,pMsg);

	cn = '\0';
	pTBL = NULL;
	pSize = NULL;
	if (ppTBL) *ppTBL = pTBL;
#if 1	/* 2021.6.14 */
	if (ppIndex) {
		pIndex = *ppIndex;
		if (pInfoParm->pi_data != (char *)pIndex) memset(pIndex,0,sizeof(tdtArrayIndex));
	}
	else {
		pIndex = &tIndex;
		memset(pIndex,0,sizeof(tdtArrayIndex));
	}
#else
	if (!ppIndex) return -1;
	pIndex = *ppIndex;
	if (pInfoParm->pi_data != (char *)pIndex) memset(pIndex,0,sizeof(tdtArrayIndex));
#endif
	if ((c=pInfoParm->pi_id) != 'R') {
#if 1	/* 2021.6.14 */
		if ((iRc=cl_get_array_psize(pInfoParm,&cn,&pSize,&pTBL)) < 0) return iRc;
		if (ppTBL) *ppTBL = pTBL;
#else
		if (pScCT = cl_search_src_ct()) {
			pTBL = pScCT->Vary->pTBL_dolu;
			if (c == 'A') {
				name = (char *)pInfoParm->pi_pos;
/*
printf("cl_get_array_index_tbl_ref: name=[%s]\n",name);
*/
				if ((cn=*name) == '#')
					pTBL = pScCT->Vary->pTBL_igeta;
				else if (cn == '%') {
					if (pInfoParm->pi_aux[1] & D_AUX1_LOCAL_VAR) {
						if (!(proc = cl_search_proc_ct())) return SysError;
						pTBL = proc->pTBL_pasento;
					}
					else
						pTBL = pScCT->Vary->pTBL_pasento;
				}
				else cn = '$';
			}
			if (ppTBL) *ppTBL = pTBL;
			pSize = (int *)pTBL[0];
DEBUGOUTL5(191,"%s: pSize = %d %d %d [%s]",_fn_,pSize[0],pSize[1],pSize[2],&pSize[3]);
DEBUGOUTL2(191,"                                    %d %d",pSize[5],pSize[6]);
		}
		else return -1;
#endif
	}
	else if (c == 'R') {
		if (pInfo=(tdtInfoParm *)pInfoParm->pi_paux) {
			if (pInfo->pi_id != 'R') {
				if (!(name=(char *)pInfoParm->pi_pos)) name = AKX_NULL_PRINT;
				/* %s: コピー元の配列[%s]が無効です。 */
				ERROROUT2(FORMAT(231),_fn_,name);
				return ECL_SCRIPT_ERROR;
			}
		}
		pSize = tSize;
	}
	index = pIndex->index;
/*
printf("cl_get_array_index_tbl_ref:1 pIndex=%08x Index=%08x\n",pIndex,index);
*/
DEBUGOUTL5(191,"cl_get_array_index_tbl_ref:1 index = %d %d %d %d %d",
index[0],index[1],index[2],index[3],index[4]);

	if (c == 'A' || c == 'R') {
		if (iRc = cl_get_array_index(pInfoParm,&pIndex)) return iRc;
		if (ppIndex) *ppIndex = pIndex;
		index = pIndex->index;
/*
printf("cl_get_array_index_tbl_ref:2 pIndex=%08x Index=%08x index[2]=%d\n",pIndex,index,index[2]);
*/
	}
	else {
		if (iRc = cl_get_parm_bin(pInfoParm,index+3,pMsg)) return iRc;
		index[1] = pSize[2] - (index[3] - 1);
	}

DEBUGOUTL5(191,"cl_get_array_index_tbl_ref:2 index = %d %d %d %d %d",
index[0],index[1],index[2],index[3],index[4]);

	if ((c=='R' && index[3]<0) ||
	    (c!='R' && (index[3]<=0 || index[3]>pSize[2]))) {
		ERROROUT1(FORMAT(232),index[3]);	/* インデックスの初期値(%d)が不正です。 */
		return -1;
	}
	/* mappedarray のときは、map 元のpSize[7]が自分より大きかったら反映する。*/
	if (c=='A' && pSize && (cn=='$' || cn=='%' || cn=='#')) {
/*
printf("cl_get_array_index_tbl_ref:reflect pSize[7]=%d index[2]=%d index[3]=%d\n",pSize[7],index[2],index[3]);
*/
		if ((m=pSize[7]-index[3]+1) > index[2]) index[2] = m;
/*
printf("cl_get_array_index_tbl_ref:reflect index[2]=%d\n",index[2]);
*/
DEBUGOUTL5(191,"cl_get_array_index_tbl_ref:3 index = %d %d %d %d %d",
index[0],index[1],index[2],index[3],index[4]);
	}
/*
printf("cl_get_array_index_tbl_ref: index=%d %d %d %d %d %d\n",
index[0],index[1],index[2],index[3],index[4],index[5]);
*/
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_check_use_mapped_array(pInfoParm)
tdtInfoParm *pInfoParm;
{
	char *name,c;

	if (pInfoParm->pi_id == 'A') {
		name = (char *)pInfoParm->pi_pos;
/*
printf("cl_check_use_mapped_array: name=[%s]\n",name);
*/
		if ((c=*name)=='%' || c=='#') {
			ERROROUT1(FORMAT(233),name);	/* 指定できない配列名(%s)です。 */
			return -1;
		}
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_check_use_hash_array(pInfoParmArray,pIndex)
tdtInfoParm *pInfoParmArray;
tdtArrayIndex *pIndex;
{
	if (pIndex->xhp ||
	    (pInfoParmArray->pi_id=='R' && (pIndex->index[2] < 0))) {
		/* cl_check_use_hash_array: can't use hash array[%s]!! */
		ERROROUT1(FORMAT(234),(char *)pInfoParmArray->pi_pos);
		return -1;
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
tdtInfoParm *cl_get_array_and_var_ent_opt(pIndex,pTBL,ix,opt)
tdtArrayIndex *pIndex;
tdtInfoParm ***pTBL;
int  ix;
char opt;
{
	int iRc,attr,attr0,iParm[4],*index;
	tdtInfoParm *pInfoParm,rInfoParm;

DEBUGOUTL4(194,"cl_get_array_and_var_ent_opt:Enter: pIndex=%08x pTBL=%08x ix=%d opt=%c",pIndex,pTBL,ix,opt)
	pInfoParm = NULL;
	if (pTBL)
		pInfoParm = cl_get_var_ent_opt(pTBL,ix,opt);
	else if (pIndex) {
		attr = pIndex->uAttr[0];
DEBUGOUTL1(194,"cl_get_array_and_var_ent_opt: attr=%d",attr)
		if (attr) {
			attr0 = 0;
			if ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK) && !pIndex->size) {
				attr0 = attr;
				attr = DEF_ZOK_VARI;

DEBUGOUTL3(194,"cl_get_array_and_var_ent_opt: ix=%d opt=%c attr0=%d",ix,opt,attr0);

			}
#if 1	/* 2021.11.23 */
			else if (attr & 0x10) {
				attr0 = attr;
				attr = DEF_ZOK_VARI;
			}
#endif
			if (attr == DEF_ZOK_VARI) {
				pInfoParm = cl_get_array_ent_opt(pIndex->pVarIndex,ix,opt);
				if (pInfoParm) {
DEBUGOUT_InfoParm(194,"cl_get_array_and_var_ent_opt: attr0=%d",pInfoParm,attr0,0);
					if (attr0 && !(pInfoParm->pi_aux[0] & ~DEF_ZOK_DATA)) {
						iParm[0] = attr0;
						iParm[1] = 0;
						cl_set_parm_init(pInfoParm,iParm,0x01);
					}
				}
			}
			else {
				if (!cl_get_array_val_opt(&rInfoParm,pIndex,ix,'s'))
					pInfoParm = (tdtInfoParm *)rInfoParm.pi_pos;
			}
			if (pInfoParm && opt=='s') {
				index = pIndex->index;

DEBUGOUTL3(194,"cl_get_array_and_var_ent_opt: index=%08x ix=%d index[2]=%d",index,ix,index[2]);

				index[2] = X_MAX(index[2],ix);
/*
printf("cl_get_array_and_var_ent_opt: opt=%c index=%08x ix=%d index[2]=%d\n",opt,index,ix,index[2]);
*/
			}
		}
	}

	return pInfoParm;
}

/****************************************/
/*										*/
/****************************************/
tdtInfoParm *cl_get_array_and_var_ent(pIndex,pTBL,ix)
tdtArrayIndex *pIndex;
tdtInfoParm ***pTBL;
int  ix;
{
	return cl_get_array_and_var_ent_opt(pIndex,pTBL,ix,'s');
}

/****************************************/
/*										*/
/****************************************/
int cl_gx_conv_index(pInfoParm,pIndex)
tdtInfoParm *pInfoParm;
tdtArrayIndex *pIndex;
{
	tdtArrayIndex tIndex;
	int  attr,i,ji_1,mx,iSTART,iIXPOS,f,m1,m2;
	int  n,*index,*index_info,nn,iRANGE,ndim,nn1,nn2;
	char c,*varnam;

	if (!pInfoParm || !pIndex) return ECL_SYSTEM_ERROR;
	c = pInfoParm->pi_id;
	n = pInfoParm->pi_dlen;
/*
printf("cl_gx_conv_index: pInfoParm->pi_id=%c len=%d\n",c,n);
*/
    if ((n == sizeof(tdtArrayIndex)) && ((c == 'A') || (c == 'R'))) {
		if (!pInfoParm->pi_data) return ECL_SYSTEM_ERROR;
		memcpy(&tIndex,pInfoParm->pi_data,n);
		pIndex->pVarIndex = tIndex.pVarIndex;
		pIndex->size = tIndex.size;
		memcpy(pIndex->uAttr,tIndex.uAttr,sizeof(pIndex->uAttr));
		pIndex->xhp = tIndex.xhp;
	}
	else return ECL_SYSTEM_ERROR;

	index = tIndex.index;

DEBUGOUTL5(191,"cl_gx_conv_index: index[0]..[4] = %d %d %d %d %d",
index[0],index[1],index[2],index[3],index[4]);
DEBUGOUTL5(191,"cl_gx_conv_index: index[5]..[9] = %d %d %d %d %d",
index[5],index[6],index[7],index[8],index[9]);

	index_info = pIndex->index;	/* 指定された各次元のインデックス */

DEBUGOUTL5(191,"cl_gx_conv_index: index_info[0]..[4] = %d %d %d %d %d",
index_info[0],index_info[1],index_info[2],index_info[3],index_info[4]);
DEBUGOUTL5(191,"cl_gx_conv_index: index_info[5]..[9] = %d %d %d %d %d",
index_info[5],index_info[6],index_info[7],index_info[8],index_info[9]);

	ndim = index[0];
	ji_1 = X_MIN(index_info[0],ndim);
	iSTART = pGlobTable->options[14] & 0x01;
	iIXPOS = pGlobTable->options[14] & 0x02;
	mx = ji_1;
	if (!(varnam=(char *)pInfoParm->pi_pos)) varnam = AKX_NULL_PRINT;
	for (i=1;i<=ndim;i++) {
		if (i <= ji_1) {
			n = index_info[i+3];
			nn = index[i+3];
			if (nn <= 0) {
				/* cl_gx_conv_index:[%s]のインデックスサイズが0です。i=%d index=%d (def=None) */
				ERROROUT3(FORMAT(235),varnam,i,n);
				return ECL_SCRIPT_ERROR;
			}
			m1 = 0;
			m2 = nn - 1;
				m1 = index[i+ndim+3];
				m2 += m1;
			if (n<m1 || n>m2) {
				/* cl_gx_conv_index:[%s]のインデックスが範囲外です。i=%d index=%d (def=%d..%d) */
				ERROROUT5(FORMAT(236),varnam,i,n,m1,m2);
				return ECL_SCRIPT_ERROR;
			}
		}
		else if (index[i+3] > 1) mx = i;
	}
/*
printf("cl_gx_conv_index: mx=%d ji_1=%d\n",mx,ji_1);
*/
	if (ji_1 > 0) {
		if (iIXPOS) {
			n = index_info[mx+3];
			n -= index[mx+ndim+3];
			for (i=1;i<mx;i++) {
				nn = index_info[mx-i+3];
				nn -= index[mx-i+ndim+3];
/*
printf("cl_gx_conv_index: i=%d n=%d nn=%d f=%x\n",i,n,nn,f);
*/
				n = n*index[mx-i+3] + nn;
			}
		}
		else {
			n = index_info[4];
			n -= index[1+ndim+3];
			for (i=2;i<=mx;i++) {
/*
printf("cl_gx_conv_index: i=%d n=%d\n",i,n);
*/
				nn = index_info[i+3];
				nn -= index[i+ndim+3];
				n = n*index[i+3] + nn;
			}
		}
	}
/*
printf("cl_gx_conv_index: n=%d index[3]=%d\n",n,index[3]);
*/
	return n + index[3];
}

/****************************************/
/*										*/
/****************************************/
tdtInfoParm *cl_get_array_ent_opt(pVarIndex,iParmNo,opt)
tdtInfoParm *pVarIndex[];
int iParmNo;
char opt;
{
	tdtInfoParm *pDummy;

	if (!pVarIndex) return NULL;

	if (!(pDummy = pVarIndex[--iParmNo])) {
		if (opt == 's' || (pGlobTable->options[0] & 0x01)) {
			if (pDummy=(tdtInfoParm *)Malloc(sizeof(tdtInfoParm))) {
				memset(pDummy,0,sizeof(tdtInfoParm));
				pVarIndex[iParmNo] = pDummy;
				if (pGlobTable->options[0] & 0x01) cl_null_data(pDummy);
			}
		}
	}
	return pDummy;
}

/****************************************/
/*										*/
/****************************************/
tdtInfoParm *cl_get_array_ent(pVarIndex,iParmNo)
tdtInfoParm *pVarIndex[];
int iParmNo;
{
	return cl_get_array_ent_opt(pVarIndex,iParmNo,'s');
}

/****************************************/
/*										*/
/****************************************/
int cl_free_array_ent(pIndex)
tdtArrayIndex *pIndex;
{
	tdtInfoParm *cpDat,**pVarIndex,**p,*pDummy;
	int *index;
	int i,n,ix,k,maxreg,attr;
	XHASHB *xhp;

	if ((xhp=(XHASHB *)pIndex->xhp)) {
		maxreg = akxs_xhash(xhp,'m',NULL);
		for (k=1;k<=maxreg;k++) {
			xhp->xha_xhix = k;
			ix = akxs_xhash2(xhp,'k',NULL,&cpDat);
			if (ix > 0) {
				memcpy(&pDummy,cpDat,sizeof(tdtInfoParm *));
				if (pDummy) {
					cl_free_info_parm(pDummy);
					Free(pDummy);
				}
			}
		}
		akxs_xhash_free(xhp);
		pIndex->xhp = NULL;
		if (pVarIndex = pIndex->pVarIndex) {
			if (!(pIndex->uAttr[1] & D_ATR1_NO_MALLOC)) Free(pVarIndex);
			pIndex->pVarIndex = NULL;
		}
	}
	else if (pVarIndex = pIndex->pVarIndex) {
		if (((attr=pIndex->uAttr[0])==DEF_ZOK_VARI) ||
		    ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK) && !pIndex->size)) {
			index = pIndex->index;
			n = index[1];
			for (i=0,p=pVarIndex;i<n;i++,p++) {
				if (pDummy = *p) {
					cl_free_info_parm(pDummy);
					Free(pDummy);
				}
			}
		}
/*
printf("cl_free_array_ent: pIndex->uAttr[1]=%08x\n",pIndex->uAttr[1]);
*/
		if (!(pIndex->uAttr[1] & D_ATR1_NO_MALLOC)) Free(pVarIndex);
		pIndex->pVarIndex = NULL;
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_get_array_val_opt(pInfoParmW,pIndex,iParmNo,opt)
tdtInfoParm *pInfoParmW;
tdtArrayIndex *pIndex;
int iParmNo;
char opt;
{
	tdtInfoParm *pInfoParm, *pParm;
	char *p,*pp;
	int *pi,val,attr,len,size,*index;
	double *pd;

	if (!pIndex) return -1;
	attr = pIndex->uAttr[0];
	size = pIndex->size;
DEBUGOUTL2(194,"cl_get_array_val_opt: attr=%d size=%d",attr,size);
	if (!attr) {
		/* cl_get_array_val_opt: can't use hash arrray!! */
		ERROROUT(FORMAT(237));
		return ECL_SCRIPT_ERROR;
	}
	p = (char *)pIndex->pVarIndex;
	iParmNo--;
	if (opt == 's') {
		if (!(pInfoParm=(tdtInfoParm *)cl_tmp_const_malloc(sizeof(tdtInfoParm))))
			return ECL_SYSTEM_ERROR;
		pParm = pInfoParm;
	}
	else if (!(pParm = pInfoParmW)) return -1;

	if (attr == DEF_ZOK_BINA) {
		pp = (char *)&((int *)p)[iParmNo];
		cl_set_parm_bin(pParm,*(int *)pp);
	}
	else if (attr == DEF_ZOK_FLOA) {
		pp = (char *)&((double *)p)[iParmNo];
		cl_set_parm_double(pParm,*(double *)pp);
	}
	else if (attr == DEF_ZOK_DECI) {
#if 1	/* 2021.10.11 */
		pp = p + iParmNo*sizeofMPA();
		memset(pParm,0,sizeof(tdtInfoParm));
		pParm->pi_id = ' ';
		pParm->pi_attr = DEF_ZOK_DECI;
		pParm->pi_dlen = sizeofMPA();
		pParm->pi_data = pp;
#else
		pp = (char *)&((MPA *)p)[iParmNo];
		cl_set_parm_mpa(pParm,(MPA *)pp);
#endif
		pParm->pi_hlen = pIndex->uAttr[2];	/* precision */
		pParm->pi_pos = pIndex->uAttr[3];	/* scale */
	}
	else if (attr == DEF_ZOK_CHAR) {
		pp = p + iParmNo*(size+1);
		*(pp+size) = '\0';
		cl_set_parm_char(pParm,pp,strlen(pp));
	}
	else if (attr == DEF_ZOK_DATE) {
#if 1	/* 2021.10.11 */
		pp = p + iParmNo*sizeofMPA();
#else
		pp = (char *)&((MPA *)p)[iParmNo];
#endif
		cl_set_parm_date(pParm,(MPA *)pp);
	}
	else if (attr == DEF_ZOK_BULK) {
		pp = p + iParmNo*(size+sizeof(int));
		memcpy(&len,pp+size,sizeof(int));
		cl_set_parm_char(pParm,pp,len);
		pParm->pi_attr = attr;
	}
DEBUGOUTL2(194,"cl_get_array_val_opt: p=%08x pp=%08x",p,pp);
DEBUGOUT_InfoParm(194,"cl_get_array_val_opt: iParm-1=%d opt=%c",pParm,iParmNo,opt);
/*
printf("cl_get_array_val_opt: opt=%c attr=%d pp=%08x\n",opt,attr,pp);
*/
	if (opt == 's') {
		pInfoParm->pi_aux[0] = attr;
		pInfoParm->pi_len = size;
		pInfoParm->pi_paux = pp;
		cl_set_parm_long(pInfoParmW,(long)pInfoParm);
		pInfoParmW->pi_id  = 'S';
DEBUGOUT_InfoParm(194,"cl_get_array_val_opt: ",pInfoParmW,0,0);
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_array_get_info_parm(ppParmI,pIndex1,pTBL1,ix1,opt)
tdtInfoParm **ppParmI;
tdtArrayIndex *pIndex1;
tdtInfoParm ***pTBL1;
int ix1;
char opt;
{
	XHASHB *xhp1;
	tdtInfoParm *pParmI;
	int iRc;
	char *cpKey,*cpDat;

	iRc = 0;
	pParmI = NULL;
	xhp1 = pIndex1->xhp;
DEBUGOUTL1(194,"cl_array_get_info_parm: xhp1=%08x",xhp1);
	if (xhp1) {
		xhp1->xha_xhix = ix1;
		if ((iRc=akxs_xhash2(xhp1,'P',&cpKey,&cpDat)) > 0) {
			memcpy(&pParmI,cpDat,sizeof(tdtInfoParm *));
			xhp1->xha_hashb->ha_key = cpKey;
/*
printf("cl_array_get_info_parm: ix1=%d key=[%s] pParm=%08x\n",ix1,cpKey,pParmI);
*/
		}
	}
	else {
		pParmI = cl_get_array_and_var_ent_opt(pIndex1,pTBL1,ix1,opt);
		iRc = 1;
	}
	*ppParmI = pParmI;
	return iRc;
}

/****************************************/
/*										*/
/****************************************/
int cl_get_array_info(pInfoParm,pIndex,ppTBL,iParm)
tdtInfoParm *pInfoParm;
tdtArrayIndex *pIndex;
tdtInfoParm ****ppTBL;
int iParm[];
{
	tdtArrayIndex *pIndexW;
	int iRc;

	pIndexW = pIndex;
	if (!(iRc=cl_get_array_info_ref(pInfoParm,&pIndexW,ppTBL,iParm))) {
		if (pIndexW != pIndex) memcpy(pIndex,pIndexW,sizeof(tdtArrayIndex));
	}
	return iRc;
}

/********1*********2*********3*********4*********5*******/
/*	引数：	ppIndex : *ppIndex には、&tIndex が、		*/
/*					    設定されていること				*/
/*					  *ppIndex には、A or R のとき、	*/
/*						配列のpIndexが返される。		*/
/*		通常配列:										*/
/*			iParm[1] : 最大要素数						*/
/*			iParm[2] : off_set (配列の開始位置(先頭が1))*/
/*			iParm[3] : 設定済み要素の先頭からの最大位置(先頭が1)*/
/*														*/
/*			iParm[2]〜iParm[3]が*指定で出力される配列のParmNoでの範囲となる */
/*			iParm[3]-iParm[2]+1が出力される個数			*/
/*		HASH配列:										*/
/*			iParm[1] : 最大要素数						*/
/*			iParm[2] : 1								*/
/*			iParm[3] : 設定済み要素数					*/
/********************************************************/
int cl_get_array_info_ref(pInfoParm,ppIndex,ppTBL,iParm)
tdtInfoParm *pInfoParm;
tdtArrayIndex **ppIndex;
tdtInfoParm ****ppTBL;
int iParm[];
{
	int iRc,ix0,*index,offset;
	XHASHB *xhp;
	tdtArrayIndex *pIndex;

	mem_set_int(iParm,0,4);
	pIndex = *ppIndex;
/*
printf("cl_get_array_info_ref:1 pIndex=%08x Index=%08x\n",pIndex,pIndex->index);
*/
	if (pInfoParm->pi_data != (char *)pIndex) memset(pIndex,0,sizeof(tdtArrayIndex));
	if (iRc=cl_get_array_index_tbl_ref(pInfoParm,ppIndex,ppTBL,"cl_get_array_info_ref:")) return iRc;
	if (pIndex = *ppIndex) {
/*
printf("cl_get_array_info_ref:2 pIndex=%08x Index=%08x\n",pIndex,pIndex->index);
*/
		if (pInfoParm->pi_id=='R' && (xhp=pIndex->xhp)) {
			iParm[1] = akxs_xhash2(xhp,'M',NULL,NULL);	/* 最大要素数 */
			iParm[2] = 1;								/* Hash Indexの開始番号 */
			iParm[3] = akxs_xhash2(xhp,'U',NULL,NULL);	/* 設定済み要素数 */
		}
		else {
			index = pIndex->index;
/*
printf("cl_get_array_info_ref: index=%08x index[1]..[3] =%d %d %d\n",index,index[1],index[2],index[3]);
*/
			iParm[1] = index[1];	/* 最大要素数 */
			iParm[2] = index[3];	/* off_set (配列の開始位置(先頭が1))*/
			offset = index[3] - 1;
			iParm[3] = X_MIN(index[2],index[1]) + offset;	/* 設定済み要素の先頭からの最大位置(先頭が1), <0 HASH 2020.4.30 */
			/* iParm[2]〜iParm[3]が*指定で出力される配列のParmNoでの範囲となる */

DEBUGOUTL4(194,"cl_get_array_info_ref: iParm[0]..[3] =%d %d %d %d",iParm[0],iParm[1],iParm[2],iParm[3]);

		}
/*
printf("cl_get_array_info_ref: iParm[0]..[3] =%d %d %d %d\n",iParm[0],iParm[1],iParm[2],iParm[3]);
*/
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_get_mapped_array(pInfoParmW,pInfoParm1,pOperator,pInfoParm2)
char *pOperator;
tdtInfoParm *pInfoParm1;
tdtInfoParm *pInfoParm2;
tdtInfoParm *pInfoParmW;
{
	static char *_fn_="cl_get_mapped_array";
	tdtInfoParm *pInfoParmA;
	tdtArrayIndex *pIndex;
	char c,id1,id2;
	int rc,*index,n,i,m,nr,iUNSIGN;
	long ix;
	ulong uix;

	if ((c=*pOperator)!='+' && c!='-') {
		/* %s: 演算(%s)は使用できません。 */
		ERROROUT2(FORMAT(238),_fn_,pOperator);
		return ECL_SCRIPT_ERROR;
	}
	if ((id1=pInfoParm1->pi_id) == ' ') {
		if (rc=cl_get_parm_bin(pInfoParm1,&ix,FORMAT(163))) return rc;	/* 左辺 */
		pInfoParmA = pInfoParm2;
		iUNSIGN = pInfoParm1->pi_scale & D_DATA_UNSIGNED;
	}
	else if ((id2=pInfoParm2->pi_id) == ' ') {
		if (rc=cl_get_parm_bin(pInfoParm2,&ix,FORMAT(164))) return rc;	/* 右辺 */
		pInfoParmA = pInfoParm1;
		iUNSIGN = pInfoParm2->pi_scale & D_DATA_UNSIGNED;
	}
	if (!iUNSIGN && c=='-') ix = -ix;	/* add 2021.3.29 */
	pIndex = (tdtArrayIndex *)pInfoParmA->pi_data;
	if (pIndex->xhp) {
		/* %s: 連想配列(%s)は指定できません。 */
		ERROROUT2(FORMAT(239),_fn_,pInfoParmA->pi_pos);
		return ECL_SCRIPT_ERROR;
	}
	if (rc=cl_gx_rep_info_set_ign(pInfoParmW,pInfoParmA,1)) return rc;
	pIndex = (tdtArrayIndex *)pInfoParmW->pi_data;
	pIndex->uAttr[1] = D_ATR1_NO_MALLOC;
	index = pIndex->index;
	n = index[1];
/*
printf("cl_get_mapped_array: ix=%d n=%d index=%d %d %d %d %d %d\n",
ix,n,index[0],index[1],index[2],index[3],index[4],index[5]);
*/
#if 1	/* 2021.3.29 */
	if (iUNSIGN) {
		if (c == '+') i = index[3] + uix;
		else i = index[3] - uix;
	}
	else i = index[3] + ix;
#else
	i = ix;
#endif
	if (i<=0 || i>n) {
		/* %s: map位置(%d)が範囲外です。 */
		ERROROUT2(FORMAT(240),_fn_,i);
		return ECL_SCRIPT_ERROR;
	}
#if 1	/* 2021.3.29 */
	index[3] = i;
#else
	index[3] += i;
#endif
	nr = n - ix;
	index[0] = 1;
	index[1] = nr;
	index[2] -= ix;
	if (index[2] <0 ) index[2] = 0;
	index[4] = nr;
	index[5] = 0;
/*
printf("cl_get_mapped_array: ix=%d nr=%d index=%d %d %d %d %d %d\n",
ix,nr,index[0],index[1],index[2],index[3],index[4],index[5]);
*/
DEBUGOUT_InfoParm(170,"cl_get_mapped_array: ",pInfoParmW,0,0);

	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_array_map(pInfoParmW,nparm,ppParm)
tdtInfoParm *pInfoParmW;
int nparm;
tdtInfoParm *ppParm[];
{
	static char *_fn_="cl_array_map";
	tdtInfoParm *pInfoParmA;
	tdtArrayIndex *pIndex;
	char c,id1,id2;
	int rc,ix,*index,n,i,ind[MAX_ARRAY_DIM+1],f,iRANGE,iSTART,ndim,i1,i2,k;

	pInfoParmA = ppParm[0];
	if ((id1=pInfoParmA->pi_id)!='A' && id1!='R') {
		/* %s: 第１引数が配列ではありません。id=[%c] */
		ERROROUT2(FORMAT(246),_fn_,id1);
		return ECL_SCRIPT_ERROR;
	}
	pIndex = (tdtArrayIndex *)pInfoParmA->pi_data;
	if (pIndex->xhp) {
		/* %s: 連想配列(%s)は指定できません。 */
		ERROROUT2(FORMAT(239),_fn_,pInfoParmA->pi_pos);
		return ECL_SCRIPT_ERROR;
	}
	if (rc=cl_func_index(&ix,nparm,ppParm)) return rc;
	index = pIndex->index;
	ndim = index[0];
	nparm = X_MIN(nparm-1,ndim);
	for (i=1;i<=nparm;i++) {
		if (rc=cl_get_parm_bin(ppParm[i],&ind[i],"index")) return rc;
/*
printf("cl_array_map: ind[%d]=%d\n",i,ind[i]);
*/
	}
	if (rc=cl_gx_rep_info_set_ign(pInfoParmW,pInfoParmA,1)) return rc;
	pIndex = (tdtArrayIndex *)pInfoParmW->pi_data;
	index = pIndex->index;
	n = index[1];
/*
printf("cl_array_map: index=");
for (i=0;i<ndim*2+4;i++) printf("%d ",index[i]);
printf("ix=%d\n",ix);
*/
	i = ix;
	if (i<=0 || i>n) {
		/* %s: map位置(%d)が範囲外です。 */
		ERROROUT2(FORMAT(240),_fn_,i);
		return ECL_SCRIPT_ERROR;
	}
	index[3] += i;
	if (pGlobTable->options[14] & 0x01) iSTART = 1;
	else iSTART = 0;
	i1 = 4;
	i2 = i1 + ndim;
	n = 1;
	for (i=1;i<=nparm;i++,i1++,i2++) {
		index[i1] -= ind[i] - index[i2];
		if (index[i1] <= 0) {
			/* %s: map位置(i=%d %d)が範囲外です。 */
			ERROROUT3(FORMAT(247),_fn_,i,ind[i]);
			return ECL_SCRIPT_ERROR;
		}
		n *= index[i1];
/*
printf("cl_array_map: index[%d]=%d n=%d\n",i1,index[i1],n);
*/
	}
	for (;i<=ndim;i++,i1++) {
		n *= index[i1];
/*
printf("              index[%d]=%d n=%d\n",i1,index[i1],n);
*/
	}
	index[2] -= index[1] - n;
	if (index[2] < 0) index[2] = 0;
/*	index[0] = i;	del 2021.5.5 */
/*
printf("cl_array_map: index=");
for (i=0;i<ndim*2+4;i++) printf("%d ",index[i]);
printf("\n");
*/
DEBUGOUT_InfoParm(170,"cl_get_mapped_array: ",pInfoParmW,0,0);

	return 0;
}
