static char sccsid[]="%Z% %M% %I% %E% %U%";
/************************************************/
/*												*/
/*	akxslike.c									*/
/*												*/
/*	errcode : -18670101 〜 -18679999			*/
/*												*/
/*			coded by A.Kobayashi 2010/06/01		*/
/*												*/
/************************************************/
#include "akxcommon.h"

#define AKX_LIKE_ESCAPE	'\\'

static int iNLike=0,iNextLike=0;
static tdtLikeMaskCtl tmaskctl[10];
static int *gusap=NULL;
static uchar escape_char=AKX_LIKE_ESCAPE;

#define AKX_LIKE_OFFS	0x20

static uchar gusAKX_LIKE_DB_OFFS[2]={AKX_LIKE_OFFS,0x00};
static uchar gusAKX_LIKE_DB_UNDL[2]={AKX_LIKE_OFFS-1,'_'};
static uchar gusAKX_LIKE_DB_PARS[2]={AKX_LIKE_OFFS-1,'%'};
static uchar gusAKX_LIKE_DB_LPAR[2]={AKX_LIKE_OFFS-1,'['};
static uchar gusAKX_LIKE_DB_RPAR[2]={AKX_LIKE_OFFS-1,']'};
static uchar gusAKX_LIKE_DB_MINS[2]={AKX_LIKE_OFFS-1,'-'};
static uchar gusAKX_LIKE_DB_NOTE[2]={AKX_LIKE_OFFS-1,'!'};
static uchar gusAKX_LIKE_DB_MASK[2]={0xff,0x00};
static int AKX_LIKE_DB_OFFS=0;
static int AKX_LIKE_DB_UNDL;
static int AKX_LIKE_DB_PARS;
static int AKX_LIKE_DB_LPAR;
static int AKX_LIKE_DB_RPAR;
static int AKX_LIKE_DB_MINS;
static int AKX_LIKE_DB_MASK;
static int AKX_LIKE_DB_NOTE;

/********************************************/
/*	41										*/
/********************************************/
static void _set_define()
{
	AKX_LIKE_DB_OFFS = gusAKX_LIKE_DB_OFFS[0]<<8 | gusAKX_LIKE_DB_OFFS[1];
	AKX_LIKE_DB_UNDL = gusAKX_LIKE_DB_UNDL[0]<<8 | gusAKX_LIKE_DB_UNDL[1];
	AKX_LIKE_DB_PARS = gusAKX_LIKE_DB_PARS[0]<<8 | gusAKX_LIKE_DB_PARS[1];
	AKX_LIKE_DB_LPAR = gusAKX_LIKE_DB_LPAR[0]<<8 | gusAKX_LIKE_DB_LPAR[1];
	AKX_LIKE_DB_RPAR = gusAKX_LIKE_DB_RPAR[0]<<8 | gusAKX_LIKE_DB_RPAR[1];
	AKX_LIKE_DB_MINS = gusAKX_LIKE_DB_MINS[0]<<8 | gusAKX_LIKE_DB_MINS[1];
	AKX_LIKE_DB_MASK = gusAKX_LIKE_DB_MASK[0]<<8 | gusAKX_LIKE_DB_MASK[1];
	AKX_LIKE_DB_NOTE = gusAKX_LIKE_DB_NOTE[0]<<8 | gusAKX_LIKE_DB_NOTE[1];
}

/********************************************/
/*	42										*/
/********************************************/
static char *_realloc(p,old_len,new_len)
void *p;
int old_len,new_len;
{
	char *np;

	if (old_len<0 || new_len<=0) return NULL;
	if (!p) {
		if (np=Malloc(new_len)) {
			memset(np,0,new_len);
		}
	}
	else {
		if (old_len>=new_len) np = (char *)p;
		else if (np=Malloc(new_len)) {
			memcpy(np,p,old_len);
			memset(np+old_len,0,new_len-old_len);
			Free(p);
		}
	}
	return np;
}

/********************************************/
/*	43										*/
/********************************************/
static int _to_db_code(s,len,d,inba,opt,escape0)
uchar *s;
int len;
#if 1	/* 2020.11.08 */
int *d;
#else
ushort *d;
#endif
char *inba;
int opt;	/* 0x01:0 not casecmp/ 1:casecmp */
			/* 0x02:1 全角半角を区別しない */
uchar escape0;
{
	int l,opt1,opt2,n,nn[3],m,m1,lkak,code_type;
	uchar c,cc[5],escape,*s0,zc[5],bc;
	int us,*d0,d1,i;
	SSP_S ssp;
/*
printf("_to_db_code: s=[%s] len=%d opt=%08x\n",s,len,opt);
*/
	s0 = s;
	d0 = d;
	opt1 = opt & AKX_LIKE_IGN_CASE;
	opt2 = opt & AKX_LIKE_IGN_HAZE;
	code_type = GET_TYPE_OPT(opt);
	escape = escape0;
	ssp.attr[0] = escape;
	l = lkak = 0;
	bc = '\0';
	while (len > 0) {
	/*	if ((m=akxqkanjilen2(s,len)) > 1) {	*/
		if ((m=akxqmbsnlen(code_type,s,len)) > 1) {
			if (inba) *inba = m;
			if (opt1) {
			/*	m1 = akxcuplw(zc,s,0);	*/
				m1 = akxcuplw_type(zc,s,0,code_type);
				d1 = zc[0]<<8 | zc[1];
				if (m1 == 3) d1 = d1<<8 | zc[2];
				else if (m1 == 4) d1 = (d1<<8 | zc[2])<<8 | zc[3];
/*
printf("_to_db_code: m=%d d1=%08x m1=%d \n",m,d1,m1);
*/
			}
			else {
				d1 = s[0]<<8 | s[1];
				if (m == 3) d1 = d1<<8 | s[2];
				else if (m == 4) d1 = (d1<<8 | s[2])<<8 | s[3];
/*
printf("_to_db_code: m=%d d1=%08x\n",m,d1);
*/
			}
			*d = d1;
			s += m;
			len -= m;
			bc = '\0';
		}
		else {
			if (inba) *inba = 1;
			c = *s;
			if (c) {
				cc[0] = AKX_LIKE_OFFS;
				if (escape) {
					if (c == escape) {
						ssp.sp = 0;
						akx_conv_yen1(s,len,&ssp);
						ssp.sp--;
						s   += ssp.sp;
						len -= ssp.sp;
						c = ssp.attr[1];
					}
					else if (c=='%' || c=='_'  || c=='[' || c==']') {
						if (c == '[') lkak++;
						else if (c == ']') lkak--;
						cc[0]--;
					}
					else if ((c=='-' || (bc=='[' && c=='!')) && lkak>0) cc[0]--;
				}
				cc[1] = opt1 ? akxcupper(c) : c;
				m1 = 1;
				if (opt2 && cc[0]==AKX_LIKE_OFFS) {
					if (len > 1) cc[2] = *(s+1);
					else cc[2] = 0;
				/*	if ((m1=akxctozen1(len,cc+1,zc,nn)) >= 2) {	*/
					if ((m1=akxctozen1_type(len,cc+1,zc,nn,code_type)) >= 2) {
						memcpy(cc,zc,m1);
						if (nn[0] == 2) {
							s++;
							len--;
						}
/*
printf("_to_db_code: cc=%02x %02x\n",cc[0],cc[1]);
*/
					}
				}
				d1 = cc[0]<<8 | cc[1];
				if (m1 >= 3) d1 = d1<<8 | cc[2];
				if (m1 >= 4) d1 = d1<<8 | cc[3];
				*d = d1;
			}
			else *d = 0;
			s++;
			len--;
			bc = c;
		}
/*
printf("_to_db_code: m=%d l=%d d=%08x\n",m,l,*d);
*/
		d++;
		l++;
		if (inba) inba++;
	}
	*d = 0;
/*
printf("_to_db_code: s=[%s]\n",s0);
printf("_to_db_code: d=[%s]\n",d0);
*/
	return l;
}

/********************************************/
/*	44										*/
/********************************************/
static int mkmask(tpmaskctl0,uspat,lb)
tdtLikeMaskCtl *tpmaskctl0;
int *uspat;
int lb;
{
	tdtLikeMask *mask,*pmask,*pmask_n;
	int maxmask;
	int i,n,ltpn,kpt,lpar,nalc;
	uchar stp0,mpn0,und0,lpn0;
	int *ptn,*ptn_n,us;

#if 1	/* 2022.3.29 */
	memset(tpmaskctl0,0,sizeof(tdtLikeMaskCtl));
	nalc = 10;
	mask = NULL;
	if (!(mask=(tdtLikeMask *)Malloc(nalc*sizeof(tdtLikeMask)))) return -1;
#else
	mask = tpmaskctl0->lmc_mask;
#endif
	n = 0;
	ltpn = 0;
	stp0 = 0;
	mpn0 = 1;
	und0 = 0;
	lpn0 = lpar = 0;
	for (i=0;i<lb;i++) {
		us = uspat[i];
		if (lpar) {
			if (us == AKX_LIKE_DB_RPAR) {
				if (i-(lpar-1) > 1) lpn0++;
				lpar = 0;
			}
		}
		else {
			if (us == AKX_LIKE_DB_LPAR) lpar = i + 1;
			else if (us == AKX_LIKE_DB_PARS) {
				ltpn += lpn0;
				mask[n].stp = stp0;
				mask[n].len = lpn0;
				mask[n].mpn = mpn0;
				mask[n].und = und0;
/*
printf("mkmask: n=%d  stp0=%d lpn0=%d mpn0=%d und0=%d\n",n,stp0,lpn0,mpn0,und0);
*/
				stp0 = i + 1;
				mpn0 = 3;
				und0 = 0;
				lpn0 = 0;
				n++;
#if 1	/* 2022.3.29 */
				if (n >= nalc) {
					nalc += 5;
					if (!(mask=(tdtLikeMask *)Realloc((char *)mask,nalc*sizeof(tdtLikeMask)))) return -1;
				}
#endif
			}
			else {
				lpn0++;
				if (us == AKX_LIKE_DB_UNDL) und0++;
			}
		}
	}
	if (lpar && (i-(lpar-1)>1)) lpn0++;
	mask[n].stp = stp0;
	ltpn += lpn0;
	mask[n].len = lpn0;
	mask[n].mpn = mpn0 - 1;
	mask[n].und = und0;
	n++;
/*
printf("mkmask: n=%d  stp0=%d lpn0=%d mpn0=%d und0=%d ltpn=%d\n",n,stp0,lpn0,mpn0-1,und0,ltpn);
*/
	tpmaskctl0->lmc_nptn  = n;
	tpmaskctl0->lmc_slptn = ltpn;
#if 1	/* 2022.3.29 */
	tpmaskctl0->lmc_mask  = mask;
#endif
/*
printf("mkmask: iNLike=%d iNextLike=%d\n",iNLike,iNextLike);
*/
	return 0;
}

/********************************************/
/*	45										*/
/********************************************/
static tdtLikeMaskCtl *_get_maskctl(uspat,lb)
int uspat[],lb;
{
	tdtLikeMaskCtl tmaskctl0,*pmaskctl;
	tdtLikeMask mask[20],*pmask,*pmask_n;
	int maxmask;
	int i,n,ltpn;
	int *ptn,*ptn_n,us;

	for (i=0;i<iNLike;i++) {
		pmaskctl = &tmaskctl[i];
		ptn = pmaskctl->lmc_pat;
/*
printf("_get_maskctl:i=%d ptn=[%s]\n",i,ptn);
*/
		if (!lb && !pmaskctl->lmc_pat_n) break;
		else if (ptn && pmaskctl->lmc_mask) {
			if (!mem_cmp_int_n(uspat,lb,ptn,pmaskctl->lmc_pat_n)) break;
		}
	}
/*
printf("_get_maskctl: i=%d\n",i);
*/
	if (i >= iNLike) {
#if 0	/* 2022.3.29 */
		tmaskctl0.lmc_nptn = 20;
		tmaskctl0.lmc_mask = mask;
#endif
		mkmask(&tmaskctl0,uspat,lb);
		if (iNLike<10) {
			i = iNLike++;
			ptn   = NULL;
			pmask = NULL;
		}
		else {
			i = iNextLike++;
			if (iNextLike>=10) iNextLike = 0;
			ptn   = tmaskctl[i].lmc_pat;
			pmask = tmaskctl[i].lmc_mask;
		}
/*
printf("_get_maskctl: iNLike=%d iNextLike=%d i=%d\n",iNLike,iNextLike,i);
*/
		n = tmaskctl0.lmc_nptn;
		pmaskctl = &tmaskctl[i];
		if (!(ptn_n=(int *)_realloc(ptn,0,(lb+1)*sizeof(int)))) {
			if (ptn) Free(ptn);
			tmaskctl[i].lmc_pat = NULL;
			tmaskctl[i].lmc_pat_n = 0;
			return NULL;
		}
#if 1	/* 2022.3.29 */
		if (pmask) Free(pmask);
		pmaskctl->lmc_mask  = tmaskctl0.lmc_mask;
#else
		if (!(pmask_n=(tdtLikeMask *)_realloc((char *)pmask,0,n*sizeof(tdtLikeMask)))) {
			if (pmask) Free(pmask);
			tmaskctl[i].lmc_mask = NULL;
			return NULL;
		}
		memcpy(pmask_n,mask,n*sizeof(tdtLikeMask));
		pmaskctl->lmc_mask  = pmask_n;
#endif
		mem_cpy_int(ptn_n,uspat,lb);
		pmaskctl->lmc_nptn  = n;
		pmaskctl->lmc_slptn = tmaskctl0.lmc_slptn;
		pmaskctl->lmc_pat_n = lb;
		pmaskctl->lmc_pat   = ptn_n;
	}
/*
printf("_get_maskctl:Exit pmaskctl=%08x\n",pmaskctl);
*/
	return pmaskctl;
}

/********************************************/
/*	46										*/
/********************************************/
static int undcmp(ap,la,ptn,lptn,lptn1)
int *ap,*ptn;
int la,lptn,lptn1;
{
	int *pap,*pptn,usptn,uspap,usptn1,usptn2;
	int n,i,j,lpar,imatch,iNOT,unmatch;
/*
printf("undcmp:Enter la=%d lptn=%d lptn1=%d\n",la,lptn,lptn1);
*/
	if (!lptn) return 0;
	n = la - lptn + 1;
	if (n <= 0) return -18674601;
	for (i=0;i<n;i++) {
/*
printf("undcmp: i=%d ap=%08x\n",i,*ap);
*/
		pap = ap;
		pptn = ptn;
		uspap = *pap;
		imatch = lpar = 0;
		for (j=0;j<lptn1;j++,pptn++) {
			usptn = *pptn;
/*
printf("undcmp: j=%d lpar=%d uspap=%08x usptn=%08x\n",j,lpar,uspap,usptn);
*/
			if (lpar) {
				if (usptn == AKX_LIKE_DB_RPAR) {
					lpar = 0;
					if (iNOT) {
						if (imatch) break;
					}
					else if (!imatch) break;
					iNOT = 0;
					pap++;
					uspap = *pap;
				}
				else if (*pptn==AKX_LIKE_DB_MINS) {
					if ((usptn2=*(pptn+1)) == AKX_LIKE_DB_RPAR) usptn2 = INT_MAX;
					else {
						pptn++;
						j++;
					}
					if (usptn1<=uspap && uspap<=usptn2) imatch = 1;
/*
printf("undcmp:1: usptn1,uspap,usptn2=%08x,%08x,%08x imatch=%d\n",usptn1,uspap,usptn2,imatch);
*/
				}
				else if (*(pptn+1)==AKX_LIKE_DB_MINS) {
					usptn1 = usptn;
					if ((usptn2=*(pptn+2)) == AKX_LIKE_DB_RPAR) usptn2 = INT_MAX;
					else {
						pptn += 2;
						j += 2;
					}
					if (usptn1<=uspap && uspap<=usptn2) imatch = 1;
/*
printf("undcmp:2: usptn1,uspap,usptn2=%08x,%08x,%08x imatch=%d\n",usptn1,uspap,usptn2,imatch);
*/
				}
				else if (uspap == usptn) imatch = 1;
/*
printf("undcmp:3: imatch=%d\n",imatch);
*/
			}
			else {
				if (usptn == AKX_LIKE_DB_LPAR) {
					lpar = 1;
					imatch = 0;
					usptn1 = 0;
					iNOT = 0;
					if (*(pptn+1) == AKX_LIKE_DB_NOTE) {
						iNOT = 1;
						pptn++;
						j++;
/*
printf("undcmp: iNOT=%d\n",iNOT);
*/
					}
				}
				else {
					if ((usptn != AKX_LIKE_DB_UNDL) && (uspap != usptn)) break;
					pap++;
					uspap = *pap;
				}
			}
		}
		if (j>=lptn1) {
/*
printf("undcmp:4: j=%d imatch=%d\n",j,imatch);
*/
			if (lpar) {
				if (iNOT) {
					if (!imatch) return i;
				}
				else if (imatch) return i;
			}
			else return i;
		}
		ap++;
	}
/*
printf("undcmp:Exit imatch=%d\n",imatch);
*/
	return -18674602;
}

/********************************************/
/*	47										*/
/********************************************/
static int _update_pos(pos,inba,sp,lenm)
int pos[],sp,lenm;
char *inba;
{
	int len,ipos;
/*
printf("_update_pos:Enter pos=%d %d %d %d sp=%d lenm=%d\n",pos[0],pos[1],pos[2],pos[3],sp,lenm);
*/
	pos[3] = lenm;
	ipos = mem_sum_byte(inba,pos[2]);
	pos[0] += pos[1] + ipos;
	pos[3] -= pos[2];
	len  = mem_sum_byte(inba+pos[2],pos[3]);
	pos[1] = len;
	pos[2] += sp;
/*
printf("_update_pos:Exit  pos=%d %d %d %d\n",pos[0],pos[1],pos[2],pos[3]);
*/
	return 0;
}

/********1*********2********3*********4*********5*********6******/
/*	48															*/
/* 引数 : IN  :													*/
/*			pos[]	 : 前回のlikeでマッチした位置と長さ			*/
/*						初回は、0クリアされていること			*/
/*						pos[2]:文字位置(先頭が0)				*/
/*						pos[3]:文字数							*/
/*		  OUT :													*/
/*			pos[]	 : 今回のlikeでマッチした位置と長さ			*/
/*						pos[0]:バイト位置(先頭が0)				*/
/*						pos[1]:バイト数							*/
/*						pos[2]:文字位置(先頭が0)				*/
/*						pos[3]:文字数							*/
/****************************************************************/
static int _pxlike_pos(plike,pos)
tdtLike *plike;
int pos[];
	/* pos[0]: start pos by byte */
	/* pos[1]: matched string len by byte */
	/* pos[2]: start pos by DBite */
	/* pos[3]: matched string len by DByte */
{
	tdtLikeMaskCtl tmaskctl0,*pmaskctl;
	tdtLikeMask mask[20],*pmask;
	int i,n,la,lb,ltpn,la0,ipos,len,ix,sp,offset,lpn1,mpn1,len2,mpn2,lpn2,ipos2,k,nk;
	uchar stp0,mpn0,und0,lpn0,escape,uc;
	char *inba;
	int *ap0,*ptn,*api,*uspat;
	int *usap;

	if (!(pmaskctl = plike->lk_maskctl)) return -18674801;

	if (pos) sp = pos[2] + pos[3];
	else sp = 0;
	inba = plike->lk_inba + sp;
	la   = plike->lk_la - sp;
	if (la <= 0) return 1;
	usap = plike->lk_usap + sp;

	n     = pmaskctl->lmc_nptn;
	pmask = pmaskctl->lmc_mask;
	ltpn  = pmaskctl->lmc_slptn;
	lb    = pmaskctl->lmc_pat_n;
	uspat = pmaskctl->lmc_pat;
/*
printf("_pxlike_pos: n=%d pmask=%08x ltpn=%d\n",n,pmask,ltpn);
*/
	if (!ltpn) {
		if (pos) _update_pos(pos,inba,sp,la);
		return 0;
	}
	api = usap;
	ix = len = ipos = 0;
/*
printf("_pxlike_pos:la=%d ltpn=%d\n",la,ltpn);
*/
	la -= ltpn;
	if (la < 0) return 1;
	mpn2 = lpn2 = 0;
	for (i=0;i<n;i++) {
		offset = 0;
		mpn1 = pmask[i].mpn;
		lpn0 = pmask[i].len;
/*
printf("_pxlike_pos: i=%d mpn=%d lpn0=%d und=%d\n",i,mpn1,lpn0,pmask[i].und);
*/
		if (mpn1 && lpn0==pmask[i].und) {
			ipos = 0;
/*
printf("_pxlike_pos: i=%d mpn =%d ipos=%d lpn0=%d\n",i,pmask[i].mpn,ipos,lpn0);
*/
		}
		else {
			mpn2 = mpn1;
			lpn2 = lpn0;
			la0 = la + lpn0;
			ap0 = api;
/*
printf("_pxlike_pos: i=%d la0=%d pmask[i].stp=%d\n",i,la0,pmask[i].stp);
*/
			ptn = uspat + pmask[i].stp;
			switch (pmask[i].mpn) {
				case 0:	/* 完全一致 */
						if (lpn0 != la0) return 1;
						break;
				case 1:	/* 前方一致 */
						la0 = lpn0;
						break;
				case 2:	/* 後方一致 */
						offset = la0 - lpn0;
						ap0 += offset;
						la0 = lpn0;
/*
printf("_pxlike_pos: i=%d offset=%d la0=%d\n",i,offset,la0);
*/
						break;
				case 3:	/* 中間一致 */
						break;
				default:
						return -11;
			}
		/*	ipos = undcmp(ap0,la0,ptn,lpn0);	*/
			if (i < n-1) lpn1 = pmask[i+1].stp - pmask[i].stp - 1;
			else lpn1 = lb - pmask[i].stp; 
/*
printf("_pxlike_pos: i=%d lpn0=%d lpn1=%d la0=%d\n",i,lpn0,lpn1,la0);
nk=X_MIN(lpn0,6);
for (k=0;k<nk;k++) printf("k=%d ap0=%08x\n",k,ap0[k]);
for (k=0;k<nk;k++) printf("k=%d ptn=%08x\n",k,ptn[k]);
*/
			ipos = undcmp(ap0,la0,ptn,lpn0,lpn1);
/*
printf("_pxlike_pos: i=%d ipos=%d\n",i,ipos);
*/
			if (ipos < 0) return 1;
/*
printf("_pxlike_pos:i=%d la0=%d ap0=[%s]\n",i,la0,ap0);
printf("        ipos=%d lpn0=%d ptn=[%s]\n",ipos,lpn0,ptn);
*/
		}
		ipos += offset;
		api += (ipos + lpn0);
		la -= ipos;	/* add 2006.8.31 Koba */
/*
printf("_pxlike_pos: i=%d ipos=%d lpn0=%d la=%d\n",i,ipos,lpn0,la);
*/
		if (pos) {
			if (!ix && lpn0) {
				pos[2] = ipos;
				ix++;
			}
			len += (ipos + lpn0);
/*
printf("_pxlike_pos: len=%d\n",len);
*/
		}
	}
#if 1	/* 2022.3.10 */
/*
printf("_pxlike_pos: opt=%02x mpn2=%d\n",plike->lk_option,mpn2);
*/
	if ((plike->lk_option & AKX_LIKE_LNGMATCH) && mpn2==3) {
		/* laは、最初にマッチした次の位置からの残りの長さになっている */
		la0 = la/* + lpn2*/;
		ap0 = api;
/*
printf("_pxlike_pos: offset=%d la0=%d lpn2=%d lpn1=%d ap0=[%s]\n",offset,la0,lpn2,lpn1,ap0);
*/
		while ((ipos2=undcmp(ap0,la0,ptn,lpn2,lpn1)) > 0) {
			ipos = ipos2 + lpn2;
			ap0 += ipos;
			len += ipos;
		/*	la0 = la - ipos2 + lpn2;	*/
			la0 -= ipos;
/*
printf("_pxlike_pos: ipos=%d len=%d la0=%d\n",ipos,len,la0);
*/
		}
	}
#endif
	if (pos) _update_pos(pos,inba,sp,len);
	return 0;
}

/********************************************/
/*	01										*/
/********************************************/
int akxs_xlike_pos(ap,lap,bp,lbp,opt,pos)
char *ap,*bp;
int lap,lbp,opt,pos[];
{
	int ret;
	char *p;
	tdtLike tlike;

	if (lbp) {
		ret = 0;
		if (!ap || !bp) ret += -1;
		if (lap<0 || lbp<0) ret += -2;
		if (lbp > 255) ret += -4;
		if (ret < 0) return -18670100 + ret;
	/*	else if (akxnskipin(bp,lbp,"%") >= lbp) ret = 100;	*/
		else if (akx_skip_opt(bp,lbp,"%",opt) >= lbp) ret = 100;
	}
	else ret = 100;
	if (ret == 100) {
		if (pos) {
			pos[0] = 0;
			pos[1] = lap;
			pos[2] = 0;
		/*	pos[3] = akxqmlen(ap,lap);	*/
			pos[3] = akxqmlen_type(ap,lap,GET_TYPE_OPT(opt));
		}
		return 0;
	}
	if (!lap && lbp>0) return 1;
	opt = opt & (0x03 | CD_TYPE_OPT_MASK);

	if (!AKX_LIKE_DB_OFFS) _set_define();

	memset(&tlike,0,sizeof(tdtLike));
	tlike.lk_max_pat = 10;
	tlike.lk_option  = opt;
	tlike.lk_usap = gusap;
	tlike.lk_alen = 0;
	if (ret=akxs_xlike_set_line(&tlike,ap,lap)) return ret;
	if (pos) memset(pos,0,sizeof(int)*4);
	gusap = tlike.lk_usap;
	if ((ret=akxs_xlike_set_pat(&tlike,bp,lbp)) < 0) return ret;
	ret = _pxlike_pos(&tlike,pos);
	return ret;
}

/********************************************/
/*	02										*/
/********************************************/
int akxs_xlike(ap,lap,bp,lbp,opt)
char *ap,*bp;
int lap,lbp,opt;
{
	return akxs_xlike_pos(ap,lap,bp,lbp,opt,NULL);
}

/********************************************/
/*	03										*/
/********************************************/
int akxs_like_pos(ap,lap,bp,lbp,pos)
char *ap,*bp;
int lap,lbp,pos[];
{
	return akxs_xlike_pos(ap,lap,bp,lbp,0,pos);
}

/********************************************/
/*	04										*/
/********************************************/
int akxs_like(ap,lap,bp,lbp)
char *ap,*bp;
int lap,lbp;
{
	return akxs_xlike(ap,lap,bp,lbp,0);
}

/********************************************/
/*	05										*/
/********************************************/
int akxs_str_like(ap,bp)
char *ap;	/* source */
char *bp;	/* patern */
{
	if (!ap || !bp) return -18670501;
/*
printf("akxs_str_like:a=[%s] b=[%s]\n",ap,bp);
*/
	if (!strcmp(bp,"%")) return 0;
	return akxs_xlike(ap,strlen(ap),bp,strlen(bp),0);
}

/********************************************/
/*	06										*/
/********************************************/
int akxs_case_like(ap,lap,bp,lbp)
char *ap,*bp;
int lap,lbp;
{
	return akxs_xlike(ap,lap,bp,lbp,1);
}

/********************************************/
/*	07										*/
/********************************************/
int akxs_case_str_like(ap,bp)
char *ap;	/* source */
char *bp;	/* patern */
{
	if (!ap || !bp) return -18670701;
	if (!strcmp(bp,"%")) return 0;
	return akxs_xlike(ap,strlen(ap),bp,strlen(bp),1);
}


/********************************************/
/*	08										*/
/********************************************/
int akxs_like_escape(escape)
uchar escape;
{
	uchar c;

	c = escape_char;
	if (escape != 0xff) escape_char = escape;
	return c;
}

/********************************************/
/*	21										*/
/* opt : 0x01: casecmp */
/*       0x02: 全角半角を区別しない */
/*       0x20: 最長一致モード */
/********************************************/
tdtLike *akxs_xlike_new(max_pat,opt/*,pos*/)
int max_pat;
int opt;	/* 0x01:0 not casecmp/ 1:casecmp */
/*int pos[];	*/
{
	tdtLike *plike;

	if (!AKX_LIKE_DB_OFFS) _set_define();

	if (max_pat <= 0) max_pat = 10;
	if (!(plike=(tdtLike *)Malloc(sizeof(tdtLike)))) return NULL;
	memset(plike,0,sizeof(tdtLike));
#if 0	/* 2022.3.26 */
	plike->lk_maskctl = (tdtLikeMaskCtl *)Malloc(sizeof(tdtLikeMaskCtl)*max_pat);
	if (!plike->lk_maskctl) {
		Free(plike);
		return NULL;
	}
#endif
	plike->lk_max_pat = max_pat;
	plike->lk_option = opt & (0xff | CD_TYPE_OPT_MASK);
	return plike;
}

/********************************************/
/*	22										*/
/********************************************/
void akxs_xlike_free(plike)
tdtLike *plike;
{
	char *p;

	if (plike) {
#if 0	/* 2022.3.26 */
		if (p=(char *)plike->lk_maskctl) Free(p);
#endif
		if (p=(char *)plike->lk_usap) Free(p);
		if (p=(char *)plike->lk_inba) Free(p);
		Free(plike);
	}
}

/********************************************/
/*	23										*/
/********************************************/
int akxs_xlike_set_line(plike,s,len)
tdtLike *plike;
char *s;
int len;
{
	int *usap;
	int alen;
	char *inba;

	if (!plike || !s) return -18672301;
	if (len < 0) return -18672302;
	alen = (len+1)*sizeof(int);
	usap = (int *)_realloc(plike->lk_usap,plike->lk_alen,alen);
	if (!usap) return -18672303;
	if (!(inba = MRealloc(plike->lk_inba,len))) return -18672304;
	plike->lk_inba =inba;
	plike->lk_usap = usap;
	plike->lk_alen = alen;
	plike->lk_la = _to_db_code(s,len,plike->lk_usap,plike->lk_inba,plike->lk_option,0);
/*
printf("akxs_xlikeSetLine: s=[%s] len=%d alen=%d la=%d\n",s,len,alen,plike->lk_la);
*/
	return 0;
}

/********************************************/
/*	24										*/
/********************************************/
int akxs_xlike_set_pat(plike,bp,lbp)
tdtLike *plike;
char *bp;
int lbp;
{
	tdtLikeMaskCtl *pmaskctl;
	int lb,uspat[256],i;
	uchar escape,uc;

	if (!plike) return -18672401;
/*	if (!lbp) return 0;
	else */if (lbp < 0) return -18672402;
	else if (lbp > 255) return -18672403;
	if (!bp) return -18672404;

	if (uc=plike->lk_escape) {
		if (uc == 0xff) escape = '\0';
		else escape = uc;
	}
	else escape = escape_char;

	lb = _to_db_code(bp,lbp,uspat,NULL,plike->lk_option,escape);
/*
printf("akxs_xlike_set_pat:lb=%d\n",lb);
for (i=0;i<lb;i++) printf("i=%d uspat=%08x\n",i,uspat[i]);
*/
	if (!(pmaskctl = _get_maskctl(uspat,lb))) return -18672405;
	plike->lk_maskctl = pmaskctl;
	return 0;
}

/********************************************/
/*	25										*/
/********************************************/
int akxs_pxlike(plike,pos)
tdtLike *plike;
int pos[];
{
	int ret;

	if (!plike) return -18672501;
	if (!plike->lk_usap || !plike->lk_maskctl) return -18672502;
	return _pxlike_pos(plike,pos);
}
