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

#define AKX_LIKE_ESCAPE	'\\'

static int iNLike=0,iNextLike=0;
static tdtLikeMaskCtl tmaskctl[10];
#if 1	/* 2020.11.08 */
static int *gusap=NULL;
#else
static ushort *gusap=NULL;
#endif
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_MASK[2]={0xff,0x00};
#if 1	/* 2020.11.08 */
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;
#else
static ushort AKX_LIKE_DB_OFFS=0;
static ushort AKX_LIKE_DB_UNDL;
static ushort AKX_LIKE_DB_PARS;
static ushort AKX_LIKE_DB_LPAR;
static ushort AKX_LIKE_DB_RPAR;
static ushort AKX_LIKE_DB_MINS;
static ushort AKX_LIKE_DB_MASK;
#endif
/********************************************/
/*                                          */
/********************************************/
static void _set_define()
{
#if 1
	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];
#else
	memcpy(&AKX_LIKE_DB_OFFS,gusAKX_LIKE_DB_OFFS,2);
	memcpy(&AKX_LIKE_DB_UNDL,gusAKX_LIKE_DB_UNDL,2);
	memcpy(&AKX_LIKE_DB_PARS,gusAKX_LIKE_DB_PARS,2);
	memcpy(&AKX_LIKE_DB_LPAR,gusAKX_LIKE_DB_LPAR,2);
	memcpy(&AKX_LIKE_DB_RPAR,gusAKX_LIKE_DB_RPAR,2);
	memcpy(&AKX_LIKE_DB_MINS,gusAKX_LIKE_DB_MINS,2);
	memcpy(&AKX_LIKE_DB_MASK,gusAKX_LIKE_DB_MASK,2);
#endif
}

/********************************************/
/*                                          */
/********************************************/
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) return (char *)p;
		if (np=Malloc(new_len)) {
			memcpy(np,p,old_len);
			memset(np+old_len,0,new_len-old_len);
			Free(p);
		}
	}
	return np;
}

static int _to_db_code(s,len,d,opt,escape0)
uchar *s;
int len;
#if 1	/* 2020.11.08 */
int *d;
#else
ushort *d;
#endif
int opt;	/* 0x01:0 not casecmp/ 1:casecmp */
			/* 0x02:1 全角半角を区別しない */
uchar escape0;
{
	int l=0,opt1,opt2,n,nn[3],m,m1,lkak;
	uchar c,cc[5],escape,*s0,zc[5];
#if 1	/* 2020.11.08 */
	int us,*d0,d1,i;
#else
	ushort us,*d0;
#endif
	SSP_S ssp;
/*
printf("_to_db_code: s=[%s] len=%d opt=%08x\n",s,len,opt);
*/
	s0 = s;
	d0 = d;
	opt1 = opt & 0x01;
	opt2 = opt & 0x02;
	escape = escape0;
	ssp.attr[0] = escape;
	lkak = 0;
	while (len > 0) {
#if 1	/* 2020.11.08 */
		if ((m=akxqkanjilen2(s,len)) > 1) {
			if (opt1) {
				m1 = akxcuplw(zc,s,0);
				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;
		}
#else
		if (akxqiskanji(s)) {
			if (opt1) {
				akxcuplw(zc,s,0);
				*d = zc[0]<<8 | zc[1];
			}
			else {
				*d = s[0]<<8 | s[1];
			}
			s++;
			len--;
		}
#endif
		else {
			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=='-' && 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) {
						memcpy(cc,zc,m1);
						if (nn[0] == 2) {
							s++;
							len--;
						}
/*
printf("_to_db_code: cc=%02x %02x\n",cc[0],cc[1]);
*/
					}
				}
#if 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
				memcpy((char *)d,cc,2);
#endif
			}
			else *d = 0;
			s++;
			len--;
		}
/*
printf("_to_db_code: m=%d l=%d d=%08x\n",m,l,*d);
*/
		d++;
		l++;
	}
	*d = 0;
/*
printf("_to_db_code: s=[%s]\n",s0);
printf("_to_db_code: d=[%s]\n",d0);
*/
	return l;
}

static int mkmask(tpmaskctl0,uspat,lb)
tdtLikeMaskCtl *tpmaskctl0;
#if 1	/* 2020.11.08 */
int *uspat;
#else
ushort *uspat;
#endif
int lb;
{
	tdtLikeMask *mask,*pmask,*pmask_n;
	int maxmask;
	int i,n,ltpn,kpt,lpar;
	uchar stp0,mpn0,und0,lpn0;
#if 1	/* 2020.11.08 */
	int *ptn,*ptn_n,us;
#else
	ushort *ptn,*ptn_n,us;
#endif

	mask = tpmaskctl0->lmc_mask;
	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) {
			/*	lpn0 = i - stp0;	*/
		/*	  if (lpn0 > 0) {	*/
				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;
			/*	i++;	*/
				n++;
		/*	  }	*/
			}
			else {
				lpn0++;
				if (us == AKX_LIKE_DB_UNDL) und0++;
			}
		}
	}
	if (lpar && (i-(lpar-1)>1)) lpn0++;
	mask[n].stp = stp0;
/*	lpn0 = lb - stp0;	*/
	ltpn += lpn0;
	mask[n].len = lpn0;
	mask[n].mpn = mpn0 - 1;
	mask[n].und = und0;
/*
printf("mkmask: n=%d  stp0=%d lpn0=%d mpn0=%d und0=%d\n",n,stp0,lpn0,mpn0-1,und0);
*/
	n++;
	tpmaskctl0->lmc_nptn   = n;
	tpmaskctl0->lmc_slptn  = ltpn;
/*
printf("mkmask: iNLike=%d iNextLike=%d\n",iNLike,iNextLike);
*/
	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("mkmask:iNLike=%d iNextLike=%d\n",iNLike,iNextLike);
*/
#if 1	/* 2020.11.08 */
	if (!(ptn_n=(int *)_realloc(ptn,0,(lb+1)*sizeof(int)))) {
#else
	if (!(ptn_n=(ushort *)_realloc(ptn,0,(lb+1)*2))) {
#endif
		if (ptn) Free(ptn);
		tmaskctl[i].lmc_pat = NULL;
		tmaskctl[i].lmc_pat_n = 0;
		return -1;
	}
	if (!(pmask_n=(tdtLikeMask *)_realloc((char *)pmask,0,n*sizeof(tdtLikeMask)))) {
		if (pmask) Free(pmask);
		tmaskctl[i].lmc_mask = NULL;
		return -1;
	}
#if 1	/* 2020.11.08 */
	mem_cpy_int(ptn_n,uspat,lb);
#else
	strcpy((char *)ptn_n,(char *)uspat);
#endif
	memcpy(pmask_n,mask,n*sizeof(tdtLikeMask));
	tmaskctl[i].lmc_nptn  = n;
	tmaskctl[i].lmc_slptn = ltpn;
	tmaskctl[i].lmc_pat_n = lb;
	tmaskctl[i].lmc_pat   = ptn_n;
	tmaskctl[i].lmc_mask  = pmask_n;
	return i;
}

static int undcmp(ap,la,ptn,lptn,lptn1)
#if 1	/* 2020.11.08 */
int *ap,*ptn;
#else
ushort *ap,*ptn;
#endif
int la,lptn,lptn1;
{
#if 1	/* 2020.11.08 */
	int *pap,*pptn,usptn,uspap,usptn1,usptn2;
#else
	ushort *pap,*pptn,usptn,uspap,usptn1,usptn2;
#endif
	int n,i,j,lpar,imatch;

	if (!lptn) return 0;
	n = la - lptn + 1;
	if (n <= 0) return -1;
	for (i=0;i<n;i++) {
/*
printf("undcmp: i=%d ap=%08x\n",i,*ap);
*/
		pap = ap;
		pptn = ptn;
		uspap = *pap;
		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 (!imatch) break;
					pap++;
					uspap = *pap;
				}
				else if (*pptn==AKX_LIKE_DB_MINS) {
#if 1	/* 2020.11.08 */
					if ((usptn2=*(pptn+1)) == AKX_LIKE_DB_RPAR) usptn2 = INT_MAX;
#else
					if ((usptn2=*(pptn+1)) == AKX_LIKE_DB_RPAR) usptn2 = USHRT_MAX;
#endif
					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 1	/* 2020.11.08 */
					if ((usptn2=*(pptn+2)) == AKX_LIKE_DB_RPAR) usptn2 = INT_MAX;
#else
					if ((usptn2=*(pptn+2)) == AKX_LIKE_DB_RPAR) usptn2 = USHRT_MAX;
#endif
					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;
			}
			else {
				if (usptn == AKX_LIKE_DB_LPAR) {
					lpar = 1;
					imatch = 0;
					usptn1 = 0;
				}
				else {
					if ((usptn != AKX_LIKE_DB_UNDL) && (uspap != usptn)) break;
					pap++;
					uspap = *pap;
				}
			}
		}
		if (j>=lptn1) {
			if (!lpar || imatch) return i;
		}
		ap++;
	}
	return -1;
}

static int _pxlike_pos(plike,bp,lbp,opt,pos)
tdtLike *plike;
char *bp;
int  lbp,opt,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;
	tdtLikeMask mask[20],*pmask;
	int i,n,la,lb,ltpn,la0,ipos,len,ix,sp,offset,lpn1;
	uchar stp0,mpn0,und0,lpn0,escape,uc;
#if 1	/* 2020.11.08 */
	int *ap0,*ptn,*api;
	int uspat[256];
	int *usap;
#else
	ushort *ap0,*ptn,*api;
	ushort uspat[256];
	ushort *usap;
#endif

	if (!bp) return -1;
	if (lbp < 0) return -2;
	if (lbp > 255) return -3;
	if ((!lbp) || (lbp==1 && *bp=='%')) {
		if (pos) {
			pos[0] += pos[1];
			pos[1] = plike->lk_alen/4 - 1 - pos[0];
			pos[2] += pos[3];
			pos[3] = plike->lk_la - pos[2];
		}
		return 0;
	}

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

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

	lb = lbp;
	lb = _to_db_code(bp,lb,uspat,opt,escape);
/*
printf("strlike:lb=%d uspat=[%s]\n",lb,(char *)uspat);
*/
	for (i=0;i<iNLike;i++) {
		ptn = tmaskctl[i].lmc_pat;
/*
printf("_pxlike_pos:i=%d ptn=[%s]\n",i,ptn);
*/
		if (ptn && tmaskctl[i].lmc_mask) {
#if 1	/* 2020.11.08 */
			if (!mem_cmp_int_n(uspat,lb,ptn,tmaskctl[i].lmc_pat_n)) break;
#else
			if (!strcmp((char *)uspat,(char *)ptn)) break;
#endif
		}
	}
	if (i>=iNLike) {
		tmaskctl0.lmc_nptn   = 20;
		tmaskctl0.lmc_mask = mask;
		i = mkmask(&tmaskctl0,uspat,lb);
		if (i<0) i = iNLike;
	}
	if (i<iNLike) {
		n     = tmaskctl[i].lmc_nptn;
		pmask = tmaskctl[i].lmc_mask;
		ltpn  = tmaskctl[i].lmc_slptn;
	}
	else {
		n     = tmaskctl0.lmc_nptn;
		pmask = tmaskctl0.lmc_mask;
		ltpn  = tmaskctl0.lmc_slptn;
	}
	if (!ltpn) {
		if (pos) {
			pos[0] += pos[1];
			pos[1] = plike->lk_alen/4 - 1 - pos[0];
			pos[2] += pos[3];
			pos[3] = 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;
	for (i=0;i<n;i++) {
		offset = 0;
		lpn0 = pmask[i].len;
		if (pmask[i].mpn && lpn0==pmask[i].und) {
			ipos = 0;
/*
printf("_pxlike_pos:i=%d ipos=%d lpn0=%d\n",i,ipos,lpn0);
*/
		}
		else {
			la0 = la + lpn0;
			ap0 = api;
			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;
						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;
			ipos = undcmp(ap0,la0,ptn,lpn0,lpn1);
/*
printf("_pxlike_pos:i=%d la0=%d ap0=[%s]\n",i,la0,ap0);
printf("        ipos=%d lpn0=%d ptn=[%s]\n",ipos,lpn0,ptn);
*/
			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: ipos=%d lpn0=%d\n",ipos,lpn0);
*/
		if (pos) {
			if (!ix && lpn0) {
				pos[2] = ipos;
				ix++;
			}
			len += (ipos + lpn0);
/*
printf("_pxlike_pos: len=%d\n",len);
*/
		}
	}
	if (pos) {
		pos[3] = len;
		len = ipos = 0;
		for (i=0;i<pos[3];i++) {
			if ((usap[i] & AKX_LIKE_DB_MASK) == AKX_LIKE_DB_OFFS) n = 1;
			else {
				if (!(usap[i] & 0xffff0000)) n = 2;
				else if (!(usap[i] & 0xff000000)) n = 3;
				else n = 4;
			}
			if (i < pos[2]) ipos += n;
			else len += n;
		}
		pos[0] += pos[1] + ipos;
		pos[1] = len;
		pos[3] -= pos[2];
		pos[2] += sp;
	}
	return 0;
}

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

	if (!ap || !bp) return -1;
	if (lap<0 || lbp<0) return -2;
	if (lbp > 255) return -3;
	if ((!lbp) || (lbp==1 && *bp=='%')) {
		if (pos) {
			pos[0] = 0;
			pos[1] = lap;
			pos[2] = 0;
			pos[3] = akxqmlen(ap,lap);
		}
		return 0;
	}
	if (!lap && lbp>0) return 1;
	opt = opt & 0x03;

	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;
	return _pxlike_pos(&tlike,bp,lbp,opt,pos);
}

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

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

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

int akxs_str_like(ap,bp)
char *ap;	/* source */
char *bp;	/* patern */
{
	if (!ap || !bp) return -1;
/*
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);
}

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

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

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));
	plike->lk_maskctl = (tdtLikeMaskCtl *)Malloc(sizeof(tdtLikeMaskCtl)*max_pat);
	if (!plike->lk_maskctl) {
		Free(plike);
		return NULL;
	}
	plike->lk_max_pat = max_pat;
	plike->lk_option = opt & 0x03;
	plike->lk_pos = pos;
	return plike;
}

int akxs_xlike_set_line(plike,s,len)
tdtLike *plike;
char *s;
int len;
{
#if 1	/* 2020.11.08 */
	int *usap;
#else
	ushort *usap;
#endif
	int alen;

	if (!plike || !s) return -1;
	if (len < 0) return -2;
#if 1	/* 2020.11.08 */
	alen = (len+1)*sizeof(int);
	usap = (int *)_realloc(plike->lk_usap,plike->lk_alen,alen);
#else
	alen = (len+1)*2;
	usap = (ushort *)_realloc(plike->lk_usap,plike->lk_alen,alen);
#endif
	if (!usap) return -4;
	plike->lk_usap = usap;
	plike->lk_alen = alen;
	plike->lk_la = _to_db_code(s,len,plike->lk_usap,plike->lk_option,0);
/*
printf("akxs_xlikeSetLine: s=[%s] len=%d alen=%d la=%d\n",s,len,alen,plike->lk_la);
*/
	return 0;
}

int akxs_pxlike(plike,bp,lbp)
tdtLike *plike;
char *bp;
int  lbp;
{
	if (!plike) return -1;
	return _pxlike_pos(plike,bp,lbp,plike->lk_option,plike->lk_pos);
}

int akxs_like_escape(escape)
uchar escape;
{
	uchar c;

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