--- tre-python.c 2009-09-19 07:38:42.000000000 -0700 +++ /home/ben/Downloads/tre-python.c 2018-03-15 23:32:07.540064053 -0700 @@ -86,9 +86,9 @@ TreFuzzynessObject *self = (TreFuzzynessObject*)obj; PyObject *o; - o = PyString_FromFormat("%s(delcost=%d,inscost=%d,maxcost=%d,subcost=%d," + o = PyUnicode_FromFormat("%s(delcost=%d,inscost=%d,maxcost=%d,subcost=%d," "maxdel=%d,maxerr=%d,maxins=%d,maxsub=%d)", - self->ob_type->tp_name, self->ap.cost_del, + Py_TYPE(self)->tp_name, self->ap.cost_del, self->ap.cost_ins, self->ap.max_cost, self->ap.cost_subst, self->ap.max_del, self->ap.max_err, self->ap.max_ins, @@ -118,8 +118,7 @@ }; static PyTypeObject TreFuzzynessType = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(NULL, 0) TRE_MODULE ".Fuzzyness", /* tp_name */ sizeof(TreFuzzynessObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -193,7 +192,7 @@ } static PyObject * -PyTreMatch_groupi(PyObject *obj, int gn) +PyTreMatch_groupi(PyObject *obj, Py_ssize_t gn) { TreMatchObject *self = (TreMatchObject*)obj; PyObject *result; @@ -220,7 +219,7 @@ PyObject *result; long gn; - gn = PyInt_AsLong(grpno); + gn = PyLong_AsLong(grpno); if (PyErr_Occurred()) return NULL; @@ -277,8 +276,7 @@ }; static PyTypeObject TreMatchType = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(NULL, 0) TRE_MODULE ".Match", /* tp_name */ sizeof(TreMatchObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -337,9 +335,18 @@ char *targ; size_t tlen; - if (!PyArg_ParseTuple(args, "SO!|i:match", &pstring, &TreFuzzynessType, + if (PyTuple_Size(args) > 0 && PyUnicode_Check(PyTuple_GetItem(args, 0))) + { + if (!PyArg_ParseTuple(args, "UO!|i:search", &pstring, &TreFuzzynessType, &fz, &eflags)) - return NULL; + return NULL; + } + else + { + if (!PyArg_ParseTuple(args, "SO!|i:search", &pstring, &TreFuzzynessType, + &fz, &eflags)) + return NULL; + } mo = newTreMatchObject(); if (mo == NULL) @@ -347,22 +354,35 @@ nsub = self->rgx.re_nsub + 1; pm = PyMem_New(regmatch_t, nsub); - if (pm != NULL) - { - mo->am.nmatch = nsub; - mo->am.pmatch = pm; - } - else + if (!pm) { - /* XXX */ Py_DECREF(mo); - return NULL; + return PyErr_NoMemory(); } - targ = PyString_AsString(pstring); - tlen = PyString_Size(pstring); + mo->am.nmatch = nsub; + mo->am.pmatch = pm; - rc = tre_reganexec(&self->rgx, targ, tlen, &mo->am, fz->ap, eflags); + if (PyUnicode_Check(pstring)) + { + Py_ssize_t len = PyUnicode_GetSize(pstring); + wchar_t *buf = calloc(sizeof(wchar_t), len); + if(!buf) + { + Py_DECREF(mo); + return PyErr_NoMemory(); + } + PyUnicode_AsWideChar(pstring, buf, len); + rc = tre_regawnexec(&self->rgx, buf, len, &mo->am, fz->ap, eflags); + free(buf); + } + else + { + targ = PyBytes_AsString(pstring); + tlen = PyBytes_Size(pstring); + + rc = tre_reganexec(&self->rgx, targ, tlen, &mo->am, fz->ap, eflags); + } if (PyErr_Occurred()) { @@ -392,7 +412,7 @@ static PyMethodDef TrePattern_methods[] = { { "search", (PyCFunction)PyTrePattern_search, METH_VARARGS, - "try to match against given string, returning " TRE_MODULE ".match object " + "try to search in the given string, returning " TRE_MODULE ".match object " "or None on failure" }, {NULL, NULL} }; @@ -411,8 +431,7 @@ } static PyTypeObject TrePatternType = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(NULL, 0) TRE_MODULE ".Pattern", /* tp_name */ sizeof(TrePatternObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -445,7 +464,7 @@ }; static TrePatternObject * -newTrePatternObject(PyObject *args) +newTrePatternObject(void) { TrePatternObject *self; @@ -460,19 +479,43 @@ PyTre_ncompile(PyObject *self, PyObject *args) { TrePatternObject *rv; - char *pattern; + PyObject *upattern = NULL; + char *pattern = NULL; int pattlen; int cflags = 0; int rc; - if (!PyArg_ParseTuple(args, "s#|i:compile", &pattern, &pattlen, &cflags)) - return NULL; + if (PyTuple_Size(args) > 0 && PyUnicode_Check(PyTuple_GetItem(args, 0))) + { + if (!PyArg_ParseTuple(args, "U|i:compile", &upattern, &cflags)) + return NULL; + } + else + { + if (!PyArg_ParseTuple(args, "s#|i:compile", &pattern, &pattlen, &cflags)) + return NULL; + } - rv = newTrePatternObject(args); + rv = newTrePatternObject(); if (rv == NULL) return NULL; - rc = tre_regncomp(&rv->rgx, (char*)pattern, pattlen, cflags); + if (upattern != NULL) + { + Py_ssize_t len = PyUnicode_GetSize(upattern); + wchar_t *buf = calloc(sizeof(wchar_t), len); + if(!buf) + { + Py_DECREF(rv); + return PyErr_NoMemory(); + } + PyUnicode_AsWideChar(upattern, buf, len); + rc = tre_regwncomp(&rv->rgx, buf, len, cflags); + free(buf); + } + else + rc = tre_regncomp(&rv->rgx, (char*)pattern, pattlen, cflags); + if (rc != REG_OK) { if (!PyErr_Occurred()) @@ -491,9 +534,8 @@ { NULL, NULL } }; -static char *tre_doc = -"Python module for TRE library\n\nModule exports " -"the only function: compile"; + +#define tre_doc "Python module for TRE library\n\nModule exports the only function: compile" static struct _tre_flags { char *name; @@ -510,40 +552,57 @@ { NULL, 0 } }; + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + TRE_MODULE ".Module", /* m_name */ + tre_doc, /* m_doc */ + -1, /* m_size */ + tre_methods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + + PyMODINIT_FUNC -inittre(void) +PyInit_tre(void) { PyObject *m; struct _tre_flags *fp; if (PyType_Ready(&TreFuzzynessType) < 0) - return; + return NULL; if (PyType_Ready(&TreMatchType) < 0) - return; + return NULL; if (PyType_Ready(&TrePatternType) < 0) - return; + return NULL; /* Create the module and add the functions */ - m = Py_InitModule3(TRE_MODULE, tre_methods, tre_doc); + + m = PyModule_Create (&moduledef); + if (m == NULL) - return; + return NULL; Py_INCREF(&TreFuzzynessType); if (PyModule_AddObject(m, "Fuzzyness", (PyObject*)&TreFuzzynessType) < 0) - return; + return NULL; Py_INCREF(&TreMatchType); if (PyModule_AddObject(m, "Match", (PyObject*)&TreMatchType) < 0) - return; + return NULL; Py_INCREF(&TrePatternType); if (PyModule_AddObject(m, "Pattern", (PyObject*)&TrePatternType) < 0) - return; + return NULL; ErrorObject = PyErr_NewException(TRE_MODULE ".Error", NULL, NULL); Py_INCREF(ErrorObject); if (PyModule_AddObject(m, "Error", ErrorObject) < 0) - return; + return NULL; /* Insert the flags */ for (fp = tre_flags; fp->name != NULL; fp++) if (PyModule_AddIntConstant(m, fp->name, fp->val) < 0) - return; + return NULL; + return m; }