/*
 *  regexp.c -- regular expression handling code.
 *
 *	$Header: /private/postgres/src/utils/adt/RCS/regexp.c,v 1.8 1991/11/11 22:39:44 mer Exp $
 */
#include "tmp/postgres.h"	/* postgres system include file */
#include "utils/log.h"		/* for logging postgres errors */

/*
 *  macros to support the regexp(3) library calls
 */
#define INIT		register char *p = instring;
#define GETC()		(*p++)
#define PEEKC()		*(p+1)
#define	UNGETC(c)	(*--p = (c))
#define	RETURN(v)	return(v)
#define	ERROR(val)	elog(WARN, "regexp library reports error %d", (val));

#define	EXPBUFSZ	256
#define	PCHARLEN	16

#ifdef linux
#include <regex.h>
#else
#ifdef sprite
#include "regexp.h"
#else
#include <regexp.h>
#endif /* sprite */
#endif /* linux */

/*
 *  interface routines called by the function manager
 */

/*
 *  routines that use the regexp stuff
 */
bool
char16regexeq(s, p)
	char *s;
	char *p;
{
#ifdef linux
	struct re_pattern_buffer rpb;
#else
	char *expbuf, *endbuf;
#endif
	char *sterm, *pterm;
	int result;

	if (!s || !p)
		return FALSE;

#ifdef linux
	memset((void *) &rpb, 0, sizeof(rpb));
	rpb.buffer = (unsigned char *) palloc(EXPBUFSZ);
	rpb.allocated = EXPBUFSZ;
#else
	expbuf = (char *) palloc(EXPBUFSZ);
	endbuf = expbuf + (EXPBUFSZ - 1);
#endif

	/* be sure the strings are null-terminated */
	sterm = (char *) palloc(PCHARLEN + 1);
	bzero(sterm, PCHARLEN + 1);
	strncpy(sterm, s, PCHARLEN);
	pterm = (char *) palloc(PCHARLEN + 1);
	bzero(pterm, PCHARLEN + 1);
	strncpy(pterm, p, PCHARLEN);

	/* compile the re */
#ifdef linux
	(void) re_compile_pattern(pterm, strlen(pterm), &rpb);
#else
	(void) compile(pterm, expbuf, endbuf, NULL);
#endif

	/* do the regexp matching */
#ifdef linux
	result = re_search(&rpb, sterm, strlen(sterm), 0, strlen(sterm), 0);
	pfree(rpb.buffer);
#else
	result = step(sterm, expbuf);
	pfree(expbuf);
#endif

	pfree(sterm);
	pfree(pterm);

#ifdef linux
	return (bool)(result >= 0);
#else
	return ((bool) result);
#endif
}

bool
char16regexne(s, p)
	char *s;
	char *p;
{
	return (!char16regexeq(s, p));
}

bool
textregexeq(s, p)
	struct varlena *s;
	struct varlena *p;
{
#ifdef linux
	struct re_pattern_buffer rpb;
#else
	char *expbuf, *endbuf;
#endif
	char *sbuf, *pbuf;
	int result;

	if (!s || !p)
		return FALSE;

	/* ---------------
	 * text is a varlena, not a string so we have to make 
	 * a string from the vl_data field of the struct. 
	 * jeff 13 July 1991
	 * ---------------
	 */
	
	/* palloc the length of the text + the null character */
	sbuf = (char *) palloc(s->vl_len - sizeof(int32) + 1);
	pbuf = (char *) palloc(p->vl_len - sizeof(int32) + 1);

#ifdef linux
	memset((void *) &rpb, 0, sizeof(rpb));
	rpb.buffer = (unsigned char *) palloc(EXPBUFSZ);
	rpb.allocated = EXPBUFSZ;
#else
	expbuf = (char *) palloc(EXPBUFSZ);
	endbuf = expbuf + (EXPBUFSZ - 1);
#endif

	bcopy(s->vl_dat, sbuf, s->vl_len - sizeof(int32));
	bcopy(p->vl_dat, pbuf, p->vl_len - sizeof(int32));
	*(sbuf + s->vl_len - sizeof(int32)) = (char)NULL;
	*(pbuf + p->vl_len - sizeof(int32)) = (char)NULL;


	/* compile the re */
#ifdef linux
	(void) re_compile_pattern(pbuf, strlen(pbuf), &rpb);
#else
	(void) compile(pbuf, expbuf, endbuf, NULL);
#endif

	/* do the regexp matching */
#ifdef linux
	result = re_search(&rpb, sbuf, strlen(sbuf), 0, strlen(sbuf), 0);
	pfree(rpb.buffer);
#else
	result = step(sbuf, expbuf);
	pfree(expbuf);
#endif

	pfree(sbuf);
	pfree(pbuf);

#ifdef linux
	return (bool)(result >= 0);
#else
	return ((bool) result);
#endif
}

bool
textregexne(s, p)
	char *s;
	char *p;
{
	return (!textregexeq(s, p));
}
