diff --git a/Modules/_sre.c b/Modules/_sre.c index 308b7260b57..3e2d9070bb3 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -28,6 +28,8 @@ * 2001-01-16 fl fixed memory leak in pattern destructor * 2001-03-20 fl lots of fixes for 2.1b2 * 2001-04-15 fl export copyright as Python attribute, not global + * 2001-04-28 fl added __copy__ methods (work in progress) + * 2001-05-14 fl fixes for 1.5.2 * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * @@ -43,9 +45,10 @@ #ifndef SRE_RECURSIVE static char copyright[] = - " SRE 2.1b2 Copyright (c) 1997-2001 by Secret Labs AB "; + " SRE 2.1.1 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" +#include "structmember.h" /* offsetof */ #include "sre.h" @@ -86,6 +89,9 @@ static char copyright[] = /* enables aggressive inlining (always on for Visual C) */ #undef USE_INLINE +/* enables copy/deepcopy handling (work in progress) */ +#undef USE_BUILTIN_COPY + #if PY_VERSION_HEX < 0x01060000 #define PyObject_DEL(op) PyMem_DEL((op)) #endif @@ -444,6 +450,7 @@ SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at) SRE_LOC_IS_WORD((int) ptr[0]) : 0; return this == that; +#if defined(HAVE_UNICODE) case SRE_AT_UNI_BOUNDARY: if (state->beginning == state->end) return 0; @@ -461,6 +468,8 @@ SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at) this = ((void*) ptr < state->end) ? SRE_UNI_IS_WORD((int) ptr[0]) : 0; return this == that; +#endif + } return 0; @@ -1286,6 +1295,8 @@ _compile(PyObject* self_, PyObject* args) if (!self) return NULL; + self->codesize = n; + for (i = 0; i < n; i++) { PyObject *o = PyList_GET_ITEM(code, i); self->code[i] = (SRE_CODE) PyInt_AsLong(o); @@ -1844,6 +1855,42 @@ error: } +static PyObject* +pattern_copy(PatternObject* self, PyObject* args) +{ +#if USE_BUILTIN_COPY + PatternObject* copy; + int offset; + + /* work in progress */ + + copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize); + if (!copy) + return NULL; + + offset = offsetof(PatternObject, groups); + + Py_XINCREF(self->groupindex); + Py_XINCREF(self->indexgroup); + Py_XINCREF(self->pattern); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset); + + return (PyObject*) copy; +#else + PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object"); + return NULL; +#endif +} + +static PyObject* +pattern_deepcopy(PatternObject* self, PyObject* args) +{ + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object"); + return NULL; +} + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS}, @@ -1851,8 +1898,9 @@ static PyMethodDef pattern_methods[] = { {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS}, {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, - /* experimental */ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, + {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, {NULL, NULL} }; @@ -2211,6 +2259,46 @@ match_regs(MatchObject* self) return regs; } +static PyObject* +match_copy(MatchObject* self, PyObject* args) +{ +#if USE_BUILTIN_COPY + MatchObject* copy; + int slots, offset; + + /* works in progress */ + + slots = 2 * (self->pattern->groups+1); + + copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots); + if (!copy) + return NULL; + + /* this value a constant, but any compiler should be able to + figure that out all by itself */ + offset = offsetof(MatchObject, string); + + Py_XINCREF(self->pattern); + Py_XINCREF(self->string); + Py_XINCREF(self->regs); + + memcpy((char*) copy + offset, (char*) self + offset, + sizeof(MatchObject) + slots * sizeof(int) - offset); + + return (PyObject*) copy; +#else + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); + return NULL; +#endif +} + +static PyObject* +match_deepcopy(MatchObject* self, PyObject* args) +{ + PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object"); + return NULL; +} + static PyMethodDef match_methods[] = { {"group", (PyCFunction) match_group, METH_VARARGS}, {"start", (PyCFunction) match_start, METH_VARARGS}, @@ -2219,6 +2307,8 @@ static PyMethodDef match_methods[] = { {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS}, {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS}, {"expand", (PyCFunction) match_expand, METH_VARARGS}, + {"__copy__", (PyCFunction) match_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction) match_deepcopy, METH_VARARGS}, {NULL, NULL} }; diff --git a/Modules/sre.h b/Modules/sre.h index 632f47efcae..365eedbac48 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -3,7 +3,7 @@ * * regular expression matching engine * - * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. */ @@ -21,15 +21,18 @@ #define SRE_CODE unsigned short #endif +#define SRE_CODE unsigned short + typedef struct { PyObject_VAR_HEAD - int groups; + int groups; /* must be first! */ PyObject* groupindex; PyObject* indexgroup; /* compatibility */ PyObject* pattern; /* pattern source (or None) */ int flags; /* flags used when compiling pattern source */ /* pattern code */ + int codesize; SRE_CODE code[1]; } PatternObject; @@ -37,7 +40,7 @@ typedef struct { typedef struct { PyObject_VAR_HEAD - PyObject* string; /* link to the target string */ + PyObject* string; /* link to the target string (must be first) */ PyObject* regs; /* cached list of matching spans */ PatternObject* pattern; /* link to the regex (pattern) object */ int pos, endpos; /* current target slice */