diff -r 07571d2968b0 Modules/_sre.c --- a/Modules/_sre.c Sun May 03 13:00:37 2015 -0400 +++ b/Modules/_sre.c Sun May 03 12:54:05 2015 -0700 @@ -269,6 +269,10 @@ [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0230ec19a0deac8]*/ +static PyTypeObject Pattern_Type; +static PyTypeObject Match_Type; +static PyTypeObject Scanner_Type; + /*[clinic input] _sre.getcodesize -> int [clinic start generated code]*/ @@ -1435,52 +1439,6 @@ return PyDictProxy_New(self->groupindex); } -static PyGetSetDef pattern_getset[] = { - {"groupindex", (getter)pattern_groupindex, (setter)NULL, - "A dictionary mapping group names to group numbers."}, - {NULL} /* Sentinel */ -}; - -#define PAT_OFF(x) offsetof(PatternObject, x) -static PyMemberDef pattern_members[] = { - {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY}, - {"flags", T_INT, PAT_OFF(flags), READONLY}, - {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_" SRE_MODULE ".SRE_Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)pattern_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ - pattern_getset, /* tp_getset */ -}; - static int _validate(PatternObject *self); /* Forward */ /*[clinic input] @@ -2469,8 +2427,6 @@ Return subgroup(s) of the match by indices or names.\n\ For 0 returns the entire match."); -static PyMethodDef match_methods[]; - static PyObject * match_lastindex_get(MatchObject *self) { @@ -2521,6 +2477,246 @@ } +static PyObject* +pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) +{ + /* create match object (from state object) */ + + MatchObject* match; + Py_ssize_t i, j; + char* base; + int n; + + if (status > 0) { + + /* create match object (with room for extra group marks) */ + /* coverity[ampersand_in_size] */ + match = PyObject_NEW_VAR(MatchObject, &Match_Type, + 2*(pattern->groups+1)); + if (!match) + return NULL; + + Py_INCREF(pattern); + match->pattern = pattern; + + Py_INCREF(state->string); + match->string = state->string; + + match->regs = NULL; + match->groups = pattern->groups+1; + + /* fill in group slices */ + + base = (char*) state->beginning; + n = state->charsize; + + match->mark[0] = ((char*) state->start - base) / n; + match->mark[1] = ((char*) state->ptr - base) / n; + + for (i = j = 0; i < pattern->groups; i++, j+=2) + if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { + match->mark[j+2] = ((char*) state->mark[j] - base) / n; + match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; + } else + match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ + + match->pos = state->pos; + match->endpos = state->endpos; + + match->lastindex = state->lastindex; + + return (PyObject*) match; + + } else if (status == 0) { + + /* no match */ + Py_INCREF(Py_None); + return Py_None; + + } + + /* internal error */ + pattern_error(status); + return NULL; +} + + +/* -------------------------------------------------------------------- */ +/* scanner methods (experimental) */ + +static void +scanner_dealloc(ScannerObject* self) +{ + state_fini(&self->state); + Py_XDECREF(self->pattern); + PyObject_DEL(self); +} + +/*[clinic input] +_sre.SRE_Scanner.match + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Scanner_match_impl(ScannerObject *self) +/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ +{ + SRE_STATE* state = &self->state; + PyObject* match; + Py_ssize_t status; + + state_reset(state); + + state->ptr = state->start; + + status = sre_match(state, PatternObject_GetCode(self->pattern), 0); + if (PyErr_Occurred()) + return NULL; + + match = pattern_new_match((PatternObject*) self->pattern, + state, status); + + if (status == 0 || state->ptr == state->start) + state->start = (void*) ((char*) state->ptr + state->charsize); + else + state->start = state->ptr; + + return match; +} + + +/*[clinic input] +_sre.SRE_Scanner.search + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Scanner_search_impl(ScannerObject *self) +/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ +{ + SRE_STATE* state = &self->state; + PyObject* match; + Py_ssize_t status; + + state_reset(state); + + state->ptr = state->start; + + status = sre_search(state, PatternObject_GetCode(self->pattern)); + if (PyErr_Occurred()) + return NULL; + + match = pattern_new_match((PatternObject*) self->pattern, + state, status); + + if (status == 0 || state->ptr == state->start) + state->start = (void*) ((char*) state->ptr + state->charsize); + else + state->start = state->ptr; + + return match; +} + +static PyObject * +pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) +{ + ScannerObject* scanner; + + /* create scanner object */ + scanner = PyObject_NEW(ScannerObject, &Scanner_Type); + if (!scanner) + return NULL; + scanner->pattern = NULL; + + /* create search state object */ + if (!state_init(&scanner->state, self, string, pos, endpos)) { + Py_DECREF(scanner); + return NULL; + } + + Py_INCREF(self); + scanner->pattern = (PyObject*) self; + + return (PyObject*) scanner; +} + +#include "clinic/_sre.c.h" + +static PyMethodDef pattern_methods[] = { + _SRE_SRE_PATTERN_MATCH_METHODDEF + _SRE_SRE_PATTERN_FULLMATCH_METHODDEF + _SRE_SRE_PATTERN_SEARCH_METHODDEF + _SRE_SRE_PATTERN_SUB_METHODDEF + _SRE_SRE_PATTERN_SUBN_METHODDEF + _SRE_SRE_PATTERN_FINDALL_METHODDEF + _SRE_SRE_PATTERN_SPLIT_METHODDEF + _SRE_SRE_PATTERN_FINDITER_METHODDEF + _SRE_SRE_PATTERN_SCANNER_METHODDEF + _SRE_SRE_PATTERN___COPY___METHODDEF + _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF + {NULL, NULL} +}; + +static PyGetSetDef pattern_getset[] = { + {"groupindex", (getter)pattern_groupindex, (setter)NULL, + "A dictionary mapping group names to group numbers."}, + {NULL} /* Sentinel */ +}; + +#define PAT_OFF(x) offsetof(PatternObject, x) +static PyMemberDef pattern_members[] = { + {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY}, + {"flags", T_INT, PAT_OFF(flags), READONLY}, + {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject Pattern_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_" SRE_MODULE ".SRE_Pattern", + sizeof(PatternObject), sizeof(SRE_CODE), + (destructor)pattern_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)pattern_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + pattern_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pattern_methods, /* tp_methods */ + pattern_members, /* tp_members */ + pattern_getset, /* tp_getset */ +}; + + +static PyMethodDef match_methods[] = { + {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, + _SRE_SRE_MATCH_START_METHODDEF + _SRE_SRE_MATCH_END_METHODDEF + _SRE_SRE_MATCH_SPAN_METHODDEF + _SRE_SRE_MATCH_GROUPS_METHODDEF + _SRE_SRE_MATCH_GROUPDICT_METHODDEF + _SRE_SRE_MATCH_EXPAND_METHODDEF + _SRE_SRE_MATCH___COPY___METHODDEF + _SRE_SRE_MATCH___DEEPCOPY___METHODDEF + {NULL, NULL} +}; + static PyGetSetDef match_getset[] = { {"lastindex", (getter)match_lastindex_get, (setter)NULL}, {"lastgroup", (getter)match_lastgroup_get, (setter)NULL}, @@ -2572,147 +2768,11 @@ match_getset, /* tp_getset */ }; -static PyObject* -pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) -{ - /* create match object (from state object) */ - - MatchObject* match; - Py_ssize_t i, j; - char* base; - int n; - - if (status > 0) { - - /* create match object (with room for extra group marks) */ - /* coverity[ampersand_in_size] */ - match = PyObject_NEW_VAR(MatchObject, &Match_Type, - 2*(pattern->groups+1)); - if (!match) - return NULL; - - Py_INCREF(pattern); - match->pattern = pattern; - - Py_INCREF(state->string); - match->string = state->string; - - match->regs = NULL; - match->groups = pattern->groups+1; - - /* fill in group slices */ - - base = (char*) state->beginning; - n = state->charsize; - - match->mark[0] = ((char*) state->start - base) / n; - match->mark[1] = ((char*) state->ptr - base) / n; - - for (i = j = 0; i < pattern->groups; i++, j+=2) - if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { - match->mark[j+2] = ((char*) state->mark[j] - base) / n; - match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; - } else - match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ - - match->pos = state->pos; - match->endpos = state->endpos; - - match->lastindex = state->lastindex; - - return (PyObject*) match; - - } else if (status == 0) { - - /* no match */ - Py_INCREF(Py_None); - return Py_None; - - } - - /* internal error */ - pattern_error(status); - return NULL; -} - - -/* -------------------------------------------------------------------- */ -/* scanner methods (experimental) */ - -static void -scanner_dealloc(ScannerObject* self) -{ - state_fini(&self->state); - Py_XDECREF(self->pattern); - PyObject_DEL(self); -} - -/*[clinic input] -_sre.SRE_Scanner.match - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self) -/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ -{ - SRE_STATE* state = &self->state; - PyObject* match; - Py_ssize_t status; - - state_reset(state); - - state->ptr = state->start; - - status = sre_match(state, PatternObject_GetCode(self->pattern), 0); - if (PyErr_Occurred()) - return NULL; - - match = pattern_new_match((PatternObject*) self->pattern, - state, status); - - if (status == 0 || state->ptr == state->start) - state->start = (void*) ((char*) state->ptr + state->charsize); - else - state->start = state->ptr; - - return match; -} - - -/*[clinic input] -_sre.SRE_Scanner.search - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self) -/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ -{ - SRE_STATE* state = &self->state; - PyObject* match; - Py_ssize_t status; - - state_reset(state); - - state->ptr = state->start; - - status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) - return NULL; - - match = pattern_new_match((PatternObject*) self->pattern, - state, status); - - if (status == 0 || state->ptr == state->start) - state->start = (void*) ((char*) state->ptr + state->charsize); - else - state->start = state->ptr; - - return match; -} - -static PyMethodDef scanner_methods[]; +static PyMethodDef scanner_methods[] = { + _SRE_SRE_SCANNER_MATCH_METHODDEF + _SRE_SRE_SCANNER_SEARCH_METHODDEF + {NULL, NULL} +}; #define SCAN_OFF(x) offsetof(ScannerObject, x) static PyMemberDef scanner_members[] = { @@ -2752,65 +2812,6 @@ 0, /* tp_getset */ }; -static PyObject * -pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) -{ - ScannerObject* scanner; - - /* create scanner object */ - scanner = PyObject_NEW(ScannerObject, &Scanner_Type); - if (!scanner) - return NULL; - scanner->pattern = NULL; - - /* create search state object */ - if (!state_init(&scanner->state, self, string, pos, endpos)) { - Py_DECREF(scanner); - return NULL; - } - - Py_INCREF(self); - scanner->pattern = (PyObject*) self; - - return (PyObject*) scanner; -} - -#include "clinic/_sre.c.h" - -static PyMethodDef pattern_methods[] = { - _SRE_SRE_PATTERN_MATCH_METHODDEF - _SRE_SRE_PATTERN_FULLMATCH_METHODDEF - _SRE_SRE_PATTERN_SEARCH_METHODDEF - _SRE_SRE_PATTERN_SUB_METHODDEF - _SRE_SRE_PATTERN_SUBN_METHODDEF - _SRE_SRE_PATTERN_FINDALL_METHODDEF - _SRE_SRE_PATTERN_SPLIT_METHODDEF - _SRE_SRE_PATTERN_FINDITER_METHODDEF - _SRE_SRE_PATTERN_SCANNER_METHODDEF - _SRE_SRE_PATTERN___COPY___METHODDEF - _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF - {NULL, NULL} -}; - -static PyMethodDef match_methods[] = { - {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, - _SRE_SRE_MATCH_START_METHODDEF - _SRE_SRE_MATCH_END_METHODDEF - _SRE_SRE_MATCH_SPAN_METHODDEF - _SRE_SRE_MATCH_GROUPS_METHODDEF - _SRE_SRE_MATCH_GROUPDICT_METHODDEF - _SRE_SRE_MATCH_EXPAND_METHODDEF - _SRE_SRE_MATCH___COPY___METHODDEF - _SRE_SRE_MATCH___DEEPCOPY___METHODDEF - {NULL, NULL} -}; - -static PyMethodDef scanner_methods[] = { - _SRE_SRE_SCANNER_MATCH_METHODDEF - _SRE_SRE_SCANNER_SEARCH_METHODDEF - {NULL, NULL} -}; - static PyMethodDef _functions[] = { _SRE_COMPILE_METHODDEF _SRE_GETCODESIZE_METHODDEF