static    char    sccsid[]="%Z% %M% %I% %E% %U%";
/*******************************************************/
/* <clfuncfile.c>                                      */
/*      func                                           */
/*******************************************************/
#include "colmn.h"

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

static int _heredoc_end();
static int _chk_heredoc_end();
static int _heredoc_end_set(/*red*/);
static int _heredoc_skip_to_eof(/*red*/);

static FILE *gHereDoc_fp = NULL;
static char *gHereDoc_nm = NULL;
static char wrk_get[D_GETCHAR_PRE_READ_LEN+1];
static SSPL_S ssp_get = {0,wrk_get,0,0,0,0,0,0,0};

/****************************************/
/*										*/
/****************************************/
int _check_fp(ope,fp,pp,pm)
char ope,**pp,*pm;
FILE *fp;
{
	HASHB *hp;
	int i,n,len1;
	char *p,*argv[2],*p1;
	ProcCT *proc;
	BlockCB *pIfCB;
	FILE **fpa;

	hp = pCLprocTable->pha_fp;
	hp->ha_key = (char *)argv;
	argv[0] = argv[1] = NULL;
	if (ope == 'S') {
#if 1	/* 2021.6.23 */
		if (pp && (p=*pp)) {
			len1 = strlen(p);
			argv[1] = p1 = Malloc(len1+2);
			*p1 = ' ';
			if (pm) {
				if (inistr(pm,"B")) *p1 = 'B';
			}
			strcpy(p1+1,p);
		}
#else
		if (pp && (p=*pp)) argv[1] = Strdup(p);
#endif
		i = akxshasls(hp,fp);
		if (i <= 0) {
			if (argv[1]) Free(argv[1]);
		}
		else if (proc = cl_search_proc_ct()) {
			if (pIfCB = proc->pcrBlockCB) {
				if (pIfCB->iUsed == D_TRY_WITH) {
					if (fpa = (FILE **)pIfCB->pSwParm) {
						n = pIfCB->iLoopMax;
						fpa[n++] = fp;
						pIfCB->iLoopMax = n;
/*
printf("_check_fp: pIfCB->iLoopMax=%d\n",pIfCB->iLoopMax);
*/
					}
				}
			}
		}
	}
	else if (ope == 'R') {
		i = akxshaslr(hp,fp);
		if (i>0 && pp) *pp = argv[1];
	}
	else if (ope == 'D') {
		i = akxshasld(hp,fp);
		if (i > 0) {
			if (pp) *pp = argv[1];
			else if (argv[1]) Free(argv[1]);
		}
	}
	return i;
}

/****************************
struct stat
{
  dev_t         st_dev;			1
  ino_t         st_ino;			2
  mode_t        st_mode;		3
  nlink_t       st_nlink;		4
  uid_t         st_uid;			5
  gid_t         st_gid;			6
  dev_t         st_rdev;		7
  off_t         st_size;		8
  timestruc_t   st_atim;		9,10
  timestruc_t   st_mtim;		11,12
  timestruc_t   st_ctim;		13,14
  blksize_t     st_blksize;		15
  blkcnt_t      st_blocks;		16
  long          st_spare4[2];
};

#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
**********************************/
#define CL_MAX_ST_VAL	17
/****************************************/
/*	stat(file) or fstat(fp)				*/
/****************************************/
static int _func_fpstat(pretval,fname,nparm,ppParm,fp)
int  *pretval;
char *fname;
int nparm;
tdtInfoParm *ppParm[];
FILE *fp;
{
	struct stat tStat;
	int st_val[CL_MAX_ST_VAL];
	tdtInfoParm *pInfoParm,rInfoParm;
	tdtInfoParm ***pTBL;
	char c,*name;
	tdtArrayIndex tIndex,*pIndex;
	int  *index,maxargs,nm;
	int  i,ix,ret,f_type;
	MPA  mpaz,*mpa;

	mpa = (MPA *)cl_get_tmpMPA(&mpaz);
	if (fname) ret = stat(fname,&tStat);
	else if (fp) ret = fstat(fileno(fp),&tStat);
	else ret = -1;
	if (ret) {
		*pretval = ret;
		mem_set_int(st_val,0,CL_MAX_ST_VAL);
		tStat.st_size = 0;
		m_ll2mpa(tStat.st_size,mpa);
		return 0;
	}
	else {
		if (S_ISFIFO(tStat.st_mode)) f_type = 1;
		else if (S_ISCHR(tStat.st_mode)) f_type = 2;
		else if (S_ISDIR(tStat.st_mode)) f_type = 3;
		else if (S_ISBLK(tStat.st_mode)) f_type = 4;
		else if (S_ISREG(tStat.st_mode)) f_type = 5;
		else if (S_ISLNK(tStat.st_mode)) f_type = 6;
		else f_type = 0;
		*pretval = f_type;	/* 2020.11.27 */

		st_val[ 0] = f_type;
		st_val[ 1] = tStat.st_dev;
		st_val[ 2] = tStat.st_ino;
		st_val[ 3] = tStat.st_mode;
		st_val[ 4] = tStat.st_nlink;
		st_val[ 5] = tStat.st_uid;
		st_val[ 6] = tStat.st_gid;
		st_val[ 7] = tStat.st_rdev;
		m_ll2mpa(tStat.st_size,mpa);
		st_val[ 9] = tStat.st_atim.tv_sec;
		st_val[10] = tStat.st_atim.tv_nsec;
		st_val[11] = tStat.st_mtim.tv_sec;
		st_val[12] = tStat.st_mtim.tv_nsec;
		st_val[13] = tStat.st_ctim.tv_sec;
		st_val[14] = tStat.st_ctim.tv_nsec;
		st_val[15] = tStat.st_blksize;
		st_val[16] = tStat.st_blocks;
	}
	if (nparm <= 0) return 0;

	pIndex = &tIndex;
	if (ret=cl_get_ITBL_maxargs_ref(nparm,ppParm,&pIndex,&pTBL,0,-1,&maxargs,NULL)) return ret;
	index = pIndex->index;

	nm = X_MIN(CL_MAX_ST_VAL,maxargs);
	ix = index[3];
	for (i=0;i<nm;i++,ix++) {
		pInfoParm = cl_get_array_and_var_ent_opt(pIndex,pTBL,ix,'s');
		if (pInfoParm) {

DEBUGOUT_InfoParm(194,"_func_stat: i=%d ix=%d",pInfoParm,i,ix);

			if (i == 8) cl_set_parm_mpa(&rInfoParm,mpa);
			else cl_set_parm_bin(&rInfoParm,st_val[i]);
			if (ret=cl_gx_rep_info_set_ign(pInfoParm,&rInfoParm,1)) return ret;
		}
		else {
			return -1;
		}
	}
	return 0;
}

/****************************************/
/*	fopen(fname, mode)					*/
/*	popen(sh_fname, mode)				*/
/*	opendir(dirname)					*/
/*	unlink(fname)						*/
/****************************************/
static int _func_fopen(pWork,nparm,ppParm,ope,iParm)
char *pWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
{
	tdtInfoParm *pInfoParm;
	int iRc,ret,i,retval,len;
	char w1[32],w2[32],*p1,*p2,*func;
	FILE *fp;
	DIR  *dp;
	struct stat tStat;

	iRc = 0;
	p1 = w1;
	if ((len = parm_to_char(ppParm[0],&p1,NULL)) >= 0) {
/*
printf("func_file: p1=[%s] len=%d\n",p1,len);
*/
		if (ope == D_FUC_FOPEN ||	/* fopen(fname,mode) */
		    ope == D_FUC_POPEN ||	/* popen(sh_fname,mode) */
		    ope == D_FUC_OPENDIR) {	/* opendir(dirname) */
			p2 = w2;
			if (nparm >= 2) {
				len = parm_to_char(ppParm[1],&p2,NULL);
/*
printf("func_file: p2=[%s] ret=%d\n",p2,iRc);
*/
			}
			else {
				strcpy(w2,"r");
			}
			if (len >= 0) {
				if (ope == D_FUC_OPENDIR) {
					dp = opendir(p1);
					func = "opendir";
					memcpy(pWork,&dp,sizeof(DIR *));
					fp = (FILE *)dp;
				}
				else {
					if (!(cl_get_option(3,0) & 0x80)) {
						if ((i=instrchar(p2,'t')) > 0) {
							len = strlen(p2);
							memcpy(p2+i-1,p2+i,len-i+1);
						}
					}
					if (ope == D_FUC_FOPEN) {
						fp = fopen(p1,p2);
						func = "fopen";
#if 1	/* 2021.6.26 */
						if (fp) {
							if ((retval = fileno(fp)) >= 0) {
								retval = fstat(retval,&tStat);
							}
							if (retval < 0) {
								ERROROUT(FORMAT(396));		/* file/pipe/dir用のfpは無効です。 */
								fclose(fp);
								fp = NULL;
							}
							else {
								if (S_ISREG(tStat.st_mode) || S_ISLNK(tStat.st_mode)) ;
								else {
									ERROROUT("fopen: not file");
									fclose(fp);
									fp = NULL;
								}
							}
						}
#endif
					}
					else {
						fp = popen(p1,p2);
						func = "popen";
					}
					memcpy(pWork,&fp,sizeof(FILE *));
				}
/*
printf("func_file: fp=%08x\n",fp);
*/
				if (fp) {
					_check_fp('S',fp,&p1,p2);
					iParm[2] = D_AULN_FILE_POINTER;
				}
				else {
					pGlobTable->exception = FILE_OPEN_EXCEPTION + errno;
					pGlobTable->error = -1;
					pGlobTable->err_no = errno;
					ERROROUT5("%s([%s],[%s]) errno=%d %s",func,
					          p1,p2,errno,strerror(errno));
				}
				iParm[0] = DEF_ZOK_BINA;
				iParm[1] = sizeof(FILE *);
			}
		}
		else if (ope == D_FUC_UNLINK ||	/* unlink(fname) */
		         ope == D_FUC_STAT) {	/* stat(fname) */
			retval = 0;
			if (ope == D_FUC_UNLINK) {
				retval = unlink(p1);
				func = "unlink";
			}
			else {
				iRc = _func_fpstat(&retval,p1,nparm-1,ppParm+1,NULL);
				func = "stat";
			}
			memcpy(pWork,&retval,sizeof(int));
/*
printf("_func_fopen: retval=%d\n",retval);
*/
			if (retval < 0) {
				pGlobTable->exception = FILE_ETC_EXCEPTION + errno;
				pGlobTable->error = -1;
				pGlobTable->err_no = errno;
				ERROROUT4("%s([%s]) errno=%d %s",
				          func,p1,errno,strerror(errno));
			}
		}
	}
	else iRc = -1;

	return iRc;
}

/****************************************/
/*	fclose(fp)							*/
/****************************************/
/********************************************************
S_ISREG(m)	通常のファイルか?
S_ISDIR(m)	ディレクトリか?
S_ISCHR(m)	キャラクター・デバイスか?
S_ISBLK(m)	ブロック・デバイスか?
S_ISFIFO(m)	FIFO (名前付きパイプ) か?
S_ISLNK(m)	シンボリック・リンクか? (POSIX.1-1996 にはない)
S_ISSOCK(m)	ソケットか? (POSIX.1-1996 にはない)

以下のフラグが st_mode フィールド用に定義されている:
S_IFMT   0170000 ファイル種別を示すビット領域を表すビットマスク
S_IFSOCK 0140000 ソケット
S_IFLNK  0120000 シンボリック・リンク
S_IFREG  0100000 通常のファイル
S_IFBLK  0060000 ブロック・デバイス
S_IFDIR  0040000 ディレクトリ
S_IFCHR  0020000 キャラクター・デバイス
S_IFIFO  0010000 FIFO
S_ISUID  0004000 set-user-ID bit
S_ISGID  0002000 set-group-ID bit (下記参照)
S_ISVTX  0001000 スティッキー・ビット (下記参照)
S_IRWXU    00700 ファイル所有者のアクセス許可用のビットマスク
S_IRUSR    00400 所有者の読み込み許可
S_IWUSR    00200 所有者の書き込み許可
S_IXUSR    00100 所有者の実行許可
S_IRWXG    00070 グループのアクセス許可用のビットマスク
S_IRGRP    00040 グループの読み込み許可
S_IWGRP    00020 グループの書き込み許可
S_IXGRP    00010 グループの実行許可
S_IRWXO    00007 他人 (others) のアクセス許可用のビットマスク
S_IROTH    00004 他人の読み込み許可
S_IWOTH    00002 他人の書き込み許可
S_IXOTH    00001 他人の実行許可
*****************************************/

static int _func_close(pWork,ope,fp)
char *pWork;
int  ope;
FILE *fp;
{
	int  retval,rc;
	char *func;
	struct stat tStat;

	func = "_func_close";
	if (fp==stdin || fp==stdout || fp==stderr) {
		retval = -1;
	}
	else {
		if ((retval = fileno(fp)) >= 0) {
			retval = fstat(retval,&tStat);
		}
		if (retval < 0) {
			ERROROUT(FORMAT(396));		/* file/pipe/dir用のfpは無効です。 */
		}
		else {
			if (fp) _check_fp('D',fp,NULL,NULL);
			if (ope == D_FUC_FCLOSE) {
				if (S_ISREG(tStat.st_mode) || S_ISLNK(tStat.st_mode) ||
				    S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode)) {
					retval = fclose(fp);
					func = "fclose";
					pGlobTable->err_no = errno;
					if (S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode))
						ERROROUT("fclose: W not file");
				}
				else {
					ERROROUT("fclose: not file/dir");
					retval = -1;
				}
			}
			else if (ope == D_FUC_PCLOSE) {
				if (S_ISFIFO(tStat.st_mode)) {
					retval = pclose(fp);
					func = "pclose";
					pGlobTable->err_no = errno;
					if (retval == 127) {
						ERROROUT("pclose: sh not executed!");
						pGlobTable->error = retval;
						pGlobTable->exception = FILE_CLOSE_EXCEPTION + errno;
					}
				}
				else {
					ERROROUT("pclose: not pipe");
					retval = -1;
				}
			}
			else if (ope == D_FUC_CLOSEDIR) {
				if (S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode)) {
					retval = closedir((DIR *)fp);
					func = "closedir";
					pGlobTable->err_no = errno;
				}
				else {
					ERROROUT("closedir: not directory");
					retval = -1;
				}
			}
			else {
				ERROROUT1("_func_close: invalid ope(%d)!!",ope);
				return -1;
			}
		}
	}
	if (retval < 0) {
		pGlobTable->exception = FILE_CLOSE_EXCEPTION + errno;
		pGlobTable->error = retval;
		ERROROUT3("%s errno=%d %s",func,errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return 0;
}

/****************************************/
/*										*/
/****************************************/
static int _check_ssp_buf(pWork,size,fp)
char *pWork;
int size;
FILE *fp;
{
	int ret,m;
	char *p;
/*
printf("_check_ssp_buf:Enter pWork=%08x size=%d fp=%08x\n",pWork,size,fp);
*/
	m = 0;
	if (fp == stdin) {
		p = ssp_get.wd;
		m = ssp_get.sp;
		if (size>=0 && m>=size) {	/* add size>=0 2022.1.8 */
			if (pWork) memzcpy(pWork,p,size);
			m -= size;
			memzcpy(p,p+size,m);
			ssp_get.sp = m;
			ret = size;
		}
		else {
			if (m > 0) {
				if (pWork) memzcpy(pWork,p,m);
				ssp_get.sp = 0;
			}
			else m = 0;
		}
	}
/*
printf("_check_ssp_buf:Exit ssp_get.sp=%d m=%d\n",ssp_get.sp,m);
*/
	return m;
}

/****************************************/
/*										*/
/****************************************/
static int _set_file_read_error(msg,fp,ret)
char *msg;
FILE *fp;
int ret;
{
	int log_flg;

	pGlobTable->err_no = errno;
	if (ferror(fp)) {
		pGlobTable->exception = FILE_READ_EXCEPTION + errno;
		ERROROUT3("%s: errno=%d %s",msg,errno,strerror(errno));
		ret = ECL_IN_ERROR;
	}
	else {
		pGlobTable->exception = FILE_READ_END_EXCEPTION;
		ret = ECL_END_OF_FILE;
		if (!(cl_get_option(7,0) & 0x10)) {
			log_flg = LOGFLG(0,-1);
			LOGFLG(0,(log_flg & ~(D_LOG_FLG_STDOUT | D_LOG_FLG_STDERR)) | D_LOG_FLG_FILE);
		}
		ERROROUT1("%s: end of file",msg);
		if (!(cl_get_option(7,0) & 0x10)) LOGFLG(0,log_flg);
	}
	pGlobTable->error = ret;
	return ret;
}

/****************************************/
/*										*/
/****************************************/
static int _chk_addr_tmp_malloc(pp,pWork,ret)
char **pp,*pWork;
int ret;
{
	char *p,*pW;

	p = *pp;
	pW = pWork;
	if (p != pWork) {
		if (p) {
			if (ret >= 0) {
				if (pW = cl_tmp_const_malloc(ret+1))
					memzcpy(pW,p,ret);
				else
					ret =ECL_MALLOC_ERROR;
			}
			Free(p);
		}
	}
	*pp = pW;
	return ret;
}

/****************************************/
/*	Input								*/
/****************************************/
static int _file_code_conv(ppWork,pWork,size,iFILE,code_type)
char **ppWork;
char *pWork;
int  size,iFILE,code_type;
{
	int ret;
	char *p,*pW;

	ret = cl_file_code_conv(&p,pWork,size,0,iFILE,code_type);
/*	p : pWork か Mallocされたアドレスが返される */
#if 1	/* 2022.4.11 */
	if (ret > 0) {
		ret = _chk_addr_tmp_malloc(&p,pWork,ret);
	}
	*ppWork = p;
#else
	pW = pWork;
	if (p != pWork) {
		if (p) {
			if (ret >= 0) {
				if (pW = cl_tmp_const_malloc(ret+1))
					memzcpy(pW,p,ret);
				else
					ret =ECL_MALLOC_ERROR;
			}
			Free(p);
		}
	}
	*ppWork = pW;
#endif
	return ret;
}

/****************************************/
/*										*/
/****************************************/
static int _getchar_code_conv(pp,nparm,ppParm,p,len,iFILE,b_mode,i_getchar)
char **pp,*p;
tdtInfoParm *ppParm[];
int nparm,len,iFILE,b_mode,i_getchar;
{
	int ret,m,ex_opt,opt,i,tr_dtypea[2],from_code,to_code;
	char *pW,*p1;

	if (len <= 0) {
		*pp = p;
		return 0;
	}
	tr_dtypea[0] = tr_dtypea[1] = 0;
	nparm = X_MIN(nparm,2);
	for (i=0;i<nparm;i++) {
		if (ret=cl_get_parm_bin(ppParm[i],&tr_dtypea[i],"_getchar_code_conv:tr_dtype:")) return -1;
	}
/*
printf("_getchar_code_conv: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
*/
	if ((from_code=tr_dtypea[0]) <= 0) {
		if (!b_mode) {
			from_code = cl_get_option(21,0);
			from_code >>= 8;
			if (iFILE) from_code >>= 4;
			from_code &= 0x0f;
		}
		else from_code = 0;
	}
	if ((to_code=tr_dtypea[1]) < 0) to_code = 0;
	if (i_getchar) {
		if ((m=akxqmbsnlen(from_code,p,len)) < 0) return m;
/*
printf("_getchar_code_conv:2 from_code=%02x m=%d\n",from_code,m);
*/
		if (!(pW=cl_tmp_const_malloc(m+1))) return ECL_MALLOC_ERROR;
		memzcpy(pW,p,m);
		ssp_get.sp = len - m;
		memzcpy(p,p+m,ssp_get.sp);
	}
	else {
		pW = p;
		m = len;
	}
/*
printf("_getchar_code_conv: m=%d b_mode=%d from_code=%02x to_code=%02x\n",m,b_mode,from_code,to_code);
*/
	if (m>=0 && from_code!=to_code) {
		if (from_code > 0) {
		/*	ex_opt = cl_get_option(21,0);
			if (b_mode) ex_opt = 0;
			if ((ex_opt & D_CODE_INPUT_MASK) || tr_dtype>=0) {	*/
				if ((ret=_file_code_conv(&p1,pW,m,iFILE,from_code)) < 0) return ret;
				m = ret;
				pW = p1;
		/*	}	*/
		}
		if (to_code > 0) {
			if ((ret=akxc_file_code_conv(&p1,pW,m,1,to_code)) < 0) return ret;
			if ((ret=_chk_addr_tmp_malloc(&p1,pW,ret)) < 0) return ret;
			m = ret;
			pW = p1;
		}
	}
	*pp = pW;
	return m;
}

/****************************************/
/*										*/
/****************************************/
static int _putchar_code_conv(pp,p,len,tr_dtypea)
char **pp,*p;
int len,tr_dtypea[];
{
	int ret,tr_dtype;
	char *p1;
/*
printf("_func_putchar: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
*/
	p1 = p;
	if ((tr_dtype=tr_dtypea[1])>0 && tr_dtypea[0]!=tr_dtype) {
		if (tr_dtype > 0) {
			tr_dtype <<= 8;	/* akxc_file_code_conv()は、inout=0のときは0xX4X3X2X1のX2を使う */
			if ((ret=akxc_file_code_conv(&p1,p,len,0,tr_dtype)) < 0) return ret;
/*
printf("_func_putchar: ret=%d p1=[%s]\n",ret,p1);
*/
			if ((ret=_chk_addr_tmp_malloc(&p1,p,ret)) < 0) return ret;
			len = ret;
		}
	}
	else if (tr_dtypea[0]>0 && tr_dtypea[0]==tr_dtypea[1]) tr_dtypea[0] = -1;
	*pp = p1;
	return len;
}

/****************************************/
/*	fgetline(fp,size,opt)				*/
/****************************************/
static int _func_fgetline(ppWork,nparm,ppParm,ope,iParm,fp)
char **ppWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	int iRc,ret,size,opt,ex_opt,iFILE,m,trim_opt;
	char *pWork,buf[2048],*pW,*p,*pWk;
	ScrPrCT	*scrct;
	ProcCT *proc;
	tdtREDIRECT *red;

	pWork = *ppWork;
	/* Get size */
	size = sizeof(buf);
	if (nparm >= 1) {
		if (!cl_is_null_parm(ppParm[0])) {
			if (iRc=cl_get_parm_bin(ppParm[0],&size,"func_file:size:")) return -1;
			size++;
		}
	}
/*
printf("func_file: ope=%d attr=%d size=%d\n",ope,attr,size);
*/
	if (size < 2) {
		ERROROUT1("FGETLINE: size(%d) < 2",size);
		return -1;
	}
	else if (size > sizeof(buf)) {
		if (!(pWork = cl_tmp_const_malloc(size)))
			return ECL_MALLOC_ERROR;
	}
	else pWork = buf;

	/* Get opt */
/*	opt = 0x02 | 0x04;	2021.2.24 */
	ex_opt = cl_get_option(3,0);
	ex_opt = ex_opt>>4;
	opt = 0x03;
	opt &= ~(ex_opt & 0x03);
	opt |= ex_opt & 0x01c;
	if (nparm >= 2) {
		if (!cl_is_null_parm(ppParm[1])) {
			if (iRc=cl_get_parm_bin(ppParm[1],&opt,"func_file:opt:")) return -1;
		}
	}
	m = _check_ssp_buf(pWork,size,fp);
	ret = akxa_read_line_opt(pWork+m,size-m,fp,opt);
	if (ret<0 && m>0) ret = m;	/* 2022.1.8 */
	/* 2021.8.7 */
	if (ret > 0) {
/*
printf("_func_fgetline: pWork=[%s]\n",pWork);
*/
		/* 2022.4.23 */
		proc = cl_search_proc_ct();
		red = proc->redirect;
/*
printf("_func_fgetline: pWork=[%s] fp=%08x\n",pWork,fp);
printf("                red->stdio[3]=%08x red->HereDoc_nm=%08x\n",red->stdio[3],red->HereDoc_nm);
*/
		pWk = pWork;
		if (p = red->HereDoc_nm) {
			trim_opt = red->pFlag2 & (D_PFLAG2_DEL_TAB | D_PFLAG2_DEL_SPACE);
/*
printf("_func_fgetline: trim_opt=%02x\n",trim_opt);
*/
			if (trim_opt) {
				pWk = akxttrim2(trim_opt|2,pWork,&ret);
/*
printf("_func_fgetline: pWk=[%s]\n",pWk);
*/
			}
/*
printf("_func_fgetline: red->HereDoc_nm=[%s]\n",p);
*/
			if (!strcmp(pWk,p)) {
				_heredoc_end(0);
				_check_ssp_buf(NULL,-1,fp);
				ret = -1;
			}
		}
	}
	if (ret < 0) {
		if ((ret=_set_file_read_error("fgetline",fp,ret)) != ECL_END_OF_FILE) {
			cl_check_close_fp(fp);	/* add 2021.12.13 */
			ssp_get.attr[3] = 0;	/* 2022.1.8 */
		}
		_chk_heredoc_end(1);	/* add 2022.4.27 */
	}
	else {
/*
printf("_func_fgetline: ope=%d size=%d ret=%d pWk=[%s]\n",ope,size,ret,pWk);
*/
		size = ret;
		if (pWork == buf) {
			if (!(pW = cl_tmp_const_malloc(size+1)))
				return ECL_MALLOC_ERROR;
			memzcpy(pW,pWk,size);
		}
		else pW = pWk;
		/* 2022.4.14 */
		if (fp == stdin) iFILE = 0;
		else iFILE = 1;
		if ((ret=_getchar_code_conv(&pW,nparm-2,ppParm+2,pW,size,iFILE,iParm[4],0)) <0) return ret;
		*ppWork = pW;
		ret = 0;
	}
#ifdef CANCEL_WHEN_EOF	/* 2022.6.24 */
	if (cl_get_option(7,0) & (0x20 | 0x40)) return ret;
	else return 0;
#else
	return 0;
#endif
}

/****************************************/
/*										*/
/****************************************/
static int _func_fwrite_conv(p,pos,fp,mode,to_code)
char *p;
int  pos,mode,to_code;
FILE *fp;
{
	char *pp,*pw;
	int  ret,lw,iFILE;
/*
printf("_func_fwrite_conv:Enter pos=%d mode=%d to_code=%d p=[%s]\n",pos,mode,to_code,p);
*/
	if (fp==stdout || fp==stderr) iFILE = 0;
	else iFILE = 1;
/*
printf("_func_fwrite_conv: iFILE=%d fp=%08x\n",iFILE,fp);
*/
	ret = pos;
	if (pos > 0) {
/*
akxaxdump(" akxaxdump(msg,dat,len)",p,pos);
*/
		pp = pw = p;
		lw = pos;
		if (!mode) {
			ret = cl_file_code_conv(&pp,p,lw,1,iFILE,to_code);
			if (ret > 0) {
				pw = pp;
				lw = ret;
			}
/*
printf("_func_fwrite_conv: cl_file_code_conv ret=%d lw=%d pw=[%s]\n",ret,lw,pw);
*/
		}
		if (ret > 0) {
			if ((ret=fwrite(pw,lw,1,fp)) <= 0) ret = -1;
			else ret = lw;
		}
		if (pp != p) Free(pp);
	}
	return ret;
}

/****************************************/
/*	fputline(fp,data1,data2,...)		*/
/****************************************/
static int _func_fputline(pWork,nparm,ppParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	static char *pnama[]={"TO_CODE","FROM_CODE"};
	int iRc,ret,i,retval,len,gopt,pos,l,m,n,iOpt[MAX_PRINT_FLGS+1],ex_opt,mode,lw,opt3,opt13,iSTR;
	int tr_dtypea[2];
	char w1[32],*p1,*p,*pp,*pW;
	tdtInfoParm *pInfoParm,*pParmW[2];

	opt3 = cl_get_option(3,0);
	opt13 = cl_get_option(13,0);
	ex_opt = cl_get_option(21,0);
	iOpt[0] = opt13 | 0x80000000;	/* iOpt[0]でflgs[]を設定する */
	mem_set_int(iOpt+1,0,MAX_PRINT_FLGS);
	if (opt13 & 0x80) iOpt[1] &= ~D_PRN_OPT_LTGT;
	else iOpt[1] |= D_PRN_OPT_LTGT;
	ret = iRc = 0;
	retval = 0;
	mode = 0;
/*
	if ((fp!=stdout && fp!=stderr) ||
	    ((fp==stdout || fp==stderr) && (ex_opt & D_CODE_OUTPUT_MASK))) flag = 1;
*/
	if (iParm[4]) mode = 1;	/* binary mode */
#if 1	/* 2022.4.14 */
	tr_dtypea[0] = tr_dtypea[1] = 0;
	pParmW[0]=pParmW[1]=NULL;
	if ((ret=cl_get_pname_info(nparm,ppParm,pParmW,pnama,2)) < 0) return ret;
	else if (ret > 0) {
		for (i=0;i<2;i++) {
			if (pInfoParm=pParmW[i]) {
				if (ret=cl_get_parm_bin(pInfoParm,&tr_dtypea[i],"_func_fputline:tr_dtype:")) return -1;
			}
		}
	}
#endif
	for (i=0;i<nparm;i++) {
		p1 = w1;
		pInfoParm = ppParm[i];
		if (pInfoParm->pi_id == D_DATA_ID_PNAME) continue;	/* add 2022.4.14 */
#if 1	/* 2021.4.12 */
		len = pInfoParm->pi_dlen;
		akxttrim(2,p=strtemp(pInfoParm->pi_data,len),len);
		iSTR = 0;
		if ((opt13 & 0x02) && *p=='/') iSTR = 1;
		else if (!(opt13 & 0x40) && pInfoParm->pi_id!=' ') iSTR = 1;
		if (iSTR) {
			len = cl_str_print(&p1,pInfoParm,iOpt);
			if (len == ECL_EX_CONTINUE) len = 0;
		}
		else
			len = parm_to_char(pInfoParm,&p1,NULL);
#else
		if (pInfoParm->pi_id==' ' && pInfoParm->pi_attr==DEF_ZOK_BULK)
			len = parm_to_char(pInfoParm,&p1,NULL);
		else {
			len = cl_str_print(&p1,pInfoParm,iOpt);
			if (len == ECL_EX_CONTINUE) len = 0;
		}
#endif
		if (len > 0) {
/*
printf("_func_fputline: iSTR=%d p1=[%s]\n",iSTR,p1);
*/
/*
printf("_func_fputline: opt3=%08x\n",opt3);
*/
#if 1	/* 2022.1.20 */
			if (opt3 & 0x200) {
				len = cl_ank_conv(&p,p1,len);
				if (p) p1 = p;
			}
#endif
			p = p1;
			l = len;
			if (opt3 & AKX_NEWLINE_CNV_LF) {
				while ((pos=akxnskipto(p,l,"\r\n")) < l) {
#if 1	/* 2022.4.14 */
					pW = p;
					if ((ret=_putchar_code_conv(&p,pW,pos,tr_dtypea)) < 0) return ret;
					pos = ret;
#endif
					if ((ret=_func_fwrite_conv(p,pos,fp,mode,tr_dtypea[0])) < 0) break;
					p += pos;
					if (*p=='\r' && *(p+1)=='\n') m = 2;
					else m = 1;
					if ((n = akxa_log_new_line(fp,opt3)) >= 0) len += n - m;
/*
printf("_func_fputline: pos=%d m=%d *p=%02x *(p+1)=%02x\n",pos,m,*p,*(p+1));
*/
					p += m;
					l -= pos+m;
				}
/*
printf("_func_fputline: pos=%d\n",pos);
*/
			}
			if (ret >= 0) {
#if 1	/* 2022.4.14 */
				pW = p;
				if ((ret=_putchar_code_conv(&p,pW,l,tr_dtypea)) < 0) return ret;
				l = ret;
#endif
				ret = _func_fwrite_conv(p,l,fp,mode,tr_dtypea[0]);
			}
			else {
				ret = -1;
				break;
			}
			retval += len;
		}
		else if (len < 0) {
			iRc = len;
			break;
		}
	}
	pGlobTable->err_no = errno;
	if (ret >= 0) {
		if ((n = akxa_log_new_line(fp,opt3)) >= 0) retval += n;
		pGlobTable->err_no = errno;
	}
	else {
		pGlobTable->error = ret;
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		retval = ret;
		ERROROUT2("fputline: errno=%d %s",errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return iRc;
}

/****************************************/
/*										*/
/****************************************/
static int _get_size_scale(name,nparm,ppParm,iParm)
char *name;
tdtInfoParm *ppParm[];
int nparm,iParm[];
{
	int iRc,attr,size,scale0,scale,dec_size,iDEC_SIZE_ZERO;

	attr   = iParm[0];
	size   = iParm[1];
	scale  = iParm[2];
	iDEC_SIZE_ZERO = 0;
	if (nparm >= 1) {
		if (!cl_is_null_parm(ppParm[0])) {
			if (iRc=cl_get_parm_bin(ppParm[0],&size,stradd(name,":size:")))
				return -1;
			if (size<=0/* && attr!=DEF_ZOK_DECI*/) {
				iDEC_SIZE_ZERO = 1;
				size = iParm[1];
			}
			if (size>0 && attr==DEF_ZOK_FLOA) {
				if (size < 4) {
					ERROROUT3("%s: attr=%d size(%d) is few!!",name,attr,size);
					return -1;
				}
			}
		}
	}
/*
printf("_get_size_scale: nparm=%d attr=%d size=%d \n",nparm,attr,size);
*/
	scale0 = scale;
	if (nparm >= 2) {
		if (!cl_is_null_parm(ppParm[1])) {
			if (iRc=cl_get_parm_bin(ppParm[1],&scale,stradd(name,":scale:"))) return -1;
			scale0 = scale;
			if (attr == DEF_ZOK_DECI) {
				if (scale <= MIN_DEC_SCALE-1) scale = MIN_DEC_SCALE;	/* add 2021.4.3 */
				if ((dec_size=size) <= 0) dec_size = X_MIN(D_DEC_PRECISION,m_get_nmpa10());
				if (X_ABS(scale) > dec_size) {
					if (scale >= 0) scale = dec_size;
					else scale = -dec_size;
				}
			/*	else if (iDEC_SIZE_ZERO) scale = iParm[2];	*//* del 2021.4.3 */
			}
		}
	}
	if (attr != DEF_ZOK_DECI) {
		if (scale < 0) scale = -scale;
		if (size>0 && size<scale) {
			ERROROUT4("%s:(W) attr=%d size(%d)<scale(%d). set scale=size.",name,attr,size,scale);
			scale = size;
		}
	}
	if (!scale) {
		switch (attr) {
			case DEF_ZOK_BINA:
					if (size > 0) scale = size;
					else scale = sizeof(int);
					break;
			case DEF_ZOK_FLOA:
					if (size > 0) scale = size;
					else scale = sizeof(double);
					break;
			case DEF_ZOK_CHAR:
			case DEF_ZOK_BULK:
			case DEF_ZOK_DATE:
					scale = size;
					break;
		}
	}
	if (attr==DEF_ZOK_BINA) {
		if      (scale >= 8) scale = 8;
		else if (scale >= 4) scale = 4;
		else if (scale >= 2) scale = 2;
	}
	else if (attr==DEF_ZOK_FLOA) {
		if (scale >= 8) scale = 8;
		else scale = 4;
	}
/*
printf("_get_size_scale: name=[%s] attr=%d size=%d scale=%d scale0=%d\n",
name,attr,size,scale,scale0);
*/
#if 0	/* 2021.4.3 */
	iParm[3] = iParm[2];
	iParm[1] = size;
	if (attr!=DEF_ZOK_DECI && scale0<0) scale = -scale;
	iParm[2] = scale;
#else
	iParm[1] = size;
	iParm[2] = scale;
	iParm[3] = scale0;	/* 2021.1.1 */
#endif
	return 0;
}

/****************************************/
/*	felread1(fp,attr,size,scale)		*/
/****************************************/
static int _func_felread1(ppWork,nparm,ppParm,ope,iParm,fp)
char **ppWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	int iRc,ret,i,len,attr,size,scale0,scale,iVal,val[2],j,k,dec_size,len2,ex_opt,iFILE,from_code,m;
	char *p1,*pWork,c,buf[256],*p2,dummy[128];
	long lVal,lVal_n;
	short s,ws;
	double dVal;
	float  fVal;
	MPA    *ma;

	pWork = *ppWork;
	iRc = size = attr = scale = 0;

	if (iRc=cl_get_parm_bin(ppParm[0],&attr,"_func_felread1:attr:")) return -1;
	switch (attr) {
		case DEF_ZOK_CHAR: size = 1; break;
		case DEF_ZOK_BINA: size = sizeof(long); break;
		case DEF_ZOK_FLOA: size = sizeof(double); break;
		case DEF_ZOK_DECI: size = X_MIN(D_DEC_PRECISION,m_get_nmpa10());
		                   scale = size/2; break;	/* D_DEC_SCALE */
		case DEF_ZOK_BULK: size = 1; break;
		case DEF_ZOK_DATE: size = D_LEN_DATE; break;
		default:
			ERROROUT1(FORMAT(397),attr);	/* _func_felread1: 属性(%d)が不正です。 */
			return -1;
	}
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = scale;
	if (ret=_get_size_scale("_func_felread1",nparm-1,ppParm+1,iParm)) return ret;
#if 0	/* 2021.4.3 */
	size   = iParm[1];
	scale  = iParm[2];
	scale0 = scale;
	if (scale0 < 0) scale = -scale;
#else
	scale0 = iParm[3];	/* 2021.1.1 0-->3 */
	size   = iParm[1];
	scale  = iParm[2];
	iParm[3] = 0;	/* 2021.1.1 */
#endif
	dec_size = size;
	if (attr == DEF_ZOK_DECI) {
	/*	dec_size = size;	*/
		size = dec_size/2+1;
		len = size + sizeofMPA();
	/*	scale = iParm[3];	*//* del 2021.4.3 */
	}
	else if (attr == DEF_ZOK_DATE) len = size + sizeofMPA();
	else len = size;
/*
printf("_func_felread1: attr=%d size=%d scale=%d len=%d\n",attr,size,scale,len);
*/
	if (!(p1=cl_tmp_const_malloc(len+1))) return ECL_MALLOC_ERROR;
	if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK || attr==DEF_ZOK_DECI) {
		*ppWork = pWork = p1;
		pWork[len] = '\0';
	}
	if (size > 0) {
		m = _check_ssp_buf(p1,size,fp);
		ret = fread(p1+m,1,size-m,fp);
		pGlobTable->err_no = errno;
/*
printf("_func_felread1: fread: ret=%d errno=%d\n",ret,errno);
*/
		if (k = ferror(fp)) ret = -1;
		else if (ret>0 && ret<size) {
			if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK || attr==DEF_ZOK_DATE) size = ret;
			else ret = -1;
		}
/*
printf("_func_felread1: ferror: k=%d errno=%d\n",k,errno);
*/
		if (ret <= 0) {
#if 1	/* 2022.6.25 */
			ret = _set_file_read_error("_func_felread1",fp,ret);
			attr = DEF_ZOK_CHAR;
			size = 0;
#else
			if (ret)
				pGlobTable->exception = FILE_READ_EXCEPTION + pGlobTable->err_no;
			else {
				ret = ECL_END_OF_FILE;
				pGlobTable->exception = FILE_READ_END_EXCEPTION;
				ERROROUT("_func_felread1: end of file");
			}
			pGlobTable->error = ret;
			attr = DEF_ZOK_CHAR;
			size = 0;
			if (k) {
				ERROROUT2("_func_felread1: errno=%d %s",errno,strerror(errno));
			}
#endif
			_chk_heredoc_end(ret);	/* add 2022.4.27 */
#ifdef CANCEL_WHEN_EOF	/* 2022.6.24 */
			if (cl_get_option(7,0) & (0x20 | 0x40)) iRc = ret;
			else iRc = attr;
#else
			iRc = attr;
#endif
		}
		else if (ret > 0) {
			len = ret;
			if (attr == DEF_ZOK_DECI) len2 = 0;
			else len2 = size - scale;
			if (len2 > 0) {
				if (((attr==DEF_ZOK_BINA || attr==DEF_ZOK_FLOA) && scale0>=0) ||
				    ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK ||
				      attr==DEF_ZOK_DATE) && scale0<0)) {
					p2 = p1;
					p1 += len2;
				}
				else p2 = p1 + len2;
			}
			switch (attr) {
			case DEF_ZOK_BINA:
				if (scale == 1) {
					lVal = *p1;
				}
				else if (scale == 2) {
					memcpy(&ws,p1,sizeof(short));
					s = ntohs(ws);
					lVal = s;
				}
				else if (scale == 4) {
					memcpy(&iVal,p1,scale);
					lVal = ntohl(iVal);
				}
				else {
#if defined(_LP64)
					memcpy(&lVal_n,p1,scale);
					lVal = x_ntohll(lVal_n);
#else
					memcpy(val,p1,scale);
					lVal = ntohl(val[1]);
#endif
				}
				memcpy(pWork,&lVal,sizeof(long));
				size = sizeof(long);
				break;
			case DEF_ZOK_FLOA:
				memcpy(val,p1,scale);
				if (scale == 4) {
					i = ntohl(val[0]);
					memcpy(&fVal,&i,sizeof(int));
					dVal = fVal;
					memcpy(pWork,&dVal,sizeof(double));
				}
				else {
					if (CLcommon.ucByteOrder) {
						i = ntohl(val[1]);
						memcpy(pWork,&i,sizeof(int));
						i = ntohl(val[0]);
						memcpy(pWork+sizeof(int),&i,sizeof(int));
					}
					else
						memcpy(pWork,val,sizeof(double));
				}
				size = 8;
				break;
			case DEF_ZOK_DECI:
				pWork = p1+size;
				if (ret = m_unpack((MPA *)pWork,p1,dec_size,scale)) {
					if (ret == MPA_ERR_INVALID)
						ERROROUT("_func_felread1: m_unpack: invalid number!!");
					pGlobTable->exception = FILE_READ_EXCEPTION;
					pGlobTable->error = ret;
				}
				if (dec_size) {
					if ((ret=cl_mpa_scale(pWork,dec_size,scale)) < 0) return ret;
				}
				*ppWork = pWork;
				break;
			case DEF_ZOK_DATE:
				ma = (MPA *)(p1+size);
				*ma = *m_get_i(1);
				memcpy(ma->num,p1,size);
				ma->exp = 6;
				ma->len = D_LEN_DATE;
				*ppWork = (char *)ma;
				size = sizeofMPA();
				break;
			case DEF_ZOK_CHAR:
				/* 2022.4.14 */
				if (fp == stdin) iFILE = 0;
				else iFILE = 1;
				if ((ret=_getchar_code_conv(&p2,nparm-4,ppParm+4,p1,size,iFILE,iParm[4],0)) < 0) return ret;
				size = ret;
				p1 = p2;
DEBUGOUTL2(120,"_func_felread1: p1=%08x size=%d",p1,size);
				*ppWork = p1;
				break;
			default:
				size = scale;
				*ppWork = p1;
			}
			iRc = attr;
		}
	}
	iParm[0] = attr;
	iParm[1] = size;
#if 1	/* 2021.9.13 */
	iParm[2] = dec_size;
	iParm[3] = scale;
	iParm[4] = 0;
#else
	iParm[2] = scale;
/*	iParm[3] = 0;	*//* 2021.4.3 *//* del 2021.4.13 */
#endif
	return iRc;
}

/****************************************/
/*	_felwrite1							*/
/****************************************/
static int _felwrite1(pInfoParm,size,scale,fp,mode,tr_dtypea)
tdtInfoParm *pInfoParm;
int size,scale;
FILE *fp;
int mode,tr_dtypea[];	/* 1:binary mode */
{
	int iRc,ret,i,retval,len,attr,iVal,val[2];
	long lVal;
	char *p1,c,buf[256],*pW;
	uchar uc;
	short ws,s;
	double dVal;
	float  fVal;
	MPA mpaz,*mpa,*ma;
/*
printf("_felwrite1: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
*/
	attr = pInfoParm->pi_attr;
	p1   = pInfoParm->pi_data;
	len  = pInfoParm->pi_dlen;
	if (attr != DEF_ZOK_DECI) {
		if (scale <= 0) scale = len;
		else if (scale < len) len = scale;
	}
/*
printf("_felwrite1: size=%d scale=%d attr=%d len=%d\n",size,scale,attr,len);
*/
	switch (attr) {
		case DEF_ZOK_BINA:
			lVal = cl_get_data_long(pInfoParm);
/*
printf("_felwrite1: iVal=%d\n",iVal);
*/
			if (scale == 1) {
				c = lVal;
				p1 = &c;
			}
			else if (scale == 2) {
				ws = lVal;
				s = ntohs(ws);
				p1 = (char *)&s;
			}
			else if (scale == 4) {
				iVal = lVal;
				i = ntohl(iVal);
				p1 = (char *)&i;
/*
printf("_felwrite1: i=%08x\n",i);
*/
			}
			else {
#if defined(_LP64)
				lVal_n = x_htonll(lVal);
				p1 = (char *)&lVal_n;
#else
				val[1] = ntohl(lVal);
				if (lVal >= 0) val[0] = 0;
				else val[0] = -1;
				p1 = (char *)val;
#endif
				len = 8;
			}
			break;
		case DEF_ZOK_FLOA:
			if (scale == 4) {
				memcpy(&dVal,p1,sizeof(double));
				fVal = dVal;
/*
printf("_felwrite1: fVal=%f\n",fVal);
*/
				memcpy(&i,&fVal,sizeof(int));
				val[0] = ntohl(i);
			}
			else {
				memcpy(&iVal,p1,sizeof(int));
				val[1] = ntohl(iVal);
				memcpy(&iVal,p1+sizeof(int),sizeof(int));
				val[0] = ntohl(iVal);
/*
printf("_felwrite1: val=%08x %08x\n",val[0],val[1]);
*/
			}
			p1 = (char *)val;
			break;
		case DEF_ZOK_DECI:
			if (!size) {
				size = X_MIN(D_DEC_PRECISION,m_get_nmpa10());
				if (scale <= MIN_DEC_SCALE-1) scale = size/2;	/* D_DEC_SCALE */
			}
			if (size && scale>MIN_DEC_SCALE-1) {	/* scale<=MIN_DEC_SCALE-1 は、scale未設定を示す */
				mpa = (MPA *)cl_get_tmpMPA(&mpaz);
				m_cpy(mpa,(MPA *)p1,0);
				ma = mpa;
				if ((ret=cl_mpa_scale(ma,size,scale)) < 0) return ret;
			}
			else ma = (MPA *)p1;
			len = m_pack_size(buf,ma,size,scale);	/* scale<-NMPA10 のときは、scaleを使用しない*/
			if (len == MPA_ERR_SIZE_OVER)
				ERROROUT1("_felwrite1: m_pack_size: size(%d) is few!!",size);
			p1 = buf;
			break;
		case DEF_ZOK_DATE:
			len = D_LEN_DATE;
			ma = (MPA *)p1;
			p1 = ma->num;
			break;
		case DEF_ZOK_CHAR:
		/*	if (to_code >= 0) {	*/
				if (len > 0) {
#if 1	/* 2022.4.14 */
					pW = p1;
					if ((ret=_putchar_code_conv(&p1,pW,len,tr_dtypea)) < 0) return ret;
					len = ret;
#endif
					if ((ret=_func_fwrite_conv(p1,len,fp,mode,tr_dtypea[0])) < 0) {
						pGlobTable->err_no = errno;
					}
				}
/*
printf("_felwrite1: attr=%d size=%d scale=%d len=%d\n",attr,size,scale,len);
*/
				return ret;
		/*	}	*/
			break;
	}
/*
printf("_felwrite1: attr=%d size=%d scale=%d len=%d\n",attr,size,scale,len);
*/
	if (len > 0) {
		if ((ret = fwrite(p1,len,1,fp)) <= 0) {
			len = -1;
			pGlobTable->err_no = errno;
		}
	}
	return len;
}

/****************************************/
/*	felwrite(fp,data1,data2,...)		*/
/****************************************/
static int _func_felwrite(pWork,nparm,ppParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	static char *pnama[]={"TO_CODE","FROM_CODE"};
	tdtInfoParm *pInfoParm,*pParmW[2];
	int iRc,ret,i,retval,len,attr,iVal,val[2],j,k,scale,tr_dtypea[2];
	char *p1,c,buf[256];

	retval = 0;
#if 1	/* 2020.4.15 */
	tr_dtypea[0] = tr_dtypea[1] = 0;
	pParmW[0] = pParmW[1] = NULL;
	if ((ret=cl_get_pname_info(nparm,ppParm,pParmW,pnama,2)) < 0) return ret;
	else if (ret > 0) {
		for (i=0;i<2;i++) {
			if (pInfoParm=pParmW[i]) {
				if (ret=cl_get_parm_bin(pInfoParm,&tr_dtypea[i],"_func_felwrite:tr_dtype:")) return -1;
			}
		}
	}
#endif
	for (i=0;i<nparm;i++) {
		pInfoParm = ppParm[i];
		if (pInfoParm->pi_id == D_DATA_ID_PNAME) continue;	/* add 2022.4.15 */
		if (ret=cl_check_data_id(pInfoParm,0)) {
			ret += ECL_CHK_VAR_ERROR;
			break;
		}
		scale = 0;
		if (pInfoParm->pi_attr == DEF_ZOK_DECI) scale = MIN_DEC_SCALE-1;
		ret = _felwrite1(pInfoParm,0,scale,fp,iParm[4],tr_dtypea);
		if (ret >= 0) {
			retval += ret;
			ret = 0;
		}
		else break;
	}
	if (ret < 0) {
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		pGlobTable->error = ret;
		pGlobTable->err_no = errno;
		retval = ret;
		if (errno)
			ERROROUT2("_func_felwrite: errno=%d %s",errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return 0;
}

/********1*********2*********3*********4*********5*********6*/
/*	felwrite1(fp,data,size,scale,to_code,from_code)			*/
/*	pParm[0]:data											*/
/************************************************************/
static int _func_felwrite1(pWork,nparm,ppParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	tdtInfoParm *pInfoParm;
	int ret,retval,attr,len,size,scale,scale0,len2,mae_clear,len3,alen,to_code,i,ii,tr_dtypea[2];
	char *p1,c,buf[256],*p2;

	retval = 0;
	pInfoParm = ppParm[0];
	if (ret=cl_check_data_id(pInfoParm,0)) return ret+ECL_CHK_VAR_ERROR;

	attr = pInfoParm->pi_attr;
	p1   = pInfoParm->pi_data;
	len  = pInfoParm->pi_dlen;
	iParm[0] = attr;
	if (attr == DEF_ZOK_DECI) {
		iParm[1] = 0;	/*D_DEC_PRECISION;*/
		iParm[2] = MIN_DEC_SCALE-1;	/* 設定なしのときの判定用 *//*D_DEC_SCALE*/
	}
	else {
		iParm[1] = len;
		iParm[2] = 0;
	}
	if (ret=_get_size_scale("_func_felwrite1",nparm-1,ppParm+1,iParm)) return ret;
#if 0	/* 2021.4.3 */
	size   = iParm[1];
	scale  = iParm[2];
	scale0 = scale;
	if (scale0 < 0) scale = -scale;
#else
	scale0 = iParm[3];	/* 2021.1.1 0-->3 */
	size   = iParm[1];
	scale  = iParm[2];
	iParm[3] = 0;	/* 2021.1.1 */
#endif
	len3 = 0;
	if (attr == DEF_ZOK_DECI) {
		len2 = 0;
	/*	scale = scale0;	*/
	}
	else {
		len2 = size - scale;
		if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK) {
			if (scale > len) {
				len3 = scale - len;
				scale = len;
			}
		}
	}
	if (len2 > 0) {
		if (((attr==DEF_ZOK_BINA || attr==DEF_ZOK_FLOA) && scale0>=0) ||
		    ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK ||
		      attr==DEF_ZOK_DATE) && scale0<0)) {
			mae_clear = 1;
		}
		else {
			mae_clear = -1;
		}
	}
	if ((alen=len2+len3) > 0) {
		p2 = buf;
		if (alen > sizeof(buf)) {
			if (!(p2=cl_tmp_const_malloc(alen))) return ECL_MALLOC_ERROR;
		}
		if (attr == DEF_ZOK_CHAR) memset(p2,' ',alen);
		else if (attr != DEF_ZOK_DECI) memset(p2,0,alen);
	}
	else mae_clear = 0;
/*
printf("_func_felwrite1: mae_clear=%d len2=%d len3=%d\n",mae_clear,len2,len3);
*/
	ret = 0;
	if (mae_clear > 0) {
		if ((ret = fwrite(p2,len2,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len2;

	}
	if (ret >= 0) {
		to_code = 0;
		tr_dtypea[0] = tr_dtypea[1] = 0;
		if (attr==DEF_ZOK_CHAR && nparm>=4) {
#if 1	/* 2022.4.15 */
			ii = 0;
			for (i=3;i<nparm;i++) {
				if (ret=cl_get_parm_bin(ppParm[i],&tr_dtypea[ii],"_func_felwrite1:tr_dtype:")) return -1;
				if (ii >= 1) break;
				ii++;
			}
/*
printf("_func_felwrite1: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
*/
#else
			if (cl_get_parm_bin(ppParm[3],&to_code,"_func_felwrite1:to_code:")) return -1;
#endif
		}
		ret = _felwrite1(pInfoParm,size,scale,fp,iParm[4],tr_dtypea);
		if (ret >= 0) {
			retval += ret;
		}
	}
	if (ret>=0 && len3>0) {
		if ((ret = fwrite(p2,len3,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len3;
	}
	if (ret>=0 && mae_clear<0) {
		if ((ret = fwrite(p2,len2,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len2;
	}
	if (ret < 0) {
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		pGlobTable->error = ret;
		pGlobTable->err_no = errno;
		retval = ret;
		if (errno)
			ERROROUT2("_func_felwrite1: errno=%d %s",errno,strerror(errno));
	}
	else ret = 0;
/*
printf("_func_felwrite1: retval=%d\n",retval);
*/
/*	iParm[3] = 0;	*//* 2021.4.3 *//* del 2021.4.13 */
	memcpy(pWork,&retval,sizeof(int));
	return ret;
}

/****************************************/
/*	getchar(fp,size,opt)				*/
/*		iParm[4]:<>0:バイナリモード		*/
/****************************************/
static int _func_getchar(ppWork,nparm,ppParm,ope,iParm,fp)
char **ppWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	int ret,from_code,m,ex_opt,len,opt,len_hd,len_min,to_code,i,tr_dtypea[2],iFILE,tr_dtype,iREAD_TO_EOF;
	char *p,*pW,*p1,c,*p_hd;
	ProcCT  *proc;
	tdtREDIRECT *red;

	pW = "";
	len_hd = ret = 0;
	len_min = D_GETCHAR_MIN_READ_LEN;
	proc = cl_search_proc_ct();
	red = proc->redirect;
	if (p_hd = red->HereDoc_nm) {
		len_hd = strlen(p_hd);
		if (len_hd > len_min) len_min = len_hd;
	}
	p = ssp_get.wd;
	if ((len=m=ssp_get.sp) < len_min) {
		if (m > 0) c = *(p+m-1);
		else c = '\0';
		if (!ssp_get.attr[3] && c!='\n') {
			ex_opt = cl_get_option(3,0);
			if (ex_opt & 0x10) opt = 0;
			else opt = 0x01;
			if ((ret=akxa_get_line(p+m,D_GETCHAR_PRE_READ_LEN+1-m,fp,opt)) > 0) {
				len = ret + m;
/*
printf("_func_getchar:1 len=%d p=[%s]\n",len,p);
*/
			}
			else {
/*
printf("_func_getchar: ret=%d c=[%s] %02x\n",ret,c,c);
*/
				ssp_get.attr[3] = 1;	/* File End */
				/* wrk_get[]にデータが残っている状態でEOFになってもエラーにせず、
				   残りのデータを返せるようにするためと、そのときにデータを読みに
				   行かないようにするため。 */
			/*	if (!ret) ret = -1;		del 2022.1.9 */
			}
		}
	}
	iREAD_TO_EOF = 1;
	if (len>0 && len_hd) {	/* 2022.1.8 */
/*
printf("_func_getchar: len_hd=%d p_hd=[%s] p=[%s]\n",len_hd,p_hd,p);
*/
		if (!memcmp(p,p_hd,len_hd)) {
		/*	_heredoc_end();	*/
			_check_ssp_buf(NULL,-1,fp);
			len = -1;
			iREAD_TO_EOF = 0;
		}
	}
	if (len > 0) {
/*
printf("_func_getchar:2 CLcommon.Quot[3]=%d len =%d p=[%s]\n",CLcommon.Quot[3],len,p);
*/
		/* 2022.4.14 */
		if (fp == stdin) iFILE = 0;
		else iFILE = 1;
		if ((m=_getchar_code_conv(&pW,nparm,ppParm,p,len,iFILE,iParm[4],1)) < 0) return m;
		ret = 0;
	}
	else {
		_chk_heredoc_end(iREAD_TO_EOF);
		if (!ret) ret = -1;
		if (ope == D_FUC_GETCHAR) p = "getchar";
		else p = "getc";
		ret = _set_file_read_error(p,fp,ret);
		ssp_get.sp = 0;
		ssp_get.attr[3] = 0;	/* 2022.1.8 */
	}
	iParm[0] = DEF_ZOK_CHAR;
	iParm[1] = m;
	iParm[2] = 0;
	iParm[3] = 0;
	iParm[4] = 0;
	*ppWork = pW;
#ifdef CANCEL_WHEN_EOF	/* 2022.6.24 */
	if (cl_get_option(7,0) & (0x20 | 0x40)) return ret;
	else return 0;
#else
	return 0;
#endif
}

/****************************************/
/*	putchar(to_code)					*/
/****************************************/
static int _func_putchar(pWork,nparm,ppParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
FILE *fp;
{
	int len1,to_code,m,ret,i,tr_dtypea[2],tr_dtype,ii;
	char *p1,*pW;

	p1 = NULL;
	m = 0;
	if ((len1=parm_to_char(ppParm[0],&p1,NULL))<0) return len1;
	else if (len1 > 0) {
		tr_dtypea[0] = tr_dtypea[1] = 0;
		ii = 0;
		for (i=1;i<nparm;i++) {
			if (ret=cl_get_parm_bin(ppParm[i],&tr_dtypea[ii],"_func_putchar:tr_dtype:")) return -1;
			if (ii >= 1) break;
			ii++;
		}
/*
printf("_func_putchar: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
*/
		tr_dtype = tr_dtypea[1];
		if ((m=akxqmbsnlen(tr_dtype,p1,len1)) < 0) return m;
/*
printf("_func_putchar:1 m=%d p1=[%s]\n",m,p1);
*/
		/* 2022.4.11 */
		/* 2022.4.14 */ 
		pW = p1;
		if ((ret=_putchar_code_conv(&p1,pW,m,tr_dtypea)) < 0) return ret;
		m = ret;
/*
printf("_func_putchar:2 m=%d p1=[%s]\n",m,p1);
*/
		/* fpがファイルかどうかは、_func_fwrite_conv()の中で調べている */
		if ((ret=_func_fwrite_conv(p1,m,fp,0,tr_dtypea[0])) < 0) {
			pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
			pGlobTable->error = ret;
			pGlobTable->err_no = errno;
			if (errno) {
				if (ope == D_FUC_PUTCHAR) p1 = "putchar";
				else p1 = "putc";
				ERROROUT3("%s: errno=%d %s",p1,errno,strerror(errno));
			}
			m = ret;
		}
	}
	memcpy(pWork,&m,sizeof(int));
	return 0;
}

/****************************************/
/*	readdir(dp)							*/
/****************************************/
static int _func_readdir(ppWork,iParm,dp)
char **ppWork;
int iParm[];
DIR *dp;
{
	struct dirent *dir;
	char *p1;
	int  len,ret;

	/*** ディレクトリのファイル名を取得する ***/
	dir = readdir(dp);
	if (dir) {
		p1  = dir->d_name;
		len = strlen(p1);
/*
printf("_func_readdir: file=[%s]\n",p1);
*/
		if (!(*ppWork = cl_tmp_const_malloc(len+1))) return ECL_MALLOC_ERROR;
		/* ファイル名のコピー */
		strcpy(*ppWork,p1);
	}
	else {
		*ppWork = "";
		if (errno) {
			ERROROUT2("_func_readdir: errno=%d %s",errno,strerror(errno));
			pGlobTable->exception = FILE_READ_EXCEPTION + errno;
			ret = -1;
		}
		else {
			pGlobTable->exception = FILE_READ_END_EXCEPTION;
			ret = ECL_END_OF_FILE;
			ERROROUT("_func_readdir: end of dir");
		}
		pGlobTable->error = ret;
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int func_file(ppWork,pOperator,nparm,ppParm,ope,iParm)
char **ppWork;
char *pOperator;
tdtInfoParm *ppParm[];
int nparm,ope,iParm[];
{
	tdtInfoParm *pInfoParm;
	int iRc,ret,size,attr,scale;
	char *pWork,*fnam;
	FILE *fp;
#if 1	/* 2022.4.23 */
	ProcCT  *scrct;
#else
	ScrPrCT	*scrct;
#endif
	tdtREDIRECT *red;
/*
printf("func_file: pOperator=%s nparm=%d ope=%d\n",pOperator,nparm,ope);
*/
	pGlobTable->error = 0;
	pWork = *ppWork;
	iRc = size = attr = scale = 0;
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = scale;
	if (ope==D_FUC_FOPEN || ope==D_FUC_POPEN ||	/* fopen, popen */
	    ope==D_FUC_OPENDIR ||	/* opendir */
	    ope==D_FUC_STAT    || 	/* stat */
	    ope==D_FUC_UNLINK) {	/* unlink */
		iRc =  _func_fopen(pWork,nparm,ppParm,ope,iParm);
	}
	else {
#if 1	/* 2022.4.23 */
		scrct = cl_search_proc_ct();
#else
		scrct = cl_search_src_ct();
#endif
		red = scrct->redirect;
		if (ope==D_FUC_FCLOSE    || ope==D_FUC_PCLOSE   ||
		    ope==D_FUC_CLOSEDIR  || ope==D_FUC_READDIR  ||
		    ope==D_FUC_FGETLINE  || ope==D_FUC_FPUTLINE ||
		    ope==D_FUC_GETC      || ope==D_FUC_PUTC     ||
		    ope==D_FUC_FELREAD1  || ope==D_FUC_FELWRITE ||
		    ope==D_FUC_FELWRITE1 || ope==D_FUC_FPSTAT   ) {
			pInfoParm = ppParm[0];
			if (pInfoParm->pi_attr == DEF_ZOK_BINA)
				fp = (FILE *)cl_get_data_long(pInfoParm);
			else {
				/* ope=%d fpの属性が不正です。 */
				ERROROUT1(FORMAT(582),ope);
				return -1;
			}
			nparm--;
			ppParm++;
		}
		/* 2021.8.7 */
		else if (ope==D_FUC_GETLINE || ope==D_FUC_ELREAD1
		                            || ope==D_FUC_GETCHAR) fp = red->stdio[0];
		else if (ope==D_FUC_PUTLINE || ope==D_FUC_ELWRITE ||
		         ope==D_FUC_PUTCHAR || ope==D_FUC_ELWRITE1) fp = red->stdio[1];
		else {
			ERROROUT1("func_file: operater=%d not defined!!",ope);
			return -1;
		}
		if (!fp) {
			ERROROUT1("ope=%d fp is NULL.",ope);
			pGlobTable->exception = FILE_EXCEPTION;
			pGlobTable->error = ret = -1;
			memcpy(pWork,&ret,sizeof(int));
		}
		else {
			if (fp == stdin) fnam = " stdin";
			else if (fp == stdout) fnam = " stdout";
			else if (fp == stderr) fnam = " stderr";
			else if (_check_fp('R',fp,&fnam,NULL) <= 0) {
/*
printf("func_file: fp=%08x\n",fp);
*/
				/* ope=%d fpはclose済みです。 */
				ERROROUT1(FORMAT(583),ope);
				pGlobTable->exception = FILE_EXCEPTION;
				pGlobTable->error = ret = -1;
				memcpy(pWork,&ret,sizeof(int));
				return 0;
			}
/*
printf("func_file: fnam=[%s]\n",fnam);
*/
			if (*fnam == 'B') iParm[4] = 1;
			else iParm[4] = 0;
			switch (ope) {
			case  D_FUC_FCLOSE:	/* fclose(fp) */
			case  D_FUC_PCLOSE:	/* pclose(fp) */
			case  D_FUC_CLOSEDIR:	/* closedir(dp) */
				iRc = _func_close(pWork,ope,fp);
				break;

			case D_FUC_FGETLINE:	/* fgetline(fp,size,opt) */
				if (fp == stdin) fp = red->stdio[0];
			case D_FUC_GETLINE:		/* getline(size,opt) */
				iRc = _func_fgetline(ppWork,nparm,ppParm,ope,iParm,fp);
				break;
			case D_FUC_GETC:		/* getc([form_code]) */
				if (fp == stdin) fp = red->stdio[0];
			case D_FUC_GETCHAR:		/* getchar([form_code]) */
				iRc = _func_getchar(ppWork,nparm,ppParm,ope,iParm,fp);
				break;

			case D_FUC_FPUTLINE:	/* fputline(fp,data1,data2,...) */
				if (fp == stdout) fp = red->stdio[1];
				else if (fp == stderr) fp = red->stdio[2];
			case D_FUC_PUTLINE:		/* putline(data1,data2,...) */
				iRc = _func_fputline(pWork,nparm,ppParm,ope,iParm,fp);
				break;

			case D_FUC_FELREAD1:	/* felread1(fp,attr,size,scale) */
				if (fp == stdin) fp = red->stdio[0];
			case D_FUC_ELREAD1:		/* elread1(attr,size,scale) */
				iRc = _func_felread1(ppWork,nparm,ppParm,ope,iParm,fp);
				break;

			case D_FUC_FELWRITE:	/* felwrite(fp,data1,data2,...) */
				if (fp == stdout) fp = red->stdio[1];
				else if (fp == stderr) fp = red->stdio[2];
			case D_FUC_ELWRITE:		/* elwrite(data1,data2,...) */
				iRc = _func_felwrite(pWork,nparm,ppParm,ope,iParm,fp);
				break;
			case D_FUC_PUTC:		/* putc([to_code]) */
				if (fp == stdout) fp = red->stdio[1];
				else if (fp == stderr) fp = red->stdio[2];
			case D_FUC_PUTCHAR:		/* putchar([to_code]) */
				iRc = _func_putchar(pWork,nparm,ppParm,ope,iParm,fp);
				break;

			case D_FUC_FELWRITE1:	/* felwrite1(fp,data,size,scale) */
				if (fp == stdout) fp = red->stdio[1];
				else if (fp == stderr) fp = red->stdio[2];
			case D_FUC_ELWRITE1:	/* elwrite1(data,size,scale) */
				iRc = _func_felwrite1(pWork,nparm,ppParm,ope,iParm,fp);
				break;

			case D_FUC_READDIR:		/* readdir(dp) */
				iRc = _func_readdir(ppWork,iParm,(DIR *)fp);
				break;

			case D_FUC_FPSTAT:		/* fpstat(fp) */
				iRc = _func_fpstat(pWork,NULL,nparm,ppParm,fp);
				break;

			default:
				ERROROUT1("func_file: operater=%d not defined!!",ope);
				iRc = -1;
			}
		}
	}
/*	iParm[0] = 0;	*/
/*
printf("func_file:Exit iRc=%d\n",iRc);
*/
	return iRc;
}

/****************************************/
/*										*/
/****************************************/
int cl_free_fp(hp)
HASHB *hp;
{
	long i,max;
	FILE *fp;
	char *p,pna[10],*argv[2];
	int rc;

	hp->ha_key = (char *)argv;
	argv[0] = argv[1] = NULL;
	max = hp->ha_maxreg;
	for (i=1;i<=max;i++) {
		hp->ha_hix = i;
		if (akxshaslk(hp,&fp) > 0) {
			p = argv[1];
			rc = cl_close_fp(fp,p,pna,sizeof(pna));
			if (rc >= 0) {
				if (p) ERROROUT2(FORMAT(398),pna,p);		/* %s[%s]をクローズしました。 */
			}
			if (p) Free(p);
		}
	}
	akxs_hasl_free(hp);
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int cl_check_close_fp(fp)
FILE *fp;
{
	char *p1,*pw;
	int ret;
/*
printf("cl_check_close_fp: fp=%08x\n",fp);
*/
	if (fp==stdin || fp==stdout || fp==stderr) {
		ret = 1;
	}
	else if ((ret=_check_fp('D',fp,&p1,NULL)) > 0) {
		if (!(pw = p1)) pw = " ";
		pw++;
		ret= cl_close_fp(fp,pw,NULL,0);
		if (ret >= 0) {
			PRINTOUT2("cl_check_close_fp: close fp=%08x file=[%s].",fp,pw);
		}
		if (p1) Free(p1);
		ret = 0;
	}
	return ret;
}

/****************************************/
/*										*/
/****************************************/
int cl_close_fp(fp,p,pna,len)
FILE *fp;
char *p,*pna;
int  len;
{
	int rc;
	char *pn;
	struct stat tStat;

	if ((rc = fileno(fp)) >= 0) {
		rc = fstat(rc,&tStat);
	}
/*
printf("rc=%d tStat.st_mode=%08x\n",rc,tStat.st_mode);
*/
	if (rc < 0) {
				/* file/pipe/dir[%s]用のfpは無効です。 */
		if (p) ERROROUT1(FORMAT(584),p);
		pn = "error";
	}
	else {
		if (S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode)) {
/*
printf("closedir fp=%08x\n",fp);
*/
			closedir((DIR *)fp);
			pn = "dir";
		}
		else if (S_ISFIFO(tStat.st_mode)) {
			pclose(fp);
			pn = "pipe";
		}
		else {
			fclose(fp);
			pn = "file";
		}
		pGlobTable->err_no = errno;
	}
	len--;
	if (pna && len>=5) strnzcpy(pna,pn,len);
	return rc;
}

/****************************************/
/*										*/
/****************************************/
int cl_ank_conv(pAns,p1,len)
char **pAns;
char *p1;
int len;
{
	char *p,*pp,*p2,c;
	int ret,i,m,k;

	if (!pAns || !(p=p1)) return -1;
	k = ret = 0;
	*pAns = NULL;
	if (len > 0) {
		ret = len;
		if (!(p2 = cl_tmp_const_malloc(len*3))) return ECL_MALLOC_ERROR;
		pp = p2;
		while (len > 0) {
			m = akxqkanjilen2(p,len);
			if (m > 1) {
				memcpy(pp,p,m);
				pp += m;
			}
			else {
				if ((c=*p)=='\t' || c=='\n' || akxqisank(c)) *pp++ = c;
				else {
					sprintf(pp,"<%d>",c);
					pp += strlen(pp);
					k++;
				}
			}
			p += m;
			len -= m;
		}
		if (k) {
			*pp = '\0';
			ret = strlen(p2);
			*pAns = p2;
		}
	}
	return ret;
}

/****************************************/
/*	inout = 0/1 : input/output			*/
/*	iFILE = 0/1 : stdio/file			*/
/*	code_type>0 : code_typeに変換		*/
/*			 =0 : option21で変換		*/
/*			 <0 ; 変換しない			*/
/****************************************/
int cl_file_code_conv(pAns,p1,len,inout,iFILE,code_type)
char **pAns;
char *p1;
int len,inout,iFILE,code_type;
{
	int opt,ret;
/*
printf("cl_file_code_conv:Enter len=%d inout=%d iFILE=%d code_type=%d\n",len,inout,iFILE,code_type);
*/
	if (len <= 0) {
		*pAns = p1;
		return len;
	}
	opt = 0;
	code_type &= 0x07;
	if (code_type > 0) {
		opt = code_type & 0x07;
		if (opt >= 7) opt = 6;
		if (!inout) opt <<= 8;
	/*	if (iFILE) opt <<= 4;	*/
	}
	else if (!code_type) {
		opt = (cl_get_option(21,0) & 0xffff);
		if (iFILE) opt = (opt>>4) & 0x0f0f;
	}
/*
printf("cl_file_code_conv: opt=%08x\n",opt);
*/
	if (opt) {
		opt |= (cl_get_option(9,0) & 0x10)<<12;

DEBUGOUTL3(120,"cl_file_code_conv: pi=%08x inout=%d opt=%08x",p1,inout,opt);

		ret = akxc_file_code_conv(pAns,p1,len,inout,opt);
	}
	else {
		ret = len;
		*pAns = p1;
	}
/*
printf("cl_file_code_conv:Exit ret=%d\n",ret);
*/
	return ret;
}

/****************************************/
/*										*/
/****************************************/
static int _heredoc_end_set(red)
tdtREDIRECT *red;
{
	int rc;
	char *p;
/*
printf("_heredoc_end_set:Enter red=%08x\n",red);
*/
	rc = 0;
	if (red->pFlag2 & D_PFLAG2_ALC_HDNM) {
		red->stdio[0] = red->stdio[3];
		red->stdio[3] = NULL;
		if ((p=red->HereDoc_nm)) {
/*
printf("_heredoc_end_set: free red->HereDoc_nm=[%s]\n",p);
*/
			Free(p);
		}
		red->pFlag2 &= ~D_PFLAG2_ALC_HDNM;
		rc = 1;
	}
	red->HereDoc_nm = NULL;
	return rc;
}

/****************************************/
/*	heredocがeofを読んだとき、または	*/
/*	fpがEOFのとき、または、heredocが	*/
/*	変更されたとき呼ばれる				*/
/****************************************/
int cl_heredoc_end(scrct,proc,read_to_eof)
ScrPrCT	*scrct;
ProcCT  *proc;
int read_to_eof;
{
	ScrPrCT	*next_scr,*cur_scr;
	ProcCT  *next_proc,*cur_proc;
	FILE *HereDocfp,*fp;
	char *p,*preHereDoc_nm;
	int iBREAK,rc;
	tdtREDIRECT *red,*redscr;
/*
printf("cl_heredoc_end:Enter\n");
*/
	if (!scrct) scrct = cl_search_src_ct();
	if (!scrct) return -1;
	if (!proc) proc = cl_search_proc_ct();
	if (!proc) return -1;
	red = proc->redirect;
	if (!red->HereDoc_nm) return 0;
	/* 2022.4.23 */
	HereDocfp = red->stdio[0];
/*
printf("cl_heredoc_end: proc=%08x HereDocfp=%08x\n",proc,HereDocfp);
*/
	if (read_to_eof) {
		if ((rc=_heredoc_skip_to_eof(red)) < 0) return rc;
	}
	p = red->HereDoc_nm;
	if (!(red->pFlag2 & D_PFLAG2_NOT_CLOSE))
		cl_check_close_fp(HereDocfp);	/* add 2022.4.22 */
	fp = NULL;
	cur_scr = scrct;
	while (cur_scr) {
		iBREAK = 0;
		redscr = cur_scr->redirect;
		cur_proc = cur_scr->CurProc;
		while (cur_proc) {
			red = cur_proc->redirect;
/*
printf("cl_heredoc_end: cur_proc=%08x red->stdio[0]=%08x\n",cur_proc,red->stdio[0]);
*/
			if (red->stdio[0] == HereDocfp) {
				_heredoc_end_set(red);
/*
printf("cl_heredoc_end: proc fp same. clear heredoc.\n");
*/
			}
			else {
/*
printf("cl_heredoc_end: not same. heredoc break .\n");
*/
				iBREAK = 1;
				break;
			}
			next_proc = cur_proc;
			cur_proc = next_proc->prePCT;
		}
		if (iBREAK) break;
/*
printf("cl_heredoc_end: cur_scr=%08x redscr->stdio[0]=%08x\n",cur_scr,redscr->stdio[0]);
*/
		if (redscr->stdio[0] == HereDocfp) {
			if (_heredoc_end_set(redscr)) break;
/*
printf("cl_heredoc_end: scr same fp. clear heredoc.\n");
*/
		}
		next_scr = cur_scr;
		cur_scr = next_scr->preScCT;
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
static int _heredoc_end(read_to_eof)
int read_to_eof;
{
	return cl_heredoc_end(NULL,NULL,read_to_eof);
}

/****************************************/
/*										*/
/****************************************/
static int _chk_heredoc_end(read_to_eof)
int read_to_eof;
{
	ProcCT *proc;
	int ret;

	ret = 0;
	proc = cl_search_proc_ct();
	if (proc->redirect->HereDoc_nm)
		ret = cl_heredoc_end(NULL,proc,read_to_eof);
	return ret;
}

/****************************************/
/*										*/
/****************************************/
static int _skip_line_to_eof(fp,p,trim_opt)
FILE *fp;
char *p;
int trim_opt;
{
	int rc;
	char buf[64],*pWk;
/*
printf("_skip_line_to_eof: trim_opt=%02x HereDoc_nm=[%s]\n",trim_opt,p);
*/
	while ((rc=akxa_read_line(buf,sizeof(buf),fp)) >= 0) {
/*
printf("_skip_line_to_eof: buf=[%s]\n",buf);
*/
		if (rc > 0) {
			if (trim_opt) {
				pWk = akxttrim2(trim_opt|2,buf,&rc);
/*
printf("_skip_line_to_eof: pWk=[%s]\n",pWk);
*/
			}
			else pWk = buf;
			if (rc > 0) {
				rc = 0;
				if (!strcmp(pWk,p)) break;
			}
		}
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
static int _heredoc_skip_to_eof(red)
tdtREDIRECT *red;
{
	FILE *HereDocfp;
	int rc,trim_opt;
	char *p;
/*
printf("_heredoc_skip_to_eof:Enter red=%08x\n",red);
*/
	rc = 0;
	HereDocfp = red->stdio[0];
	p = red->HereDoc_nm;
	if (p) {
		trim_opt = red->pFlag2 & (D_PFLAG2_DEL_TAB | D_PFLAG2_DEL_SPACE);
		_skip_line_to_eof(HereDocfp,p,trim_opt);
	}
	else {
			/* %s: heredocの内部設定(stdio[3]=%08x HereDocfp=%08x p=%08x)が不正です。*/
		ERROROUT4(FORMAT(633),"_heredoc_skip_to_eof",red->stdio[3],HereDocfp,p);
		rc = -1;
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
int cl_heredoc_skip_to_eof_close(red)
tdtREDIRECT *red;
{
	int rc;
/*
printf("cl_heredoc_skip_to_eof_close:Enter red=%08x\n",red);
*/
	rc = 0;
	if (red->pFlag2 & D_PFLAG2_NOT_CLOSE)
		rc = _heredoc_skip_to_eof(red);
	else
		cl_check_close_fp(red->stdio[0]);
	_heredoc_end_set(red);

	return rc;
}

/************************************************/
/* proc or scrctが終了するときに呼ばれる		*/
/* proc or scrctがHEREDOCを設定したprocであり	*/
/* HEREDOCが元に戻っていないときは、			*/
/* 終端文字列まで読み込む。						*/
/************************************************/
int cl_heredoc_skip_to_eof(red)
tdtREDIRECT *red;
{
	FILE *HereDocfp;
	char *p;
	int i,rc,f;
/*
printf("cl_heredoc_skip_to_eof:Enter red=%08x\n",red);
*/
	if (!red) return -1;
	rc = 0;
	/* 2022.4.23 */
	if (red->stdio[3] && (red->pFlag2 & D_PFLAG2_ALC_HDNM)) {
		if ((rc=cl_heredoc_skip_to_eof_close(red)) < 0) return rc;
	}
/*
printf("cl_heredoc_skip_to_eof: red->pFlag2=%08x\n",red->pFlag2);
*/
	f = D_PFLAG2_SET_STDIN;
	for (i=0;i<3;i++) {
		if (red->pFlag2 & f) {
			cl_check_close_fp(red->stdio[i]);
			red->stdio[i] = NULL;
		}
		f += f;
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
int cl_dummy_get_line(fp)
FILE *fp;
{
	int c,c2,len;

	len = 0;
	while ((c=getc(fp)) != EOF) {
		len++;
		if (c == '\r') {
			c2 = getc(fp);
			if (c2 == '\n') {
				len++;
				break;
			}
			else ungetc(c2,fp);
		}
		else if (c == '\n') break;
	}
	if (c < 0) len = -len;
	return len;
}

/****************************************/
/*										*/
/****************************************/
int cl_skip_line(fp,n)
FILE *fp;
int n;
{
	int i,ii,rc;

	ii = 0;
	for (i=0;i<n;i++) {
		rc = cl_dummy_get_line(fp);
		if (rc <= 0) {
			if (rc < 0) ii++;
			ii = -ii;
			break;
		}
		ii++;
	}
/*
printf("cl_skip_line: ii=%d\n",ii);
*/
	return ii;
}

/****************************************/
/*										*/
/****************************************/
int cl_func_redirect(pInfoParmW,nparm,ppParm)
tdtInfoParm *pInfoParmW;
int  nparm;
tdtInfoParm *ppParm[];
{
	static char *_fn_="cl_func_redirect";
	static char stdio[8];
	FILE *fp;
	long lVal;
	int rc,len,dlen,opt,opt_n,stdio_no,reset;
	char *name,*fnam,*p,*p0;
	tdtInfoParm *pInfoParm;
	ProcCT *proc;
	tdtREDIRECT *red;

	if ((rc=cl_get_parm_long(ppParm[0],&fp,"fp:")) < 0) return rc;
	else if (rc > 0) return ECL_SCRIPT_ERROR;
	if (fp) {
		if (nparm < 2) {
			ERROROUT1(FORMAT(42),_fn_);	/* %s: パラメータが足りません。 */
			return ECL_SCRIPT_ERROR;
		}
		fnam = NULL;
		if (fp == stdin) fnam = " stdin";
		else if (fp == stdout) fnam = " stdout";
		else if (fp == stderr) fnam = " stderr";
		if (fnam) {
			ERROROUT2(FORMAT(318),_fn_,fnam);	/* %s: %sは使用できません。 */
			return ECL_SCRIPT_ERROR;
		}
	}
	else if (nparm >= 3) {
		ERROROUT1(FORMAT(41),_fn_);	/* %s: 不要なパラメータがあります。 */
		return ECL_SCRIPT_ERROR;
	}
	name = NULL;
	stdio_no = 0;
	if (nparm >= 2) {
		pInfoParm = ppParm[1];
		if (pInfoParm->pi_id==' ' && pInfoParm->pi_attr==DEF_ZOK_BINA) {
			stdio_no = cl_get_data_long(pInfoParm);
			if (stdio_no <0 || stdio_no>2) {
				ERROROUT1(FORMAT(577),rc);	/* (%d)が不正です。*/
				return ECL_SCRIPT_ERROR;
			}
			cl_is_redirect_fp(stdio,stdio_no+1);
			len = 1;
			name = "";
		}
		else if ((len=parm_to_char(ppParm[1],&name,NULL)) <= 0) {
			ERROROUT1(FORMAT(486),_fn_);	/* %s: パラメータがNULLです。 */
			return ECL_SCRIPT_ERROR;
		}
		else {
			if (nparm >= 3) {
				if ((rc=cl_get_parm_bin(ppParm[2],&opt,"opt")) < 0) return ECL_SCRIPT_ERROR;
			}
			else opt = 0;
			strcpy(stdio,"STDIN");
		}
	}
	if (fp) {
		dlen = sizeof(FILE *) + len + sizeof(int);
#if 1
		if (p = cl_tmp_const_malloc(dlen)) {
#else
		if (p = Malloc(dlen)) {
#endif
#if defined(_LP64)
			lVal = x_htonll((long)fp);
#else
			lVal = htonl((uint)fp);
#endif
			opt_n = htonl(opt);
			p0 = p;
			memcpy(p,&lVal,sizeof(FILE *));
			p += sizeof(FILE *);
			memcpy(p,&opt_n,sizeof(int));
			memcpy(p+sizeof(int),name,len);
#if 1
			if (pInfoParm = (tdtInfoParm *)cl_tmp_const_malloc(sizeof(tdtInfoParm))) {
#else
			if (pInfoParm = (tdtInfoParm *)Malloc(sizeof(tdtInfoParm))) {
#endif
				memset(pInfoParm,0,sizeof(tdtInfoParm));
				pInfoParm->pi_id = ' ';
				pInfoParm->pi_attr = DEF_ZOK_BULK;
				pInfoParm->pi_data = p0;
				pInfoParm->pi_dlen = dlen;
			/*	pInfoParm->pi_scale |= D_DATA_MALLOC;	*/
				cl_set_parm_long(pInfoParmW,(long)pInfoParm);
				pInfoParmW->pi_id = D_DATA_ID_PNAME;
/*
printf("%s: stdio=[%s]\n",_fn_,stdio);
*/
				pInfoParmW->pi_paux = stdio;
			/*	pInfoParmW->pi_scale |= D_DATA_MALLOC | D_DATA_INDEX_FREE;	*/
				rc = 0;
			}
			else rc = -1;
		}
		else rc = -1;
	}
	else {
		proc = cl_search_proc_ct();
		red = proc->redirect;
		if (!stdio_no && red->HereDoc_nm) rc = cl_heredoc_end(NULL,proc,1);
		else {
			reset = 1;
			if (stdio_no == 1) reset = 2;
			else if (stdio_no == 2) reset = 4;
			/* 2022.5.22 */
			rc = cl_reset_stdio_redirect(red,reset,proc);
		}
	}
	return rc;
}

/****************************************/
/*										*/
/****************************************/
int cl_is_redirect_fp(name,fn)
char *name;
int fn;
{
	static char *white[] = {
		 "1","STDIN" ,"SYSIN" ,""
		,"2","STDOUT","SYSOUT",""
		,"3","STDERR","SYSERR",""
		,NULL};
	int rc;
	char wrk[12];

	if (fn > 0) {
		cmn_i_to_a(fn,wrk);
		if ((rc=akxs_seqr_str_num(white,-1,wrk,0x01)) > 0) {
			strcpy(name,white[rc]);
		}
	}
	else if ((rc=akxs_seqr_str(white,-1,name,0x21)) > 0) {
		rc = atoi(white[rc-1]);
	}
	if (rc < 0) rc = 0;
	return rc;
}
