Fixed memory leaks.

Used PyObject on attr functions.
Code style update.
Reviewer: Hugo Parente Lima <hugo.lima@openbossa.org>,
          Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
Renato Filho 2010-05-17 13:56:53 -03:00
commit 005aeaf829
5 changed files with 149 additions and 138 deletions

View file

@ -89,7 +89,7 @@ QByteArray MethodData::type() const
return m_type; return m_type;
} }
DynamicQMetaObject::DynamicQMetaObject(const char *className, const QMetaObject* metaObject) DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject)
{ {
d.superdata = metaObject; d.superdata = metaObject;
d.stringdata = 0; d.stringdata = 0;
@ -105,7 +105,7 @@ DynamicQMetaObject::~DynamicQMetaObject()
delete[] d.data; delete[] d.data;
} }
void DynamicQMetaObject::addSignal(const char *signal, const char *type) void DynamicQMetaObject::addSignal(const char* signal, const char* type)
{ {
//search for a empty space //search for a empty space
MethodData blank; MethodData blank;
@ -125,7 +125,7 @@ void DynamicQMetaObject::addSignal(const char *signal, const char *type)
updateMetaObject(); updateMetaObject();
} }
void DynamicQMetaObject::addSlot(const char *slot, const char *type) void DynamicQMetaObject::addSlot(const char* slot, const char* type)
{ {
//search for a empty space //search for a empty space
MethodData blank; MethodData blank;
@ -150,13 +150,14 @@ void DynamicQMetaObject::removeSlot(uint index)
} }
} }
DynamicQMetaObject* DynamicQMetaObject::createBasedOn(PyObject *pyObj, PyTypeObject *type, const QMetaObject *base) DynamicQMetaObject* DynamicQMetaObject::createBasedOn(PyObject* pyObj, PyTypeObject* type, const QMetaObject* base)
{ {
PyObject *key, *value; PyObject* key;
PyObject* value;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
QString className(type->tp_name); QString className(type->tp_name);
className = className.mid(className.lastIndexOf(".")+1); className = className.mid(className.lastIndexOf('.')+1);
DynamicQMetaObject *mo = new PySide::DynamicQMetaObject(className.toAscii(), base); DynamicQMetaObject *mo = new PySide::DynamicQMetaObject(className.toAscii(), base);
while (PyDict_Next(type->tp_dict, &pos, &key, &value)) { while (PyDict_Next(type->tp_dict, &pos, &key, &value)) {
@ -180,7 +181,7 @@ DynamicQMetaObject* DynamicQMetaObject::createBasedOn(PyObject *pyObj, PyTypeObj
//Register Slots //Register Slots
if (PyObject_HasAttrString(value, PYSIDE_SLOT_LIST_ATTR)) { if (PyObject_HasAttrString(value, PYSIDE_SLOT_LIST_ATTR)) {
PyObject *signature_list = PyObject_GetAttrString(value, PYSIDE_SLOT_LIST_ATTR); PyObject *signature_list = PyObject_GetAttrString(value, PYSIDE_SLOT_LIST_ATTR);
for(Py_ssize_t i=0, i_max=PyList_Size(signature_list); i < i_max; i++) { for(Py_ssize_t i = 0, i_max = PyList_Size(signature_list); i < i_max; i++) {
PyObject *signature = PyList_GET_ITEM(signature_list, i); PyObject *signature = PyList_GET_ITEM(signature_list, i);
QString sig(PyString_AsString(signature)); QString sig(PyString_AsString(signature));
//slot the slot type and signature //slot the slot type and signature

View file

@ -50,17 +50,17 @@ namespace PySide
class MethodData class MethodData
{ {
public: public:
MethodData(){} MethodData(){}
MethodData(const char *signature, const char *type); MethodData(const char *signature, const char *type);
void clear(); void clear();
QByteArray signature() const; QByteArray signature() const;
QByteArray type() const; QByteArray type() const;
bool operator==(const MethodData &other) const; bool operator==(const MethodData &other) const;
private: private:
QByteArray m_signature; QByteArray m_signature;
QByteArray m_type; QByteArray m_type;
}; };
class PYSIDE_API DynamicQMetaObject : public QMetaObject class PYSIDE_API DynamicQMetaObject : public QMetaObject
@ -76,7 +76,7 @@ public:
void removeSlot(uint index); void removeSlot(uint index);
//Retrieve Python metadata to create QMetaObject (class name, signals, slot) //Retrieve Python metadata to create QMetaObject (class name, signals, slot)
static DynamicQMetaObject *createBasedOn(PyObject *obj, PyTypeObject *type, const QMetaObject* base); static DynamicQMetaObject* createBasedOn(PyObject* obj, PyTypeObject* type, const QMetaObject* base);
private: private:
QLinkedList<MethodData> m_signals; QLinkedList<MethodData> m_signals;

View file

@ -1,5 +1,3 @@
#define protected public
#include <shiboken.h> #include <shiboken.h>
#include <Python.h> #include <Python.h>
#include <QDebug> #include <QDebug>
@ -18,9 +16,9 @@ extern "C"
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
bool initialized; bool initialized;
char *signal_name; char* signalName;
char **signatures; char** signatures;
int signatures_size; int signaturesSize;
} SignalData; } SignalData;
static int signal_init(PyObject*, PyObject*, PyObject*); static int signal_init(PyObject*, PyObject*, PyObject*);
@ -28,17 +26,17 @@ static void signal_free(void*);
static void signal_instance_free(void*); static void signal_instance_free(void*);
//methods //methods
static PyObject* signal_instance_connect(PyObject *self, PyObject *args, PyObject *kw); static PyObject* signal_instance_connect(PyObject*, PyObject*, PyObject*);
static PyObject* signal_instance_disconnect(PyObject *self, PyObject *args); static PyObject* signal_instance_disconnect(PyObject*, PyObject*);
static PyObject* signal_instance_emit(PyObject *self, PyObject *args); static PyObject* signal_instance_emit(PyObject*, PyObject*);
static PyObject* signal_instance_get_item(PyObject *self, PyObject *key); static PyObject* signal_instance_get_item(PyObject*, PyObject*);
//aux //aux
static char* signal_build_signature(const char *name, const char *signature); static char* signal_build_signature(const char*, const char*);
static const char* signal_get_type_name(PyObject *type); static char* signal_get_type_name(PyObject*);
static void signal_append_signature(SignalData *self, char *signature); static void signal_append_signature(SignalData*, char*);
static void signal_instance_initialize(PyObject *instance, PyObject *name, SignalData *data, PyObject *source, int index); static void signal_instance_initialize(PyObject*, PyObject*, SignalData*, PyObject *, int);
static char* signal_parse_signature(PyObject *args); static char* signal_parse_signature(PyObject*);
PyTypeObject Signal_Type = { PyTypeObject Signal_Type = {
PyObject_HEAD_INIT(0) PyObject_HEAD_INIT(0)
@ -172,12 +170,12 @@ PyAPI_FUNC(void) init_signal(PyObject* module)
} // extern "C" } // extern "C"
PyObject* signal_instance_get_item(PyObject *self, PyObject *key) PyObject* signal_instance_get_item(PyObject* self, PyObject* key)
{ {
SignalInstanceData *data = reinterpret_cast<SignalInstanceData*>(self); SignalInstanceData* data = reinterpret_cast<SignalInstanceData*>(self);
char *sig_key = signal_parse_signature(key); char* sigKey = signal_parse_signature(key);
char *sig = signal_build_signature(data->signal_name, sig_key); char* sig = signal_build_signature(data->signalName, sigKey);
free(sig_key); free(sigKey);
while(data) { while(data) {
if (strcmp(data->signature, sig) == 0) { if (strcmp(data->signature, sig) == 0) {
@ -192,32 +190,32 @@ PyObject* signal_instance_get_item(PyObject *self, PyObject *key)
return 0; return 0;
} }
void signal_update_source(PyObject *source) void signal_update_source(PyObject* source)
{ {
PyObject *key, *value; PyObject* key;
PyObject* value;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
PyTypeObject *obType = source->ob_type; PyTypeObject* obType = source->ob_type;
while (PyDict_Next(obType->tp_dict, &pos, &key, &value)) { while (PyDict_Next(obType->tp_dict, &pos, &key, &value)) {
if (value->ob_type == &Signal_Type) { if (value->ob_type == &Signal_Type) {
PyObject *signal_instance = (PyObject*)PyObject_New(SignalInstanceData, &SignalInstance_Type); Shiboken::AutoDecRef signalInstance(reinterpret_cast<PyObject*>(PyObject_New(SignalInstanceData, &SignalInstance_Type)));
signal_instance_initialize(signal_instance, key, reinterpret_cast<SignalData*>(value), source, 0); signal_instance_initialize(signalInstance, key, reinterpret_cast<SignalData*>(value), source, 0);
PyObject_SetAttr(source, key, signal_instance); PyObject_SetAttr(source, key, signalInstance);
Py_DECREF(signal_instance);
} }
} }
} }
const char* signal_get_type_name(PyObject *type) char* signal_get_type_name(PyObject* type)
{ {
if (PyType_Check(type)) { if (PyType_Check(type)) {
//tp_name return the full name //tp_name return the full name
Shiboken::AutoDecRef type_name(PyObject_GetAttrString(type, "__name__")); Shiboken::AutoDecRef typeName(PyObject_GetAttrString(type, "__name__"));
return PyString_AS_STRING((PyObject*)type_name); return strdup(PyString_AS_STRING(typeName.object()));
} else if (PyString_Check(type)) { } else if (PyString_Check(type)) {
return PyString_AS_STRING(type); return strdup(PyString_AS_STRING(type));
} }
return ""; return 0;
} }
char* signal_build_signature(const char *name, const char *signature) char* signal_build_signature(const char *name, const char *signature)
@ -232,17 +230,19 @@ char* signal_parse_signature(PyObject *args)
char *signature = 0; char *signature = 0;
if (args && !PySequence_Check(args) && (args != Py_None && args)) if (args && !PySequence_Check(args) && (args != Py_None && args))
return strdup(signal_get_type_name(args)); return signal_get_type_name(args);
for(Py_ssize_t i=0, i_max=PySequence_Size(args); i < i_max; i++) { for(Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) {
Shiboken::AutoDecRef arg(PySequence_ITEM(args, i)); Shiboken::AutoDecRef arg(PySequence_ITEM(args, i));
const char *type_name = signal_get_type_name(arg); char* typeName = signal_get_type_name(arg);
if (strlen(type_name) > 0) { if (typeName) {
if (signature) { if (signature) {
signature = reinterpret_cast<char*>(realloc(signature, (strlen(signature) + 1 + strlen(typeName)) * sizeof(char*)));
signature = strcat(signature, ","); signature = strcat(signature, ",");
signature = strcat(signature, type_name); signature = strcat(signature, typeName);
free(typeName);
} else { } else {
signature = strdup(type_name); signature = typeName;
} }
} }
} }
@ -250,49 +250,48 @@ char* signal_parse_signature(PyObject *args)
return signature; return signature;
} }
void signal_append_signature(SignalData *self, char *signature) void signal_append_signature(SignalData* self, char* signature)
{ {
self->signatures_size++; self->signaturesSize++;
if (self->signatures_size > 1) { if (self->signaturesSize > 1) {
self->signatures = (char**) realloc(self->signatures, sizeof(char**) * self->signatures_size); self->signatures = (char**) realloc(self->signatures, sizeof(char**) * self->signaturesSize);
} else { } else {
self->signatures = (char**) malloc(sizeof(char**)); self->signatures = (char**) malloc(sizeof(char**));
} }
self->signatures[self->signatures_size-1] = signature; self->signatures[self->signaturesSize-1] = signature;
} }
int signal_init(PyObject *self, PyObject *args, PyObject *kwds) int signal_init(PyObject* self, PyObject* args, PyObject* kwds)
{ {
static PyObject *emptyTuple = 0; static PyObject *emptyTuple = 0;
static const char *kwlist[] = {"name", 0}; static const char *kwlist[] = {"name", 0};
char* arg_name = 0; char* argName = 0;
if (emptyTuple == 0) if (emptyTuple == 0)
emptyTuple = PyTuple_New(0); emptyTuple = PyTuple_New(0);
if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds, if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds,
"|s:QtCore."SIGNAL_CLASS_NAME, (char**) kwlist, &arg_name)) "|s:QtCore."SIGNAL_CLASS_NAME, (char**) kwlist, &argName))
return 0; return 0;
bool tupled_args = false; bool tupledArgs = false;
SignalData *data = reinterpret_cast<SignalData*>(self); SignalData *data = reinterpret_cast<SignalData*>(self);
if (arg_name) { if (argName) {
data->signal_name = strdup(arg_name); data->signalName = strdup(argName);
} }
for(Py_ssize_t i=0, i_max=PyTuple_Size(args); i < i_max; i++) { for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
PyObject *arg = PyTuple_GET_ITEM(args, i); PyObject *arg = PyTuple_GET_ITEM(args, i);
if (PySequence_Check(arg)) { if (PySequence_Check(arg)) {
tupled_args = true; tupledArgs = true;
signal_append_signature(data, signal_parse_signature(arg)); signal_append_signature(data, signal_parse_signature(arg));
} }
} }
if (!tupled_args) if (!tupledArgs)
signal_append_signature(data, signal_parse_signature(args)); signal_append_signature(data, signal_parse_signature(args));
return 1; return 1;
} }
@ -301,25 +300,25 @@ void signal_free(void *self)
PyObject *pySelf = reinterpret_cast<PyObject*>(self); PyObject *pySelf = reinterpret_cast<PyObject*>(self);
SignalData *data = reinterpret_cast<SignalData*>(self); SignalData *data = reinterpret_cast<SignalData*>(self);
for(int i=0, i_max=data->signatures_size; i < i_max; i++) { for(int i = 0, i_max = data->signaturesSize; i < i_max; i++) {
if (data->signatures[i]) if (data->signatures[i])
free(data->signatures[i]); free(data->signatures[i]);
} }
free(data->signatures); free(data->signatures);
free(data->signal_name); free(data->signalName);
data->initialized = false; data->initialized = false;
data->signatures_size = 0; data->signaturesSize = 0;
pySelf->ob_type->tp_base->tp_free(self); pySelf->ob_type->tp_base->tp_free(self);
} }
void signal_instance_free(void *self) void signal_instance_free(void* self)
{ {
PyObject *pySelf = reinterpret_cast<PyObject*>(self); PyObject *pySelf = reinterpret_cast<PyObject*>(self);
SignalInstanceData *data = reinterpret_cast<SignalInstanceData*>(self); SignalInstanceData *data = reinterpret_cast<SignalInstanceData*>(self);
free(data->signal_name); free(data->signalName);
free(data->signature); free(data->signature);
while(data) { while(data) {
@ -329,23 +328,23 @@ void signal_instance_free(void *self)
pySelf->ob_type->tp_base->tp_free(self); pySelf->ob_type->tp_base->tp_free(self);
} }
void signal_instance_initialize(PyObject *instance, PyObject *name, SignalData *data, PyObject *source, int index) void signal_instance_initialize(PyObject* instance, PyObject* name, SignalData* data, PyObject* source, int index)
{ {
if (data->initialized) if (data->initialized)
return; return;
SignalInstanceData *self = reinterpret_cast<SignalInstanceData*>(instance); SignalInstanceData *self = reinterpret_cast<SignalInstanceData*>(instance);
if (data->signal_name) if (data->signalName)
self->signal_name = strdup(data->signal_name); self->signalName = strdup(data->signalName);
else else
self->signal_name = strdup(PyString_AsString(name)); self->signalName = strdup(PyString_AsString(name));
self->source = source; self->source = source;
self->signature = signal_build_signature(self->signal_name, data->signatures[index]); self->signature = signal_build_signature(self->signalName, data->signatures[index]);
index++; index++;
if (index < data->signatures_size) { if (index < data->signaturesSize) {
self->next = (PyObject*)PyObject_New(SignalInstanceData, &SignalInstance_Type); self->next = reinterpret_cast<PyObject*>(PyObject_New(SignalInstanceData, &SignalInstance_Type));
signal_instance_initialize(self->next, name, data, source, index); signal_instance_initialize(self->next, name, data, source, index);
} }
@ -353,7 +352,7 @@ void signal_instance_initialize(PyObject *instance, PyObject *name, SignalData *
data->initialized = true; data->initialized = true;
} }
PyObject* signal_instance_connect(PyObject *self, PyObject *args, PyObject *kwds) PyObject* signal_instance_connect(PyObject* self, PyObject* args, PyObject* kwds)
{ {
PyObject *slot; PyObject *slot;
PyObject *type; PyObject *type;
@ -400,7 +399,7 @@ PyObject* signal_instance_connect(PyObject *self, PyObject *args, PyObject *kwds
return 0; return 0;
} }
PyObject* signal_instance_disconnect(PyObject *self, PyObject *args) PyObject* signal_instance_disconnect(PyObject* self, PyObject* args)
{ {
SignalInstanceData *source = reinterpret_cast<SignalInstanceData*>(self); SignalInstanceData *source = reinterpret_cast<SignalInstanceData*>(self);
Shiboken::AutoDecRef pyArgs(PyList_New(0)); Shiboken::AutoDecRef pyArgs(PyList_New(0));
@ -443,7 +442,7 @@ PyObject* signal_instance_disconnect(PyObject *self, PyObject *args)
return 0; return 0;
} }
PyObject* signal_instance_emit(PyObject *self, PyObject *args) PyObject* signal_instance_emit(PyObject* self, PyObject* args)
{ {
SignalInstanceData *source = reinterpret_cast<SignalInstanceData*>(self); SignalInstanceData *source = reinterpret_cast<SignalInstanceData*>(self);
@ -460,11 +459,11 @@ PyObject* signal_instance_emit(PyObject *self, PyObject *args)
return PyObject_CallObject(pyMethod, tupleArgs); return PyObject_CallObject(pyMethod, tupleArgs);
} }
PyObject* signal_new(const char *name, ...) PyObject* signal_new(const char* name, ...)
{ {
va_list listSignatures; va_list listSignatures;
char *sig; char* sig;
SignalData *self = PyObject_New(SignalData, &Signal_Type); SignalData* self = PyObject_New(SignalData, &Signal_Type);
va_start(listSignatures, name); va_start(listSignatures, name);
sig = va_arg(listSignatures, char*); sig = va_arg(listSignatures, char*);

View file

@ -1,5 +1,5 @@
#ifndef QSIGNAL_H #ifndef PYSIDE_SIGNAL_H
#define QSIGNAL_H #define PYSIDE_SIGNAL_H
#include <pysidemacros.h> #include <pysidemacros.h>
#include <Python.h> #include <Python.h>
@ -10,10 +10,10 @@ namespace PySide
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
char *signal_name; char* signalName;
char *signature; char* signature;
PyObject *source; PyObject* source;
PyObject *next; PyObject* next;
} SignalInstanceData; } SignalInstanceData;
@ -21,10 +21,11 @@ extern "C"
{ {
PyAPI_DATA(PyTypeObject) Signal_Type; PyAPI_DATA(PyTypeObject) Signal_Type;
PyAPI_DATA(PyTypeObject) SignalInstance_Type; PyAPI_DATA(PyTypeObject) SignalInstance_Type;
PYSIDE_API PyAPI_FUNC(PyObject*) signal_new(const char *name, ...); PYSIDE_API PyAPI_FUNC(PyObject*) signal_new(const char* name, ...);
}; //extern "C" }; //extern "C"
PYSIDE_API void signal_update_source(PyObject *source); PYSIDE_API void signal_update_source(PyObject* source);
} //namespace PySide } //namespace PySide
#endif #endif

View file

@ -8,16 +8,20 @@
typedef struct typedef struct
{ {
PyObject_HEAD PyObject_HEAD
char* slot_name; char* slotName;
char* args; char* args;
char* result_type; char* resultType;
} SlotData; } SlotData;
extern "C" extern "C"
{ {
static int slot_init(PyObject *self, PyObject *arg, PyObject *kw); static int slot_init(PyObject*, PyObject*, PyObject*);
static PyObject* slot_call(PyObject *self, PyObject *arg, PyObject *kw); static PyObject* slot_call(PyObject*, PyObject*, PyObject*);
//aux
static char* slot_get_type_name(PyObject*);
// Class Definition ----------------------------------------------- // Class Definition -----------------------------------------------
static PyTypeObject Slot_Type = { static PyTypeObject Slot_Type = {
@ -70,7 +74,7 @@ static PyTypeObject Slot_Type = {
0, /*tp_del */ 0, /*tp_del */
}; };
PyAPI_FUNC(void) init_slot(PyObject* module) PyAPI_FUNC(void) init_slot(PyObject *module)
{ {
if (PyType_Ready(&Slot_Type) < 0) if (PyType_Ready(&Slot_Type) < 0)
return; return;
@ -82,91 +86,97 @@ PyAPI_FUNC(void) init_slot(PyObject* module)
} // extern "C" } // extern "C"
static const char* slot_get_type_name(PyObject *type) char* slot_get_type_name(PyObject *type)
{ {
if (PyType_Check(type)) { if (PyType_Check(type)) {
//tp_name return the full name //tp_name return the full name
Shiboken::AutoDecRef type_name(PyObject_GetAttrString(type, "__name__")); Shiboken::AutoDecRef typeName(PyObject_GetAttrString(type, "__name__"));
return PyString_AS_STRING((PyObject*)type_name); return strdup(PyString_AS_STRING(typeName.object()));
} else if (PyString_Check(type)) { } else if (PyString_Check(type)) {
return PyString_AS_STRING(type); return strdup(PyString_AS_STRING(type));
} }
return ""; return 0;
} }
static int slot_init(PyObject *self, PyObject *args, PyObject *kw) int slot_init(PyObject *self, PyObject *args, PyObject *kw)
{ {
static PyObject *emptyTuple = 0; static PyObject *emptyTuple = 0;
static const char *kwlist[] = {"name", "result", 0}; static const char *kwlist[] = {"name", "result", 0};
char* arg_name = 0; char* argName = 0;
PyObject* arg_result = 0; PyObject* argResult = 0;
if (emptyTuple == 0) if (emptyTuple == 0)
emptyTuple = PyTuple_New(0); emptyTuple = PyTuple_New(0);
if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore."SLOT_DEC_NAME, (char**) kwlist, &arg_name, &arg_result)) if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore."SLOT_DEC_NAME, (char**) kwlist, &argName, &argResult))
return 0; return 0;
SlotData *data = reinterpret_cast<SlotData*>(self); SlotData *data = reinterpret_cast<SlotData*>(self);
for(Py_ssize_t i=0, i_max=PyTuple_Size(args); i < i_max; i++) { for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
PyObject *arg_type = PyTuple_GET_ITEM(args, i); PyObject *argType = PyTuple_GET_ITEM(args, i);
const char *type_name = slot_get_type_name(arg_type); char *typeName = slot_get_type_name(argType);
if (strlen(type_name) > 0) { if (typeName) {
if (data->args) { if (data->args) {
data->args = reinterpret_cast<char*>(realloc(data->args, (strlen(data->args) + 1 + strlen(typeName)) * sizeof(char*)));
data->args = strcat(data->args, ","); data->args = strcat(data->args, ",");
data->args = strcat(data->args, type_name); data->args = strcat(data->args, typeName);
free(typeName);
} else { } else {
data->args = strdup(type_name); data->args = typeName;
} }
} }
} }
if (arg_name) if (argName)
data->slot_name = strdup(arg_name); data->slotName = strdup(argName);
if (arg_result) if (argResult)
data->result_type = strdup(slot_get_type_name(arg_result)); data->resultType = slot_get_type_name(argResult);
else else
data->result_type = strdup("void"); data->resultType = strdup("void");
return 1; return 1;
} }
static PyObject* slot_call(PyObject *self, PyObject *args, PyObject *kw) PyObject* slot_call(PyObject* self, PyObject* args, PyObject* kw)
{ {
PyObject *callback; static PyObject* pySlotName = 0;
PyObject* callback;
callback = PyTuple_GetItem(args, 0); callback = PyTuple_GetItem(args, 0);
Py_INCREF(callback); Py_INCREF(callback);
if (PyFunction_Check(callback)) { if (PyFunction_Check(callback)) {
SlotData *data = reinterpret_cast<SlotData*>(self); SlotData *data = reinterpret_cast<SlotData*>(self);
if (!data->slot_name) { if (!data->slotName) {
PyObject *func_name = ((PyFunctionObject*)callback)->func_name; PyObject *funcName = reinterpret_cast<PyFunctionObject*>(callback)->func_name;
data->slot_name = strdup(PyString_AS_STRING(func_name)); data->slotName = strdup(PyString_AS_STRING(funcName));
} }
QString signature; QString signature;
signature.sprintf("%s %s(%s)", data->result_type, data->slot_name, data->args); signature.sprintf("%s %s(%s)", data->resultType, data->slotName, data->args);
if (!pySlotName)
pySlotName = PyString_FromString(PYSIDE_SLOT_LIST_ATTR);
PyObject *pySignature = PyString_FromString(QMetaObject::normalizedSignature(signature.toAscii())); PyObject *pySignature = PyString_FromString(QMetaObject::normalizedSignature(signature.toAscii()));
PyObject *signature_list = 0; PyObject *signatureList = 0;
if (PyObject_HasAttrString(callback, PYSIDE_SLOT_LIST_ATTR)) { if (PyObject_HasAttr(callback, pySlotName)) {
signature_list = PyObject_GetAttrString(callback, PYSIDE_SLOT_LIST_ATTR); signatureList = PyObject_GetAttr(callback, pySlotName);
} else { } else {
signature_list = PyList_New(0); signatureList = PyList_New(0);
PyObject_SetAttrString(callback, PYSIDE_SLOT_LIST_ATTR, signature_list); PyObject_SetAttr(callback, pySlotName, signatureList);
Py_DECREF(signature_list); Py_DECREF(signatureList);
} }
PyList_Append(signature_list, pySignature); PyList_Append(signatureList, pySignature);
Py_DECREF(pySignature); Py_DECREF(pySignature);
//clear data //clear data
free(data->slot_name); free(data->slotName);
data->slot_name = 0; data->slotName = 0;
free(data->result_type); free(data->resultType);
data->result_type = 0; data->resultType = 0;
free(data->args); free(data->args);
data->args = 0; data->args = 0;
return callback; return callback;