regexmodule.c 15.2 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
*/

/***********************************************************
Guido van Rossum's avatar
Guido van Rossum committed
7 8 9 10
Copyright (c) 2000, BeOpen.com.
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
All rights reserved.
11

Guido van Rossum's avatar
Guido van Rossum committed
12 13
See the file "Misc/COPYRIGHT" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum's avatar
Guido van Rossum committed
14 15 16
******************************************************************/

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

20
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
21

Guido van Rossum's avatar
Guido van Rossum committed
22 23
#include <ctype.h>

24
#include "regexpr.h"
Guido van Rossum's avatar
Guido van Rossum committed
25

26
static PyObject *RegexError;	/* Exception */	
Guido van Rossum's avatar
Guido van Rossum committed
27 28

typedef struct {
29
	PyObject_HEAD
Guido van Rossum's avatar
Guido van Rossum committed
30 31 32
	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 */
33 34 35 36 37
	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
38 39 40 41 42
} regexobject;

/* Regex object methods */

static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
43
reg_dealloc(regexobject *re)
Guido van Rossum's avatar
Guido van Rossum committed
44
{
45
	if (re->re_patbuf.buffer)
46
		free(re->re_patbuf.buffer);
47 48 49 50 51
	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);
52
	PyObject_Del(re);
Guido van Rossum's avatar
Guido van Rossum committed
53 54
}

55
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
56
makeresult(struct re_registers *regs)
Guido van Rossum's avatar
Guido van Rossum committed
57
{
58 59 60
	PyObject *v;
	int i;
	static PyObject *filler = NULL;
61

62 63 64 65 66 67 68 69
	if (filler == NULL) {
		filler = Py_BuildValue("(ii)", -1, -1);
		if (filler == NULL)
			return NULL;
	}
	v = PyTuple_New(RE_NREGS);
	if (v == NULL)
		return NULL;
70

71 72 73 74 75 76 77 78 79 80
	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);
81 82
		if (w == NULL || PyTuple_SetItem(v, i, w) < 0) {
			Py_DECREF(v);
83
			return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
84 85 86 87 88
		}
	}
	return v;
}

89
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
90
regobj_match(regexobject *re, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
91
{
92
	PyObject *argstring;
Guido van Rossum's avatar
Guido van Rossum committed
93
	char *buffer;
94
	int size;
95
	int offset = 0;
Guido van Rossum's avatar
Guido van Rossum committed
96
	int result;
97

98
	if (!PyArg_ParseTuple(args, "O|i:match", &argstring, &offset))
99
		return NULL;
100
	if (!PyArg_Parse(argstring, "t#", &buffer, &size))
101 102
		return NULL;

103
	if (offset < 0 || offset > size) {
104
		PyErr_SetString(RegexError, "match offset out of range");
105 106
		return NULL;
	}
107
	Py_XDECREF(re->re_lastok);
108
	re->re_lastok = NULL;
109
	result = _Py_re_match(&re->re_patbuf, (unsigned char *)buffer, size, offset,
110
			      &re->re_regs);
Guido van Rossum's avatar
Guido van Rossum committed
111
	if (result < -1) {
Guido van Rossum's avatar
Guido van Rossum committed
112 113 114 115
		/* 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
116 117
		return NULL;
	}
118
	if (result >= 0) {
119 120
		Py_INCREF(argstring);
		re->re_lastok = argstring;
121
	}
122
	return PyInt_FromLong((long)result); /* Length of the match or -1 */
Guido van Rossum's avatar
Guido van Rossum committed
123
}
124

125
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
126
regobj_search(regexobject *re, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
127
{
128
	PyObject *argstring;
Guido van Rossum's avatar
Guido van Rossum committed
129 130
	char *buffer;
	int size;
131
	int offset = 0;
Guido van Rossum's avatar
Guido van Rossum committed
132 133
	int range;
	int result;
134
	
135
	if (!PyArg_ParseTuple(args, "O|i:search", &argstring, &offset))
136
		return NULL;
137
	if (!PyArg_Parse(argstring, "t#:search", &buffer, &size))
138 139
		return NULL;

140
	if (offset < 0 || offset > size) {
141
		PyErr_SetString(RegexError, "search offset out of range");
142
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
143
	}
144 145 146 147
	/* 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! */
148
	range = size - offset;
149
	Py_XDECREF(re->re_lastok);
150
	re->re_lastok = NULL;
151
	result = _Py_re_search(&re->re_patbuf, (unsigned char *)buffer, size, offset, range,
Guido van Rossum's avatar
Guido van Rossum committed
152 153
			   &re->re_regs);
	if (result < -1) {
Guido van Rossum's avatar
Guido van Rossum committed
154 155 156 157
		/* 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
158 159
		return NULL;
	}
160
	if (result >= 0) {
161 162
		Py_INCREF(argstring);
		re->re_lastok = argstring;
163
	}
164
	return PyInt_FromLong((long)result); /* Position of the match or -1 */
Guido van Rossum's avatar
Guido van Rossum committed
165 166
}

167 168 169 170
/* get the group from the regex where index can be a string (group name) or
   an integer index [0 .. 99]
 */
static PyObject*
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
171
group_from_index(regexobject *re, PyObject *index)
172 173
{
	int i, a, b;
174 175 176 177 178 179 180 181
	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");
182
			return NULL;
183
		}
184 185 186 187 188

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

189
	if (i < 0 || i >= RE_NREGS) {
190
		PyErr_SetString(RegexError, "group() index out of range");
191 192 193
		return NULL;
	}
	if (re->re_lastok == NULL) {
194
		PyErr_SetString(RegexError,
195
			   "group() only valid after successful match/search");
196 197 198 199 200
		return NULL;
	}
	a = re->re_regs.start[i];
	b = re->re_regs.end[i];
	if (a < 0 || b < 0) {
201 202
		Py_INCREF(Py_None);
		return Py_None;
203
	}
204 205 206 207 208 209 210 211 212
	
	if (!(v = PyString_AsString(re->re_lastok)))
		return NULL;

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


static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
213
regobj_group(regexobject *re, PyObject *args)
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
{
	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;
254 255
}

256

257
static struct PyMethodDef reg_methods[] = {
258 259 260
	{"match",	(PyCFunction)regobj_match, 1},
	{"search",	(PyCFunction)regobj_search, 1},
	{"group",	(PyCFunction)regobj_group, 1},
Guido van Rossum's avatar
Guido van Rossum committed
261 262 263
	{NULL,		NULL}		/* sentinel */
};

264 265 266 267 268 269 270 271 272

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


273
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
274
regobj_getattr(regexobject *re, char *name)
Guido van Rossum's avatar
Guido van Rossum committed
275
{
276
	if (strcmp(name, "regs") == 0) {
277
		if (re->re_lastok == NULL) {
278 279
			Py_INCREF(Py_None);
			return Py_None;
280 281 282
		}
		return makeresult(&re->re_regs);
	}
283 284
	if (strcmp(name, "last") == 0) {
		if (re->re_lastok == NULL) {
285 286
			Py_INCREF(Py_None);
			return Py_None;
287
		}
288
		Py_INCREF(re->re_lastok);
289 290
		return re->re_lastok;
	}
291 292
	if (strcmp(name, "translate") == 0) {
		if (re->re_translate == NULL) {
293 294
			Py_INCREF(Py_None);
			return Py_None;
295
		}
296
		Py_INCREF(re->re_translate);
297 298
		return re->re_translate;
	}
299 300
	if (strcmp(name, "groupindex") == 0) {
		if (re->re_groupindex == NULL) {
301 302
			Py_INCREF(Py_None);
			return Py_None;
303
		}
304
		Py_INCREF(re->re_groupindex);
305 306 307 308
		return re->re_groupindex;
	}
	if (strcmp(name, "realpat") == 0) {
		if (re->re_realpat == NULL) {
309 310
			Py_INCREF(Py_None);
			return Py_None;
311
		}
312
		Py_INCREF(re->re_realpat);
313 314 315 316
		return re->re_realpat;
	}
	if (strcmp(name, "givenpat") == 0) {
		if (re->re_givenpat == NULL) {
317 318
			Py_INCREF(Py_None);
			return Py_None;
319
		}
320
		Py_INCREF(re->re_givenpat);
321 322
		return re->re_givenpat;
	}
323
	if (strcmp(name, "__members__") == 0) {
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
		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) {
339
				Py_DECREF(list);
340
				return NULL;
341
			}
342
			i++;
343 344 345
		}
		return list;
	}
346
	return Py_FindMethod(reg_methods, (PyObject *)re, name);
Guido van Rossum's avatar
Guido van Rossum committed
347 348
}

349 350
static PyTypeObject Regextype = {
	PyObject_HEAD_INIT(&PyType_Type)
351 352 353 354
	0,				     /*ob_size*/
	"regex",			     /*tp_name*/
	sizeof(regexobject),		     /*tp_size*/
	0,				     /*tp_itemsize*/
Guido van Rossum's avatar
Guido van Rossum committed
355
	/* methods */
356 357 358 359 360 361
	(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
362 363
};

364 365 366 367 368 369
/* reference counting invariants:
   pattern: borrowed
   translate: borrowed
   givenpat: borrowed
   groupindex: transferred
*/
370
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
371
newregexobject(PyObject *pattern, PyObject *translate, PyObject *givenpat, PyObject *groupindex)
Guido van Rossum's avatar
Guido van Rossum committed
372 373
{
	regexobject *re;
374 375
	char *pat;
	int size;
376

377
	if (!PyArg_Parse(pattern, "t#", &pat, &size))
378 379
		return NULL;
	
380 381
	if (translate != NULL && PyString_Size(translate) != 256) {
		PyErr_SetString(RegexError,
382
				"translation table must be 256 bytes");
383 384
		return NULL;
	}
385
	re = PyObject_New(regexobject, &Regextype);
Guido van Rossum's avatar
Guido van Rossum committed
386 387 388 389
	if (re != NULL) {
		char *error;
		re->re_patbuf.buffer = NULL;
		re->re_patbuf.allocated = 0;
390
		re->re_patbuf.fastmap = (unsigned char *)re->re_fastmap;
391
		if (translate) {
392
			re->re_patbuf.translate = (unsigned char *)PyString_AsString(translate);
393 394 395 396
			if (!re->re_patbuf.translate)
				goto finally;
			Py_INCREF(translate);
		}
397 398 399 400
		else
			re->re_patbuf.translate = NULL;
		re->re_translate = translate;
		re->re_lastok = NULL;
401
		re->re_groupindex = groupindex;
402
		Py_INCREF(pattern);
403
		re->re_realpat = pattern;
404
		Py_INCREF(givenpat);
405
		re->re_givenpat = givenpat;
406
		error = _Py_re_compile_pattern((unsigned char *)pat, size, &re->re_patbuf);
Guido van Rossum's avatar
Guido van Rossum committed
407
		if (error != NULL) {
408
			PyErr_SetString(RegexError, error);
409
			goto finally;
Guido van Rossum's avatar
Guido van Rossum committed
410 411
		}
	}
412
	return (PyObject *)re;
413 414 415
  finally:
	Py_DECREF(re);
	return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
416 417
}

418
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
419
regex_compile(PyObject *self, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
420
{
421 422
	PyObject *pat = NULL;
	PyObject *tran = NULL;
423

424
	if (!PyArg_ParseTuple(args, "S|S:compile", &pat, &tran))
425
		return NULL;
426
	return newregexobject(pat, tran, pat, NULL);
Guido van Rossum's avatar
Guido van Rossum committed
427 428
}

429
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
430
symcomp(PyObject *pattern, PyObject *gdict)
431
{
432
	char *opat, *oend, *o, *n, *g, *v;
433
	int group_count = 0;
434
	int sz;
435 436
	int escaped = 0;
	char name_buf[128];
437
	PyObject *npattern;
438 439
	int require_escape = re_syntax & RE_NO_BK_PARENS ? 0 : 1;

440 441 442 443 444 445 446 447 448
	if (!(opat = PyString_AsString(pattern)))
		return NULL;

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

	oend = opat + sz;
	o = opat;

449
	if (oend == opat) {
450
		Py_INCREF(pattern);
451 452 453
		return pattern;
	}

454 455
	if (!(npattern = PyString_FromStringAndSize((char*)NULL, sz)) ||
	    !(n = PyString_AsString(npattern)))
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
		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 == '>') {
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
				    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;
				    }
488 489
				    Py_DECREF(group_name);
				    Py_DECREF(group_index);
490 491
				    ++o;     /* eat the '>' */
				    break;
492
				}
Guido van Rossum's avatar
Guido van Rossum committed
493
				if (!isalnum(Py_CHARMASK(*o)) && *o != '_') {
494 495 496 497 498 499
					o = backtrack;
					break;
				}
				*g++ = *o++;
			}
		}
500
		else if (*o == '[' && !escaped) {
501
			*n++ = *o;
502
			++o;		     /* eat the char following '[' */
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
			*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;
		}
	}

523 524 525 526 527 528
	if (!(v = PyString_AsString(npattern))) {
		Py_DECREF(npattern);
		return NULL;
	}
	/* _PyString_Resize() decrements npattern on failure */
	if (_PyString_Resize(&npattern, n - v) == 0)
529 530 531 532 533 534 535
		return npattern;
	else {
		return NULL;
	}

}

536
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
537
regex_symcomp(PyObject *self, PyObject *args)
538
{
539 540 541 542
	PyObject *pattern;
	PyObject *tran = NULL;
	PyObject *gdict = NULL;
	PyObject *npattern;
543
	PyObject *retval = NULL;
544

545
	if (!PyArg_ParseTuple(args, "S|S:symcomp", &pattern, &tran))
546 547
		return NULL;

548
	gdict = PyDict_New();
549
	if (gdict == NULL || (npattern = symcomp(pattern, gdict)) == NULL) {
550 551
		Py_DECREF(gdict);
		Py_DECREF(pattern);
552 553
		return NULL;
	}
554 555 556
	retval = newregexobject(npattern, tran, pattern, gdict);
	Py_DECREF(npattern);
	return retval;
557 558 559
}


560 561
static PyObject *cache_pat;
static PyObject *cache_prog;
Guido van Rossum's avatar
Guido van Rossum committed
562 563

static int
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
564
update_cache(PyObject *pat)
Guido van Rossum's avatar
Guido van Rossum committed
565
{
566 567 568 569 570 571
	PyObject *tuple = Py_BuildValue("(O)", pat);
	int status = 0;

	if (!tuple)
		return -1;

Guido van Rossum's avatar
Guido van Rossum committed
572
	if (pat != cache_pat) {
573
		Py_XDECREF(cache_pat);
Guido van Rossum's avatar
Guido van Rossum committed
574
		cache_pat = NULL;
575
		Py_XDECREF(cache_prog);
576 577 578 579 580
		cache_prog = regex_compile((PyObject *)NULL, tuple);
		if (cache_prog == NULL) {
			status = -1;
			goto finally;
		}
Guido van Rossum's avatar
Guido van Rossum committed
581
		cache_pat = pat;
582
		Py_INCREF(cache_pat);
Guido van Rossum's avatar
Guido van Rossum committed
583
	}
584 585 586
  finally:
	Py_DECREF(tuple);
	return status;
Guido van Rossum's avatar
Guido van Rossum committed
587 588
}

589
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
590
regex_match(PyObject *self, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
591
{
592
	PyObject *pat, *string;
593 594
	PyObject *tuple, *v;

595
	if (!PyArg_Parse(args, "(SS)", &pat, &string))
Guido van Rossum's avatar
Guido van Rossum committed
596 597 598
		return NULL;
	if (update_cache(pat) < 0)
		return NULL;
599 600 601 602 603 604

	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
605 606
}

607
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
608
regex_search(PyObject *self, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
609
{
610
	PyObject *pat, *string;
611 612
	PyObject *tuple, *v;

613
	if (!PyArg_Parse(args, "(SS)", &pat, &string))
Guido van Rossum's avatar
Guido van Rossum committed
614 615 616
		return NULL;
	if (update_cache(pat) < 0)
		return NULL;
617 618 619 620 621 622

	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
623 624
}

625
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
626
regex_set_syntax(PyObject *self, PyObject *args)
Guido van Rossum's avatar
Guido van Rossum committed
627 628
{
	int syntax;
629
	if (!PyArg_Parse(args, "i", &syntax))
Guido van Rossum's avatar
Guido van Rossum committed
630 631
		return NULL;
	syntax = re_set_syntax(syntax);
632 633 634 635 636
	/* wipe the global pattern cache */
	Py_XDECREF(cache_pat);
	cache_pat = NULL;
	Py_XDECREF(cache_prog);
	cache_prog = NULL;
637
	return PyInt_FromLong((long)syntax);
Guido van Rossum's avatar
Guido van Rossum committed
638 639
}

640
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
641
regex_get_syntax(PyObject *self, PyObject *args)
642 643 644 645 646 647 648
{
	if (!PyArg_Parse(args, ""))
		return NULL;
	return PyInt_FromLong((long)re_syntax);
}


649
static struct PyMethodDef regex_global_methods[] = {
650 651
	{"compile",	regex_compile, 1},
	{"symcomp",	regex_symcomp, 1},
652 653 654
	{"match",	regex_match, 0},
	{"search",	regex_search, 0},
	{"set_syntax",	regex_set_syntax, 0},
655
	{"get_syntax",  regex_get_syntax, 0},
656
	{NULL,		NULL}		     /* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
657 658
};

659
DL_EXPORT(void)
Guido van Rossum's avatar
Guido van Rossum committed
660 661
initregex()
{
662
	PyObject *m, *d, *v;
663 664
	int i;
	char *s;
Guido van Rossum's avatar
Guido van Rossum committed
665
	
666 667
	m = Py_InitModule("regex", regex_global_methods);
	d = PyModule_GetDict(m);
Guido van Rossum's avatar
Guido van Rossum committed
668 669
	
	/* Initialize regex.error exception */
670
	v = RegexError = PyErr_NewException("regex.error", NULL, NULL);
671 672 673
	if (v == NULL || PyDict_SetItemString(d, "error", v) != 0)
		goto finally;
	
674
	/* Initialize regex.casefold constant */
675 676 677 678 679 680 681 682 683 684 685
	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;
686
	}
687 688 689 690 691 692 693
	if (PyDict_SetItemString(d, "casefold", v) < 0)
		goto finally;
	Py_DECREF(v);

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