/* regexp.c */

#include "internal.h"
#include "regexp.h"
#include <setjmp.h>
#include <stdio.h>
#include <ctype.h>


#if ( defined BB_GREP || defined BB_SED)

/* This also tries to find a needle in a haystack, but uses
 * real regular expressions....  The fake regular expression
 * version of find_match lives in utility.c.  Using this version
 * will add 3.9k to busybox...
 *  -Erik Andersen
 */
extern int find_match(char *haystack, char *needle, int ignoreCase)
{
    int status;
    struct regexp*  re;
    re = regcomp( needle);
    status = regexec(re, haystack, FALSE, ignoreCase);
    free( re);
    return( status);
}

#if defined BB_SED
/* This performs substitutions after a regexp match has been found.  
 * The new string is returned.  It is malloc'ed, and do must be freed. */
extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase)
{
    int status;
    struct regexp*  re;
    char *s, buf[BUF_SIZE], *d = buf;

    re = regcomp( needle);
    status = regexec(re, haystack, FALSE, ignoreCase);
    if (status==TRUE) {
	s=haystack;

	do {
	    /* copy stuff from before the match */
	    while (s < re->startp[0])
		*d++ = *s++;
	    /* substitute for the matched part */
	    regsub(re, newNeedle, d);
	    s = re->endp[0];
	    d += strlen(d);
	} while (regexec(re, s, FALSE, ignoreCase) == TRUE);
	 /* copy stuff from after the match */
	while ( (*d++ = *s++) ) {}
	d[0] = '\0';
	strcpy(haystack, buf);
    }
    free( re);
    return( status);
}
#endif


/* code swiped from elvis-tiny 1.4 (a clone of vi) and adjusted to 
 * suit the needs of busybox by Erik Andersen.
 *
 * From the README:
 * "Elvis is freely redistributable, in either source form or executable form.
 * There are no restrictions on how you may use it".
 * Elvis was written by Steve Kirkendall <kirkenda@cs.pdx.edu>
 *
 *
 * This file contains the code that compiles regular expressions and executes
 * them.  It supports the same syntax and features as vi's regular expression
 * code.  Specifically, the meta characters are:
 *	^	matches the beginning of a line
 *	$	matches the end of a line
 *	\<	matches the beginning of a word
 *	\>	matches the end of a word
 *	.	matches any single character
 *	[]	matches any character in a character class
 *	\(	delimits the start of a subexpression
 *	\)	delimits the end of a subexpression
 *	*	repeats the preceding 0 or more times
 * NOTE: You cannot follow a \) with a *.
 *
 * The physical structure of a compiled RE is as follows:
 *	- First, there is a one-byte value that says how many character classes
 *	  are used in this regular expression
 *	- Next, each character class is stored as a bitmap that is 256 bits
 *	  (32 bytes) long.
 *	- A mixture of literal characters and compiled meta characters follows.
 *	  This begins with M_BEGIN(0) and ends with M_END(0).  All meta chars
 *	  are stored as a \n followed by a one-byte code, so they take up two
 *	  bytes apiece.  Literal characters take up one byte apiece.  \n can't
 *	  be used as a literal character.
 *
 */



static char *previous;	/* the previous regexp, used when null regexp is given */
#if defined BB_SED
static char *previous1;	/* a copy of the text from the previous substitution for regsub()*/
#endif


/* These are used to classify or recognize meta-characters */
#define META		'\0'
#define BASE_META(m)	((m) - 256)
#define INT_META(c)	((c) + 256)
#define IS_META(m)	((m) >= 256)
#define IS_CLASS(m)	((m) >= M_CLASS(0) && (m) <= M_CLASS(9))
#define IS_START(m)	((m) >= M_START(0) && (m) <= M_START(9))
#define IS_END(m)	((m) >= M_END(0) && (m) <= M_END(9))
#define IS_CLOSURE(m)	((m) >= M_SPLAT && (m) <= M_QMARK)
#define ADD_META(s,m)	(*(s)++ = META, *(s)++ = BASE_META(m))
#define GET_META(s)	(*(s) == META ? INT_META(*++(s)) : *s)

/* These are the internal codes used for each type of meta-character */
#define M_BEGLINE	256		/* internal code for ^ */
#define M_ENDLINE	257		/* internal code for $ */
#define M_BEGWORD	258		/* internal code for \< */
#define M_ENDWORD	259		/* internal code for \> */
#define M_ANY		260		/* internal code for . */
#define M_SPLAT		261		/* internal code for * */
#define M_PLUS		262		/* internal code for \+ */
#define M_QMARK		263		/* internal code for \? */
#define M_CLASS(n)	(264+(n))	/* internal code for [] */
#define M_START(n)	(274+(n))	/* internal code for \( */
#define M_END(n)	(284+(n))	/* internal code for \) */

/* These are used during compilation */
static int	class_cnt;	/* used to assign class IDs */
static int	start_cnt;	/* used to assign start IDs */
static int	end_stk[NSUBEXP];/* used to assign end IDs */
static int	end_sp;
static char	*retext;	/* points to the text being compiled */

/* error-handling stuff */
jmp_buf	errorhandler;
#define FAIL(why)  do {fprintf(stderr, why); longjmp(errorhandler, 1);} while (0)




/* This function builds a bitmap for a particular class */
/* text -- start of the class */
/* bmap -- the bitmap */
static char *makeclass(char* text, char* bmap)
{
	int		i;
	int		complement = 0;


	/* zero the bitmap */
	for (i = 0; bmap && i < 32; i++)
	{
		bmap[i] = 0;
	}

	/* see if we're going to complement this class */
	if (*text == '^')
	{
		text++;
		complement = 1;
	}

	/* add in the characters */
	while (*text && *text != ']')
	{
		/* is this a span of characters? */
		if (text[1] == '-' && text[2])
		{
			/* spans can't be backwards */
			if (text[0] > text[2])
			{
				FAIL("Backwards span in []");
			}

			/* add each character in the span to the bitmap */
			for (i = text[0]; bmap && i <= text[2]; i++)
			{
				bmap[i >> 3] |= (1 << (i & 7));
			}

			/* move past this span */
			text += 3;
		}
		else
		{
			/* add this single character to the span */
			i = *text++;
			if (bmap)
			{
				bmap[i >> 3] |= (1 << (i & 7));
			}
		}
	}

	/* make sure the closing ] is missing */
	if (*text++ != ']')
	{
		FAIL("] missing");
	}

	/* if we're supposed to complement this class, then do so */
	if (complement && bmap)
	{
		for (i = 0; i < 32; i++)
		{
			bmap[i] = ~bmap[i];
		}
	}

	return text;
}




/* This function gets the next character or meta character from a string.
 * The pointer is incremented by 1, or by 2 for \-quoted characters.  For [],
 * a bitmap is generated via makeclass() (if re is given), and the
 * character-class text is skipped.
 */
static int gettoken(sptr, re)
	char	**sptr;
	regexp	*re;
{
	int	c;

	c = **sptr;
	++*sptr;
	if (c == '\\')
	{
		c = **sptr;
		++*sptr;
		switch (c)
		{
		  case '<':
			return M_BEGWORD;

		  case '>':
			return M_ENDWORD;

		  case '(':
			if (start_cnt >= NSUBEXP)
			{
				FAIL("Too many \\(s");
			}
			end_stk[end_sp++] = start_cnt;
			return M_START(start_cnt++);

		  case ')':
			if (end_sp <= 0)
			{
				FAIL("Mismatched \\)");
			}
			return M_END(end_stk[--end_sp]);

		  case '*':
			return M_SPLAT;

		  case '.':
			return M_ANY;

		  case '+':
			return M_PLUS;

		  case '?':
			return M_QMARK;

		  default:
			return c;
		}
	}
	else {
		switch (c)
		{
		  case '^':
			if (*sptr == retext + 1)
			{
				return M_BEGLINE;
			}
			return c;

		  case '$':
			if (!**sptr)
			{
				return M_ENDLINE;
			}
			return c;

		  case '.':
			return M_ANY;

		  case '*':
			return M_SPLAT;

		  case '[':
			/* make sure we don't have too many classes */
			if (class_cnt >= 10)
			{
				FAIL("Too many []s");
			}

			/* process the character list for this class */
			if (re)
			{
				/* generate the bitmap for this class */
				*sptr = makeclass(*sptr, re->program + 1 + 32 * class_cnt);
			}
			else
			{
				/* skip to end of the class */
				*sptr = makeclass(*sptr, (char *)0);
			}
			return M_CLASS(class_cnt++);

		  default:
			return c;
		}
	}
	/*NOTREACHED*/
}




/* This function calculates the number of bytes that will be needed for a
 * compiled RE.  Its argument is the uncompiled version.  It is not clever
 * about catching syntax errors; that is done in a later pass.
 */
static unsigned calcsize(text)
	char		*text;
{
	unsigned	size;
	int		token;

	retext = text;
	class_cnt = 0;
	start_cnt = 1;
	end_sp = 0;
	size = 5;
	while ((token = gettoken(&text, (regexp *)0)) != 0)
	{
		if (IS_CLASS(token))
		{
			size += 34;
		}
		else if (IS_META(token))
		{
			size += 2;
		}
		else
		{
			size++;
		}
	}

	return size;
}



/*---------------------------------------------------------------------------*/


/* This function checks for a match between a character and a token which is
 * known to represent a single character.  It returns 0 if they match, or
 * 1 if they don't.
 */
static int match1(regexp* re, char ch, int token, int ignoreCase)
{
	if (!ch)
	{
		/* the end of a line can't match any RE of width 1 */
		return 1;
	}
	if (token == M_ANY)
	{
		return 0;
	}
	else if (IS_CLASS(token))
	{
		if (re->program[1 + 32 * (token - M_CLASS(0)) + (ch >> 3)] & (1 << (ch & 7)))
			return 0;
	}
//fprintf(stderr, "match1: ch='%c' token='%c': ", ch, token);
	if (ch == token
		|| (ignoreCase==TRUE && tolower(ch) == tolower(token)))
	{
//fprintf(stderr, "match\n");
		return 0;
	}
//fprintf(stderr, "no match\n");
	return 1;
}



/* This function checks characters up to and including the next closure, at
 * which point it does a recursive call to check the rest of it.  This function
 * returns 0 if everything matches, or 1 if something doesn't match.
 */
/* re   -- the regular expression */
/* str  -- the string */
/* prog -- a portion of re->program, an compiled RE */
/* here -- a portion of str, the string to compare it to */
static int match(regexp* re, char* str, char* prog, char* here, int ignoreCase)
{
	int		token;
	int		nmatched;
	int		closure;

	for (token = GET_META(prog); !IS_CLOSURE(token); prog++, token = GET_META(prog))
	{
		switch (token)
		{
		/*case M_BEGLINE: can't happen; re->bol is used instead */
		  case M_ENDLINE:
			if (*here)
				return 1;
			break;

		  case M_BEGWORD:
			if (here != str &&
			   (here[-1] == '_' ||
			     (isascii(here[-1]) && isalnum(here[-1]))))
				return 1;
			break;

		  case M_ENDWORD:
			if ((here[0] == '_' || isascii(here[0])) && isalnum(here[0]))
				return 1;
			break;

		  case M_START(0):
		  case M_START(1):
		  case M_START(2):
		  case M_START(3):
		  case M_START(4):
		  case M_START(5):
		  case M_START(6):
		  case M_START(7):
		  case M_START(8):
		  case M_START(9):
			re->startp[token - M_START(0)] = (char *)here;
			break;

		  case M_END(0):
		  case M_END(1):
		  case M_END(2):
		  case M_END(3):
		  case M_END(4):
		  case M_END(5):
		  case M_END(6):
		  case M_END(7):
		  case M_END(8):
		  case M_END(9):
			re->endp[token - M_END(0)] = (char *)here;
			if (token == M_END(0))
			{
				return 0;
			}
			break;

		  default: /* literal, M_CLASS(n), or M_ANY */
			if (match1(re, *here, token, ignoreCase) != 0)
				return 1;
			here++;
		}
	}

	/* C L O S U R E */

	/* step 1: see what we have to match against, and move "prog" to point
	 * the the remainder of the compiled RE.
	 */
	closure = token;
	prog++, token = GET_META(prog);
	prog++;

	/* step 2: see how many times we can match that token against the string */
	for (nmatched = 0;
	     (closure != M_QMARK || nmatched < 1) && *here && match1(re, *here, token, ignoreCase) == 0;
	     nmatched++, here++)
	{
	}

	/* step 3: try to match the remainder, and back off if it doesn't */
	while (nmatched >= 0 && match(re, str, prog, here, ignoreCase) != 0)
	{
		nmatched--;
		here--;
	}

	/* so how did it work out? */
	if (nmatched >= ((closure == M_PLUS) ? 1 : 0))
		return 0;
	return 1;
}


/* This function compiles a regexp. */
extern regexp *regcomp(char* text)
{
	int		needfirst;
	unsigned	size;
	int		token;
	int		peek;
	char		*build;
	regexp		*re; // Ignore compiler whining.  If we longjmp, we don't use re anymore.


	/* prepare for error handling */
	re = (regexp *)0;
	if (setjmp(errorhandler))
	{
		if (re)
		{
			free(re);
		}
		return (regexp *)0;
	}

	/* if an empty regexp string was given, use the previous one */
	if (*text == 0)
	{
		if (!previous)
		{
			FAIL("No previous RE");
		}
		text = previous;
	}
	else /* non-empty regexp given, so remember it */
	{
		if (previous)
			free(previous);
		previous = (char *)malloc((unsigned)(strlen(text) + 1));
		if (previous)
			strcpy(previous, text);
	}

	/* allocate memory */
	class_cnt = 0;
	start_cnt = 1;
	end_sp = 0;
	retext = text;
	size = calcsize(text) + sizeof(regexp);
	re = (regexp *)malloc((unsigned)size);

	if (!re)
	{
		FAIL("Not enough memory for this RE");
	}

	/* compile it */
	build = &re->program[1 + 32 * class_cnt];
	re->program[0] = class_cnt;
	for (token = 0; token < NSUBEXP; token++)
	{
		re->startp[token] = re->endp[token] = (char *)0;
	}
	re->first = 0;
	re->bol = 0;
	re->minlen = 0;
	needfirst = 1;
	class_cnt = 0;
	start_cnt = 1;
	end_sp = 0;
	retext = text;
	for (token = M_START(0), peek = gettoken(&text, re);
	     token;
	     token = peek, peek = gettoken(&text, re))
	{
		/* special processing for the closure operator */
		if (IS_CLOSURE(peek))
		{
			/* detect misuse of closure operator */
			if (IS_START(token))
			{
				FAIL("* or \\+ or \\? follows nothing");
			}
			else if (IS_META(token) && token != M_ANY && !IS_CLASS(token))
			{
				FAIL("* or \\+ or \\? can only follow a normal character or . or []");
			}

			/* it is okay -- make it prefix instead of postfix */
			ADD_META(build, peek);

			/* take care of "needfirst" - is this the first char? */
			if (needfirst && peek == M_PLUS && !IS_META(token))
			{
				re->first = token;
			}
			needfirst = 0;

			/* we used "peek" -- need to refill it */
			peek = gettoken(&text, re);
			if (IS_CLOSURE(peek))
			{
				FAIL("* or \\+ or \\? doubled up");
			}
		}
		else if (!IS_META(token))
		{
			/* normal char is NOT argument of closure */
			if (needfirst)
			{
				re->first = token;
				needfirst = 0;
			}
			re->minlen++;
		}
		else if (token == M_ANY || IS_CLASS(token))
		{
			/* . or [] is NOT argument of closure */
			needfirst = 0;
			re->minlen++;
		}

		/* the "token" character is not closure -- process it normally */
		if (token == M_BEGLINE)
		{
			/* set the BOL flag instead of storing M_BEGLINE */
			re->bol = 1;
		}
		else if (IS_META(token))
		{
			ADD_META(build, token);
		}
		else
		{
			*build++ = token;
		}
	}

	/* end it with a \) which MUST MATCH the opening \( */
	ADD_META(build, M_END(0));
	if (end_sp > 0)
	{
		FAIL("Not enough \\)s");
	}

	return re;
}




/* This function searches through a string for text that matches an RE. */
/* re  -- the compiled regexp to search for */
/* str -- the string to search through */
/* bol -- does str start at the beginning of a line? (boolean) */
/* ignoreCase -- ignoreCase or not */
extern int regexec(struct regexp* re, char* str, int bol, int ignoreCase)
{
	char	*prog;	/* the entry point of re->program */
	int	len;	/* length of the string */
	char	*here;

	/* if must start at the beginning of a line, and this isn't, then fail */
	if (re->bol && bol==TRUE)
	{
		return FALSE;
	}

	len = strlen(str);
	prog = re->program + 1 + 32 * re->program[0];

	/* search for the RE in the string */
	if (re->bol)
	{
		/* must occur at BOL */
		if ((re->first
			&& match1(re, *(char *)str, re->first, ignoreCase))/* wrong first letter? */
		 || len < re->minlen			/* not long enough? */
		 || match(re, (char *)str, prog, str, ignoreCase))	/* doesn't match? */
			return FALSE;			/* THEN FAIL! */
	}
	else if (ignoreCase == FALSE)
	{
		/* can occur anywhere in the line, noignorecase */
		for (here = (char *)str;
		     (re->first && re->first != *here)
			|| match(re, (char *)str, prog, here, ignoreCase);
		     here++, len--)
		{
			if (len < re->minlen)
				return FALSE;
		}
	}
	else
	{
		/* can occur anywhere in the line, ignorecase */
		for (here = (char *)str;
		     (re->first && match1(re, *here, (int)re->first, ignoreCase))
			|| match(re, (char *)str, prog, here, ignoreCase);
		     here++, len--)
		{
			if (len < re->minlen)
				return FALSE;
		}
	}

	/* if we didn't fail, then we must have succeeded */
	return TRUE;
}




#if defined BB_SED
/* This performs substitutions after a regexp match has been found.  */
extern void regsub(regexp* re, char* src, char* dst)
{
	char	*cpy;
	char	*end;
	char	c;
	char		*start;
	int		mod;

	mod = 0;

	start = src;
	while ((c = *src++) != '\0')
	{
		/* recognize any meta characters */
		if (c == '&')
		{
			cpy = re->startp[0];
			end = re->endp[0];
		}
		else if (c == '~')
		{
			cpy = previous1;
			if (cpy)
				end = cpy + strlen(cpy);
		}
		else
		if (c == '\\')
		{
			c = *src++;
			switch (c)
			{
			  case '0':
			  case '1':
			  case '2':
			  case '3':
			  case '4':
			  case '5':
			  case '6':
			  case '7':
			  case '8':
			  case '9':
				/* \0 thru \9 mean "copy subexpression" */
				c -= '0';
				cpy = re->startp[(int)c];
				end = re->endp[(int)c];
				break;
			  case 'U':
			  case 'u':
			  case 'L':
			  case 'l':
				/* \U and \L mean "convert to upper/lowercase" */
				mod = c;
				continue;

			  case 'E':
			  case 'e':
				/* \E ends the \U or \L */
				mod = 0;
				continue;
			  case '&':
				/* "\&" means "original text" */
				*dst++ = c;
				continue;

			  case '~':
				/* "\~" means "previous text, if any" */
				*dst++ = c;
				continue;
			  default:
				/* ordinary char preceded by backslash */
				*dst++ = c;
				continue;
			}
		}
		else
		{
			/* ordinary character, so just copy it */
			*dst++ = c;
			continue;
		}

		/* Note: to reach this point in the code, we must have evaded
		 * all "continue" statements.  To do that, we must have hit
		 * a metacharacter that involves copying.
		 */

		/* if there is nothing to copy, loop */
		if (!cpy)
			continue;

		/* copy over a portion of the original */
		while (cpy < end)
		{
			switch (mod)
			{
			  case 'U':
			  case 'u':
				/* convert to uppercase */
				if (isascii(*cpy) && islower(*cpy))
				{
					*dst++ = toupper(*cpy);
					cpy++;
				}
				else
				{
					*dst++ = *cpy++;
				}
				break;

			  case 'L':
			  case 'l':
				/* convert to lowercase */
				if (isascii(*cpy) && isupper(*cpy))
				{
					*dst++ = tolower(*cpy);
					cpy++;
				}
				else
				{
					*dst++ = *cpy++;
				}
				break;

			  default:
				/* copy without any conversion */
				*dst++ = *cpy++;
			}

			/* \u and \l end automatically after the first char */
			if (mod && (mod == 'u' || mod == 'l'))
			{
				mod = 0;
			}
		}
	}
	*dst = '\0';

	/* remember what text we inserted this time */
	if (previous1)
		free(previous1);
	previous1 = (char *)malloc((unsigned)(strlen(start) + 1));
	if (previous1)
		strcpy(previous1, start);
}
#endif

#endif /* BB_REGEXP */


