/* Pcre objects */

#include "Python.h"

#ifndef Py_eval_input
/* For Python 1.4, graminit.h has to be explicitly included */
#include "graminit.h"
#define Py_eval_input eval_input
#endif

#ifndef FOR_PYTHON
#define FOR_PYTHON
#endif

#include "pcre.h"
#include "pcre-int.h"

static PyObject *ErrorObject;

typedef struct {
	PyObject_HEAD
	pcre *regex;
	pcre_extra *regex_extra;
        int num_groups;
} PcreObject;

staticforward PyTypeObject Pcre_Type;

#define PcreObject_Check(v)	((v)->ob_type == &Pcre_Type)
#define NORMAL			0
#define CHARCLASS		1
#define REPLACEMENT		2

#define CHAR 			0
#define MEMORY_REFERENCE 	1
#define SYNTAX 			2
#define NOT_SYNTAX 		3
#define SET			4
#define WORD_BOUNDARY		5
#define NOT_WORD_BOUNDARY	6
#define BEGINNING_OF_BUFFER	7
#define END_OF_BUFFER		8
#define STRING                  9

static PcreObject *
newPcreObject(PyObject *args)
{
	PcreObject *self;
	self = PyObject_New(PcreObject, &Pcre_Type);
	if (self == NULL)
		return NULL;
	self->regex = NULL;
	self->regex_extra = NULL;
	return self;
}

/* Pcre methods */

static void
PyPcre_dealloc(PcreObject *self)
{
	if (self->regex) (pcre_free)(self->regex);
	if (self->regex_extra) (pcre_free)(self->regex_extra);
	PyObject_Del(self);
}


static PyObject *
PyPcre_exec(PcreObject *self, PyObject *args)
{
        char *string;
	int stringlen, pos = 0, options=0, endpos = -1, i, count;
	int offsets[100*2]; 
	PyObject *list;

	if (!PyArg_ParseTuple(args, "t#|iii:match", &string, &stringlen, 
                                     &pos, &endpos, &options))
		return NULL;
	if (endpos == -1) {endpos = stringlen;}
	count = pcre_exec(self->regex, self->regex_extra, 
			  string, endpos, pos, options,
			  offsets, sizeof(offsets)/sizeof(int) );
	/* If an error occurred during the match, and an exception was raised,
	   just return NULL and leave the exception alone.  The most likely
	   problem to cause this would be running out of memory for
	   the failure stack. */
	if (PyErr_Occurred())
	{
		return NULL;
	}
	if (count==PCRE_ERROR_NOMATCH) {Py_INCREF(Py_None); return Py_None;}
	if (count<0)
	{
		PyObject *errval = Py_BuildValue("si", "Regex execution error", count);
		PyErr_SetObject(ErrorObject, errval);
		Py_XDECREF(errval);
		return NULL;
	}
	
	list=PyList_New(self->num_groups+1);
	if (list==NULL) return NULL;
	for(i=0; i<=self->num_groups; i++)
	{
		PyObject *v;
		int start=offsets[i*2], end=offsets[i*2+1];
		/* If the group wasn't affected by the match, return -1, -1 */
		if (start<0 || count<=i) 
		{start=end=-1;}
		v=Py_BuildValue("ii", start, end);
		if (v==NULL) {Py_DECREF(list); return NULL;}
		PyList_SetItem(list, i, v);
	}
	return list;
}

static PyMethodDef Pcre_methods[] = {
	{"match",	(PyCFunction)PyPcre_exec,	1},
	{NULL,		NULL}		/* sentinel */
};

static PyObject *
PyPcre_getattr(PcreObject *self, char *name)
{
	return Py_FindMethod(Pcre_methods, (PyObject *)self, name);
}


staticforward PyTypeObject Pcre_Type = {
	PyObject_HEAD_INIT(NULL)
	0,			/*ob_size*/
	"pcre.Pcre",		/*tp_name*/
	sizeof(PcreObject),	/*tp_basicsize*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)PyPcre_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)PyPcre_getattr, /*tp_getattr*/
	0,                      /*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};
/* --------------------------------------------------------------------- */

static PyObject *
PyPcre_compile(PyObject *self, PyObject *args)
{
	PcreObject *rv;
	PyObject *dictionary;
	char *pattern;
	const char *error;
	
	int options, erroroffset;
	if (!PyArg_ParseTuple(args, "siO!:pcre_compile", &pattern, &options,
			      &PyDict_Type, &dictionary))
		return NULL;
	rv = newPcreObject(args);
	if ( rv == NULL )
		return NULL;

	rv->regex = pcre_compile((char*)pattern, options, 
				 &error, &erroroffset, dictionary);
	if (rv->regex==NULL) 
	{
		Py_DECREF(rv);
		if (!PyErr_Occurred())
		{
			PyObject *errval = Py_BuildValue("si", error, erroroffset);
			PyErr_SetObject(ErrorObject, errval);
			Py_XDECREF(errval);
		}
		return NULL;
	}
	rv->regex_extra=pcre_study(rv->regex, 0, &error);
	if (rv->regex_extra==NULL && error!=NULL) 
	{
		PyObject *errval = Py_BuildValue("si", error, 0);
		Py_DECREF(rv);
		PyErr_SetObject(ErrorObject, errval);
		Py_XDECREF(errval);
		return NULL;
	}
        rv->num_groups = pcre_info(rv->regex, NULL, NULL);
	if (rv->num_groups<0) 
	{
		PyObject *errval = Py_BuildValue("si", error, rv->num_groups);
		PyErr_SetObject(ErrorObject, errval);
		Py_XDECREF(errval);
		Py_DECREF(rv);
		return NULL;
	}
	return (PyObject *)rv;
}

static PyObject *
PyPcre_expand_escape(unsigned char *pattern, int pattern_len,
                     int *indexptr, int *typeptr)
{
	unsigned char c;
	int index = *indexptr;
  
	if (pattern_len<=index)
	{
		PyErr_SetString(ErrorObject, "escape ends too soon");
		return NULL;
	}
	c=pattern[index]; index++;
	*typeptr=CHAR;

	switch (c)
	{
	case('t'):
		*indexptr=index;
		return Py_BuildValue("c", (char)9);
	case('n'):
		*indexptr = index;
		return Py_BuildValue("c", (char)10);
	case('v'):
		*indexptr = index;
		return Py_BuildValue("c", (char)11);
	case('r'):
		*indexptr = index;
		return Py_BuildValue("c", (char)13);
	case('f'):
		*indexptr = index;
		return Py_BuildValue("c", (char)12);
	case('a'):
		*indexptr = index;
		return Py_BuildValue("c", (char)7);
	case('b'):
		*indexptr=index;
		return Py_BuildValue("c", (char)8);
	case('\\'):
		*indexptr=index;
		return Py_BuildValue("c", '\\');

	case('x'):
	{
		int x, ch, end;

		x = 0; end = index;
		while ( (end<pattern_len && pcre_ctypes[ pattern[end] ] & ctype_xdigit) != 0)
		{
			ch = pattern[end];
			x = x * 16 + pcre_lcc[ch] -
				(((pcre_ctypes[ch] & ctype_digit) != 0)? '0' : 'W');
			x &= 255;
			end++;
		}
		if (end==index)
		{
			PyErr_SetString(ErrorObject, "\\x must be followed by hex digits");
			return NULL;
		}
		*indexptr = end;
		return Py_BuildValue("c", (char)x);
	}

	case('E'):    case('G'):    case('L'):    case('Q'):
	case('U'):    case('l'):    case('u'):
	{
		char message[50];
		PyOS_snprintf(message, sizeof(message),
			      "\\%c is not allowed", c);
		PyErr_SetString(ErrorObject, message);
		return NULL;
	}

	case('g'):
	{
		int end, i;
		int group_num = 0, is_number=0;

		if (pattern_len<=index)
		{
			PyErr_SetString(ErrorObject, "unfinished symbolic reference");
			return NULL;
		}
		if (pattern[index]!='<')
		{
			PyErr_SetString(ErrorObject, "missing < in symbolic reference");
			return NULL;
		}
		index++;
		end=index;
		while (end<pattern_len && pattern[end]!='>')
			end++;
		if (end==pattern_len)
		{
			PyErr_SetString(ErrorObject, "unfinished symbolic reference");
			return NULL;
		}

		if (index==end)		/* Zero-length name */
		{
			/* XXX should include the text of the reference */
			PyErr_SetString(ErrorObject, "zero-length symbolic reference");
			return NULL;
		}
		if ((pcre_ctypes[pattern[index]] & ctype_digit)) /* First char. a digit */
		{
		        is_number = 1;
			group_num = pattern[index] - '0';
		}

		for(i=index+1; i<end; i++)
		{
		        if (is_number && 
			    !(pcre_ctypes[pattern[i]] & ctype_digit) )
			{
				/* XXX should include the text of the reference */
				PyErr_SetString(ErrorObject, "illegal non-digit character in \\g<...> starting with digit");
				return NULL;			       
			}
			else {group_num = group_num * 10 + pattern[i] - '0';}
			if (!(pcre_ctypes[pattern[i]] & ctype_word) )
			{
				/* XXX should include the text of the reference */
				PyErr_SetString(ErrorObject, "illegal symbolic reference");
				return NULL;
			}
		}	
	    
		*typeptr = MEMORY_REFERENCE;
		*indexptr = end+1;
		/* If it's a number, return the integer value of the group */
		if (is_number) return Py_BuildValue("i", group_num);
		/* Otherwise, return a string containing the group name */
		return Py_BuildValue("s#", pattern+index, end-index);
	}

	case('0'):
	{
		/* \0 always indicates an octal escape, so we consume up to 3
		   characters, as long as they're all octal digits */
		int octval=0, i;
		index--;
		for(i=index;
		    i<=index+2 && i<pattern_len 
			    && (pcre_ctypes[ pattern[i] ] & ctype_odigit );
		    i++)
		{
			octval = octval * 8 + pattern[i] - '0';
		}
		if (octval>255)
		{
			PyErr_SetString(ErrorObject, "octal value out of range");
			return NULL;
		}
		*indexptr = i;
		return Py_BuildValue("c", (unsigned char)octval);
	}

	case('1'):    case('2'):    case('3'):    case('4'):
	case('5'):    case('6'):    case('7'):    case('8'):
	case('9'):
	{
		/* Handle \?, where ? is from 1 through 9 */
		int value=0;
		index--;
		/* If it's at least a two-digit reference, like \34, it might
		   either be a 3-digit octal escape (\123) or a 2-digit
		   decimal memory reference (\34) */

		if ( (index+1) <pattern_len && 
		     (pcre_ctypes[ pattern[index+1] ] & ctype_digit) )
		{
			if ( (index+2) <pattern_len && 
			     (pcre_ctypes[ pattern[index+2] ] & ctype_odigit) &&
			     (pcre_ctypes[ pattern[index+1] ] & ctype_odigit) &&
			     (pcre_ctypes[ pattern[index  ] ] & ctype_odigit)
				)
			{
				/* 3 octal digits */
				value= 8*8*(pattern[index  ]-'0') +
					8*(pattern[index+1]-'0') +
					(pattern[index+2]-'0');
				if (value>255)
				{
					PyErr_SetString(ErrorObject, "octal value out of range");
					return NULL;
				}
				*indexptr = index+3;
				return Py_BuildValue("c", (unsigned char)value);
			}
			else
			{
				/* 2-digit form, so it's a memory reference */
				value= 10*(pattern[index  ]-'0') +
					(pattern[index+1]-'0');
				if (value<1 || EXTRACT_MAX<=value)
				{
					PyErr_SetString(ErrorObject, "memory reference out of range");
					return NULL;
				}
				*typeptr = MEMORY_REFERENCE;
				*indexptr = index+2;
				return Py_BuildValue("i", value);
			}
		}
		else 
		{
			/* Single-digit form, like \2, so it's a memory reference */
			*typeptr = MEMORY_REFERENCE;
			*indexptr = index+1;
			return Py_BuildValue("i", pattern[index]-'0');
		}
	}

	default:
	  /* It's some unknown escape like \s, so return a string containing
	     \s */
		*typeptr = STRING;
		*indexptr = index;
		return Py_BuildValue("s#", pattern+index-2, 2);
	}
}

static PyObject *
PyPcre_expand(PyObject *self, PyObject *args)
{
	PyObject *results, *match_obj;
	PyObject *repl_obj, *newstring;
	unsigned char *repl;
	int size, total_len, i, start, pos;

	if (!PyArg_ParseTuple(args, "OS:pcre_expand", &match_obj, &repl_obj)) 
		return NULL;

	repl=(unsigned char *)PyString_AsString(repl_obj);
	size=PyString_Size(repl_obj);
	results=PyList_New(0);
	if (results==NULL) return NULL;
	for(start=total_len=i=0; i<size; i++)
	{
		if (repl[i]=='\\')
		{
			PyObject *value;
			int escape_type;

			if (start!=i)
			{
				int status;
				PyObject *s = PyString_FromStringAndSize(
					(char *)repl+start, i-start);
				if (s == NULL) {
					Py_DECREF(results);
					return NULL;
				}
				status = PyList_Append(results, s);
				Py_DECREF(s);
				if (status < 0) {
					Py_DECREF(results);
					return NULL;
				}
				total_len += i-start;
			}
			i++;
			value=PyPcre_expand_escape(repl, size, &i, &escape_type);
			if (value==NULL)
			{
				/* PyPcre_expand_escape triggered an exception of some sort,
				   so just return */
				Py_DECREF(results);
				return NULL;
			}
			switch (escape_type)
			{
			case (CHAR):
				PyList_Append(results, value);
				total_len += PyString_Size(value);
				break;
			case(MEMORY_REFERENCE):
			{
				PyObject *r, *tuple, *result;
				r=PyObject_GetAttrString(match_obj, "group");
				if (r == NULL) {
					Py_DECREF(results);
					return NULL;
				}
				tuple=PyTuple_New(1);
				Py_INCREF(value);
				PyTuple_SetItem(tuple, 0, value);
				result=PyEval_CallObject(r, tuple);
				Py_DECREF(r); Py_DECREF(tuple);
				if (result==NULL)
				{
					/* The group() method triggered an exception of some sort */
					Py_DECREF(results);
					Py_DECREF(value);
					return NULL;
				}
				if (result==Py_None)
				{
					char message[50];
					PyOS_snprintf(message, sizeof(message),
						"group did not contribute to the match");
					PyErr_SetString(ErrorObject, 
							message);
					Py_DECREF(result);
					Py_DECREF(value);
					Py_DECREF(results);
					return NULL;
				}
				/* typecheck that it's a string! */
				if (!PyString_Check(result))
				{
					Py_DECREF(results);
					Py_DECREF(result);
					PyErr_SetString(ErrorObject, 
							"group() must return a string value for replacement");
					return NULL;
				}
				PyList_Append(results, result);
				total_len += PyString_Size(result);
				Py_DECREF(result);
			}
			break;
			case(STRING):
			  {
			    PyList_Append(results, value);
			    total_len += PyString_Size(value);
			    break;
			  }
			default:
				Py_DECREF(results);
				PyErr_SetString(ErrorObject, 
						"bad escape in replacement");
				return NULL;
			}
			Py_DECREF(value);
			start=i;
			i--; /* Decrement now, because the 'for' loop will increment it */
		}
	} /* endif repl[i]!='\\' */

	if (start!=i)
	{
		int status;
		PyObject *s = PyString_FromStringAndSize((char *)repl+start, 
							 i-start);
		if (s == NULL) {
			Py_DECREF(results);
			return NULL;
		}
		status = PyList_Append(results, s);
		Py_DECREF(s);
		if (status < 0) {
			Py_DECREF(results);
			return NULL;
		}
		total_len += i-start;
	}

	/* Whew!  Now we've constructed a list containing various pieces of
	   strings that will make up our final result.  So, iterate over 
	   the list concatenating them.  A new string measuring total_len
	   bytes is allocated and filled in. */
     
	newstring=PyString_FromStringAndSize(NULL, total_len);
	if (newstring==NULL)
	{
		Py_DECREF(results);
		return NULL;
	}

	repl=(unsigned char *)PyString_AsString(newstring);
	for (pos=i=0; i<PyList_Size(results); i++)
	{
		PyObject *item=PyList_GetItem(results, i);
		memcpy(repl+pos, PyString_AsString(item), PyString_Size(item) );
		pos += PyString_Size(item);
	}
	Py_DECREF(results);
	return newstring;
}


/* List of functions defined in the module */

static PyMethodDef pcre_methods[] = {
	{"pcre_compile",		PyPcre_compile,		1},
	{"pcre_expand",		PyPcre_expand,		1},
	{NULL,		NULL}		/* sentinel */
};


/*
 * Convenience routine to export an integer value.
 * For simplicity, errors (which are unlikely anyway) are ignored.
 */

static void
insint(PyObject *d, char *name, int value)
{
	PyObject *v = PyInt_FromLong((long) value);
	if (v == NULL) {
		/* Don't bother reporting this error */
		PyErr_Clear();
	}
	else {
		PyDict_SetItemString(d, name, v);
		Py_DECREF(v);
	}
}


/* Initialization function for the module (*must* be called initpcre) */

DL_EXPORT(void)
initpcre(void)
{
	PyObject *m, *d;

        Pcre_Type.ob_type = &PyType_Type;

	/* Create the module and add the functions */
	m = Py_InitModule("pcre", pcre_methods);

	/* Add some symbolic constants to the module */
	d = PyModule_GetDict(m);
	ErrorObject = PyErr_NewException("pcre.error", NULL, NULL);
	PyDict_SetItemString(d, "error", ErrorObject);

	/* Insert the flags */
	insint(d, "IGNORECASE", PCRE_CASELESS);
	insint(d, "ANCHORED", PCRE_ANCHORED);
	insint(d, "MULTILINE", PCRE_MULTILINE);
	insint(d, "DOTALL", PCRE_DOTALL);
	insint(d, "VERBOSE", PCRE_EXTENDED);
	insint(d, "LOCALE", PCRE_LOCALE);
}

