regexmodule.c 16.5 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2 3 4 5 6
/*
XXX support range parameter on search
XXX support mstop parameter on search
*/

/***********************************************************
7 8
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.
Guido van Rossum's avatar
Guido van Rossum committed
9 10 11

                        All Rights Reserved

12 13
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
Guido van Rossum's avatar
Guido van Rossum committed
14
provided that the above copyright notice appear in all copies and that
15
both that copyright notice and this permission notice appear in
Guido van Rossum's avatar
Guido van Rossum committed
16
supporting documentation, and that the names of Stichting Mathematisch
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum's avatar
Guido van Rossum committed
34 35 36 37

******************************************************************/

/* Regular expression objects */
38 39
/* This uses Tatu Ylonen's copyleft-free reimplementation of
   GNU regular expressions */
Guido van Rossum's avatar
Guido van Rossum committed
40

41
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
42

Guido van Rossum's avatar
Guido van Rossum committed
43 44
#include <ctype.h>

45
#include "regexpr.h"
Guido van Rossum's avatar
Guido van Rossum committed
46

47
static PyObject *RegexError;	/* Exception */	
Guido van Rossum's avatar
Guido van Rossum committed
48 49

typedef struct {
50
	PyObject_HEAD
Guido van Rossum's avatar
Guido van Rossum committed
51 52 53
	struct re_pattern_buffer re_patbuf; /* The compiled expression */
	struct re_registers re_regs; /* The registers from the last match */
	char re_fastmap[256];	/* Storage for fastmap */
54 55 56 57 58
	PyObject *re_translate;	/* String object for translate table */
	PyObject *re_lastok;	/* String object last matched/searched */
	PyObject *re_groupindex;	/* Group name to index dictionary */
	PyObject *re_givenpat;	/* Pattern with symbolic groups */
	PyObject *re_realpat;	/* Pattern without symbolic groups */
Guido van Rossum's avatar
Guido van Rossum committed
59 60 61 62 63 64 65 66
} regexobject;

/* Regex object methods */

static void
reg_dealloc(re)
	regexobject *re;
{
67 68 69 70 71 72 73
	PyMem_XDEL(re->re_patbuf.buffer);
	Py_XDECREF(re->re_translate);
	Py_XDECREF(re->re_lastok);
	Py_XDECREF(re->re_groupindex);
	Py_XDECREF(re->re_givenpat);
	Py_XDECREF(re->re_realpat);
	PyMem_DEL(re);
Guido van Rossum's avatar
Guido van Rossum committed
74 75
}

76
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
77 78 79
makeresult(regs)
	struct re_registers *regs;
{
80 81 82
	PyObject *v;
	int i;
	static PyObject *filler = NULL;
83

84 85 86 87 88 89 90 91
	if (filler == NULL) {
		filler = Py_BuildValue("(ii)", -1, -1);
		if (filler == NULL)
			return NULL;
	}
	v = PyTuple_New(RE_NREGS);
	if (v == NULL)
		return NULL;
92

93 94 95 96 97 98 99 100 101 102
	for (i = 0; i < RE_NREGS; i++) {
		int lo = regs->start[i];
		int hi = regs->end[i];
		PyObject *w;
		if (lo == -1 && hi == -1) {
			w = filler;
			Py_INCREF(w);
		}
		else
			w = Py_BuildValue("(ii)", lo, hi);
103 104
		if (w == NULL || PyTuple_SetItem(v, i, w) < 0) {
			Py_DECREF(v);
105
			return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
106 107 108 109 110
		}
	}
	return v;
}

111
static PyObject *
112
regobj_match(re, args)
Guido van Rossum's avatar
Guido van Rossum committed
113
	regexobject *re;
114
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
115
{
116
	PyObject *argstring;
Guido van Rossum's avatar
Guido van Rossum committed
117
	char *buffer;
118
	int size;
119
	int offset = 0;
Guido van Rossum's avatar
Guido van Rossum committed
120
	int result;
121

122
	if (!PyArg_ParseTuple(args, "O|i:match", &argstring, &offset))
123
		return NULL;
124
	if (!PyArg_Parse(argstring, "t#", &buffer, &size))
125 126
		return NULL;

127
	if (offset < 0 || offset > size) {
128
		PyErr_SetString(RegexError, "match offset out of range");
129 130
		return NULL;
	}
131
	Py_XDECREF(re->re_lastok);
132
	re->re_lastok = NULL;
133
	result = _Py_re_match(&re->re_patbuf, (unsigned char *)buffer, size, offset,
134
			      &re->re_regs);
Guido van Rossum's avatar
Guido van Rossum committed
135
	if (result < -1) {
136 137 138 139
		/* Serious failure of some sort; if re_match didn't 
		   set an exception, raise a generic error */
	        if (!PyErr_Occurred())
		        PyErr_SetString(RegexError, "match failure");
Guido van Rossum's avatar
Guido van Rossum committed
140 141
		return NULL;
	}
142
	if (result >= 0) {
143 144
		Py_INCREF(argstring);
		re->re_lastok = argstring;
145
	}
146
	return PyInt_FromLong((long)result); /* Length of the match or -1 */
Guido van Rossum's avatar
Guido van Rossum committed
147
}
148

149
static PyObject *
150
regobj_search(re, args)
Guido van Rossum's avatar
Guido van Rossum committed
151
	regexobject *re;
152
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
153
{
154
	PyObject *argstring;
Guido van Rossum's avatar
Guido van Rossum committed
155 156
	char *buffer;
	int size;
157
	int offset = 0;
Guido van Rossum's avatar
Guido van Rossum committed
158 159
	int range;
	int result;
160
	
161
	if (!PyArg_ParseTuple(args, "O|i:search", &argstring, &offset))
162
		return NULL;
163
	if (!PyArg_Parse(argstring, "t#:search", &buffer, &size))
164 165
		return NULL;

166
	if (offset < 0 || offset > size) {
167
		PyErr_SetString(RegexError, "search offset out of range");
168
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
169
	}
170 171 172 173
	/* NB: In Emacs 18.57, the documentation for re_search[_2] and
	   the implementation don't match: the documentation states that
	   |range| positions are tried, while the code tries |range|+1
	   positions.  It seems more productive to believe the code! */
174
	range = size - offset;
175
	Py_XDECREF(re->re_lastok);
176
	re->re_lastok = NULL;
177
	result = _Py_re_search(&re->re_patbuf, (unsigned char *)buffer, size, offset, range,
Guido van Rossum's avatar
Guido van Rossum committed
178 179
			   &re->re_regs);
	if (result < -1) {
180 181 182 183
		/* Serious failure of some sort; if re_match didn't 
		   set an exception, raise a generic error */
	        if (!PyErr_Occurred())
	  	        PyErr_SetString(RegexError, "match failure");
Guido van Rossum's avatar
Guido van Rossum committed
184 185
		return NULL;
	}
186
	if (result >= 0) {
187 188
		Py_INCREF(argstring);
		re->re_lastok = argstring;
189
	}
190
	return PyInt_FromLong((long)result); /* Position of the match or -1 */
Guido van Rossum's avatar
Guido van Rossum committed
191 192
}

193 194 195 196 197
/* get the group from the regex where index can be a string (group name) or
   an integer index [0 .. 99]
 */
static PyObject*
group_from_index(re, index)
198
	regexobject *re;
199
	PyObject *index;
200 201
{
	int i, a, b;
202 203 204 205 206 207 208 209
	char *v;

	if (PyString_Check(index))
		if (re->re_groupindex == NULL ||
		    !(index = PyDict_GetItem(re->re_groupindex, index)))
		{
			PyErr_SetString(RegexError,
					"group() group name doesn't exist");
210
			return NULL;
211
		}
212 213 214 215 216

	i = PyInt_AsLong(index);
	if (i == -1 && PyErr_Occurred())
		return NULL;

217
	if (i < 0 || i >= RE_NREGS) {
218
		PyErr_SetString(RegexError, "group() index out of range");
219 220 221
		return NULL;
	}
	if (re->re_lastok == NULL) {
222
		PyErr_SetString(RegexError,
223
			   "group() only valid after successful match/search");
224 225 226 227 228
		return NULL;
	}
	a = re->re_regs.start[i];
	b = re->re_regs.end[i];
	if (a < 0 || b < 0) {
229 230
		Py_INCREF(Py_None);
		return Py_None;
231
	}
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
	
	if (!(v = PyString_AsString(re->re_lastok)))
		return NULL;

	return PyString_FromStringAndSize(v+a, b-a);
}


static PyObject *
regobj_group(re, args)
	regexobject *re;
	PyObject *args;
{
	int n = PyTuple_Size(args);
	int i;
	PyObject *res = NULL;

	if (n < 0)
		return NULL;
	if (n == 0) {
		PyErr_SetString(PyExc_TypeError, "not enough arguments");
		return NULL;
	}
	if (n == 1) {
		/* return value is a single string */
		PyObject *index = PyTuple_GetItem(args, 0);
		if (!index)
			return NULL;
		
		return group_from_index(re, index);
	}

	/* return value is a tuple */
	if (!(res = PyTuple_New(n)))
		return NULL;

	for (i = 0; i < n; i++) {
		PyObject *index = PyTuple_GetItem(args, i);
		PyObject *group = NULL;

		if (!index)
			goto finally;
		if (!(group = group_from_index(re, index)))
			goto finally;
		if (PyTuple_SetItem(res, i, group) < 0)
			goto finally;
	}
	return res;

  finally:
	Py_DECREF(res);
	return NULL;
284 285
}

286

287
static struct PyMethodDef reg_methods[] = {
288 289 290
	{"match",	(PyCFunction)regobj_match, 1},
	{"search",	(PyCFunction)regobj_search, 1},
	{"group",	(PyCFunction)regobj_group, 1},
Guido van Rossum's avatar
Guido van Rossum committed
291 292 293
	{NULL,		NULL}		/* sentinel */
};

294 295 296 297 298 299 300 301 302


static char* members[] = {
	"last", "regs", "translate",
	"groupindex", "realpat", "givenpat",
	NULL
};


303
static PyObject *
304
regobj_getattr(re, name)
Guido van Rossum's avatar
Guido van Rossum committed
305 306 307
	regexobject *re;
	char *name;
{
308
	if (strcmp(name, "regs") == 0) {
309
		if (re->re_lastok == NULL) {
310 311
			Py_INCREF(Py_None);
			return Py_None;
312 313 314
		}
		return makeresult(&re->re_regs);
	}
315 316
	if (strcmp(name, "last") == 0) {
		if (re->re_lastok == NULL) {
317 318
			Py_INCREF(Py_None);
			return Py_None;
319
		}
320
		Py_INCREF(re->re_lastok);
321 322
		return re->re_lastok;
	}
323 324
	if (strcmp(name, "translate") == 0) {
		if (re->re_translate == NULL) {
325 326
			Py_INCREF(Py_None);
			return Py_None;
327
		}
328
		Py_INCREF(re->re_translate);
329 330
		return re->re_translate;
	}
331 332
	if (strcmp(name, "groupindex") == 0) {
		if (re->re_groupindex == NULL) {
333 334
			Py_INCREF(Py_None);
			return Py_None;
335
		}
336
		Py_INCREF(re->re_groupindex);
337 338 339 340
		return re->re_groupindex;
	}
	if (strcmp(name, "realpat") == 0) {
		if (re->re_realpat == NULL) {
341 342
			Py_INCREF(Py_None);
			return Py_None;
343
		}
344
		Py_INCREF(re->re_realpat);
345 346 347 348
		return re->re_realpat;
	}
	if (strcmp(name, "givenpat") == 0) {
		if (re->re_givenpat == NULL) {
349 350
			Py_INCREF(Py_None);
			return Py_None;
351
		}
352
		Py_INCREF(re->re_givenpat);
353 354
		return re->re_givenpat;
	}
355
	if (strcmp(name, "__members__") == 0) {
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
		int i = 0;
		PyObject *list = NULL;

		/* okay, so it's unlikely this list will change that often.
		   still, it's easier to change it in just one place.
		 */
		while (members[i])
			i++;
		if (!(list = PyList_New(i)))
			return NULL;

		i = 0;
		while (members[i]) {
			PyObject* v = PyString_FromString(members[i]);
			if (!v || PyList_SetItem(list, i, v) < 0) {
371
				Py_DECREF(list);
372
				return NULL;
373
			}
374
			i++;
375 376 377
		}
		return list;
	}
378
	return Py_FindMethod(reg_methods, (PyObject *)re, name);
Guido van Rossum's avatar
Guido van Rossum committed
379 380
}

381 382
static PyTypeObject Regextype = {
	PyObject_HEAD_INIT(&PyType_Type)
383 384 385 386
	0,				     /*ob_size*/
	"regex",			     /*tp_name*/
	sizeof(regexobject),		     /*tp_size*/
	0,				     /*tp_itemsize*/
Guido van Rossum's avatar
Guido van Rossum committed
387
	/* methods */
388 389 390 391 392 393
	(destructor)reg_dealloc,	     /*tp_dealloc*/
	0,				     /*tp_print*/
	(getattrfunc)regobj_getattr,	     /*tp_getattr*/
	0,				     /*tp_setattr*/
	0,				     /*tp_compare*/
	0,				     /*tp_repr*/
Guido van Rossum's avatar
Guido van Rossum committed
394 395
};

396 397 398 399 400 401
/* reference counting invariants:
   pattern: borrowed
   translate: borrowed
   givenpat: borrowed
   groupindex: transferred
*/
402
static PyObject *
403
newregexobject(pattern, translate, givenpat, groupindex)
404 405 406 407
	PyObject *pattern;
	PyObject *translate;
	PyObject *givenpat;
	PyObject *groupindex;
Guido van Rossum's avatar
Guido van Rossum committed
408 409
{
	regexobject *re;
410 411
	char *pat;
	int size;
412

413
	if (!PyArg_Parse(pattern, "t#", &pat, &size))
414 415
		return NULL;
	
416 417
	if (translate != NULL && PyString_Size(translate) != 256) {
		PyErr_SetString(RegexError,
418
				"translation table must be 256 bytes");
419 420
		return NULL;
	}
421
	re = PyObject_NEW(regexobject, &Regextype);
Guido van Rossum's avatar
Guido van Rossum committed
422 423 424 425
	if (re != NULL) {
		char *error;
		re->re_patbuf.buffer = NULL;
		re->re_patbuf.allocated = 0;
426
		re->re_patbuf.fastmap = (unsigned char *)re->re_fastmap;
427
		if (translate) {
428
			re->re_patbuf.translate = (unsigned char *)PyString_AsString(translate);
429 430 431 432
			if (!re->re_patbuf.translate)
				goto finally;
			Py_INCREF(translate);
		}
433 434 435 436
		else
			re->re_patbuf.translate = NULL;
		re->re_translate = translate;
		re->re_lastok = NULL;
437
		re->re_groupindex = groupindex;
438
		Py_INCREF(pattern);
439
		re->re_realpat = pattern;
440
		Py_INCREF(givenpat);
441
		re->re_givenpat = givenpat;
442
		error = _Py_re_compile_pattern((unsigned char *)pat, size, &re->re_patbuf);
Guido van Rossum's avatar
Guido van Rossum committed
443
		if (error != NULL) {
444
			PyErr_SetString(RegexError, error);
445
			goto finally;
Guido van Rossum's avatar
Guido van Rossum committed
446 447
		}
	}
448
	return (PyObject *)re;
449 450 451
  finally:
	Py_DECREF(re);
	return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
452 453
}

454
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
455
regex_compile(self, args)
456 457
	PyObject *self;
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
458
{
459 460
	PyObject *pat = NULL;
	PyObject *tran = NULL;
461

462
	if (!PyArg_ParseTuple(args, "S|S:compile", &pat, &tran))
463
		return NULL;
464
	return newregexobject(pat, tran, pat, NULL);
Guido van Rossum's avatar
Guido van Rossum committed
465 466
}

467
static PyObject *
468
symcomp(pattern, gdict)
469 470
	PyObject *pattern;
	PyObject *gdict;
471
{
472
	char *opat, *oend, *o, *n, *g, *v;
473
	int group_count = 0;
474
	int sz;
475 476
	int escaped = 0;
	char name_buf[128];
477
	PyObject *npattern;
478 479
	int require_escape = re_syntax & RE_NO_BK_PARENS ? 0 : 1;

480 481 482 483 484 485 486 487 488
	if (!(opat = PyString_AsString(pattern)))
		return NULL;

	if ((sz = PyString_Size(pattern)) < 0)
		return NULL;

	oend = opat + sz;
	o = opat;

489
	if (oend == opat) {
490
		Py_INCREF(pattern);
491 492 493
		return pattern;
	}

494 495
	if (!(npattern = PyString_FromStringAndSize((char*)NULL, sz)) ||
	    !(n = PyString_AsString(npattern)))
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
		return NULL;

	while (o < oend) {
		if (*o == '(' && escaped == require_escape) {
			char *backtrack;
			escaped = 0;
			++group_count;
			*n++ = *o;
			if (++o >= oend || *o != '<')
				continue;
			/* *o == '<' */
			if (o+1 < oend && *(o+1) == '>')
				continue;
			backtrack = o;
			g = name_buf;
			for (++o; o < oend;) {
				if (*o == '>') {
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
				    PyObject *group_name = NULL;
				    PyObject *group_index = NULL;
				    *g++ = '\0';
				    group_name = PyString_FromString(name_buf);
				    group_index = PyInt_FromLong(group_count);
				    if (group_name == NULL ||
					group_index == NULL ||
					PyDict_SetItem(gdict, group_name,
						       group_index) != 0)
				    {
					    Py_XDECREF(group_name);
					    Py_XDECREF(group_index);
					    Py_XDECREF(npattern);
					    return NULL;
				    }
528 529
				    Py_DECREF(group_name);
				    Py_DECREF(group_index);
530 531
				    ++o;     /* eat the '>' */
				    break;
532
				}
Guido van Rossum's avatar
Guido van Rossum committed
533
				if (!isalnum(Py_CHARMASK(*o)) && *o != '_') {
534 535 536 537 538 539
					o = backtrack;
					break;
				}
				*g++ = *o++;
			}
		}
540
		else if (*o == '[' && !escaped) {
541
			*n++ = *o;
542
			++o;		     /* eat the char following '[' */
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
			*n++ = *o;
			while (o < oend && *o != ']') {
				++o;
				*n++ = *o;
			}
			if (o < oend)
				++o;
		}
		else if (*o == '\\') {
			escaped = 1;
			*n++ = *o;
			++o;
		}
		else {
			escaped = 0;
			*n++ = *o;
			++o;
		}
	}

563 564 565 566 567 568
	if (!(v = PyString_AsString(npattern))) {
		Py_DECREF(npattern);
		return NULL;
	}
	/* _PyString_Resize() decrements npattern on failure */
	if (_PyString_Resize(&npattern, n - v) == 0)
569 570 571 572 573 574 575
		return npattern;
	else {
		return NULL;
	}

}

576
static PyObject *
577
regex_symcomp(self, args)
578 579
	PyObject *self;
	PyObject *args;
580
{
581 582 583 584
	PyObject *pattern;
	PyObject *tran = NULL;
	PyObject *gdict = NULL;
	PyObject *npattern;
585
	PyObject *retval = NULL;
586

587
	if (!PyArg_ParseTuple(args, "S|S:symcomp", &pattern, &tran))
588 589
		return NULL;

590
	gdict = PyDict_New();
591
	if (gdict == NULL || (npattern = symcomp(pattern, gdict)) == NULL) {
592 593
		Py_DECREF(gdict);
		Py_DECREF(pattern);
594 595
		return NULL;
	}
596 597 598
	retval = newregexobject(npattern, tran, pattern, gdict);
	Py_DECREF(npattern);
	return retval;
599 600 601
}


602 603
static PyObject *cache_pat;
static PyObject *cache_prog;
Guido van Rossum's avatar
Guido van Rossum committed
604 605 606

static int
update_cache(pat)
607
	PyObject *pat;
Guido van Rossum's avatar
Guido van Rossum committed
608
{
609 610 611 612 613 614
	PyObject *tuple = Py_BuildValue("(O)", pat);
	int status = 0;

	if (!tuple)
		return -1;

Guido van Rossum's avatar
Guido van Rossum committed
615
	if (pat != cache_pat) {
616
		Py_XDECREF(cache_pat);
Guido van Rossum's avatar
Guido van Rossum committed
617
		cache_pat = NULL;
618
		Py_XDECREF(cache_prog);
619 620 621 622 623
		cache_prog = regex_compile((PyObject *)NULL, tuple);
		if (cache_prog == NULL) {
			status = -1;
			goto finally;
		}
Guido van Rossum's avatar
Guido van Rossum committed
624
		cache_pat = pat;
625
		Py_INCREF(cache_pat);
Guido van Rossum's avatar
Guido van Rossum committed
626
	}
627 628 629
  finally:
	Py_DECREF(tuple);
	return status;
Guido van Rossum's avatar
Guido van Rossum committed
630 631
}

632
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
633
regex_match(self, args)
634 635
	PyObject *self;
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
636
{
637
	PyObject *pat, *string;
638 639
	PyObject *tuple, *v;

640
	if (!PyArg_Parse(args, "(SS)", &pat, &string))
Guido van Rossum's avatar
Guido van Rossum committed
641 642 643
		return NULL;
	if (update_cache(pat) < 0)
		return NULL;
644 645 646 647 648 649

	if (!(tuple = Py_BuildValue("(S)", string)))
		return NULL;
	v = regobj_match((regexobject *)cache_prog, tuple);
	Py_DECREF(tuple);
	return v;
Guido van Rossum's avatar
Guido van Rossum committed
650 651
}

652
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
653
regex_search(self, args)
654 655
	PyObject *self;
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
656
{
657
	PyObject *pat, *string;
658 659
	PyObject *tuple, *v;

660
	if (!PyArg_Parse(args, "(SS)", &pat, &string))
Guido van Rossum's avatar
Guido van Rossum committed
661 662 663
		return NULL;
	if (update_cache(pat) < 0)
		return NULL;
664 665 666 667 668 669

	if (!(tuple = Py_BuildValue("(S)", string)))
		return NULL;
	v = regobj_search((regexobject *)cache_prog, tuple);
	Py_DECREF(tuple);
	return v;
Guido van Rossum's avatar
Guido van Rossum committed
670 671
}

672
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
673
regex_set_syntax(self, args)
674 675
	PyObject *self;
	PyObject *args;
Guido van Rossum's avatar
Guido van Rossum committed
676 677
{
	int syntax;
678
	if (!PyArg_Parse(args, "i", &syntax))
Guido van Rossum's avatar
Guido van Rossum committed
679 680
		return NULL;
	syntax = re_set_syntax(syntax);
681 682 683 684 685
	/* wipe the global pattern cache */
	Py_XDECREF(cache_pat);
	cache_pat = NULL;
	Py_XDECREF(cache_prog);
	cache_prog = NULL;
686
	return PyInt_FromLong((long)syntax);
Guido van Rossum's avatar
Guido van Rossum committed
687 688
}

689 690 691 692 693 694 695 696 697 698 699
static PyObject *
regex_get_syntax(self, args)
	PyObject *self;
	PyObject *args;
{
	if (!PyArg_Parse(args, ""))
		return NULL;
	return PyInt_FromLong((long)re_syntax);
}


700
static struct PyMethodDef regex_global_methods[] = {
701 702
	{"compile",	regex_compile, 1},
	{"symcomp",	regex_symcomp, 1},
703 704 705
	{"match",	regex_match, 0},
	{"search",	regex_search, 0},
	{"set_syntax",	regex_set_syntax, 0},
706
	{"get_syntax",  regex_get_syntax, 0},
707
	{NULL,		NULL}		     /* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
708 709
};

710
DL_EXPORT(void)
Guido van Rossum's avatar
Guido van Rossum committed
711 712
initregex()
{
713
	PyObject *m, *d, *v;
714 715
	int i;
	char *s;
Guido van Rossum's avatar
Guido van Rossum committed
716
	
717 718
	m = Py_InitModule("regex", regex_global_methods);
	d = PyModule_GetDict(m);
Guido van Rossum's avatar
Guido van Rossum committed
719 720
	
	/* Initialize regex.error exception */
721
	v = RegexError = PyErr_NewException("regex.error", NULL, NULL);
722 723 724
	if (v == NULL || PyDict_SetItemString(d, "error", v) != 0)
		goto finally;
	
725
	/* Initialize regex.casefold constant */
726 727 728 729 730 731 732 733 734 735 736
	if (!(v = PyString_FromStringAndSize((char *)NULL, 256)))
		goto finally;
	
	if (!(s = PyString_AsString(v)))
		goto finally;

	for (i = 0; i < 256; i++) {
		if (isupper(i))
			s[i] = tolower(i);
		else
			s[i] = i;
737
	}
738 739 740 741 742 743 744
	if (PyDict_SetItemString(d, "casefold", v) < 0)
		goto finally;
	Py_DECREF(v);

	if (!PyErr_Occurred())
		return;
  finally:
745
	/* Nothing */ ;
Guido van Rossum's avatar
Guido van Rossum committed
746
}