/* methods */ PyObject * sr_py_base_thread_distance(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *other; int dist_type = SR_DISTANCE_LEVENSHTEIN; static const char *kwlist[] = { "other", "dist_type", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i", (char **)kwlist, &sr_py_base_thread_type, &other, &dist_type)) return NULL; struct sr_py_base_thread *t1 = (struct sr_py_base_thread *)self; struct sr_py_base_thread *t2 = (struct sr_py_base_thread *)other; if (frames_prepare_linked_list(t1) < 0) return NULL; if (frames_prepare_linked_list(t2) < 0) return NULL; if (Py_TYPE(self) != Py_TYPE(other)) { PyErr_SetString(PyExc_TypeError, "Both threads must have the same type"); return NULL; } if (dist_type < 0 || dist_type >= SR_DISTANCE_NUM) { PyErr_SetString(PyExc_ValueError, "Invalid distance type"); return NULL; } float dist = sr_distance(dist_type, t1->thread, t2->thread); return PyFloat_FromDouble((double)dist); }
static bool prepare_thread_array(PyObject *thread_list, struct sr_thread *threads[], int n) { int i; PyTypeObject *thread_type = NULL; for (i = 0; i < n; i++) { PyObject *obj = PyList_GetItem(thread_list, i); if (!PyObject_TypeCheck(obj, &sr_py_base_thread_type)) { PyErr_SetString(PyExc_TypeError, "Must be a list of satyr.BaseThread objects"); return false; } /* check that the type is the same as in the previous thread */ if (thread_type && obj->ob_type != thread_type) { PyErr_SetString(PyExc_TypeError, "All threads in the list must have the same type"); return false; } thread_type = obj->ob_type; struct sr_py_base_thread *to = (struct sr_py_base_thread*)obj; if (frames_prepare_linked_list(to) < 0) return false; threads[i] = (struct sr_thread*)to->thread; } return true; }
PyObject * sr_py_base_thread_get_duphash(PyObject *self, PyObject *args, PyObject *kwds) { const char *prefix = NULL; int frames = 0, flags = 0; static const char *kwlist[] = { "frames", "flags", "prefix", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iis", (char **)kwlist, &frames, &flags, &prefix)) return NULL; struct sr_py_base_thread *this = (struct sr_py_base_thread *)self; if (frames_prepare_linked_list(this) < 0) return NULL; char *hash = sr_thread_get_duphash((struct sr_thread *)this->thread, frames, (char *)prefix, flags); if (!hash) { PyErr_SetString(PyExc_RuntimeError, "cannot obtain duphash"); return NULL; } PyObject *result = PyString_FromString(hash); free(hash); return result; }
/* comparison */ static int sr_py_base_thread_cmp(struct sr_py_base_thread *self, struct sr_py_base_thread *other) { if (Py_TYPE(self) != Py_TYPE(other)) { /* distinct types must be unequal */ return normalize_cmp(Py_TYPE(self) - Py_TYPE(other)); } if (frames_prepare_linked_list(self) < 0 || frames_prepare_linked_list(other) < 0) { /* exception is already set */ return -1; } return normalize_cmp(sr_thread_cmp(self->thread, other->thread)); }
/* methods */ PyObject * sr_py_core_thread_dup(PyObject *self, PyObject *args) { struct sr_py_core_thread *this = (struct sr_py_core_thread *)self; if (frames_prepare_linked_list((struct sr_py_base_thread *)this) < 0) return NULL; struct sr_py_core_thread *to = (struct sr_py_core_thread*) PyObject_New(struct sr_py_core_thread, &sr_py_core_thread_type); if (!to) return PyErr_NoMemory(); to->frame_type = &sr_py_core_frame_type; to->thread = sr_core_thread_dup(this->thread, false); if (!to->thread) return NULL; to->frames = frames_to_python_list((struct sr_thread *)to->thread, to->frame_type); return (PyObject *)to; }