static char sccsid[]="%Z% %M% %I% %E% %U%";
/*******************************************/
/*								*/
/*      coded by A.Kobayashi 2010.5.20   */
/*	更新 : 2018.09.09 		*/
/*								*/
/******************************************/
#include "akxcommon.h"

#ifdef CYGWIN64
#define UTF_8
#else
#if defined(AIX) || defined(WIN) || defined(HPUX) || defined(CYGWIN)
#define SJIS
#else
#define EUC
#endif
#endif

#ifndef SS2
#define SS2		0x8e	/* Hankaku Kana */
#define SS3		0x8f	/* G3 AREA      */
#endif

#ifdef UTF_8
static uchar  gucCodeType = CD_TYPE_UTF8;
#else
#ifdef EUC
static uchar  gucCodeType = CD_TYPE_EUC;
#else
static uchar  gucCodeType = CD_TYPE_SJIS;
#endif
#endif

#if 1
static char *gCodeStr[]=
	{"0","SYSCODE",""
	,"1","EUC",""
	,"2","CP932","SJIS","S-JIS",""
	,"3","ISO-2022-JP-3","JIS",""
	,""
	,"5","UTF-8","UTF8",""
	,"6","UCS-4-INTERNAL",""
	,""
	,""
	,"257","NARROW",""
	,"258","WIDE",""
	,NULL};
#else
static char *gCodeStr[]={"SYSCODE","EUC","SJIS","JIS","EBCDIC","UTF-8","UNICODE"
	,"","EBCDIK","256","NARROW","WIDE",NULL};
#endif

static uchar kigo[]=
{' '
,'!','"','#','$','%','&','\'','(',')','*'
,'+',',','-','.','/',':',';','<','=','>'
,'?','@','[','\\',']','^','_','`','{','|'
,'}','~','\'','"','\'','"','\0'};

static ushort dkigo[]=
{0x2121
,0x212a,0x2149,0x2174,0x2170,0x2173,0x2175,0x2147,0x214a,0x214b,0x2176
,0x215c,0x2124,0x215d,0x2125,0x213f,0x2127,0x2128,0x2163,0x2161,0x2164
,0x2129,0x2177,0x214e,0x216f,0x214f,0x2130,0x2132,0x212e,0x2150,0x2143
,0x2151,0x2141,0x216c,0x216d,0x212d,0x212f,0x0000};

typedef struct {
	short flag;
	short hkey;
	short next;
	short data;
} HaslCell;

#define HASL_MSO	29

static HaslCell gCell[41]=
{0,   0, 0,  0
,1,8526, 0, 91
,1,8527,35, 93
,1,8528,39,123
,1,8529, 0,125
,1,8559, 0, 92
,1,8560, 0, 36
,0,   0, 0,  0
,0,   0, 0,  0
,1,8563, 0, 37
,1,8564, 0, 35
,1,8565, 0, 38
,1,8566, 0, 42
,1,8567, 0, 64
,1,8481, 0, 32
,1,8540,31, 43
,1,8541, 0, 45
,1,8484,37, 44
,1,8485, 0, 46
,1,8515, 0,124
,1,8487,32, 58
,1,8488, 0, 59
,1,8547,34, 60
,1,8490,30, 33
,0,   0, 0,  0
,1,8521, 0, 34
,1,8522,40, 40
,1,8523,36, 41
,1,8495, 0, 34
,1,8496, 0, 94
,1,8519,33, 39
,1,8511, 0, 47
,1,8545, 0, 61
,1,8548, 0, 62
,1,8489, 0, 63
,1,8498,38, 95
,1,8494, 0, 96
,1,8513, 0,126
,1,8556, 0, 39
,1,8557, 0, 34
,1,8493, 0, 39};

typedef struct {
	ushort knj_s;
	ushort knj_e;
	char   step;
	uchar  kna_s;
	uchar  kna_e;
	uchar  dakuten;
} tdtKanaKan;

static tdtKanaKan kanakan[]=
{0x2522,0x252a,2,0xb1,0xb5,0
,0x2521,0x2529,2,0xa7,0xab,0
,0x252b,0x2533,2,0xb6,0xba,0
,0x252c,0x2534,2,0xb6,0xba,0xde
,0x2535,0x253d,2,0xbb,0xbf,0
,0x2536,0x253e,2,0xbb,0xbf,0xde
,0x253f,0x2541,2,0xc0,0xc1,0
,0x2543,0x2543,1,0xaf,0xaf,0
,0x2544,0x2544,1,0xc2,0xc2,0
,0x2546,0x2548,2,0xc3,0xc4,0
,0x2540,0x2542,2,0xc0,0xc1,0xde
,0x2545,0x2545,1,0xc2,0xc2,0xde
,0x2547,0x2549,2,0xc3,0xc4,0xde
,0x254a,0x254e,1,0xc5,0xc9,0
,0x254f,0x255b,3,0xca,0xce,0
,0x2550,0x255c,3,0xca,0xce,0xde
,0x2551,0x255d,3,0xca,0xce,0xdf
,0x255e,0x2562,1,0xcf,0xd3,0
,0x2564,0x2568,2,0xd4,0xd6,0
,0x2563,0x2567,2,0xac,0xae,0
,0x2569,0x256d,1,0xd7,0xdb,0
,0x256f,0x256f,1,0xdc,0xdc,0
,0x2570,0x2570,1,0xb2,0xb2,0
,0x2571,0x2571,1,0xb4,0xb4,0
,0x2572,0x2572,1,0xa6,0xa6,0
,0x2573,0x2573,1,0xdd,0xdd,0
,0x2574,0x2574,1,0xb3,0xb3,0xde
,0x2575,0x2575,1,0xb6,0xb6,0
,0x2576,0x2576,1,0xb9,0xb9,0
,0x213c,0x213c,1,0xb0,0xb0,0
,0x213d,0x213e,1,0x2d,0x2d,0
,0,0,0,0,0,0};

static ushort _kigo2zen(uc)
uchar uc;
{
	ushort us;

	if (uc == ' ') us = 0x2121;
	else if (uc>='!' && uc<='/') us = dkigo[uc-'!'+1];
	else if (uc>=':' && uc<='@') us = dkigo[uc-':'+16];
	else if (uc>='[' && uc<='`') us = dkigo[uc-'['+23];
	else if (uc>='{' && uc<='~') us = dkigo[uc-'{'+29];
	else us = 0;

	return us;
}

static uchar _zen2kigo(us)
short us;
{
	int i,n;
	HaslCell *cell,*ce;

	cell = gCell;
	i = (n=us)%HASL_MSO+1;
L10:
	ce = &cell[i];
	if (ce->hkey == us) return (uchar)ce->data;
	else if ((i=ce->next)>0) goto L10;

	return 0;
}

static int _kanjikana(us,ucp)
ushort us;
uchar  *ucp;
{
	tdtKanaKan *p;
	ushort wus,wus_e;
	uchar uc;
	int byte,k,kk;

	byte = 0;
	p = kanakan;
	while (p->knj_s) {
		uc = p->kna_s;
		wus_e = p->knj_e;
		k = p->step;
		kk = 0;
		if (uc < p->kna_e) kk++;
		for (wus=p->knj_s; wus<=wus_e; wus+=k,uc+=kk) {
			if (us == wus) {
				*ucp++ = uc;
				byte++;
				if (uc = p->dakuten) {
					*ucp++ = uc;
					byte++;
				}
				break;
			}
		}
		if (byte) break;
		p++;
	}
	return byte;
}

static int _kanakanji(uc,uc1,usp)
uchar uc,uc1;
ushort *usp;
{
	tdtKanaKan *p;
	uchar uc_s,uc_e;
	ushort us;
	int byte,k;

	us = byte = 0;
	p = kanakan;
	if (uc1!=0xde && uc1!=0xdf) uc1 = 0;
	while (p->knj_s) {
		if (uc1 == p->dakuten) {
			uc_s = p->kna_s;
			uc_e = p->kna_e;
			if (uc>=uc_s && uc<=uc_e) {
				us = p->knj_s + (uc-uc_s)*p->step;
				byte++;
				if (uc1) byte++;
				break;
			}
		}
		p++;
	}
	if (!us && uc1) byte = _kanakanji(uc,0,usp);
	else if (usp) *usp = us;
	return byte;
}

int akxt_set_code_type(ucCodeType)
uchar ucCodeType;
{
	return gucCodeType = ucCodeType;
}

int akxt_get_code_type()
{
	return gucCodeType;
}

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;
}

int akxqissjis(c)
uchar c;
{
	if ((c>=0x81 && c<=0x9f) || (c>=0xe0 && c<=0xfc))
		return 2;
	else
		return 0;
}

int akxqkanjilen1(c1)
uchar c1;
{
	return akxqmbslen1(gucCodeType,c1);
}

int akxqmbslen1(code_type,c1)
uchar code_type,c1;
{
	uchar p[4];

	p[0] = c1;
	if (code_type == CD_TYPE_EUC) {
		/********************/
		/*		EUC			*/
		/********************/
		p[1] = 0xa1;
	}
	else if (code_type == CD_TYPE_SJIS) {
		/********************/
		/*		SJIS		*/
		/********************/
		p[1] = 0x40;
	}
	else if (code_type == CD_TYPE_UTF8) {
		/********************/
		/*		UTF-8		*/
		/********************/
		p[3] = p[2] = p[1] = 0x0;
	}
	return akxqmbslen(code_type,p);
}

int akxqkanjilen(p)
uchar *p;
{
	return akxqmbslen(gucCodeType,p);
}

int akxqkanjilen2(p,len)
uchar *p;
int   len;
{
	return akxqmbsnlen(gucCodeType,p,len);
}

int akxqmbsnlen(code_type,p,len)
uchar code_type,*p;
int len;
{
	uchar c1,c2;

	if (!p || len<=0) return 0;
	if (!code_type) code_type = gucCodeType;

	c2 = '\0';
	if (code_type == CD_TYPE_EUC) {
		/********************/
		/*		EUC			*/
		/********************/
		c1 = *p++;
		if (len >= 2) c2 = *p;
		if (c1==SS3) return 3;
		else if ((c1==SS2) ||
			((c1>=0xa1) && (c1<=0xfe) && (c2>=0xa1) && (c2<=0xfe))) return 2;
	}
	else if (code_type == CD_TYPE_SJIS) {
		/********************/
		/*		SJIS		*/
		/********************/
		if (len >= 2) c2 = *(p+1);
		if (akxqissjis(*p) &&
		    ((c2>=0x40 && c2<=0x7e)||(c2>=0x80 && c2<=0xfc))) return 2;
	}
	else if (code_type == CD_TYPE_UTF8) {
		/********************/
		/*		UTF-8		*/
		/********************/
		return akxqu8nlen(p,len);
	}
	return 1;
}

int akxqmbslen(code_type,p)
uchar code_type,*p;
{
	int len;

	if ((len=akxqmbsnlen(code_type,p,4)) < 0) len = -len;
	return len;
}

int akxqiskanji1(c1)
uchar c1;
{
	return akxqismbs1(gucCodeType,c1);
}

int akxqismbs1(code_type,c1)
uchar code_type,c1;
{
	int len;

	if ((len=akxqmbslen1(code_type,c1)) == 1) len = 0;
	return len;
}

int akxqiskanji(p)
uchar *p;
{
	return akxqismbs(gucCodeType,p);
}

int akxqismbs(code_type,p)
uchar code_type,*p;
{
	int len;
	char sjis[4];
	uchar uc;

	if ((len=akxqmbslen(code_type,p)) == 1) len = 0;
/* 2020.5.7
	else if (code_type == CD_TYPE_UTF8) {
		akxcu8tos1(p,sjis);
		uc = *sjis;
		if (uc>=161 && uc<=223) len = 0;
	}
*/
	return len;
}

#if 1
int akxqisank_type(int type, char c)
{
	int rc;
	uchar uc;

	rc = 0;
	uc = (uchar)c;
	if (type == CD_TYPE_SJIS) {
		if ((uc>=0x20 && uc<=0x7e) || (uc>=0xa1 && uc<=0xdf)) rc = 1;
	}
/*	else if (type==CD_TYPE_EUC I1 type==CD_TYPE_UTF8) I */
	else {
		if (uc>=0x20 && uc<=0x7e) rc = 1;
	}
	return rc;
}

int akxqisank(char c)
{
	return akxqisank_type(gucCodeType, c);
}

char akxctoank_type(int type, char c)
{
	if (!akxqisank_type(gucCodeType, c)) c = '.';
	return c;
}

char akxctoank(char c)
{
	return akxctoank_type(gucCodeType, c);
}
#else
int akxqisank(c)
uchar c;
{
	if (gucCodeType==CD_TYPE_EUC || gucCodeType==CD_TYPE_UTF8) {
		/********************/
		/*	EUC or UTF-8	*/
		/********************/
		if ((c>=0x20 && c<=0x7e))
			return (1);
		else
			return (0);
	}
	else if (gucCodeType == CD_TYPE_SJIS) {
		/********************/
		/*	SJIS			*/
		/********************/
		if ((c>=0x20 && c<=0x7e) ||
		    (c>=0xa1 && c<=0xdf) )
			return (1);
		else
			return (0);
	}
}

char akxctoank(c)
uchar c;
{
	if (akxqisank(c))
		return ((char)c);
	else
		return ('.');
}
#endif

int akxqis_hankaku_kana_type(type,p,mlen)
int type;
char *p;
int mlen;
{
	int code,rc;
	uchar uc;

	rc = 0;
	uc = *p;
	if (type==CD_TYPE_SJIS || type==CD_TYPE_JIS) {
		if (mlen == 1) {
			if (uc>=0xa1 && uc<=0xdf) rc = mlen; /* 半角カナ */
		}
	}
	else if (type == CD_TYPE_UTF8) {
		if (mlen == 3) {
			code = uc;
			code = code<<8 | (uchar)*(p+1);
			code = code<<8 | (uchar)*(p+2);
			if ((code>=0xEFBDA1 && uc<=0xEFBDBF) ||
			    (code>=0xEFBE80 && uc<=0xEFBE9F) ) rc = mlen; /* 半角カナ */
		}
	}
	else if (type == CD_TYPE_EUC) {
		if (mlen == 2) {
			if (uc == 0x8e) rc = mlen; /* 半角カナ */
		}
	}
	return rc;
}

int akxqis_hankaku_kana(p,mlen)
char *p;
int mlen;
{
	return akxqis_hankaku_kana_type(gucCodeType,p,mlen);
}

#define SO	0x0e
#define SI	0x0f

int akxqmbsnalen(p,len,attr)
int len;
uchar *p,attr[];
{
	uchar c1,c2,code_type;
	int type,mode,nb,bits;

	if (!p || len<0) return -1;
	if (!len) return 0;
	if (attr) {
		if (!(code_type = attr[0])) {
			attr[0] = code_type = gucCodeType;
		}
	}
	else code_type = gucCodeType;
	type = code_type;

	mode = 1;
	nb = 0;
	bits = 8;
	if ((type == CD_TYPE_EUC) || (type == CD_TYPE_SJIS) ||
	    (type == CD_TYPE_UTF8)) {
		nb = akxqmbsnlen(code_type,p,len);
		mode = nb;
	}
	else if (type == CD_TYPE_JIS) {
		if (!attr) return -2;
		if (len == 1) {
			mode = 1;
			nb = 1;
			bits = 8;
		}
		else {
			mode = attr[1];
			c1 = *p++;
			if (c1 == SO || c1 == SI) {
				mode = 1;
				if (c1 == SI) bits = 7;
				else if (c1 == SO) bits = 8;
				nb = 1;
			}
			else if (len>=3 && c1 == 0x1b) {
				c1 = *p++;
				c2 = *p;
				if (c1 == '$') {
					mode = 2;
					bits = 16;
					if (c2=='@' || c2=='B') nb = 5;
					else {
						mode = 0;
						nb = 2;
					}
				}
				else if (c1 == '(') {
					mode = 1;
					bits = 8;
					if (c2=='B' || c2=='J') nb = 4;
					else if (c2=='I') {
						nb = 4;
						bits = 7;
					}
					else {
						mode = 0;
						nb = 2;
					}
				}
				else {
					mode = 0;
					nb = 1;
				}
			}
			else {
				if (mode <= 1) {
					mode = nb = 1;
				}
				else {
					mode = nb = 2;
				}
			}
		}
	}
	else return -3;
	if (attr) {
		attr[1] = mode;
		attr[2] = nb;
		attr[3] = bits;
	}
	return nb;
}

int akxtmget(p,len,ssp)
char *p;
int len;
SSP_S *ssp;	/* ssp.attr[0]:kanji code kind    */
			/*     attr[1]:mode 1=ANK,2=KANJI */
			/*     attr[2]:got byte */
			/*     attr[3]:7/8/16 bit */
{
	int m,mode,nb,sp;
	char *wd;
	uchar *attr;

	if (!p || !ssp) return -1;
	sp = ssp->sp;
	wd = ssp->wd;
	attr = ssp->attr;
	p += sp;
	len -= sp;
	m = akxqmbsnalen(p,len,attr);
	if (m <= 0) return m;
	if (attr[0] == CD_TYPE_JIS) {
		mode = attr[1];
		nb   = attr[2];
		sp += nb;
		while (!mode) {
			if (!p[nb-1]) return 0;
			p += nb;
			len -= nb;
			m = akxqmbsnalen(p,len,attr);
			if (m < 0) return m;
			mode = attr[1];
			nb   = attr[2];
			sp += nb;
		}
		if(wd) memcpy(wd,p,nb);
		m = nb;
	}
	else {
		if (m <= 0) m = 1;
		if(wd) memcpy(wd,p,m);
		sp += m;
	}
	ssp->sp = sp;
	return m;
}

int akxtmput(p,len,ssp)
char *p;
int len;
SSP_S *ssp;	/* ssp.attr[0]:ESC mode*/
			/*     attr[1]:mode 1=ANK,2=KANJI */
			/*     attr[2]:put len */
			/*     attr[3]:before mode */
{
	int m,mode,bmode,sp,esc_mode,nb;
	char *wd;
	uchar *attr;

	if (!p || !ssp) return -1;
	sp = ssp->sp;
	len -= sp;
	nb = 0;
	if (len > 0) {
		wd = ssp->wd;
		attr = ssp->attr;
		esc_mode = attr[0];
		mode = attr[1];
		m = attr[2];
		bmode = attr[3];
		p += sp;
		if (mode == 2) {
			if (bmode == 2) {
				memcpy(p,wd,m);
				nb = m;
			}
			else if (len < 5) nb = 0;
			else {
				*p++ = 0x1b;
				*p++ = '$';
				if (esc_mode) *p++ = 'B';
				else          *p++ = '@';
				memcpy(p,wd,m);
				nb = m + 3;
			}
		}
		else {
			if (bmode == 2) {
				if (len < 4) nb = 0;
				else {
					*p++ = 0x1b;
					*p++ = '(';
					if (esc_mode) *p++ = 'J';
					else          *p++ = 'B';
					*p = *wd;
					nb = m + 3;
				}
			}
			else if (len < 1) nb = 0;
			else {
				*p = *wd;
				nb = 1;
			}
		}
		attr[3] = mode;
		ssp->sp = sp + nb;
	}
	return nb;
}

/****************************/
/*	S-JIS --> JIS			*/
/****************************/
int akxcstoj(n, inc, outc)
int		n;
uchar *inc, *outc;
{
	int m,len=n,nout,nb;
	SSP_S ssp;
	uchar *pi=inc,w[4];

	ssp.sp = 0;
	ssp.attr[0] = 0;
	ssp.attr[3] = 0;
	while (len>0) {
		m = akxqmbsnlen(CD_TYPE_SJIS,pi,len);
		ssp.attr[1] = m;
		ssp.attr[2] = m;
		if (m == 2) {
			akxcstoj1(pi,w);
			ssp.wd = w;
		}
		else ssp.wd = pi;
		pi += m;
		len -= m;
		nb = akxtmput(outc,INT_MAX,&ssp);
	}
	return ssp.sp;
}

/****************************/
/*	JIS --> S-JIS			*/
/****************************/
int akxcjtos(n, inc, outc)
int		n;
uchar *inc, *outc;
{
	int m,len,nb;
	SSP_S ssp;
	uchar *po=outc,*w;

	ssp.sp = 0;
	ssp.attr[0] = CD_TYPE_JIS;
	len = 0;
	while ((nb=akxtmget(inc,n,&ssp)) > 0) {
		m = ssp.attr[1];
		w = ssp.wd+(nb-m);
		if (m == 2) akxcjtos1(w,po);
		else *po = *w;
		po += m;
		len += m;
	}
	return len;
}

/****************************/
/*	EUC --> S-JIS			*/
/****************************/
static ushort sj_to_euc();
static ushort jis_to_sj();

#define	Z_BEGIN		0xa1	/* Zenkaku Start */
#define	Z_END		0xfe	/* Zenkaku End */
#define AKX_DEFAULT_CODE	0x3f3f	/* '??' */;

int akxcetos(n, inc, outc)
int		n;
uchar *inc, *outc;
{
	int i, j, stat, max=n;
	ushort c,c1,c2;
	ushort s1,s2;
	uchar *pi=inc,*po=outc;

	stat = j = 0;
	for (i=0;i<max;i++) {
		c = *pi++;
		switch (stat) {
		case 0:
			if (Z_BEGIN <= c  && c <= Z_END) { /* Zenkaku */
				c1 = c & 0x7f;
				stat = 1;
			}
			else if (c == SS2) {	 /* Hankaku Kana */
				stat = 2;
			}
			else {	/* ASCII */
				*po++ = c;
				j++;
			}
			break;
		case 1:
			stat = 0;
			if (!(c & 0x80)) {
				*po++ = '?';
				*po++ = '?';
				j += 2;
				break;
			}
		 	c2 = c & 0x7f;
			jis_to_sj(c1,c2,&s1,&s2); /* Convert JIS to Sift_JIS */
			*po++ = s1;
			*po++ = s2;
			j += 2;
			break;
		case 2:
			*po++ = c;
			j++;
			stat = 0;
			break;
		}
	}
	if (stat) j = -j;
	return j;
}

static ushort jis_to_sj(jis1,jis2,ibm1,ibm2)
ushort jis1,jis2,*ibm1,*ibm2;
{
	ushort sj1,sj2;

	if(jis1 >= 0x5f) jis1 += 0x80;

	if(jis1 & 0x01) {
		if(jis2 >= 0x60) jis2 = jis2 + 0x01;
		sj1 = (jis1 - 0x31)/2 + 0x89;
		sj2 = jis2 + 0x1f;
	}
	else {
		sj1 = (jis1 - 0x30)/2 + 0x88;
		sj2 = jis2 + 0x7e;
	}
	sj1 &= 0xff;
	sj2 &= 0xff;
	*ibm1 = sj1;
	*ibm2 = sj2;
	sj1 = sj1<<8 + sj2;
	return ntohs(sj1);
}

/****************************************/
/*	S-JIS --> EUC  Convert Routine		*/
/*	opt=0:only replace					*/
/*	rep=NULL:replace default			*/
/*	   =""  :suppress					*/
/****************************************/
int akxcstoe2(n, inc, outc, opt, rep)
uchar *inc,*outc,*rep;
int n,opt;
{
	int i, j, stat, replen=-1,max=n;
	ushort c,c1;
	ushort s1,s2,us;
	uchar w[3];
	uchar *pi=inc,*po=outc;

	if (rep) replen = strlen(rep);
	stat = j = 0;
	for (i=0;i<max;i++) {
		c = *pi++;
		switch (stat) {
		case 0:
			if((c>=0x81 && c<=0x9f) || (c>=0xe0 && c<=0xfc)) {
				c1 = c;			/* ZENKAKU */
				stat = 1;
			}
			else if((0xa1 <= c) && (c <= 0xdf)) { /* Hankaku Kana */
				*po++ = SS2;
				*po++ = c;
				j += 2;
			}
			else { 				/* ASCII */
				*po++ = c;
				j++;
			}
			break;
		case 1:
			stat = 0;
			if (c<0x40 || c==0x7f || c>0xfc) {	/* invalid */
				*po++ = '?';
				j++;
				i--;
			}
			else {
				if (c1<0xf0) {
					sj_to_euc(c1,c,&s1,&s2);/* Change Shift_JIS into EUC */
				}
				else {
					if (replen<0) {
						us = AKX_DEFAULT_CODE;
						s1 = us>>8;
						s2 = us & 0x00ff;
					}
					else {
						if (replen>0) {
							memcpy(po,rep,replen);
							j += replen;
							po += replen;
						}
						continue;
					}
				}
				*po++ = s1;
				*po++ = s2;
				j += 2;
			}
			break;
		}
	}
	return j;
}

int akxcstoe(n, inc, outc)
int				n;
uchar	*inc, *outc;
{
	return akxcstoe2(n, inc, outc, 0, NULL);
}

static ushort sj_to_euc(sj1,sj2,euc1,euc2)
ushort sj1,sj2,*euc1,*euc2;
{
	ushort eu1,eu2;

	if (sj1 >= 0xe0) sj1 -=  0x40;	/* The 2nd standard of JIS */

	if (sj2 >= 0x9f) {
		eu1 = (sj1 - 0x88)*2 + 0xb0;
		eu2 = sj2 + 0x02;
	}
	else {
		if (sj2 >= 0x7f) sj2 -= 0x01;
		eu1 = (sj1 - 0x89)*2 + 0xb1;
		eu2 = sj2 + 0x61;
	}
	*euc1 = eu1;
	*euc2 = eu2;
	eu1 = eu1<<8 + eu2;
	return ntohs(eu1);
}

int akxcetos1(euc,sjis)
uchar *sjis,*euc;
{
	int ret;
	ushort sjis1,sjis2;
	uchar uc1,uc2;

	uc1 = *euc++;
	uc2 = *euc;
	if (uc1 == SS2) {
		*sjis++ = uc2;
		*sjis   = '\0';
		ret = 1;
	}
	else {
		ret = jis_to_sj(uc1 & 0x7f,uc2 & 0x7f,&sjis1,&sjis2);
		*sjis++ = sjis1;
		*sjis   = sjis2;
		ret = 2;
	}
	return ret;
}

int akxcstoe1(sjis,euc)
uchar *sjis,*euc;
{
	int ret;
	ushort euc1,euc2;
	uchar uc;

	uc = *sjis;
	if((0xa1<=uc) && (uc<=0xdf)) { /* Hankaku Kana */
		euc1 = SS2;
		euc2 = uc;
		ret= euc1<<8 + euc2;
		ret= ntohs(ret);
	}
	else {
		ret = sj_to_euc(*sjis,*(sjis+1),&euc1,&euc2);
	}
	*euc++ = euc1;
	*euc   = euc2;
	return ret;
}

int akxcjtos1(jis,sjis)
uchar *jis,*sjis;
{
	ushort c1,c2;

	c1 = *jis++;
	c2 = *jis;

	if (c1 & 1) {
		c1 = (c1 >> 1) + 0x71;
		c2 += 0x1f;
		if (c2 >= 0x7f) c2++;
	}
	else {
		c1 = (c1 >> 1) + 0x70;
		c2 += 0x7e;
	}
	if (c1 > 0x9f) c1 += 0x40;

	c1 &= 0xff;
	c2 &= 0xff;
	*sjis++ = c1;
	*sjis   = c2;

	c1 = c1<<8 | c2;
	return ntohs(c1);
}

int akxcstoj1(sjis,jis)
uchar *sjis,*jis;
{
	ushort c1,c2;

	c1 = *sjis++;
	c2 = *sjis;

	c1 -= (c1 <= 0x9f) ? 0x70 : 0xb0;
	c1 <<= 1;
	if (c2 < 0x9f) {
		c2 -= (c2 < 0x7f) ? 0x1f : 0x20;
		c1--;
	}
	else
		c2 -= 0x7e;

	c1 &= 0xff;
	c2 &= 0xff;
	*jis++ = c1;
	*jis   = c2;

	c1 = c1<<8 | c2;
	return ntohs(c1);
}

/****************************************/
/*										*/
/****************************************/
int akxcetoj1(euc,jis)
uchar *euc,*jis;
{
	uchar uc1,uc2;

	uc1 = (*euc++) & 0x7f;
	uc2 =  *euc    & 0x7f;
	*jis++ = uc1;
	*jis   = uc2;
	return 2;
}

/****************************************/
/*										*/
/****************************************/
int akxcjtoe1(jis,euc)
uchar *jis,*euc;
{
	uchar uc1,uc2;

	uc1 = (*jis++) | 0x80;
	uc2 =  *jis    | 0x80;
	*euc++ = uc1;
	*euc   = uc2;
	return 2;
}

int akxcstou81(sjis,utf8)
uchar *sjis,*utf8;
{
	ushort us,usw;

	memcpy(&usw,sjis,2);
	us = ntohs(usw);
	return akxc_sj_to_utf8(us,utf8,NULL);
}

int akxcu8tos1(utf8,sjis)
uchar *utf8,*sjis;
{
	int len;
	ushort us,usw;
	uchar uc;

	len = 0;
	akxc_utf8_to_sj(utf8,&us,NULL);
/*
printf("akxcu8tos1: us=%08x\n",us);
*/
	uc = us;
	if (us) {
		len = 1;
		if (us & 0xff00) {
			sjis[1] = uc;
			uc = us>>8;
			len++;
		}
	}
	*sjis = uc;
	return len;
}

/****************************************/
/*	全角 JIS --> type					*/
/*  ret : type=CD_TYPE_UTF8 : out len	*/
/*		  type=その他		: 全角code	*/
/****************************************/
int akxcfromjis(pd,ps,type)
char *ps,*pd;
int type;
{
	int ret;
	ushort us,usw;
	char w[4];
	UINT4 ul;

	if (type <= 0) type = akxt_get_code_type();
	if (type == CD_TYPE_UTF8) {
		akxcjtos1(ps,w);
		ret = akxcstou81(w,pd);
/*
ul = akxcmb2ul(pd,ret);
printf("akxcfromjis: ret=%d ul=%08x\n",ret,ul);
*/
	}
	else {
		if (type == CD_TYPE_EUC) {
			pd[0] = ps[0] | 0x80;
			pd[1] = ps[1] | 0x80;
		}
		else if (type == CD_TYPE_SJIS) {
			akxcjtos1(ps,pd);
		}
		memcpy(&usw,pd,2);
		ret = ntohs(usw);
	}
	return ret;
}

/****************************************/
/*	全角 type --> JIS					*/
/****************************************/
ushort akxctojis(pd,ps,type)
char *ps,*pd;
int type;
{
	ushort us,usw;
	char w[4];

	if (type == CD_TYPE_EUC) {
		pd[0] = ps[0] & 0x7f;
		pd[1] = ps[1] & 0x7f;
	}
	else if (type == CD_TYPE_SJIS) {
		akxcstoj1(ps,pd);
	}
	else if (type == CD_TYPE_UTF8) {
		akxcu8tos1(ps,w);
		akxcstoj1(w,pd);
	}
	memcpy(&usw,pd,2);
	us = ntohs(usw);
	return us;
}

/****************************************/
/*	Zenkaku --> Hankaku					*/
/****************************************/
int akxctohan(n, inc, outc)
int  n;
char *inc,*outc;
{
	return akxctohan_opt(n, inc, outc, 0);
}

int akxctohan_type(n, inc, outc, from_type)
int  n,from_type;
char *inc,*outc;
{
	return akxctohan_type_opt(n,inc,outc,from_type,0);
}

int akxctohan_opt(n, inc, outc, opt)
int  n,opt;
char *inc,*outc;
{
	int from_type;

	from_type = akxt_get_code_type();
	return akxctohan_type_opt(n,inc,outc,from_type,opt);
}

int akxctohan_type_opt(n, inc, outc, from_type, opt)
int  n,from_type,opt;
char *inc,*outc;
{
	int  len1,i,byte,mode,ret;
	char *p1,*p;
	uchar  uc,w[5];
	ushort us,usw,sjis;
	UINT4 ul;
/*
printf("akxctohan_type_opt:Enter n=%d from_type=%d opt=%08x\n",n,from_type,opt);
*/
	if (from_type <= 0) from_type = akxt_get_code_type();
	len1 = n;
	p1 = inc;
	p  = outc;
/*	for (i=0;i<len1;i++) {	*/
	while (len1 > 0) {
/*
printf("akxctohan_type_opt: *p1=%02x\n",*p1 & 0xff);
*/
#if 1	/* 2020.5.5 */
		if (mode=akxqismbs(from_type,p1)) {
#else
		if (akxqiskanji(p1)) {
#endif
			us = akxctojis(w,p1,from_type);
/*
ul = akxcmb2ul(p1,mode);
printf("akxctohan_type_opt: mode=%d ul=%08x us=%04x\n",mode,ul,us);
*/
			byte = 0;
			uc = 0;
			if (!(opt & 0x01) && us >= 0x2330 && us <= 0x2339) { /* 0-9 */
				uc = (us - 0x2330) + '0';
			}
			else if (!(opt & 0x02) && us >= 0x2341 && us <= 0x235A) { /* A-Z */
				uc = (us - 0x2341) + 'A';
			}
			else if (!(opt & 0x04) && us >= 0x2361 && us <= 0x237a) { /* a-z */
				uc = (us - 0x2361) + 'a';
			}
			else if (!(opt & 0x10) &&
			         ((us >= 0x2501 && us <= 0x2576) || /* ァ- ヶ */
			          (us >= 0x213c && us <= 0x213e))) { /* ー ― ‐  */
#if 1	/* 2020.12.4 */
				byte = _kanjikana(us,w);
/*
printf("akxctohan_type_opt: w[0]=%02x(%c) w[1]=%02x(%c)\n",w[0],w[0],w[1],w[1]);
*/
				if (from_type == CD_TYPE_UTF8) {
					sjis = w[0];
					ret = akxc_sj_to_utf8(sjis,p,NULL);
					if (byte > 1) {
						p += ret;
						sjis = w[1];
						byte = akxc_sj_to_utf8(sjis,p,NULL);
					}
					else byte = ret;
				}
				else if (from_type == CD_TYPE_EUC) {
					p[0] = SS2;
					p[1] = w[0];
					if (byte > 1) {
						p += 2;
						p[0] = SS2;
						p[1] = w[1];
						byte = 2;
					}
				}
				else memcpy(p,w,byte);
#else
				byte = _kanjikana(us,p);
#endif
			}
			else if (!(opt & 0x08)) uc = _zen2kigo(us);
/*
printf("akxctohan_type_opt: byte=%d uc=%d\n",byte,uc);
*/
			if (byte) {
				p  += byte;
			/*	p1 += 2;	*/
			}
			else if (uc) {
				*p++ = uc;
			/*	p1 += 2;	*/
			}
			else {
			/*	*p++ = *p1++;
				*p++ = *p1++;	*/
				memcpy(p,p1,mode);
				p  += mode;
			}
		/*	i++;	*/
			len1 -= mode;
			p1 += mode;
		}
		else {
		/*	*p++ = *p1++;	*/
			byte = akxqmbslen(from_type,p1);
/*
printf("akxctohan_type_opt: mode=%d byte=%d\n",mode,byte);
*/
			memcpy(p,p1,byte);
			p  += byte;
			p1 += byte;
			len1 -= byte;
		}
	}
	*p = '\0';
	return strlen(outc);
}

/****************************************/
/*	Hankaku --> Zenkaku					*/
/****************************************/
int akxctozen(n, inc, outc)
int  n;
char *inc,*outc;
{
	int from_type;

	from_type = akxt_get_code_type();
	return akxctozen_type(n, inc, outc, from_type);
}

int akxctozen_type(n, inc, outc, from_type)
int  n,from_type;
char *inc,*outc;
{
	int  len1,i,byte,out_len,nn[3];
	char *p1,*p;
	uchar  uc,uc1;
	ushort us,usw;

	len1 = n;
	p1 = inc;
	p  = outc;
	out_len = 0;
#if 1
	while (len1 > 0) {
		byte = akxctozen1_type(len1, p1, p, nn, from_type);
		if (outc) p += byte;
		p1 += nn[0];
		len1 -= nn[0];
		out_len += byte;
	}
	if (outc) outc[out_len] = '\0';
#else
	for (i=0;i<len1;i++) {
		if ((byte=akxqkanjilen(p1)) >= 2) {
			if (outc) {
				memcpy(p,p1,byte);
				p += byte;
				p1 += byte;
			}
			i += byte-1;
			out_len += byte;
		}
		else {
			uc = *p1++;
			us = 0;
			if ((uc >= '0' && uc <= '9') ||
			    (uc >= 'A' && uc <= 'Z') ||
			    (uc >= 'a' && uc <= 'z')) {
				if (outc) {
					if (!(opt & 0x01) && uc >= '0' && uc <= '9') {
						us = (uc - '0') + 0x2330;
					}
					else if (!(opt & 0x02) && uc >= 'A' && uc <= 'Z') {
						us = (uc - 'A') + 0x2341;
					}
					else if (!(opt & 0x04) && uc >= 'a' && uc <= 'z') {
						us = (uc - 'a') + 0x2361;
					}
				}
				else us = 0x2121;
			}
			else if (uc >= 0xa6 && uc <= 0xdd) {
				if (i < len1) uc1 = *p1;
				else uc1 = 0;
				byte = _kanakanji(uc,uc1,&us);
				if (byte == 2) {
					i++;
					p1++;
				}
			}
			else us = _kigo2zen(uc);

			if (us) {
				if (outc) {
					usw = htons(us);
					us = akxcfromjis(p,&usw,type);
					p += 2;
				}
				out_len += 2;
			}
			else {
				if (outc) *p++ = uc;
				out_len++;
			}
		}
	}
	if (outc) *p = '\0';
#endif
	return out_len;
}

int akxctozen1(n, inc, outc, nn)
int  n,nn[];
char *inc,*outc;
{
	int out_len;

	out_len = akxctozen1_type(n, inc, outc, nn, -1);
	if (outc) outc[out_len] = '\0';
	return out_len;
}

int akxctozen1_type(n, inc, outc, nn, from_type)
int  n,nn[],from_type;
char *inc,*outc;
{
	return akxctozen1_type_opt(n, inc, outc, nn, from_type, 0);
}

int akxctozen1_type_opt(n, inc, outc, nn, from_type, opt)
int  n,nn[],from_type,opt;
char *inc,*outc;
{
	int  len1,i,byte,out_len,to_type,byte_sjis,in_len,olen,byte2;
	char *p1,*p,sjis[4],*pp,wrk[4];
	uchar  uc,uc1;
	ushort us,usw;
	UINT4 ul;
/*
printf("akxctozen1_type_opt:Enter n=%d from_type=%d opt=%08x\n",n,from_type,opt);
*/
	len1 = n;
	pp = p1 = inc;
	p  = outc;
	in_len = out_len = byte2 = 0;
	if (from_type < 0) from_type = akxt_get_code_type();
/*	if (len1 >= 2) {	*/
		byte = akxqmbsnlen(from_type,p1,len1);
	/*	byte = akxqkanjilen(p1);	*/
/*
printf("akxctozen1_type_opt: byte=%d\n",byte);
*/
		byte_sjis = 0;
		if (from_type == CD_TYPE_UTF8) {
			byte_sjis = akxcu8tos1(p1,sjis);
			uc = *sjis;
/*
printf("akxctozen1_type_opt: byte_sjis=%d uc=%d(%02x)\n",byte_sjis,uc,uc);
*/
			if (uc>=161 && uc<=223) {
				byte2 = akxqmbsnlen(from_type,p1+byte,len1-byte);
			/*	byte2 = akxqkanjilen(p1+byte);	*/
				pp = sjis;
				in_len = byte;
				akxcu8tos1(p1+byte,sjis+1);
			}
		}
		if (!in_len && byte>=2) {
/*
printf("akxctozen1_type_opt: in_len=%d byte=%d\n",in_len,byte);
*/
			nn[0] = byte;
			nn[1] = byte;
			nn[2] = 1;
			if (outc) {
				memcpy(outc,inc,byte);
			}
			return byte;
		}
/*	}	*/
	to_type = 0;
	us = 0;
	byte = 1;
	uc = *pp++;
	if ((uc >= '0' && uc <= '9') ||
	    (uc >= 'A' && uc <= 'Z') ||
	    (uc >= 'a' && uc <= 'z')) {
	/*	if (outc) {	*/
			if (!(opt & 0x01) && uc >= '0' && uc <= '9') {
				us = (uc - '0') + 0x2330;
			}
			else if (!(opt & 0x02) && uc >= 'A' && uc <= 'Z') {
				us = (uc - 'A') + 0x2341;
			}
			else if (!(opt & 0x04) && uc >= 'a' && uc <= 'z') {
				us = (uc - 'a') + 0x2361;
			}
	/*	}
		else us = 0x2121;	*/
	}
	else if (!(opt & 0x10) && uc >= 0xa1 && uc <= 0xdf) {
		if (len1 > 1) uc1 = *pp;
		else uc1 = 0;
		byte = _kanakanji(uc,uc1,&us);
		if (byte >= 2) in_len += byte2;
/*
printf("akxctozen1_type_opt: uc=%d uc1=%d byte=%d byte2=%d us=%04x\n",uc,uc1,byte,byte2,us);
*/
	}
	else if (!(opt & 0x08)) us = _kigo2zen(uc);
/*
printf("akxctozen1_type_opt: us=%04x\n",us);
*/
	if (us) {
		olen = 2;
		usw = htons(us);
		us = akxcfromjis(wrk,&usw,to_type);
		if (akxt_get_code_type()==CD_TYPE_UTF8) olen = us;
/*
ul = akxcmb2ul(wrk,olen);
printf("akxctozen1_type_opt: olen=%d ul=%08x\n",olen,ul);
*/
		if (outc) memcpy(outc,wrk,us);
	/*	p += olen;	*/
	/*	out_len += olen;	*/
		out_len = olen;
	}
	else {
	/*	if (outc) *p++ = uc;	*/
		if (outc) *p = uc;
		out_len++;
	}
	if (!in_len) in_len = byte;
/*
printf("akxctozen1_type_opt: in_len=%d out_len=%d\n",in_len,out_len);
*/
	nn[0] = in_len;
	nn[1] = out_len;
	nn[2] = byte;
	return nn[1];
}

int akxt_chk_lang_type(lang)
char *lang;
{
	int type=0;

	if (!strcmp(lang,"ja_JP") || !strcmp(lang,"ujis"))
		type = CD_TYPE_EUC;
	else if (!strcmp(lang,"Ja_JP")) type = CD_TYPE_SJIS;
	else if (!strcmp(lang,"JA_JP")) type = CD_TYPE_UTF8;
	else if (!strcmp(lang,"ja")) type = akxt_get_code_type();
	else {
		if (stristr(lang,"EUC")) type = CD_TYPE_EUC;
		else if (stristr(lang,"SJIS") || stristr(lang,"S-JIS"))
			type = CD_TYPE_SJIS;
		else if (stristr(lang,"UTF8") || stristr(lang,"UTF-8"))
			type = CD_TYPE_UTF8;
	}
	return type;
}

int akxt_get_lang_type(key,opt,buf,buflen)
char *key,*buf;
int  opt,buflen;
{
	static struct {
		char *lang;
		int   type;
	} reg[]={NULL,0,NULL,0};

	char *lang=NULL,*p;
	int  type=-1,i=-1;

	if (!key) key = "LANG";

	if (!strcmp(key,"LANG")) i = 0;
	else if (!strcmp(key,"NLS_LANG")) i = 1;

	if (!opt && i>=0) {
		if (lang = reg[i].lang) {
			type = reg[i].type;
			i = -2;
/*
printf("akxt_get_lang_type:1: lang=[%s] type=%d i=%d\n",lang,type,i);
*/
		}
	}

	if (!lang) {
		if (lang=getenv(key)) {
#if 1
			if (!(type=akxt_chk_lang_type(lang))) type = -1;
#else
			if (!strcmp(lang,"ja_JP") || !strcmp(lang,"ujis"))
				type = CD_TYPE_EUC;
			else if (!strcmp(lang,"Ja_JP")) type = CD_TYPE_SJIS;
			else if (!strcmp(lang,"JA_JP")) type = CD_TYPE_UTF8;
			else if (!strcmp(lang,"ja")) type = akxt_get_code_type();
			else {
				if (stristr(lang,"EUC")) type = CD_TYPE_EUC;
				else if (stristr(lang,"SJIS") || stristr(lang,"S-JIS"))
					type = CD_TYPE_SJIS;
				else if (stristr(lang,"UTF8") || stristr(lang,"UTF-8"))
					type = CD_TYPE_UTF8;
			}
#endif
		}
		else lang = "";
/*
printf("akxt_get_lang_type:2: lang=[%s] type=%d i=%d\n",lang,type,i);
*/
	}

	if (buf) strnzcpy(buf,lang,buflen-1);
	if (i >= 0) {
		if (p=reg[i].lang) Free(p);
		reg[i].lang = Strdup(lang);
		reg[i].type = type;
	}
	return type;
}

/****************************************/
/*			   To						*/
/*			   SJIS EUC  UTF8 JIS		*/
/* From	SJIS	○	 ○	  ○   ○		*/
/*		EUC		○	 ○					*/
/*		UTF8	○		  ○			*/
/*		JIS		○			   ○		*/
/****************************************/
int akxt_code_trans(pParm, pParmd)
tdtGeneralData *pParm, *pParmd;
{
	int rc,len_s,len_d;
	uchar type_s,type_d,ds_d;
	char  *up_s,*up_d;

	type_s = pParm->gd_code;
	type_d = pParmd->gd_code;
	up_s = pParm->gd_data;
	up_d = pParmd->gd_data;
	len_s = pParm->gd_dlen;
	pParmd->gd_attr = AKX_ZOK_CHAR;
	if (up_d) ds_d = pParmd->gd_scale;
	else pParmd->gd_scale = ds_d = 0;
	pParmd->gd_dlen  = 0;
	if (len_s<=0 || type_s==type_d) {
		if (len_s>=0 && up_d) {
			memnzcpy(up_d,up_s,len_s,len_s);
		}
		return pParmd->gd_dlen=len_s;
	}
	if (type_s == CD_TYPE_SJIS) {
		if (type_d == CD_TYPE_EUC) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s+1))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
			len_d = akxcstoe(len_s,up_s,up_d);
		}
		else if (type_d == CD_TYPE_UTF8) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s*3+1))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
			len_d = akxcstou8(len_s,up_s,up_d);
		}
		else if (type_d == CD_TYPE_JIS) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s*3+4))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
			len_d = akxcstoj(len_s,up_s,up_d);
		}
		else {
			return -1;
		}
	}
	else if (type_s == CD_TYPE_EUC) {
		if (type_d == CD_TYPE_SJIS) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s+1))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
			len_d = akxcetos(len_s,up_s,up_d);
		}
		else {
			return -1;
		}
	}
	else if (type_s == CD_TYPE_UTF8) {
		if (type_d == CD_TYPE_SJIS) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s+1))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
/*
printf("akxt_code_trans: len_s=%d up_s=%08x up_d=%08x\n",len_s,up_s,up_d);
*/
			len_d = akxcu8tos(len_s,up_s,up_d);
/*
printf("akxt_code_trans: len_d=%d\n",len_d);
*/
		}
		else {
			return -1;
		}
	}
	else if (type_s == CD_TYPE_JIS) {
		if (type_d == CD_TYPE_SJIS) {
			if (!up_d) {
				if (!(up_d=Malloc(len_s+1))) return -1;
				ds_d = AKX_DATA_MALLOC;
			}
			len_d = akxcjtos(len_s,up_s,up_d);
		}
		else {
			return -1;
		}
	}
	else {
		return -1;
	}
	pParmd->gd_data = up_d;
	pParmd->gd_scale = ds_d;
	if (len_d >= 0) {
		up_d[len_d] = '\0';
	}
	else if (ds_d & AKX_DATA_MALLOC) {
		Free(up_d);
		pParmd->gd_data = NULL;
		pParmd->gd_scale = 0;
	}
	return pParmd->gd_dlen=len_d;
}
#if 0
/****************************************/
/*										*/
/****************************************/
int akxc_code_trans1(type_s,type_d,up_s,len_s,up_d)
int type_s,type_d,len_s;
uchar *up_s,*up_d;
{
	int i,ret;
	ushort us;
	uchar uc1,uc2;

	ret = len_s;
	if (!up_s || !up_d)
		return -1;
	else if (type_s == type_d) {
		memcpy(up_d,up_s,len_s);
		return len_s;
	}
	else if (type_s == CD_TYPE_UTF8)
		ret = akxcu8tos1(up_s,up_d);
	else if (len_s == 1) {
		*up_d = *up_s;
		return len_s;
	}
	else if (type_s == CD_TYPE_EUC) {
		if (type_d == CD_TYPE_JIS) {
			uc1 = (*up_s++) & 0x7f;
			uc2 =  *up_s    & 0x7f;
			*up_d++ = uc1;
			*up_d   = uc2;
			return len_s;
		}
		else
			us = akxcetos1(up_s,up_d);
	}
	else if (type_s == CD_TYPE_JIS) {
		if (type_d == CD_TYPE_EUC) {
			uc1 = (*up_s++) | 0x80;
			uc2 =  *up_s    | 0x80;
			*up_d++ = uc1;
			*up_d   = uc2;
			return len_s;
		}
		else
			us = akxcjtos1(up_s,up_d);
	}
	else
		return -1;

	if (type_d == CD_TYPE_EUC)
		us = akxcstoe1(up_s,up_d);
	else if (type_d == CD_TYPE_UTF8)
		ret = akxcstou81(up_s,up_d);
	else if (type_d == CD_TYPE_JIS)
		us = akxcstoj1(up_s,up_d);
	else
		return -1;
	return ret;
}
#endif
/****************************************/
/*										*/
/****************************************/
int akxc_code_conv_init(ct,type_d,type_s)
tdtCodeConv *ct;
int type_d,type_s;
{
	int ret,dlen1,dlen2,opt1,opt2,(*qlen1)(),(*qlen2)(),(*fun1)(),(*fun2)();

	if (!ct) return -1;

	qlen1 = NULL;
	qlen2 = NULL;
	fun1  = NULL;
	fun2  = NULL;
	ct->cc_type_s = type_s;
	ct->cc_type_d = type_d;
	dlen1 = dlen2 = 0;
	opt2 = opt1 = ret = 0;
	if (type_s == type_d)
		;
	else if (type_s == CD_TYPE_UTF8)
		fun1 = akxcu8tos1;
	else if (type_s == CD_TYPE_EUC) {
		if (type_d == CD_TYPE_JIS) {
			fun1 = akxcetoj1;
			dlen2 = -1;
		}
		else
			fun1 = akxcetos1;
	}
	else if (type_s == CD_TYPE_JIS) {
		dlen1 = 2;
		if (type_d == CD_TYPE_EUC) {
			fun1 = akxcjtoe1;
			dlen2 = -1;
		}
		else
			fun1 = akxcjtos1;
	}
	else if (type_s == CD_TYPE_SJIS)
		;
	else
		ret = -1;

	if (!ret && !dlen2 && type_s!=type_d) {
		if (type_d == CD_TYPE_EUC) {
			fun2 = akxcstoe1;
			dlen2 = 2;
			opt2 = 2;
		}
		else if (type_d == CD_TYPE_UTF8) {
			fun2 = akxcstou81;
			opt2 = 1;
		}
		else if (type_d == CD_TYPE_JIS) {
			fun2 = akxcstoj1;
			dlen2 = 2;
		}
		else if (type_d == CD_TYPE_SJIS)
			;
		else
			ret = -1;
	}
	if (ret < 0) ct->cc_type_s = ret;
	ct->cc_qlen1 = qlen1;
	ct->cc_qlen2 = qlen2;
	ct->cc_func1 = fun1;
	ct->cc_func2 = fun2;
	ct->cc_dlen[0] = dlen1;
	ct->cc_dlen[1] = dlen2;
	ct->cc_opt[0] = opt1;
	ct->cc_opt[1] = opt2;
/*
printf("akxc_code_conv_init: type_s=%d type_d=%d fun1=%08x fun2=%08x dlen1=%d dlen2=%d opt1=%d opt2=%d ret=%d\n"
,type_s,type_d,fun1,fun2,dlen1,dlen2,opt1,opt2,ret);
*/
	return ret;
}

/****************************************/
/*										*/
/****************************************/
int static _code_conv(type_s,inptr,outptr,inleft,func,lena)
uchar *inptr,*outptr;
int  type_s,inleft,lena[];
int  (*func)();
{
	uchar ww[5],c,attr[4];
	int  slen,slen1,dlen,dlen1,ret,opt;
	ushort us,sjis;

	if (lena) {
		opt   = lena[0];
		dlen1 = lena[1];
	}
	else {
		opt = dlen1 = 0;
	}
/*
printf("_code_conv: type_s=%d inptr=%08x outptr=%08x inleft=%d func=%08x dlen1=%d opt=%d\n"
,type_s,inptr,outptr,inleft,func,dlen1,opt);
*/
	if (type_s == CD_TYPE_JIS) {
		memcpy(attr,&lena[3],4);
		attr[0] = type_s;
		if ((slen1=akxqmbsnalen(inptr,inleft,attr)) < 0) return slen1;
		memcpy(&lena[3],attr,4);
		slen = attr[1];
		inptr += slen1 - slen;
/*
printf("_code_conv: slen1=%d attr=%d %d %d %d\n",slen1,attr[0],attr[1],attr[2],attr[3]);
*/
	}
	else {
		if ((slen1=akxqmbsnlen(type_s,inptr,inleft)) < 0) return slen1;
		slen = slen1;
	}
	dlen = slen;
	if (opt == 1) {
		sjis = *inptr;
		if (slen == 2) sjis = sjis<<8 | *(++inptr);
/*
printf("_code_conv: slen=%d sjis=%04x\n",slen,sjis);
*/
		dlen = akxc_sj_to_utf8(sjis,outptr,NULL);
	}
	else if (slen == 1) {
		c = *inptr;
		dlen = 1;
		if (opt==2 && (0xa1<=c) && (c<=0xdf)) { /* Hankaku Kana */
			*outptr++ = SS2;
			dlen= 2;
		}
		*outptr = c;
	}
	else if (func) {
		dlen = dlen1;
		ret = func(inptr,outptr);
		if (dlen <= 0) dlen = ret;
	}
	if (lena) lena[2] = slen1;
/*
printf("_code_conv: slen=%d dlen=%d\n",slen,dlen);
*/
	return dlen;
}

/****************************************/
/*										*/
/****************************************/
int akxc_code_conv(ct,pinptr,pinleft,poutptr,poutleft)
tdtCodeConv *ct;
char **pinptr,**poutptr;
int  *pinleft,*poutleft;
{
	tdtGeneralData Parms,Parmd;
	char *inptr,*outptr,w[5],ww[5],*p_s,*p_d;
	int  ret,inleft,outleft,min_len,type_s,type_d,slen,dlen,lena[4];
	int  (*fun1)(),(*fun2)();
	ushort us,sjis;
	uchar uc1,uc2;
	SSP_S ssp2;

	if (!ct || !pinptr || !pinleft) return -1;
	if ((type_s=ct->cc_type_s) < 0) type_s;
	inleft = *pinleft;
	if (poutleft) outleft = *poutleft;
	else outleft = INT_MAX;
	if (inleft<=0 || outleft<=0) return 0;
	type_d = ct->cc_type_d;
	inptr  = *pinptr;
	if (poutptr) outptr = *poutptr;
	else outptr = NULL;
	fun1 = ct->cc_func1;
	fun2 = ct->cc_func2;
/*
printf("akxc_code_conv: type_s=%d type_d=%d inleft=%d outleft=%d inptr=%08x outptr=%08x fun1=%08x fun2=%08x opt=%d\n"
,type_s,type_d,inleft,outleft,inptr,outptr,fun1,fun2,lena[0]);
*/
	ret = 0;
	if (type_d == CD_TYPE_JIS) {
		ssp2.sp = 0;
		ssp2.attr[0] = 0;
		ssp2.attr[3] = 0;
	}
	if (type_s == type_d) {
		min_len = X_MIN(inleft,outleft);
		if (outptr) memcpy(outptr,inptr,min_len);
		outleft -= min_len;
	}
	else {
		lena[3] = 0;
		while (inleft>0 && outleft>0) {
			if (fun1 && fun2) {
				p_d = ww;
				p_s = p_d;
			}
			else if (fun1) p_d = w;
			else p_s = inptr;
			if (fun1) {
				lena[0] = ct->cc_opt[0];
				lena[1] = ct->cc_dlen[0];
				dlen = _code_conv(type_s,inptr,p_d,inleft,fun1,lena);
				if (dlen < 0) {
/*
printf("akxc_code_conv: code error!! dlen=%d \n",dlen);
*/
					ret = dlen;
					break;
				}
				slen = lena[2];
			}
			else {
				dlen = inleft;
			}
			if (fun2) {
				lena[0] = ct->cc_opt[1];
				lena[1] = ct->cc_dlen[1];
				dlen = _code_conv(CD_TYPE_SJIS,p_s,w,dlen,fun2,lena);
				if (dlen < 0) {
/*
printf("akxc_code_conv: code error!! dlen=%d \n",dlen);
*/
					ret = dlen;
					break;
				}
				if (!fun1) slen = lena[2];
			}
			if (dlen > outleft) break;
			if (outptr) {
				if (type_d ==CD_TYPE_JIS) {
					ssp2.sp = 0;
					ssp2.attr[1] = dlen;
					ssp2.attr[2] = dlen;
					ssp2.wd = w;
					dlen = akxtmput(outptr,INT_MAX,&ssp2);
				}
				else memcpy(outptr,w,dlen);
			}
			inptr   += slen;
			inleft  -= slen;
			outptr  += dlen;
			outleft -= dlen;
/*
printf("akxc_code_conv: inleft=%d outleft=%d\n",inleft,outleft);
*/
		}
	}
	*pinptr  = inptr;
	*pinleft = inleft;
	if (poutptr)  *poutptr  = outptr;
	if (poutleft) *poutleft = outleft;
	return ret;
}

/****************************************/
/*										*/
/****************************************/
int akxqmlen(s,slen)
char *s;
int slen;
{
	char *p=s;
	int len=slen;
	int count,m;

	count = 0;
	while (len > 0) {
		if (len >= 2) {
		/*	m = akxqkanjilen(p);	*/
			m = akxqkanjilen2(p,len);
			len -= m;
			p += m;
		}
		else {
			len--;
			p++;
		}
		count++;
	}
	return count;
}

/****************************************/
/*										*/
/****************************************/
int akxqm2len(s,slen,mlen)
char *s;
int slen,mlen;
{
	char *p=s;
	int len=slen;
	int i,count,m;

	count = 0;
	for (i=0;i<mlen && len>0;i++) {
		if (len >= 2) {
			m = akxqkanjilen(p);
			len -= m;
			p += m;
			count += m;
		}
		else {
			len--;
			p++;
			count++;
		}
	}
	return count;
}

/****************************************/
/*										*/
/****************************************/
int akxqstrlen(s)
char *s;
{
	return akxqmlen(s,strlen(s));
}

/********************************************************/
/*														*/
/********************************************************/
int akxcuppern(d,s,len)
char *d,*s;
int len;
{
	return  akxcuplwn(0,d,s,len);
}

/********************************************************/
/*														*/
/********************************************************/
int akxclowern(d,s,len)
char *d,*s;
int len;
{
	return  akxcuplwn(1,d,s,len);
}

/********************************************************/
/*														*/
/********************************************************/
int akxcuplwn(opt,d,s,len)
int opt;	/* 0:upper, 1:lower */
char *d,*s;
int len;
{
	char *pd,*ps;
	int  n,i;

	if (d && s) {
		pd = d;
		ps = s;
	}
	else {
		if (s) {
			pd = ps = s;
		}
		else if (d) {
			pd = ps = d;
		}
		else return -1;
	}
	for (i=0;i<len;) {
		n = akxcuplw(pd,ps,opt);
		ps += n;
		pd += n;
		i += n;
	}
	*pd = '\0';
	return len;
}

/********************************************************/
/*														*/
/********************************************************/
int akxcuplw(pd,ps,opt)
char *pd,*ps;
int opt;	/* 0:upper, 1:lower */
{
	int n,type;
	ushort us,usw;
	char c,cc,w[5];

	if (n=akxqiskanji(ps)) {
		type = akxt_get_code_type();
		us = akxctojis(w,ps,type);
/*
printf("akxcuplw: us=0x%02x\n",us);
*/
		usw = 0;
		if (us >= 0x2341 && us <= 0x235A) { /* A-Z */
			if (opt) usw = 0x2361 + us - 0x2341;
		}
		else if (us >= 0x2361 && us <= 0x237a) { /* a-z */
			if (!opt) usw = 0x2341 + us - 0x2361;
		}
		if (usw) {
/*
printf("akxcuplw: usw=0x%02x\n",usw);
*/
			us = htons(usw);
			memcpy(w,(char *)&us,2);
			us = akxcfromjis(pd,w,type);
		}
		else if (pd != ps) memcpy(pd,ps,n);
	}
	else {
		c = *ps;
		if (opt) cc = tolower(c);
		else cc = toupper(c);
		*pd = cc;
		n = 1;
	}
	return n;
}

#include <iconv.h>

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

/********1*********2*********3*********4*********5*********6*********/
/* 引数 : IN  : tr_dtypea[] : 文字コード							*/
/*							  [0]:変換先							*/
/*							  [1]:変換元							*/
/*				tr_code[]   : iconvで指定するコード文字列			*/
/*				p1          : 変換する文字列の先頭アドレス			*/
/*				len         : 変換する文字列のバイト数				*/
/*				opt         : オプション							*/
/*        OUT : pAns  : tr_dtypea[0]=tr_dtypea[1]のときは、p1		*/
/*						p1以外のときは、エラーがあっても、Malloc	*/
/*						されたアドレス。NULLの可能性もある			*/
/* 返却 : >= 0 : 正常  変換された長さ								*/
/*				       tr_dtypea[0]=tr_dtypea[1]のときは、len		*/
/*        <  0 : エラー												*/
/********************************************************************/
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)
		rc = akxc_code_conv_init(&ct,tr_dtypea[0],tr_dtypea[1]);
	else {
#ifdef NO_ICONV
		rc = 0;
#else
		if ((cd = iconv_open(tr_code[0],tr_code[1])) == (iconv_t)(-1)) rc = -1;
		else rc = 0;
		iICONV = 1;
#endif
	}
#else
	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;
}

/****************************************/
/*										*/
/****************************************/
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];

	opt = opt0;
	dtype = akxt_get_code_type();
	if (inout) {	/* output */
		stype = dtype;
		dtype = CD_TYPE_SJIS;
		opt &= 0xff;
		if (opt) dtype = opt;
	}
	else {			/* input */
		stype = CD_TYPE_SJIS;
		opt = (opt>>8) & 0xff;
		if (opt) stype = opt;
	}
	if (stype == dtype) {
		*pAns = p1;
		ret = len;
	}
	else {
		tr_dtypea[0] = dtype;
		tr_dtypea[1] = stype;
		tr_code[0] = akxc_get_code_str(dtype);
		if (!tr_code[0]) {
			XERROROUTL1(0,"変換先コード(%d)が不正です。",dtype);
			return -2001;
		}
		tr_code[1] = akxc_get_code_str(stype);
		if (!tr_code[1]) {
			XERROROUTL1(0,"変換元コード(%d)が不正です。",stype);
			return -2002;
		}
/*
printf("akxc_file_code_conv: dtype=%d stype=%d tr_code[0]=%s tr_code[1]=%s\n",dtype,stype,tr_code[0],tr_code[1]);
*/
		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;
}

/****************************/
/*	UTF-8					*/
/****************************/
#define AKX_SJIS_START		0x8140
#define AKX_SJIS_OFFSET		(AKX_SJIS_START-256)

#ifdef UTF8_SRC
#define AKX_SJIS_AKI_START	0xA000
#define AKX_SJIS_START2		0xE040
#define AKX_SJIS_OFFSET2	(AKX_SJIS_START2-AKX_SJIS_AKI_START)
#define AKX_SJIS_MAX		(65536-AKX_SJIS_OFFSET-AKX_SJIS_OFFSET2)
#define AKX_SJIS_HASH_MAX	11500
#define AKX_SJIS_HASH_PRE	11467
#endif

static int gexe_set_utf8=0;
static UINT4 *gucs4=NULL;
static UINT4 *gutf8=NULL;
static HASHB *ha=NULL;
static HASHB *ha4=NULL;

#ifdef UTF8_SRC

static int _init_sj_utf8();
static int _Unihaslr();

int akxc_set_utf8_file(file)
char *file;
{
	return 0;
}

int akxc_set_sj_utf8(file)
char *file;
{
	return 0;
}
#else

static char *hkey[2],*h4key[2];
static char *utf8_file;

int akxc_set_utf8_file(file)
char *file;
{
	if (!(utf8_file=Strdup(file))) return -1;
	return 0;
}

int akxc_set_sj_utf8(file)
char *file;
{
	FILE *fp;
	char buf[128],parm[256],*argv[3],*p,c,*hkey[2],*h4key[2];
	int  len,n,ret,offset,iha4;
	ushort ucs2;
	UINT4  val,sj,utf8,ucs4,ix;

	if (!file) return -1;
	if (!(fp=fopen(file,"r"))) {
		XERROROUTL5(200,"%s open error",file,0,0,0,0);
		return -2;
	}

	gexe_set_utf8 = 1;
	len = AKX_SJIS_MAX*sizeof(UINT4)*2;
	if (!gucs4) {
		if (!(gucs4=(UINT4 *)Malloc(len))) {
			XERROROUTL5(200,"gucs4 malloc error",0,0,0,0,0);
			ret = -3;
			goto Err;
		}
	}
	memset(gucs4,0,len);
	gutf8 = gucs4 + AKX_SJIS_MAX;

	if (ha) akxs_hasl_free(ha);
	ha = akxs_hasl_new(4,AKX_SJIS_HASH_MAX,0);
	if (!ha) {
		XERROROUTL5(200,"akxs_hasl_new errno=%d",errno,0,0,0,0);
		ret = -3;
		goto Err;
	}
/*
printf("UTF8: id=%c%c len=%d maxreg=%d mso=%d\n",
ha->ha_id[0],ha->ha_id[1],ha->ha_keylen,ha->ha_maxreg,ha->ha_prereg);
*/
	ha->ha_key = (char *)hkey;
	if (ha4) akxs_hasl_free(ha4);
	ha4 = akxs_hasl_new(4,AKX_SJIS_HASH_MAX,0);
	if (!ha4) {
		XERROROUTL5(200,"akxs_hasl_new errno=%d",errno,0,0,0,0);
		ret = -4;
		goto Err;
	}
/*
printf("UCS4: id=%c%c len=%d maxreg=%d mso=%d\n",
ha->ha_id[0],ha->ha_id[1],ha->ha_keylen,ha->ha_maxreg,ha->ha_prereg);
*/
	ha4->ha_key = (char *)h4key;

printf("--sjis-- --ucs4-- --utf8-- - ix- -iha- -iha4\n");

	while ((len = akxa_read_line(buf,sizeof(buf),fp)) > 0) {
		if ((c=*buf) == '#') continue;
		else if (c == '\t') offset = 1;
		else offset = 8;
		n = akxtgetargv2(buf+offset,argv,3,parm,sizeof(parm),1);
		if (n >= 2) {
			p = argv[0] + 2;
			ret = akxccvx(p,strlen(p),&val);
			sj = val;
			if (n>=3 && *argv[2]=='(') p = argv[2] + 1;
			else p = argv[1] + 2;
			ret = akxccvx(p,strlen(p),&val);
			ucs4 = val;
			if (ucs4 <= 0x7f) {
				utf8 = ucs4<<24;
			}
			else if (ucs4 <= 0x7ff) {
				utf8 = ((ucs4&0x07c0)<<2 | (ucs4&0x3f) | 0xc080)<<16;
			}
			else if (ucs4 <= 0xffff) {
				utf8 = ((ucs4&0xf000)<<4 | (ucs4&0x0fc0)<<2 | (ucs4&0x3f) |
				        0xe08080)<<8;
			}
			else {
				utf8 = (ucs4&0x1c0000)<<6 | (ucs4&0x3f000)<<4 |
				       (ucs4&0xfc0)<<2 | (ucs4&0x3f) | 0xf0808080;
			}
			if ((ix=sj) >= AKX_SJIS_START) ix = sj - AKX_SJIS_OFFSET;
			gucs4[ix] = ucs4;
			gutf8[ix] = utf8;
			hkey[1] = (char *)sj;
			ret = akxshasls(ha,utf8);
			h4key[1] = (char *)sj;
			iha4 = akxshasls(ha4,ucs4);

printf("%08x %08x %08x %5d %5d %5d\n",sj,ucs4,utf8,ix,ret,iha4);

		}
	}
	ret = 0;
Err:
	fclose(fp);
	return ret;
}
#endif

int akxc_sj_to_utf8(sjis,utf8c,ucs4)
ushort  sjis;
uchar  *utf8c;
UINT4  *ucs4;
{
	int len,ret;
	UINT4 w,utf8,ix,sj,ucs4w;

	if (!gexe_set_utf8) {
#ifdef UTF8_SRC
		if (ret=_init_sj_utf8()) return ret;
#else
		if (ret=akxc_set_sj_utf8(utf8_file)) return ret;
#endif
	}
	if (!gutf8) return -1;
	sj = sjis;
#ifdef UTF8_SRC
	if ((ix=sj) >= AKX_SJIS_START) {
		ix = sj - AKX_SJIS_OFFSET;
		if (sj>=AKX_SJIS_START2) ix -= AKX_SJIS_OFFSET2;
	}
#else
	if ((ix=sj) >= AKX_SJIS_START) ix = sj - AKX_SJIS_OFFSET;
#endif
/*
printf("akxc_sj_to_utf8: %04x %08x\n",sjis,utf8);
*/
	if (utf8c) {
		utf8 = gutf8[ix];
	/*	len = akxqu8len((utf8>>24) & 0xff);	*/
		w = htonl(utf8);
/*
printf("akxc_sj_to_utf8: sjis=%04x utf8=%08x w=%08x\n",sjis,utf8,w);
*/
		len = akxqu8nlen(&w, 4);
		memcpy(utf8c,&w,len);
	}
	else len = 0;
	if (ucs4) *ucs4 = gucs4[ix];
/*
printf("akxc_sj_to_utf8: sjis=%04x utf8=%08x len=%d\n",sjis,utf8,len);
*/
	return len;
}

int akxcstou8(n, inc, outc)
int   n;
uchar *inc, *outc;
{
	int i,j,len;
	uchar  c1;
	ushort sjis;

	j = 0;
	for (i=0;i<n;i++,inc++) {
		sjis = c1 = *inc;
		if (akxqiskanji1(c1)) {
			if (i+1 < n) {
				if (akxqiskanji(inc)) {
					i++;
					sjis = sjis<<8 | *(++inc);
				}
			}
			else break;
		}
		len = akxc_sj_to_utf8(sjis,outc,NULL);
		outc += len;
		j    += len;
	}
	return j;
}

int akxc_utf8_to_sj(utf8c,sjis,ucs4)
uchar  *utf8c;
ushort *sjis;
UINT4  *ucs4;
{
	int len,ret;
	UINT4 w,utf8,ix,sj,ucs4w;
	char **argv;

	if (!gexe_set_utf8) {
#ifdef UTF8_SRC
		if (ret=_init_sj_utf8()) return ret;
#else
		if (ret=akxc_set_sj_utf8(utf8_file)) return ret;
#endif
	}
	if (!ha) return -1;
	len = akxqu8len(*utf8c);
	sj = ucs4w = w = 0;
	memcpy(&w,utf8c,len);
	utf8 = ntohl(w);
#ifdef UTF8_SRC
/*
printf("akxc_utf8_to_sj: utf8=%08x\n",utf8);
*/
	if ((ret = _Unihaslr(ha,utf8)) > 0) {
#else
	if ((ret = akxshaslr(ha,utf8)) > 0) {
#endif
/*
printf("akxc_utf8_to_sj: ha->ha_key=%08x hkey=%08x\n",ha->ha_key,hkey);
*/
#ifdef UTF8_SRC
		sj = (UINT4)ha->ha_next;
		if ((ix=sj) >= AKX_SJIS_START) {
			ix = sj - AKX_SJIS_OFFSET;
			if (sj>=AKX_SJIS_START2) ix -= AKX_SJIS_OFFSET2;
		}
#else
		if (!(argv=(char **)ha->ha_key)) return -1;
		sj = (UINT4)argv[1];
		if ((ix=sj) >= AKX_SJIS_START) ix = sj - AKX_SJIS_OFFSET;
#endif
		ucs4w = gucs4[ix];
	}
	if (sjis) *sjis = sj;
	if (ucs4) *ucs4 = ucs4w;
/*
printf("akxc_utf8_to_sj: utf8=%08x len=%d ret=%5d sj=%08x ucs4=%08x\n",utf8,len,ret,sj,ucs4w);
*/
	return len;
}

int akxcu8tos(n, inc, outc)
int   n;
uchar *inc, *outc;
{
	int i,j,len;
	ushort sjis;

	j = 0;
	for (i=0;i<n;i+=len) {
		if ((len = akxc_utf8_to_sj(inc,&sjis,NULL)) < 0) return len;
		inc += len;
		if (sjis) {
			*outc = sjis;
			if (sjis & 0xff00) {
				outc[1] = *outc;
				*outc++ = sjis>>8;
				j++;
			}
			outc++;
			j++;
		}
	}
	return j;
}

#if 1
int akxqu8len(c)
uchar c;
{
	UINT4 u1;
	int mlen;

	mlen = 1;
	u1 = (UINT4)c;
	if (u1 < 0xc2) ;
	else if (u1 < 0xe0) {
		if (u1 <= 0xdf) mlen = 2;
	}
	else if (u1 < 0xf0) {
		if (u1 <= 0xef) mlen = 3;
	}
	else if (u1 <= 0xf4) mlen = 4;
	return mlen;
}

int akxqu8nlen(p_str, len)
char *p_str;
int len;
{
	UINT4 u1,u2,u3,u4;
	int mlen;
	char *p;

	if (!(p=p_str)) return -1;
	if (len <= 0) return akxqu8len(*p);
/*	else if (len == 1) return 1; */

	mlen = 1;
	u1 = (UINT4)*p & 0xff;
/*
printf("akxqu8nlen: len=%d u1=%08x\n”,len,u1);
*/
	if (u1 < 0xc2) ;
	else if (u1 < 0xe0) {
		if (u1<=0xdf) {
			if (len >= 2) {
				u2 = (UINT4)*(++p) & 0xff;
				if (u2>=0x80 && u2<=0xbf) mlen = 2;
			}
			else mlen = -2;
		}
	}
	else if (u1 < 0xf0) {
		if (len >= 3) {
			u2 = (UINT4)*(++p) & 0xff;
			if (u1==0xe0) {
				if (u2>=0xa0 && u2<=0xbf) mlen = 3;
			}
			else if ((u1>=0xe1 && u1<=0xec) || (u1>=0xee && u1<=0xef)) {
				if (u2>=0x80 && u2<=0xbf) mlen = 3;
			}
			else if (u1==0xed) {
				if (u2>=0x80 && u2<=0x9f) mlen = 3;
			}
			if (mlen>1) {
				u3 = (UINT4)*(++p) & 0xff;
				if (u1==0xef && u2==0xbb && u3==0xbf) mlen = 103; /* BOM */
				else if (u3>=0x80 && u3<=0xbf) ;
				else mlen = 1;
			}
		}
		else mlen = -3;
	}
	else {
		if (len >= 4) {
			u2 = (UINT4)*(++p) & 0xff;
			if (u1==0xf0) {
				if (u2>=0x90 && u2<=0xbf) mlen = 4;
			}
			else if (u1<0xf4) {
				if (u2>=0x80 && u2<=0xbf) mlen = 4;
			}
			else if (u1==0xf4) {
				if (u2>=0x80 && u2<=0x8f) mlen = 4;
			}
			if (mlen>1) {
				u3 = (UINT4)*(++p) & 0xff;
				if (u3>=0x80 && u3<=0xbf) {
					u4 = (int)*(++p) & 0xff;
					if (u4>=0x80 && u4<=0xbf) ;
					else mlen = 1;
				}
				else mlen = 1;
			}
		}
		else mlen = -4;
	}
	return mlen;
}
#else
int akxqu8len(c1)
uchar c1;
{
	UINT4 utf8;
	int len;

	utf8 = c1;
	if (!(utf8 & 0x80)) len = 1;
	else if ((utf8 & 0xe0) == 0xc0) len = 2;
	else if ((utf8 & 0xf0) == 0xe0) len = 3;
	else len = 4;
	return len;
}
#endif

#ifdef UTF8_SRC
#include "akxutf8_src.c"
#endif
