static char sccsid[]="%Z% %M% %I% %E% %U%";
/********************************************/
/*	akxcodeap.c								*/
/* oded by A.Kobayashi 2023.4.9				*/
/*											*/
/*	27 -185270101 〜 -185279999				*/
/********************************************/
#include "akxcommon.h"
#include <iconv.h>

static int chk_okuri(/*dat,rem_len,byte_kana,cc*/);

static char *gCodeStr[]=
	{"0","SYSCODE",""
	,"1","EUC-JISX0213","EUC-JIS-2004","EUC-JP","EUCJP","EUC",""
	,"2","SHIFT_JISX0213","SHIFT_JIS-2004","CP932","SJIS","S-JIS",""
	,"3","ISO-2022-JP-3","JIS",""
	,"4","CP939","EBCDIC",""
	,"5","UTF-8","UTF8",""
	,"6","UCS-4-INTERNAL",""
	,"7","JEF",""
	,"8","CP930","EBCDIK",""
	, "256","UPPER",""		/* 0x0100 大文字 */
	, "512","LOWER",""		/* 0x0200 小文字 */
	, "768","PROPER",""		/* 0x0300 先頭大文字他は小文字 */
	,"1024","WIDE",""		/* 0x0400 全角 */
	,"2048","NARROW",""		/* 0x0800 半角 */
	,"4096","HEBON",""		/* 0x1000 全角カナをヘボン式ローマ字 */
	,"8192","KATAKANA",""	/* 0x2000 全角ひらがなをカタカナへ */
	,"16384","HIRAGANA",""	/* 0x4000 全角カタカナをひらがなへ */
	,"32768","FURIGANA",""	/* 0x8000 漢字を全角フリガナへ */
	,NULL};

/****************************************/
/*	01									*/
/****************************************/
char *akxc_get_code_str(type)
int type;
{
	int i;
	char *code,w[12];
/*
printf("akxc_get_code_str: type=%d\n",type);
*/
	code = NULL;
	akxcitoa(type,w,10,-1);
	i = akxs_seqr_str_num(gCodeStr,-1,w,0x01);
	if (i > 0) code = gCodeStr[i];
/*
printf("akxc_get_code_str: i=%d code=[%s]\n",i,code);
*/
	return code;
}

/***02*******************************************/
/*		pospa <> NULLのとき						*/
/*			pospa[0]: 一致した先頭のコード文字	*/
/*			pospa[1]: 一致したコード文字		*/
/*  返却 : > 0 : 文字コード						*/
/*		   = 0 : SYSCODE						*/
/*		   =-1 : 一致しなかった					*/
/*		   < 0 : code_str=NULL	 				*/
/************************************************/
int akxc_get_code_num2(code_str,pospa)
char *code_str,*pospa[];
{
	int i,type,posa[2];
/*
printf("akxc_get_code_num: code_str=[%s]\n",code_str);
*/
	type = -1;
	i = akxs_seqr_str_grp(gCodeStr,-1,code_str,0x21,posa);
	if (i > 0) {
/*
printf("akxc_get_code_num: gCodeStr[i-1]=[%s]\n",gCodeStr[i-1]);
*/
		type = atoi(gCodeStr[i-1]);
		if (pospa) {
			pospa[0] = gCodeStr[i];
			pospa[1] = gCodeStr[posa[1]-1];
		}
	}
	else if (i < 0) type = i;
/*
printf("akxc_get_code_num: i=%d code=[%s]\n",i,code);
*/
	return type;
}

/***03***********************************/
/*  返却 : > 0 : 文字コード				*/
/*		   < 0 : code_str=NULL			*/
/*		   = 0 : 一致しなかった			*/
/*				 or SYSCODE				*/
/****************************************/
int akxc_get_code_num(code_str)
char *code_str;
{
	return akxc_get_code_num2(code_str,NULL);
}

/****************************************/
/*	04									*/
/****************************************/
char **akxc_get_code_str_addr()
{
	return gCodeStr;
}

/****************************************/
/*	11									*/
/****************************************/
static char *_chk_tr_code(tr_code)
char *tr_code;
{
	int set;

	set = 0;
	if (!tr_code) set = 1;
	else if (!*tr_code) set = 1;
	if (set) {
		tr_code = akxc_get_code_str(akxt_get_code_type());
	}
	return tr_code;
}

/****************************************/
/*	12									*/
/****************************************/
static int _get_code_str(tr_code,tr_dtypea)
char *tr_code[];
int  tr_dtypea[];
{
	int ret,dtype,stype;
	char *dcode,*scode;

	ret = 0;
	dtype = tr_dtypea[0] & CD_TYPE_CODE;
	stype = tr_dtypea[1] & CD_TYPE_CODE;
	if (!dtype) dtype = akxt_get_code_type();
	if (!stype) stype = akxt_get_code_type();
/*
printf("_get_code_str: dtype=%d stype=%d\n",dtype,stype);
*/
	dcode = akxc_get_code_str(dtype);
	if (!dcode) {
		XERROROUTL1(0,"変換先コード(%d)が不正です。",dtype);
		ret = -185271201;
	}
	scode = akxc_get_code_str(stype);
	if (!scode) {
		XERROROUTL1(0,"変換元コード(%d)が不正です。",stype);
		ret += -2;
	}
	tr_code[0] = dcode;
	tr_code[1] = scode;
	if (ret) ret += -4;
/*
printf("_get_code_str: tr_code[0]=%s tr_code[1]=%s\n",tr_code[0],tr_code[1]);
*/
	return ret;
}

/****************************************/
/*	13									*/
/****************************************/
static int _get_code_num(tr_dtypea,tr_code)
int  tr_dtypea[];
char *tr_code[];
{
	int ret,dtype,stype;
	char *dcode,*scode;
/*
printf("_get_code_num: tr_code[0]=%s tr_code[1]=%s\n",tr_code[0],tr_code[1]);
*/
	ret = 0;
	dcode = tr_code[0];
	scode = tr_code[1];
	dtype = akxc_get_code_num(dcode);
	if (dtype < 0) {
		if (dtype == -1) {
			XERROROUTL1(0,"変換先encodeing文字列(%s)が不正です。",dcode);
			ret = -185271301;
		}
		else return dtype;
	}
	if (!dtype) dtype = akxt_get_code_type();

	stype = akxc_get_code_num(scode);
	if (stype < 0) {
		if (stype == -1) {
			XERROROUTL1(0,"変換元encodeing文字列(%s)が不正です。",scode);
			ret += -2;
		}
		else return stype;
	}
	if (!stype) stype = akxt_get_code_type();

	tr_dtypea[0] = dtype;
	tr_dtypea[1] = stype;
	if (ret) ret += -4;
/*
printf("_get_code_num: tr_dtypea[0]=%s tr_dtypea[1]=%s\n",tr_dtypea[0],tr_dtypea[1]);
*/
	return ret;
}

/****************************************/
/*	14									*/
/****************************************/
static int _chk_native_tr_dtypea(ptr_dtypea,tr_dtypeaw,tr_code)
int  *ptr_dtypea[],tr_dtypeaw[];
char *tr_code[];
{
	int *tr_dtypea,dtype,stype,rc;

	tr_dtypea = *ptr_dtypea;
	if (!tr_dtypea) {
		if (!tr_code) return -1;
		if (rc=_get_code_num(tr_dtypea,tr_code)) return rc;
	}
#if 1	/* 2023.2.18 */
/*	else if (!(dtype=tr_dtypea[0] & CD_TYPE_CODE) || !(stype=tr_dtypea[1] & CD_TYPE_CODE)) {*/
/*	上記if文では、!dtypeのとき、stype=〜の式が実行されない */
	else {
		dtype = tr_dtypea[0] & CD_TYPE_CODE;
		stype = tr_dtypea[1] & CD_TYPE_CODE;
		if (!dtype || !stype) {
			if (!dtype) dtype = akxt_get_code_type();
			if (!stype) stype = akxt_get_code_type();
			tr_dtypea = tr_dtypeaw;
			tr_dtypea[0] = dtype;
			tr_dtypea[1] = stype;
			*ptr_dtypea = tr_dtypeaw;
		}
	}
#endif
	return 0;
}

/****************************************/
/*	15									*/
/****************************************/
static int _chk_iconv_tr_code(ptr_code,tr_codew,tr_dtypea)
char **ptr_code[],*tr_codew[];
int  tr_dtypea[];
{
	int rc;
	char **tr_code;

	tr_code = *ptr_code;
	if (!tr_code) {
		if (!tr_dtypea) return -1;
		*ptr_code = tr_codew;
		if (rc=_get_code_str(tr_codew,tr_dtypea)) return rc;
	}
#if 1	/* 2023.2.18 */
	else {
		if (!(tr_code[0] = _chk_tr_code(tr_code[0]))) return -185271501;
		if (!(tr_code[1] = _chk_tr_code(tr_code[1]))) return -185271502;
	}
#endif
	return 0;
}
/* 16 */
/********1*********2*********3*********4*********5*********6*********/
/* 名称 : akxc_str_conv_native										*/
/* 引数 : IN  : tr_dtypea[] : 文字コード							*/
/*							  [0]:変換先							*/
/*							  [1]:変換元							*/
/*				p1          : 変換する文字列の先頭アドレス			*/
/*				len         : 変換する文字列のバイト数				*/
/*				opt         : オプション(予約)						*/
/*		  OUT : pAns  : tr_dtypea[0]=tr_dtypea[1]のとき、または、	*/
/*						Mallocエラーのときは、p1					*/
/*						p1以外のときは、エラーがあっても、Malloc	*/
/*						されたアドレス。							*/
/*				ew_cnt[]: ew_cnt[0] : err_cnt						*/
/*						  ew_cnt[1] : wrn_cnt						*/
/* 返却 : >= 0 : 正常  変換された長さ								*/
/*				       tr_dtypea[0]=tr_dtypea[1]のときは、len		*/
/*        <  0 : エラー												*/
/********************************************************************/
int akxc_str_conv_native(pAns,tr_dtypea,p1,len,opt,ew_cnt)
char **pAns;
int  tr_dtypea[],len,opt,ew_cnt[];
char *p1;
{
	char *inptr; 		/* Pointer used for input buffer  */
	char *outptr;		/* Pointer used for output buffer */
	char *inbuf;		/* input buffer */
	char *outbuf;		/* output buffer  */
	tdtCodeConv ct;		/* conversion descriptor		  */
	size_t inleft;		/* number of bytes left in inbuf  */
	size_t outleft;		/* number of bytes left in outbuf */
	int rc;				/* return code of akxc_code_conv()*/
	int  ret,outlen,dtype0,dtype1,i,err_cnt,wrn_cnt;
	ParList *par;

	if (!pAns || !p1 || len<0) return -185271601;
	ret = 0;
	ew_cnt[0] = ew_cnt[1] = 0;
	if (opt & CD_NOT_MALLOC) {
		if (par=(ParList *)*pAns) {
			if (!(outbuf = par->par)) return -185271602;
			outlen = par->parlen;
		}
		else return -185271603;
	}
	else *pAns = p1;
/*
printf("akxc_str_conv_native:Enter tr_dtypea[0]=%d tr_dtypea[1]=%d opt=%08\n"
,tr_dtypea[0],tr_dtypea[1],opt);
*/
	dtype0 = tr_dtypea[0] & CD_TYPE_CODE;
	dtype1 = tr_dtypea[1] & CD_TYPE_CODE;
	if (!dtype0) dtype0 = akxt_get_code_type();
	if (!dtype1) dtype1 = akxt_get_code_type();
	if (dtype0 == dtype1) return len;
	rc = akxc_code_conv_init(&ct,dtype0,dtype1);
/*
printf("akxc_str_conv_native:init rc=%d\n",rc);
*/
	if (rc < 0) {
		XERROROUTL2(200,"Cannot open converter from %d to %d",dtype1,dtype0);
		return -185271604;
	}

	if (!(opt & CD_NOT_MALLOC)) {
		outlen = len*4 + 1;
		if (!(outbuf = Malloc(outlen))) return -185271605;
	}
	inleft = len;
	outleft = outlen;
	inptr = p1;
	outptr = outbuf;

	err_cnt = wrn_cnt = 0;
	for (i=0;i<len;i++) {
		rc = akxc_code_conv(&ct, &inptr, &inleft, &outptr, &outleft);
/*
printf("akxc_str_conv_native:code_conv rc=%d\n",rc);
*/
		if (rc < 0) {
			err_cnt++;
			inptr++;
			*outptr++ = '?';
			inleft--;
			outleft--;
			XERROROUTL1(200,"Error in converting characters. rc=%d",rc);
		}
		if (inleft <= 0) break;
	}
	if (rc > 0) {
		wrn_cnt = rc;
		ret = 0;
	}
	len = outlen - outleft;
	outbuf[len]='\0';
	ew_cnt[0] = err_cnt;
	ew_cnt[1] = wrn_cnt;
/*
printf("akxc_str_conv_native: ret=%d inleft=%d outleft=%d len=%d [%s]\n",ret,inleft,outleft,len,outbuf);
*/
	if (!(opt & CD_NOT_MALLOC)) *pAns = outbuf;
	if (!ret) ret = len;
/*
printf("akxc_str_conv_native:Exit ret=%d err_cnt=%d wrn_cnt=%d\n",ret,err_cnt,wrn_cnt);
*/
	return ret;
}

/* 17 */
/********1*********2*********3*********4*********5*********6*********/
/* 名称 : akxc_str_conv_iconv										*/
/* 引数 : IN  : tr_code[]   : コード文字列							*/
/*							  [0]:変換先							*/
/*							  [1]:変換元							*/
/*				p1          : 変換する文字列の先頭アドレス			*/
/*				len         : 変換する文字列のバイト数				*/
/*				opt         : オプション(予約)						*/
/*		  OUT : pAns  : pAns<>NULLのとき、変換先の先頭アドレスが返る*/
/*						Mallocされたアドレス。						*/
/*						Mallocエラーのときは、p1が返る				*/
/*				ew_cnt[]: ew_cnt[0] : err_cnt						*/
/*						  ew_cnt[1] : wrn_cnt						*/
/* 返却 : >= 0 : 正常  変換された長さ								*/
/*        <  0 : エラー												*/
/********************************************************************/
#ifdef USE_ICONV
int akxc_str_conv_iconv(pAns,tr_code,p1,len,opt,ew_cnt)
char **pAns;
int  len,opt,ew_cnt[];
char *tr_code[],*p1;
{
	char *inptr; 		/* Pointer used for input buffer  */
	char *outptr;		/* Pointer used for output buffer */
	char *inbuf;		/* input buffer */
	char *outbuf;		/* output buffer  */
	iconv_t cd;			/* conversion descriptor		  */
	size_t inleft;		/* number of bytes left in inbuf  */
	size_t outleft;		/* number of bytes left in outbuf */
	int rc;				/* return code of iconv()		  */
	int ret,outlen,i,err_cnt,wrn_cnt,tr_dtypea[2];
	uchar uc;
	ParList *par;

	if (!pAns || !p1 || len<0) return -185271701;
	ret = 0;
	ew_cnt[0] = ew_cnt[1] = 0;
	if (opt & CD_NOT_MALLOC) {
		if (par=(ParList *)*pAns) {
			if (!(outbuf = par->par)) return -185271702;
			outlen = par->parlen;
		}
		else return -185271703;
	}
	else *pAns = p1;
/*
printf("akxc_str_conv_iconv:Enter tr_code[0]=[%s] tr_code[1]=[%s] opt=%08x\n",tr_code[0],tr_code[1],opt);
*/
#ifdef NO_ICONV
	rc = 0;
#else
	if (!tr_code[0] || !tr_code[1]) return -185271704;
#if 1	/* 2023.2.18 */
	if (rc=_get_code_num(tr_dtypea,tr_code)) return rc;
/*
printf("akxc_str_conv_iconv: tr_dtypea[0]=%d tr_dtypea[1]=%d\n",tr_dtypea[0],tr_dtypea[1]);
printf("akxc_str_conv_iconv: tr_code[0]=[%s] tr_code[1]=[%s]\n",tr_code[0],tr_code[1]);
*/
	if (tr_dtypea[0] == tr_dtypea[1]) return len;
#endif
	if ((cd = iconv_open(tr_code[0],tr_code[1])) == (iconv_t)(-1)) rc = -185270703;
	else rc = 0;
/*
printf("akxc_str_conv_iconv:init rc=%d\n",rc);
*/
	if (rc < 0) {
		XERROROUTL2(200,"Cannot open converter from %s to %s",tr_code[1],tr_code[0]);
/*
printf("Cannot open converter from %s to %s\n",tr_code[1],tr_code[0]);
*/
		return -185271705;
	}

	if (!(opt & CD_NOT_MALLOC)) {
		outlen = len*4 + 1;
		if (!(outbuf = Malloc(outlen))) return -185271706;
	}
	inleft = len;
	outleft = outlen;
	inptr = p1;
	outptr = outbuf;
	err_cnt = wrn_cnt = 0;

	for (i=0;i<len;i++) {
		rc = iconv(cd, &inptr, &inleft, &outptr, &outleft);
/*
printf("akxc_str_conv_iconv: rc=%d\n",rc);
*/
		if (rc == -1) {
			if (errno==EILSEQ || errno==EINVAL) {
#if 1	/* 2022.11.17 */
				uc = (uchar)*inptr;
/*
printf("akxc_str_conv_iconv: inptr=%02x\n",uc);
*/
				if ((uc==0x5c || uc==0x7e) && (opt & CD_NOT_ERROR_7E)) {
					*outptr++ = uc;
				}
				else {
					*outptr++ = '?';
					err_cnt++;
				}
#else
				*outptr++ = '?';
				err_cnt++;
#endif
				inptr++;
				inleft--;
				outleft--;
/*
printf("akxc_str_conv_iconv: inleft=%d outleft=%d\n",inleft,outleft);
*/
			}
			else {
				XERROROUTL1(200,"Error in converting characters. errno=%d",errno);
				ret = -185271707;
				break;
			}
		}
		else {
			wrn_cnt = rc;
			ret = 0;
			break;
		}
		if (inleft <= 0) break;
	}
	iconv_close(cd);
	ew_cnt[0] = err_cnt;
	ew_cnt[1] = wrn_cnt;
	len = outlen - outleft;
	outbuf[len]='\0';
/*
{
char wrk[256];
i=akxcctox(outbuf,len,wrk);
*(wrk+i)='\0';
printf("akxc_str_conv_iconv: len=%d [%s] %s\n",len,outbuf,wrk);
}
*/
/*
printf("akxc_str_conv_iconv: ret=%d inleft=%d outleft=%d len=%d [%s]\n",ret,inleft,outleft,len,outbuf);
*/
	if (!(opt & CD_NOT_MALLOC)) if (pAns) *pAns = outbuf;
	if (!ret) ret = len;
#endif
	return ret;
}
#endif

/* 18 */
/********1*********2*********3*********4*********5*********6*********/
/* 名称 : akxc_str_conv												*/
/* 引数 : IN  : tr_dtypea[] : 文字コード							*/
/*							  [0]:変換先							*/
/*							  [1]:変換元							*/
/*							  iconv未使用時にNULLのときは、			*/
/*							  tr_codeから変換する。					*/
/*							  tr_codeもNULLのときは、エラー			*/
/*				tr_code[]   : iconvで指定するコード文字列			*/
/*							  [0]:変換先							*/
/*							  [1]:変換元							*/
/*							  iconv使用時にNULLのときは、			*/
/*							  tr_dtypeaから変換する					*/
/*							  tr_dtypeaもNULLのときは、エラー		*/
/*				p1          : 変換する文字列の先頭アドレス			*/
/*				len         : 変換する文字列のバイト数				*/
/*				opt         : オプション							*/
/*							  = CD_USE_CODE_CONVビットON :			*/
/*									akxc_str_conv_nativeを実行する	*/
/*							  = その他 :							*/
/*									akxc_str_conv_iconvを実行する	*/
/*		  OUT : pAns  : tr_dtypea[0]=tr_dtypea[1]のときは、p1		*/
/*						p1以外のときは、エラーがあっても、Malloc	*/
/*						されたアドレス。NULLの可能性もある			*/
/* 返却 : >= 0 : 正常  変換された長さ								*/
/*		  <  0 : エラー												*/
/********************************************************************/
#if 1
int akxc_str_conv(pAns,tr_dtypea,tr_code,p1,len,opt)
char **pAns;
int  tr_dtypea[],len,opt;
char *tr_code[],*p1;
{
	int rc,ew_cnt[2],iNATIVE,tr_dtypeaw[2],dtype,stype;
	char *tr_codew[2];
	uchar *up1;

	if (!pAns || !p1 || len<0) return -185271801;
/*
printf("akxc_str_conv:Enter len=%d opt=%08x\n",len,opt);
if (tr_dtypea) printf("akxc_str_conv:tr_dtypea=%d %d\n",tr_dtypea[0],tr_dtypea[1]);
if (tr_code) printf("akxc_str_conv:tr_code=[%s][%s]\n",tr_code[0],tr_code[1]);
*/
	iNATIVE = 0;
#ifdef USE_ICONV
	if (opt & CD_USE_CODE_CONV) iNATIVE = 1;
#else
	iNATIVE = 1;
#endif
#if 1	/* 2023.3.8 */
	if (!(opt & CD_NOT_CHECK_YEN)) {
		if (!iNATIVE) {		/* '\','~' があるかどうかチェックする */
			if ((rc=_chk_iconv_tr_code(&tr_code,tr_codew,tr_dtypea)) < 0) return rc;
			if ((rc=_get_code_num(tr_dtypea,tr_code)) < 0) return rc;
/*
printf("akxc_str_conv: YEN check: tr_dtypea=%d %d\n",tr_dtypea[0],tr_dtypea[1]);
*/
			if (tr_dtypea[0]==CD_TYPE_UTF8 || tr_dtypea[1]==CD_TYPE_UTF8) {
				if (akxs_in_mem_chars(p1,len,"\\~",SET_TYPE_OPT(tr_dtypea[1])) > 0) iNATIVE = 1;
			}
		}
	}
#endif
	if (iNATIVE) {
		/* 2023.3.8 */
		if ((rc=_chk_native_tr_dtypea(&tr_dtypea,tr_dtypeaw,tr_code)) < 0) return rc;
	}
	else {
		/* 2023.3.8 */
		if ((rc=_chk_iconv_tr_code(&tr_code,tr_codew,tr_dtypea)) < 0) return rc;
	}
#if 1	/* 2022.11.17 */
	if (len>=3 && tr_dtypea[1]==CD_TYPE_UTF8) {
		up1 = (uchar *)p1;
		if (*up1==0xEF && *(up1+1)==0xBB && *(up1+2)==0xBF) {
/*
printf("akxc_str_conv: BOM\n");
*/
			p1 += 3;
			len -= 3;
		}
	}
#endif
#ifdef USE_ICONV
/*	if (opt & CD_USE_CODE_CONV) {	*/
	if (iNATIVE) {
		rc = akxc_str_conv_native(pAns,tr_dtypea,p1,len,opt,ew_cnt);
	}
	else {
#if 1	/* 2022.11.17 */
		if (tr_dtypea[1] == CD_TYPE_UTF8) opt |= CD_NOT_ERROR_7E;
#endif
		rc = akxc_str_conv_iconv(pAns,tr_code,p1,len,opt,ew_cnt);
	}
#else
	rc = akxc_str_conv_native(pAns,tr_dtypea,p1,len,opt,ew_cnt);
#endif
					/* 変換エラーが %d個ありました。 */
	if (ew_cnt[0] > 0) XERROROUTL3(0,"変換エラーが %d個ありました。len=%d opt=%08x",ew_cnt[0],rc,opt);
					/* 不可逆変換が %d個ありました。 */
	if (ew_cnt[1] > 0) XERROROUTL3(0,"不可逆変換が %d個ありました。len=%d opt=%08x",ew_cnt[1],rc,opt);
	return rc;
}
#else
int akxc_str_conv(pAns,tr_dtypea,tr_code,p1,len,opt)
char **pAns;
int  tr_dtypea[],len,opt;
char *tr_code[],*p1;
{
	char *inptr; 		/* Pointer used for input buffer  */
	char *outptr;		/* Pointer used for output buffer */
	char *inbuf;		/* input buffer */
	char *outbuf;		/* output buffer  */
	iconv_t cd;			/* conversion descriptor		  */
	tdtCodeConv ct;		/* conversion descriptor		  */
	size_t inleft;		/* number of bytes left in inbuf  */
	size_t outleft;		/* number of bytes left in outbuf */
	int rc;				/* return code of iconv()		  */
	int  ret,outlen,i,err_cnt,wrn_cnt,iICONV;

	ret = 0;
	if (pAns) *pAns = p1;
/*
printf("akxc_str_conv:Enter tr_dtypea[0]=%d tr_dtypea[1]=%d opt=%08\n"
,tr_dtypea[0],tr_dtypea[1],opt);
*/
/*	if (!tr_code[0] || !tr_code[1]) return -1009;	*/
/*
printf("akxc_str_conv: tr_code[0]=[%s] tr_code[1]=[%s]\n",tr_code[0],tr_code[1]);
*/
/*	if (tr_dtypea[0] == tr_dtypea[1]) return len;	*/

	iICONV = 0;
/*	opt = cl_get_option(9,0);	*/
#ifdef USE_ICONV
	if (opt & CD_USE_CODE_CONV) {
		if (tr_dtypea[0] == tr_dtypea[1]) return len;
		rc = akxc_code_conv_init(&ct,tr_dtypea[0],tr_dtypea[1]);
	}
	else {
#ifdef NO_ICONV
		rc = 0;
#else
		if (!tr_code[0] || !tr_code[1]) return -1009;
		if ((cd = iconv_open(tr_code[0],tr_code[1])) == (iconv_t)(-1)) rc = -1;
		else rc = 0;
		iICONV = 1;
#endif
	}
#else
	if (tr_dtypea[0] == tr_dtypea[1]) return len;
	rc = akxc_code_conv_init(&ct,tr_dtypea[0],tr_dtypea[1]);
#endif
/*
printf("akxc_str_conv:init rc=%d\n",rc);
*/
	if (rc < 0) {
		XERROROUTL2(200,"Cannot open converter from %s to %s",tr_code[1],tr_code[0]);
		return -1001;
	}

	outlen = len*4 + 1;
/*	outbuf = cl_tmp_const_malloc(outlen);	*/
	if (!(outbuf = Malloc(outlen))) return -1901;
	inleft = len;
	outleft = outlen;
	inptr = p1;
	outptr = outbuf;
	err_cnt = wrn_cnt = 0;

	if (!iICONV || (opt & CD_USE_CODE_CONV)) {
		rc = akxc_code_conv(&ct, &inptr, &inleft, &outptr, &outleft);
/*
printf("akxc_str_conv:code_conv rc=%d\n",rc);
*/
		if (rc < 0) {
			err_cnt++;
			XERROROUTL1(200,"Error in converting characters. rc=%d",rc);
			ret = -1001;
		}
	}
#ifdef USE_ICONV
	else {
#ifdef NO_ICONV
		rc = 0;
#else
		for (i=0;i<len;i++) {
			rc = iconv(cd, &inptr, &inleft, &outptr, &outleft);
/*
printf("akxc_str_conv:iconv rc=%d\n",rc);
*/
			if (rc == -1) {
				if (errno==EILSEQ || errno==EINVAL) {
					err_cnt++;
					inptr++;
					*outptr++ = '?';
					inleft--;
					outleft--;
/*
printf("akxc_str_conv:iconv inleft=%d outleft=%d\n",inleft,outleft);
*/
					if (inleft <= 0) break;
				}
				else {
					XERROROUTL1(200,"Error in converting characters. errno=%d",errno);
					ret = -1002;
					break;
				}
			}
			else {
				wrn_cnt = rc;
				ret = 0;
				break;
			}
		}
		iconv_close(cd);
#endif
	}
#endif
					/* 変換エラーが %d個ありました。 */
	if (err_cnt > 0) XERROROUTL1(0,"変換エラーが %d個ありました。",err_cnt);
					/* 不可逆変換が %d個ありました。 */
	if (wrn_cnt > 0) XERROROUTL1(0,"不可逆変換が %d個ありました。",wrn_cnt);
	len = outlen - outleft;
	outbuf[len]='\0';
/*
printf("akxc_str_conv: ret=%d inleft=%d outleft=%d len=%d [%s]\n",ret,inleft,outleft,len,outbuf);
*/
	if (pAns) *pAns = outbuf;
#if 1	/* 2020.10.19 */
	if (!ret) ret = len;
#endif
	return ret;
}
#endif

/****************************************/
/*	19									*/
/****************************************/
int akxc_file_code_conv(pAns,p1,len,inout,opt0)
char **pAns;
char *p1;
int len,opt0;
int inout;	/* 0/1=in/out */
{
	int  ret,stype,dtype,tr_dtypea[2],code,opt;
	char *tr_code[2];
/*
printf("akxc_file_code_conv: inout=%d opt0=%08x\n",inout,opt0);
*/
/*
printf("akxc_file_code_conv: len=%d p1=[%s]\n",len,p1);
*/
	ret = 0;
	opt = opt0;
	dtype = akxt_get_code_type();
	if (inout) {	/* output *//* system code --> 指定コード */
		stype = dtype;
		dtype = CD_TYPE_UTF8;	/*CD_TYPE_SJIS;*/
		opt &= CD_TYPE_CODE;
		if (opt) dtype = opt;
	}
	else {			/* input *//* 指定コード --> system code */
		stype = CD_TYPE_UTF8;	/*CD_TYPE_SJIS;*/
		opt = (opt>>8) & CD_TYPE_CODE;
		if (opt) stype = opt;
	}
/*
printf("akxc_file_code_conv: dtype=%08x stype=%08x\n",dtype,stype);
*/
/*
printf("akxc_file_code_conv: p1=[%s]\n",p1);
*/
	if (stype == dtype) {
		*pAns = p1;
		ret = len;
	}
	else {
		tr_dtypea[0] = dtype;
		tr_dtypea[1] = stype;
#if 1	/* 2022.11.23 */
		if (!(ret=_get_code_str(tr_code,tr_dtypea)))
#else
		tr_code[0] = akxc_get_code_str(dtype);
		if (!tr_code[0]) {
			XERROROUTL1(0,"変換先コード(%d)が不正です。",dtype);
			return -185271901;
		}
		tr_code[1] = akxc_get_code_str(stype);
		if (!tr_code[1]) {
			XERROROUTL1(0,"変換元コード(%d)が不正です。",stype);
			return -185271902;
		}
#endif
		ret = akxc_str_conv(pAns,tr_dtypea,tr_code,p1,len,opt0);
	}
/*
printf("akxc_file_code_conv:Exit len=%d p1=%08x ret=%d *pAns=%08x\n",len,p1,ret,*pAns);
*/
	return ret;
}

/****************************************/
/*	21									*/
/****************************************/
static int henkan(xha,par,s,len_s,code_type)
XHASHB *xha;
ParList *par;
char *s;
int len_s,code_type;
{
	static MCAT mcat={'M','C',256,0,0,0,NULL,0};
	int i,n,m,m1,dlen;
	long ih;
	char c,*p,*dat,*p1,wrk[10],*pd;

	ih = 0;
	n = 0;
	p = s;
	mcat.mc_ipos = 0;
	while (len_s > 0) {
		m = akxqmbsnlen(code_type,p,len_s);
		if (len_s > m) {
			m1 = m + akxqmbsnlen(code_type,p+m,len_s-m);
			memzcpy(wrk,p,m1);
			pd = "";
			ih = akxs_xhash2(xha,'R',wrk,&pd);
/*
printf("henkan:1 m=%d m1=%d wrk=[%s] ih=%d pd=[%s]\n",m,m1,wrk,ih,pd);
*/
		}
		else ih = 0;
		if (ih > 0) {
			n++;
			m =m1;
			dlen = strlen(pd);
		}
		else {
			memzcpy(wrk,p,m);
			pd = "";
			ih = akxs_xhash2(xha,'R',wrk,&pd);
/*
printf("henkan:2 wrk=[%s] ih=%d pd=[%s]\n",wrk,ih,pd);
*/
			if (ih > 0) {
				n++;
				dlen = strlen(pd);
			}
			else {
				pd = p;
				dlen = m;
			}
		}
		len_s -= m;
		p += m;
/*
printf("henkan:3 m=%d len_s=%d\n",m,len_s);
*/
		akxtmcat(&mcat,pd,dlen);
	}
	akxtmcats(&mcat,"");
	par->parlen = mcat.mc_ipos;
	par->par = mcat.mc_bufp;
	return n;
}

/****************************************/
/*	22									*/
/****************************************/
static int regist(xha,dat,hebon)
XHASHB *xha;
char *dat,*hebon;
{
	char *da[10],*he[10],*heb,parm1[128],parm2[128];
	int i,n;
	long ih;
/*
printf("regist: data=[%s] hebon=[%s]\n",dat,hebon);
*/
	n = akxtgetargv(dat,da,10,parm1,sizeof(parm1));
	akxtgetargv(hebon,he,10,parm2,sizeof(parm2));
	for (i=0;i<n;i++) {
		if (!*hebon) heb = "";
		else heb = he[i];
		ih = akxs_xhash2(xha,'S',da[i],heb);
/*
printf("regist: i=%d key=[%s] heb=[%s] ih=%d\n",i,da[i],heb,ih);
*/
	}
	return n;
}

/* 23 */
/********1*********2*********3*********4*********5*******/
/* opt : 0x0100 : (  256) 大文字に変換					*/
/*		 0x0200 : (  512) 小文字に変換(優先)			*/
/*		 0x0300 : (  768) 先頭大文字他は小文字			*/
/*		 0x0400 : ( 1024) 全角文字に変換				*/
/*		 0x0800 : ( 2048) 半角文字に変換(優先)			*/
/*		 0x1000 : ( 4096) 全角カナをヘボン式ローマ字	*/
/*		 0x2000	: ( 8192) 全角ひらがなをカタカナへ		*/
/*		 0x4000	: (16384) 全角カタカナをひらがなへ		*/
/*		 0x7f000000 : code_type							*/
/********************************************************/
int akxc_to_hebon(par,s,s_len,opt)
ParList *par;
char *s;
int s_len,opt;
{
	static XHASHB *xha,*xha2;
	static int init_hebon=0;
	static char wrk[128],*p0=NULL,wrk2[128],*p20=NULL,wrk3[128],*p30=NULL;
	int ret,i,d_len,code_type,pos,w_used,tr_dtypea[2],iCONV;
	long ih,optw;
	char *hebon,*d,*p,*pAns;

	if (!init_hebon ) {

		xha  = akxs_xhash_new2(0,150,149,0);
		xha2 = akxs_xhash_new2(0, 30, 29,0);

		/* 拗音・特殊音 */
		i = regist(xha, "キャ キュ キョ", "kya kyu kyo");
		i = regist(xha, "シャ シュ ショ", "sha shu sho");
		i = regist(xha, "チャ チュ チョ", "cha chu cho");
		i = regist(xha, "ニャ ニュ ニョ", "nya nyu nyo");
		i = regist(xha, "ヒャ ヒュ ヒョ", "hya hyu hyo");
		i = regist(xha, "ミャ ミュ ミョ", "mya myu myo");
		i = regist(xha, "リャ リュ リョ", "rya ryu ryo");
		i = regist(xha, "ギャ ギュ ギョ", "gya gyu gyo");
		i = regist(xha, "ジャ ジュ ジョ", "ja ju jo");
		i = regist(xha, "ヂャ ヂュ ヂョ", "ja ju jo");
		i = regist(xha, "ビャ ビュ ビョ", "bya byu byo");
		i = regist(xha, "ピャ ピュ ピョ", "pya pyu pyo");
		i = regist(xha, "ヴァ ヴィ ヴ ヴェ ヴォ", "ba bi bu be bo");
		i = regist(xha, "ファ フィ フェ フォ", "fa fi fe fo");
		i = regist(xha, "ティ", "ti");

		/* 直音 */
		i = regist(xha, "ア イ ウ エ オ", "a i u e o");
		i = regist(xha, "カ キ ク ケ コ", "ka ki ku ke ko");
		i = regist(xha, "サ シ ス セ ソ", "sa shi su se so");
		i = regist(xha, "タ チ ツ テ ト", "ta chi tsu te to");
		i = regist(xha, "ナ ニ ヌ ネ ノ", "na ni nu ne no");
		i = regist(xha, "ハ ヒ フ ヘ ホ", "ha hi fu he ho");
		i = regist(xha, "マ ミ ム メ モ", "ma mi mu me mo");
		i = regist(xha, "ヤ ユ ヨ", "ya yu yo");
		i = regist(xha, "ラ リ ル レ ロ", "ra ri ru re ro");
		i = regist(xha, "ワ ヰ ヱ ヲ", "wa i e o");
		i = regist(xha, "ガ ギ グ ゲ ゴ", "ga gi gu ge go");
		i = regist(xha, "ザ ジ ズ ゼ ゾ", "za ji zu ze zo");
		i = regist(xha, "ダ ヂ ヅ デ ド", "da ji zu de do");
		i = regist(xha, "バ ビ ブ ベ ボ", "ba bi bu be bo");
		i = regist(xha, "パ ピ プ ペ ポ", "pa pi pu pe po");

		/* 撥音 */
	/*	i = regist(xha, "ン", "n");	*/
		i = regist(xha2, "nb nm np", "mb mm mp");

		/* 促音 */
		i = regist(xha2, "ッk ッs ッt ッn ッh ッm ッy ッr ッw", "kk ss tt n hh mm yy rr ww");
		i = regist(xha2, "ッg ッz ッd ッb ッp", "gg zz dd bb pp");
		i = regist(xha2, "ッc ッf ッj", "tc ff jj");
		i = regist(xha2, "ンa ンi ンu ンe ンo ンy" ,"'n''a' 'n''i' 'n''u' 'n''e' 'n''o' 'n''y'");
		i = regist(xha2, "ンb ンm ンp" ,"mb mm mp");
		i = regist(xha2, "ァ ィ ゥ ェ ォ" ,"a i u e o");
	/*	i = regist(xha, "ッ", "");	*/

		/* 長音 */
		i = regist(xha2, "iー eー", "ii ei");
		i = regist(xha2, "aー uー oー", "a u o");
	/*	i = regist(xha2, "ー", "");	*/

		/* 長音 */
		i = regist(xha2, "uu ou", "u o");
		i = regist(xha2, "oo", "o");

		init_hebon = 1;
	}

	if (!(p=s) || !par || s_len<0) return -185272301;

	code_type = GET_TYPE_OPT(opt);
	pAns = s;
	if ((iCONV=akxq_code_type_cmp(0,code_type))) {
		tr_dtypea[0] = 0;
		tr_dtypea[1] = code_type;
/*
printf("akxc_to_hebon:0 code_type=%08x s_len=%d s=[%s]\n",code_type,s_len,s);
*/
		s_len = akxc_str_conv(&pAns,tr_dtypea,NULL,p,s_len,0);
		p = pAns;
/*
printf("akxc_to_hebon:1 s_len=%d s=[%s]\n",s_len,p);
*/
		opt &= ~CD_TYPE_OPT_MASK;
	}
	/************/
	/* 辞書変換 */
	/************/
	ret =  akxckj2eng(par,p,s_len,opt);
	d_len = par->parlen;
	hebon = par->par;
/*
printf("akxc_to_hebon:2 d_len=%d s=[%s]\n",d_len,hebon);
*/
	if (s != pAns) Free(pAns);

	ih = henkan(xha,par,hebon,d_len,code_type);
	d_len = par->parlen;
	hebon = par->par;
	if (ret>0 || ih>0) {
		pos = akxs_mright(s,s_len,2,opt);
		p = "oo";
		if (memcmp(s+pos,p,strlen(p))) {
			akxmemwork(d_len+1,&p,&p0,wrk,sizeof(wrk));
			memzcpy(p,hebon,d_len);
			ih = henkan(xha2,par,p,d_len,code_type);
			d_len = par->parlen;
			hebon = par->par;
		}
	}
	w_used = 0;
/*	if (!ih) {	*/
		akxmemwork(d_len+1,&d,&p0,wrk,sizeof(wrk));
		d_len = akxcreplace_chars_opt2(d,d_len+1,hebon,d_len,"ーッ", "",opt);
		hebon = d;
		w_used = 1;
/*	}	*/
		akxmemwork(d_len+1,&d,&p30,wrk,sizeof(wrk3));
		d_len = akxcreplace_chars_opt2(d,d_len+1,hebon,d_len,"ン", "n",opt);
		hebon = d;
		w_used = 3;
/*
printf("akxc_to_hebon: d_len=%d hebon=[%s]\n",d_len,hebon);
*/
	optw = opt & CD_TYPE_PROPER;
	if (optw) {
		if (optw & CD_TYPE_LOWER) optw = 1;
		else if (optw & CD_TYPE_UPPER) optw = 0;
/*
printf("akxc_to_hebon: opt=%08x optw=%08x\n",opt,optw);
*/
		akxmemwork(d_len+1,&d,&p20,wrk2,sizeof(wrk2));
		d_len = akxcuplwn_type(optw,d,hebon,d_len,code_type);	/* 0:upper, 1:lower */
		hebon = d;
		w_used = 2;
	}
	if (opt & (CD_TYPE_WIDE | CD_TYPE_NARROW)) {
	/*	if (w_used == 2)
			akxmemwork(d_len*3+1,&d,&p30,wrk3,sizeof(wrk3));
		else	*/
			akxmemwork(d_len*3+1,&d,&p0,wrk,sizeof(wrk));
		if (opt & CD_TYPE_NARROW)
			d_len = akxctohan_type(d_len, hebon, d, code_type);
		else
			d_len = akxctozen_type(d_len, hebon, d, code_type);
		hebon = d;
	}
	if (iCONV) {
		tr_dtypea[0] = code_type;
		tr_dtypea[1] = 0;
/*
printf("akxc_to_hebon:2 code_type=%08x\n",code_type);
*/
		d_len = akxc_str_conv(&pAns,tr_dtypea,NULL,hebon,d_len,0);
		if (pAns && hebon!=pAns) {
			akxmemwork(d_len+1,&d,&p20,wrk2,sizeof(wrk2));
			memzcpy(d,pAns,d_len);
			hebon = d;
			Free(pAns);
		}
	}
	par->parlen = d_len;
	par->par = hebon;
	return d_len;
}

/****************************************/
/*	24									*/
/****************************************/
char *to_hebon(s,opt)
char *s;
int opt;
{
	ParList par;

	akxc_to_hebon(&par,s,strlen(s),opt);
	return par.par;
}

static int   init_jisho = 0;
static char *jisho_kana[] =
	{"コード","アクション","フラグ","データ","レベル"
	,"ファイル","パートナ","ベンダー","テスト","オーダ"
	,"サービス","セット","プロジェクト","オープン","インターネット"
	,"パック","ステータス","コンサルティング","ロック","バージョン"
	,"シリーズ","カウント","ラック","メール","アドレス"
	,"レンタル","ディスパッチャー","ライセンス","ロット","グループ"
	,"プレ","システム","メッセージ","アサイン","ソリューション"
	,"アプリケーション","パスワード"
/*
	,"作成","更新","削除"
	,"日付","作成日","更新日","削除日","日時"
	,"作成日付","更新日付","削除日付","時間"
	,"作成日時","更新日時","削除日時"
*/
	,NULL};
static char *jisho_hebon[] =
	{"cd","action","flg","data","level"
	,"file","partner","vendor","test","order"
	,"service","set","project","open","internet"
	,"pack","status","consulting","lock","version"
	,"series","count","rack","mail","address"
	,"rental","dispatcher","lisence","rot","group"
	,"pre","system","message","asign","solution"
	,"application","password"
/*
	,"make","update","delete"
	,"date","makedate","updatedate","deletedate","datetime"
	,"makedate","updatedate","deletedate","time"
	,"makedate","updatedate","deletedate"
*/
	,NULL};
/*
static int   jisho_klen[60];
static int   jisho_byte[60];
*/
static int   max_jisho = 0;
static XHASHB *xha_jisho;
static MCAT2 *mcat_jisho;
static MCAT2 *mcat_byte;

/****************************************/
/*	25									*/
/****************************************/
static int _jisho_init(opt)
int opt;
{
	int byte_kana,i,n,*byte_lena,ret;
	char *d;
	long ih;

	if (!init_jisho) {
		xha_jisho  = akxs_xhash_new2(0,100,97,0);
		mcat_jisho = akxs_mseq_new(sizeof(int),100,NULL,NULL);
		mcat_byte = akxs_mseq_new(sizeof(int),10,NULL,NULL);
		max_jisho = 0;
		while (d=jisho_kana[max_jisho]) {
			if ((byte_kana=strlen(d)) > 0) {
/*
printf("akxc_to_hebon: k=%d byte=%d kana=[%s] hebon=[%s]\n",
max_jisho,byte_kana,jisho_kana[max_jisho],jisho_hebon[max_jisho]);
*/
				if ((ih=akxs_xhash2(xha_jisho,'S',d,jisho_hebon[max_jisho])) < 0) return ih;
				max_jisho++;
				if ((ret=akxs_mseq_set(mcat_jisho,ih-1,&byte_kana)) < 0) return ret;
				if ((ret=akxs_mseq_s(mcat_byte,&byte_kana)) < 0) return ret;
			}
		}
		if ((ret=akxnmstrsort_opt(mcat_byte->mc_bufp,mcat_byte->mc_ipos,sizeof(int),1)) < 0) return ret;
/*
byte_lena = (int *)mcat_byte->mc_bufp;
n=mcat_byte->mc_ipos;
printf("_jisho_init: n=%d\n",n);
for (i=0;i<n;i++) printf("_jisho_init: len=%d\n",byte_lena[i]);
*/
		init_jisho = 1;
	}
	return 0;
}

/****************************************/
/*	26									*/
/****************************************/
static int _set_kana_hebon(mcat,kana,byte_kana,hebon,byte_he)
MCAT *mcat;
char *kana,*hebon;
int byte_kana,byte_he;
{
	int ret;

	if (!mcat || !kana || !hebon) ret = -185272601;
	else if (byte_kana>=0 && byte_he>=0) {
		akxtmcat(mcat,kana,byte_kana);
		akxtmcats(mcat," ");
		akxtmcat(mcat,hebon,byte_he);
		akxtmcats(mcat,"\n");
		ret = 0;
	}
	return ret;
}

/****************************************/
/*	27									*/
/****************************************/
int akxc_jisho_regist(par,dat,hebon,opt)
ParList *par;
char *dat,*hebon;
int opt;
{
	static MCAT mcat={'M','C',256,0,0,0,NULL,0};
	char *da[10],*he[10],*heb,parm1[128],parm2[128],*p,*hebr;
	int i,n,byte_kana,ret,k,m,nh,opt1,opt2,max_jisho0,nn,ih,kk;
/*
printf("jisho_regist: data=[%s] hebon=[%s]\n",dat,hebon);
*/
	ret = 0;
	_jisho_init();
	if (!dat) ret = 100;
	else if (!*dat) ret = 100;
	opt1 = opt & 0x01;
	if (opt1) {
		if (!par) return -185272701;
		par->parlen = 0;
		par->par = NULL;
		mcat.mc_ipos = 0;
	}
	if (ret==100 && !opt) return max_jisho;
	opt2 = opt & 0x02;
	nh = n = m = 0;
	max_jisho0 = max_jisho;
	nn = max_jisho0;
	if (!ret) {
		if ((n=akxtgetargv(dat,da,10,parm1,sizeof(parm1))) > 0) nn = n;
		else if (n < 0) return n;
		if (hebon) {
			if ((nh=akxtgetargv(hebon,he,10,parm2,sizeof(parm2))) < 0) return nh;
		}
	}
/*
printf("akxc_jisho_regist: n=%d nh=%d nn=%d\n",n,nh,nn);
*/
	kk = 1;
	for (i=0;i<nn;i++) {
		heb = "";
		if (n > 0) {
			p = da[i];
			byte_kana = strlen(p);
			if (hebon && *hebon) heb = he[i];
		}
		else {
			ih = 0;
			while (!ih) {
				xha_jisho->xha_xhix = kk++;
				ih = akxs_xhash2(xha_jisho,'P',&p,&heb);
			}
			if (ih < 0) return ih;
			if ((ret=akxs_mseq_get(mcat_jisho,ih-1,&byte_kana)) < 0) return ret;
		}
		if (byte_kana > 0) {
			if (n > 0) {
				ret = akxs_xhash2(xha_jisho,'R',p,&hebr);
				if (ret > 0) heb = hebr;
			}
			else ret = i + 1;
/*
printf("akxc_jisho_regist: i=%d ret=%d\n",i,ret);
*/
			if (ret >= 0) {
				if (opt2 && ret>0) {
					ret = akxs_xhash2(xha_jisho,'D',p,&heb);
					max_jisho--;
				}
				else if (n>0 && nh>0) {
					if ((ret=akxs_xhash2(xha_jisho,'S',p,heb)) < 0) return ret;
/*
printf("akxc_jisho_regist: i=%d ret=%d kana=[%s] heb=[%s]\n",i,ret,p,heb);
*/
					if (ret > 0) {
						max_jisho++;
						if ((ret=akxs_mseq_s(mcat_byte,&byte_kana)) < 0) return ret;
					}
				}
				m++;
/*
printf("akxc_jisho_regist: i=%d max_jisho=%d kana=[%s] heb=[%s] ih=%d\n",i,max_jisho,p,heb);
*/
				if (opt1) {
					_set_kana_hebon(&mcat,p,byte_kana,heb,strlen(heb));
				}
			}
		}
	}
	if ((ret=akxnmstrsort_opt(mcat_byte->mc_bufp,mcat_byte->mc_ipos,sizeof(int),1)) < 0) return ret;
	if (opt1) {
		par->parlen = mcat.mc_ipos;
		par->par = mcat.mc_bufp;
	}
	return m;
}

/****************************************/
/*	32									*/
/****************************************/
int akxc_jisho_henkan(par,xha_jisho,mcat_byte,s,s_len,opt)
ParList *par;
XHASHB *xha_jisho;
MCAT2 *mcat_byte;
char *s;
int s_len,opt;
{
	static MCAT mcat={'M','C',256,0,0,0,NULL,0};
	static char wrk[128],*p0=NULL,wrk2[128],*p02=NULL;;
	int k,n,m,d_len,rem_len,len_kana,byte_kana,byte_he,code_type,tr_dtypea[2],iCONV;
	int *len_byte,max_len_byte,ret;
	long ih,coll;
	char *dat,*he,*hebon,*d,*pAns,cc[2];

	if (!(dat=s) || !par || s_len < 0) return -185272801;

	code_type = GET_TYPE_OPT(opt);
	if ((iCONV=akxq_code_type_cmp(0,code_type))) {
		tr_dtypea[0] = 0;
		tr_dtypea[1] = code_type;
		if ((s_len=akxc_str_conv(&pAns,tr_dtypea,NULL,dat,s_len,0)) < 0) return s_len;
		if (pAns && dat!=pAns) {
			akxmemwork(s_len+1,&dat,&p0,wrk,sizeof(wrk));
			memzcpy(dat,pAns,s_len);
			Free(pAns);
		}
	}
/*
printf("akxc_jisho_henkan: code_type=%08x iCONV=%d\n",code_type,iCONV);
*/
#if 1
	akxmemwork(s_len+1,&d,&p02,wrk2,sizeof(wrk2));
	if ((ret=akxctokhkana_type(s_len,dat,d,CD_TYPE_KTKANA)) < 0) return ret;
	dat = d;
	s_len = ret;
/*
printf("akxc_jisho_henkan: s_len=%d dat=[%s]\n",s_len,dat);
*/
#endif

	mcat.mc_ipos = n = 0;
	rem_len = s_len;
	len_byte = (int *)mcat_byte->mc_bufp;
	max_len_byte = mcat_byte->mc_ipos;
/*
coll = akxs_xhash2(xha_jisho,'C',"",NULL);
printf("akxc_jisho_henkan:1 coll=%d\n",coll);
*/
	while (rem_len > 0) {
/*
printf("akxc_jisho_henkan: dat=[%s]\n",dat);
*/
		he = NULL;
		for (k=0;k<max_len_byte;k++) {
			byte_kana = len_byte[k];
			if (byte_kana > 0) {
				if (rem_len >= byte_kana) {
					if ((ih=akxs_xhashn2(xha_jisho,'R',dat,byte_kana,&he)) > 0) {
/*
printf("akxc_jisho_henkan: ih=%d byte_kana=%d dat=[%s]\n",ih,byte_kana,dat);
*/
						break;
					}
					else if (ih < 0) return ih;
				}
			}
			else break;
		}
		if (he) {
			rem_len -= byte_kana;
			dat += byte_kana;
			byte_he = strlen(he);
			n++;
/*
printf("akxc_jisho_henkan: rem_len=%d byte_kana=%d byte_he=%d he=[%s] dat=[%s]\n",
rem_len,byte_kana,byte_he,he,dat);
*/
		}
		else {
			m = akxqkanjilen2(dat,rem_len);
			he = dat;
			rem_len -= m;
			dat += m;
			byte_he = m;
		}
		akxtmcat(&mcat,he,byte_he);
	}
	akxtmcats(&mcat,"");
	hebon = mcat.mc_bufp;
	d_len = mcat.mc_ipos;
/*
coll = akxs_xhash2(xha_jisho,'C',"",NULL);
printf("akxc_jisho_henkan:2 coll=%d\n",coll);
*/
	if (iCONV) {
		tr_dtypea[0] = code_type;
		tr_dtypea[1] = 0;
/*
printf("akxc_jisho_henkan:2 code_type=%08x\n",code_type);
*/
		if ((d_len=akxc_str_conv(&pAns,tr_dtypea,NULL,hebon,d_len,0)) < 0) return d_len;
		if (pAns && hebon!=pAns) {
			akxmemwork(d_len+1,&d,&p0,wrk,sizeof(wrk));
			memzcpy(d,pAns,d_len);
			hebon = d;
			Free(pAns);
		}
	}
	par->parlen = d_len;
	par->par = hebon;
	return n;
}

#define MAX_KJ2FR	133800
#define PRE_KJ2FR	133781

static int init_kj2fr = 0;
static int max_kj2fr;
static XHASHB *xha_kj2fr;
static MCAT2 *kj_byte;
static char *hfr2kj_file;
static int hfr2kj_file_code;
/****************************************/
/*	41									*/
/****************************************/
static int _get_tail_ank(d,byte_kj,cc,opt)
char *d,cc[];
int byte_kj,opt;
{
	int m;

	m = akxs_mright(d,byte_kj,1,opt);
/*
printf("_kj2fr_init: m=%d\n",m);
*/
	if ((byte_kj-m) == 1) {
		byte_kj--;
		cc[0] = *(d+byte_kj);
/*
printf("_kj2fr_init: c=[%c]\n",cc[0]);
*/
	}
	else  cc[0] = '\0';
	return byte_kj;
}

/****************************************/
/*	31									*/
/****************************************/
static int _reg_add_okuri(xha_kj2fr,kj_byte,knj,byte_kj,fur,len,cc,buf,opt)
XHASHB *xha_kj2fr;
MCAT2 *kj_byte;
char *knj,*fur,*buf,cc[];
int byte_kj,len,opt;
{
	char c,*str,*dknj,*dfur,*dknj_okri,*dfur_okri,*pk,*p1,*pf;
	int ret,m,str_len,byte_kj_okr;
	long ih;

	ret = 0;
	c = cc[0];
	if (c == 'r') str = "ラリルレロ";
	else if (c == 'k') str = "カキクケコ";
	else if (c == 's') str = "サシスセソ";
	else if (c == 'i') str = "イ";
	else if (c=='p' || c=='t') str = "ッ";
	else str = NULL;
	if (str) {
		str_len = strlen(str);
		dknj = buf;
		memzcpy(dknj,knj,byte_kj);
		dfur = buf + byte_kj + 5;
		memzcpy(dfur,fur,len);
		dknj_okri = dknj + byte_kj;
		dfur_okri = dfur + len;
		pk = dknj_okri;
		pf = dfur_okri;
/*
printf("_reg_add_okuri: c=[%c]\n",c);
*/
	}
	else {
		str_len = 1;
		m = 1;
		dknj = knj;
		dfur = fur;
		byte_kj_okr = byte_kj;
	}
	p1 = str;
	while (str_len > 0) {
		if (str) {
			m = akxqkanjilen(p1);
			memzcpy(pk,p1,m);
			memzcpy(pf,p1,m);
			byte_kj_okr = byte_kj + m;
		}
/*
printf("_reg_add_okuri: m=%d dknj=[%s] dfur=[%s]\n",m,dknj,dfur);
*/
		if (!(ih=akxs_xhash2(xha_kj2fr,'R',dknj,NULL))) {
			if ((ih=akxs_xhash2(xha_kj2fr,'S',dknj,dfur)) < 0) {
				ret = ih;
				break;
			}
		}
		else if (ih < 0) {
			ret = ih;
			break;
		}
		max_kj2fr++;
		if ((ret=akxs_mseq_s(kj_byte,&byte_kj_okr)) < 0) break;
		str_len -= m;
		p1 += m;
	}
	return ret;
}

/****************************************/
/*	46									*/
/****************************************/
int akxc_set_hfr2kj_file(file,code)
char *file,*code;
{
	if (!(hfr2kj_file=Strdup(file))) return -185274601;
	hfr2kj_file_code = akxc_get_code_num(code);
	return 0;
}

/****************************************/
/*	47									*/
/****************************************/
static int _kj2fr_init(opt)
int opt;
{
	int byte_kj,n,ret,len,tr_dtypea[2],m,i,*byte_lena,dat_count;
	long ih,coll;
	FILE *fp;
	char *d,buf[128],parm[256],*argv[3],*p,c,*pAns,wrk[512],cc[2];
	ParList par;

	ret = 0;
	if (!init_kj2fr) {
/*
printf("_kj2fr_init: hfr2kj_file_code=%d hfr2kj_file=[%s]\n",hfr2kj_file_code,hfr2kj_file);
*/
		if (!hfr2kj_file) return -1;
		if (!(fp=fopen(hfr2kj_file,"r"))) {
			XERROROUTL5(200,"%s open error",hfr2kj_file,0,0,0,0);
			return -185274701;
		}
		xha_kj2fr = akxs_xhashm_new2(0,MAX_KJ2FR,PRE_KJ2FR,0,AKX_HASX_OPT_NOT_DELETE,NULL,NULL);
/*
printf("_kj2fr_init: xha_kj2fr=%08x\n",xha_kj2fr);
*/
		if (!(kj_byte = akxs_mseq_new(sizeof(int),30,NULL,NULL))) return -185274702;;
		dat_count = max_kj2fr = 0;
		tr_dtypea[0] = 0;
		tr_dtypea[1] = hfr2kj_file_code;
		par.parlen = sizeof(wrk);
		par.par = wrk;
		pAns = (char *)&par;
		cc[1] = '\0';
		while ((len = akxa_read_line(buf,sizeof(buf),fp)) >= 0) {
			if (!len || (c=*buf)=='#' || c==';') continue;
			else if (c=='/' && *(buf+1)=='/') break;
			if ((ret=akxc_str_conv(&pAns,tr_dtypea,NULL,buf,len,opt|CD_NOT_MALLOC)) < 0) break;
			n = akxtgetargv2(par.par,argv,3,parm,sizeof(parm),1);
/*
printf("_kj2fr_init: n=%d\n",n);
*/
			if (n >= 2) {
				dat_count++;
				d = argv[1];
				if ((byte_kj=strlen(d)) > 0) {
					p = argv[0];
					len = strlen(p);
/*
printf("_kj2fr_init: len=%d p=[%s]\n",len,p);
*/
					if ((ret=akxctokhkana_type(len,p,buf,CD_TYPE_KTKANA)) < 0) break;
/*
printf("_kj2fr_init: ret=%d buf=[%s]\n",ret,buf);
*/
					ret = _get_tail_ank(buf,ret,cc,opt);
					*(buf+ret) = '\0';
					c = cc[0];
					byte_kj = _get_tail_ank(d,byte_kj,cc,opt);
					if (!cc[0]) cc[0] = c;
					if ((ret=_reg_add_okuri(xha_kj2fr,kj_byte,d,byte_kj,buf,ret,cc,argv[2],opt)) < 0) break;
				}
			}
			else if (n < 0) {
				ret = n;
				break;
			}
		}
		if (ret >= 0) {
/*
printf("_kj2fr_init: dat_count=%d max_kj2fr=%d kj_byte max=%d\n",dat_count,max_kj2fr,kj_byte->mc_ipos);
*/
			ret = akxnmstrsort_opt(kj_byte->mc_bufp,kj_byte->mc_ipos,sizeof(int),1);
/*
byte_lena = (int *)kj_byte->mc_bufp;
n=kj_byte->mc_ipos;
printf("_kj2fr_init: n=%d\n",n);
for (i=0;i<n;i++) printf("_jisho_init: len=%d\n",byte_lena[i]);
*/
/*
coll = akxs_xhash2(xha_kj2fr,'C',"",NULL);
printf("_kj2fr_init: coll=%d\n",coll);
*/
		}
		if (ret >= 0) init_kj2fr = 1;
		fclose(fp);
	}
/*
printf("_kj2fr_init: ret=%d\n",ret);
*/
	return ret;
}
/****************************************/
/*	51									*/
/****************************************/
int akxckj2eng(par,s,s_len,opt)
ParList *par;
char *s;
int s_len,opt;
{
	int ret;

	memset(par,0,sizeof(ParList));
	if ((ret=_jisho_init(opt)) >= 0)
		ret = akxc_jisho_henkan(par,xha_jisho,mcat_byte,s,s_len,opt);
	return ret;
}

/****************************************/
/*	52									*/
/****************************************/
int akxckj2fr(par,s,s_len,opt)
ParList *par;
char *s;
int s_len,opt;
{
	int ret;

	memset(par,0,sizeof(ParList));
	if ((ret=_kj2fr_init(opt)) >= 0)
		ret = akxc_jisho_henkan(par,xha_kj2fr,kj_byte,s,s_len,opt);
/*
printf("akxckj2fr: parlen=%d par=[%s]\n",par->parlen,par->par);
*/
	return ret;
}

