aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-03 09:44:52 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-06 11:44:20 +0000
commit06f97eca45ddadf4f04229cf14d5dc0bbd867316 (patch)
tree84c9daa0e963166e75663a370432feee911220f0 /sources/pyside2/libpyside
parent06e53faac0b1bcdffc966e0676a39a5f50f93592 (diff)
Port property/signal/slot handling of libpyside to use QByteArray
Introduce C++ structs with QByteArray to be used for signal and slot names and signatures, removing a lot of code dealing with char * pointers, strdup() and reallocating. Change-Id: I28acf727bc6cf468285b153c85b0a342fd79f7d8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/pyside2/libpyside')
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp13
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp29
-rw-r--r--sources/pyside2/libpyside/pysideproperty_p.h39
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp213
-rw-r--r--sources/pyside2/libpyside/pysidesignal_p.h45
-rw-r--r--sources/pyside2/libpyside/pysideslot.cpp59
6 files changed, 171 insertions, 227 deletions
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
index 417ffef5..c5de54aa 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
@@ -464,16 +464,9 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
if (Signal::checkType(value)) {
// Register signals.
auto data = reinterpret_cast<PySideSignal *>(value);
- const char *signalName = Shiboken::String::toCString(key);
- data->signalName = strdup(signalName);
- QByteArray sig;
- sig.reserve(128);
- for (int i = 0; i < data->signaturesSize; ++i) {
- sig = signalName;
- sig += '(';
- if (data->signatures[i])
- sig += data->signatures[i];
- sig += ')';
+ data->data->signalName = Shiboken::String::toCString(key);
+ for (const auto &s : data->data->signatures) {
+ const auto sig = data->data->signalName + '(' + s.signature + ')';
if (m_baseObject->indexOfSignal(sig) == -1)
m_builder->addSignal(sig);
}
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 091b0c44..c48a6f88 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -152,11 +152,6 @@ static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject * /* args */, Py
{
PySideProperty* me = reinterpret_cast<PySideProperty*>(subtype->tp_alloc(subtype, 0));
me->d = new PySidePropertyPrivate;
- memset(me->d, 0, sizeof(PySidePropertyPrivate));
- PySidePropertyPrivate* pData = me->d;
- pData->designable = true;
- pData->scriptable = true;
- pData->stored = true;
return reinterpret_cast<PyObject *>(me);
}
@@ -170,21 +165,29 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
static const char *kwlist[] = {"type", "fget", "fset", "freset", "fdel", "doc", "notify",
"designable", "scriptable", "stored", "user",
"constant", "final", 0};
+ char *doc{};
+
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O|OOOOsObbbbbb:QtCore.QProperty",
const_cast<char**>(kwlist),
/*OO*/ &type, &(pData->fget),
/*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel),
- /*s*/ &(pData->doc),
+ /*s*/ &doc,
/*O*/ &(pData->notify),
/*bbbbbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored), &(pData->user), &(pData->constant), &(pData->final))) {
return 0;
}
+ if (doc) {
+ pData->doc = doc;
+ free(doc);
+ } else {
+ pData->doc.clear();
+ }
pData->typeName = PySide::Signal::getTypeName(type);
- if (!pData->typeName)
+ if (pData->typeName.isEmpty())
PyErr_SetString(PyExc_TypeError, "Invalid property type or type name.");
else if (pData->constant && (pData->fset || pData->notify))
PyErr_SetString(PyExc_TypeError, "A constant property cannot have a WRITE method or a NOTIFY signal.");
@@ -287,9 +290,6 @@ static int qpropertyClear(PyObject* self)
Py_CLEAR(data->notify);
- free(data->typeName);
- free(data->doc);
- free(data->notifySignature);
delete data;
reinterpret_cast<PySideProperty*>(self)->d = 0;
return 0;
@@ -459,13 +459,14 @@ bool isFinal(const PySideProperty* self)
const char* getNotifyName(PySideProperty* self)
{
- if (!self->d->notifySignature) {
+ if (self->d->notifySignature.isEmpty()) {
PyObject* str = PyObject_Str(self->d->notify);
- self->d->notifySignature = strdup(Shiboken::String::toCString(str));
+ self->d->notifySignature = Shiboken::String::toCString(str);
Py_DECREF(str);
}
- return self->d->notifySignature;
+ return self->d->notifySignature.isEmpty()
+ ? nullptr : self->d->notifySignature.constData();
}
void setMetaCallHandler(PySideProperty* self, MetaCallHandler handler)
@@ -475,7 +476,7 @@ void setMetaCallHandler(PySideProperty* self, MetaCallHandler handler)
void setTypeName(PySideProperty* self, const char* typeName)
{
- self->d->typeName = strdup(typeName);
+ self->d->typeName = typeName;
}
void setUserData(PySideProperty* self, void* data)
diff --git a/sources/pyside2/libpyside/pysideproperty_p.h b/sources/pyside2/libpyside/pysideproperty_p.h
index f08e5f54..4db63802 100644
--- a/sources/pyside2/libpyside/pysideproperty_p.h
+++ b/sources/pyside2/libpyside/pysideproperty_p.h
@@ -41,35 +41,32 @@
#define PYSIDE_QPROPERTY_P_H
#include <sbkpython.h>
+#include <QtCore/QByteArray>
#include <QMetaObject>
#include "pysideproperty.h"
struct PySideProperty;
-extern "C"
+struct PySidePropertyPrivate
{
-
-struct PySidePropertyPrivate {
- char* typeName;
- PySide::Property::MetaCallHandler metaCallHandler;
- PyObject* fget;
- PyObject* fset;
- PyObject* freset;
- PyObject* fdel;
- PyObject* notify;
- char* notifySignature;
- char* doc;
- bool designable;
- bool scriptable;
- bool stored;
- bool user;
- bool constant;
- bool final;
- void* userData;
+ QByteArray typeName;
+ PySide::Property::MetaCallHandler metaCallHandler = nullptr;
+ PyObject *fget = nullptr;
+ PyObject *fset = nullptr;
+ PyObject *freset = nullptr;
+ PyObject *fdel = nullptr;
+ PyObject *notify = nullptr;
+ QByteArray notifySignature;
+ QByteArray doc;
+ bool designable = true;
+ bool scriptable = true;
+ bool stored = true;
+ bool user = false;
+ bool constant = false;
+ bool final = false;
+ void *userData = nullptr;
};
-} // extern "C"
-
namespace PySide { namespace Property {
/**
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index cf99de78..0f1993e7 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -71,11 +71,11 @@ namespace Signal {
QMetaMethod::Attributes m_attributes = QMetaMethod::Compatibility;
};
- static char* buildSignature(const char*, const char*);
+ static QByteArray buildSignature(const QByteArray &, const QByteArray &);
static void appendSignature(PySideSignal*, const SignalSignature &);
static void instanceInitialize(PySideSignalInstance*, PyObject*, PySideSignal*, PyObject*, int);
- static char* parseSignature(PyObject*);
- static PyObject* buildQtCompatible(const char*);
+ static QByteArray parseSignature(PyObject *);
+ static PyObject* buildQtCompatible(const QByteArray &);
}
}
@@ -215,28 +215,27 @@ int signalTpInit(PyObject* self, PyObject* args, PyObject* kwds)
bool tupledArgs = false;
PySideSignal* data = reinterpret_cast<PySideSignal*>(self);
- if (argName) {
- data->signalName = strdup(argName);
- }
+ if (!data->data)
+ data->data = new PySideSignalData;
+ if (argName)
+ data->data->signalName = argName;
for (Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
PyObject* arg = PyTuple_GET_ITEM(args, i);
if (PySequence_Check(arg) && !Shiboken::String::check(arg)) {
tupledArgs = true;
- char *sig = PySide::Signal::parseSignature(arg);
+ const auto sig = PySide::Signal::parseSignature(arg);
PySide::Signal::appendSignature(
data,
PySide::Signal::SignalSignature(sig));
- free(sig);
}
}
if (!tupledArgs) {
- char *sig = PySide::Signal::parseSignature(args);
+ const auto sig = PySide::Signal::parseSignature(args);
PySide::Signal::appendSignature(
data,
PySide::Signal::SignalSignature(sig));
- free(sig);
}
return 1;
@@ -246,17 +245,8 @@ void signalFree(void* self)
{
PyObject* pySelf = reinterpret_cast<PyObject*>(self);
PySideSignal* data = reinterpret_cast<PySideSignal*>(self);
-
- for (int i = 0, i_max = data->signaturesSize; i < i_max; i++) {
- if (data->signatures[i])
- free(data->signatures[i]);
- }
-
- free(data->signatures);
- free(data->signatureAttributes);
- free(data->signalName);
- data->initialized = 0;
- data->signaturesSize = 0;
+ delete data->data;
+ data->data = nullptr;
Py_XDECREF(data->homonymousMethod);
data->homonymousMethod = 0;
@@ -266,20 +256,15 @@ void signalFree(void* self)
PyObject* signalGetItem(PyObject* self, PyObject* key)
{
PySideSignal* data = reinterpret_cast<PySideSignal*>(self);
- char* sigKey;
+ QByteArray sigKey;
if (key) {
sigKey = PySide::Signal::parseSignature(key);
} else {
- if (data->signatures[0])
- sigKey = strdup(data->signatures[0]);
- else
- sigKey = strdup("void");
+ sigKey = data->data == nullptr || data->data->signatures.isEmpty()
+ ? PySide::Signal::voidType() : data->data->signatures.constFirst().signature;
}
- char* sig = PySide::Signal::buildSignature(data->signalName, sigKey);
- free(sigKey);
- PyObject* pySignature = Shiboken::String::fromCString(sig);
- free(sig);
- return pySignature;
+ auto sig = PySide::Signal::buildSignature(data->data->signalName, sigKey);
+ return Shiboken::String::fromCString(sig.constData());
}
@@ -294,8 +279,6 @@ void signalInstanceFree(void* self)
PySideSignalInstance* data = reinterpret_cast<PySideSignalInstance*>(self);
PySideSignalInstancePrivate* dataPvt = data->d;
- free(dataPvt->signalName);
- free(dataPvt->signature);
Py_XDECREF(dataPvt->homonymousMethod);
@@ -422,7 +405,8 @@ PyObject* signalInstanceConnect(PyObject* self, PyObject* args, PyObject* kwds)
Py_XDECREF(result);
}
if (!PyErr_Occurred()) // PYSIDE-79: inverse the logic. A Null return needs an error.
- PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s.", source->d->signature);
+ PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s.",
+ source->d->signature.constData());
return 0;
}
@@ -472,23 +456,20 @@ PyObject* signalInstanceEmit(PyObject* self, PyObject* args)
PyObject* signalInstanceGetItem(PyObject* self, PyObject* key)
{
PySideSignalInstance* data = reinterpret_cast<PySideSignalInstance*>(self);
- char* sigKey = PySide::Signal::parseSignature(key);
- char* sig = PySide::Signal::buildSignature(data->d->signalName, sigKey);
- free(sigKey);
- const char* sigName = data->d->signalName;
-
+ const auto sigName = data->d->signalName;
+ const auto sigKey = PySide::Signal::parseSignature(key);
+ const auto sig = PySide::Signal::buildSignature(sigName, sigKey);
while (data) {
- if (strcmp(data->d->signature, sig) == 0) {
- free(sig);
+ if (data->d->signature == sig) {
PyObject* result = reinterpret_cast<PyObject*>(data);
Py_INCREF(result);
return result;
}
- data = reinterpret_cast<PySideSignalInstance*>(data->d->next);
+ data = data->d->next;
}
- PyErr_Format(PyExc_IndexError, "Signature %s not found for signal: %s", sig, sigName);
- free(sig);
+ PyErr_Format(PyExc_IndexError, "Signature %s not found for signal: %s",
+ sig.constData(), sigName.constData());
return 0;
}
@@ -539,7 +520,8 @@ PyObject* signalInstanceDisconnect(PyObject* self, PyObject* args)
Py_DECREF(result);
}
- PyErr_Format(PyExc_RuntimeError, "Failed to disconnect signal %s.", source->d->signature);
+ PyErr_Format(PyExc_RuntimeError, "Failed to disconnect signal %s.",
+ source->d->signature.constData());
return 0;
}
@@ -640,72 +622,59 @@ void updateSourceObject(PyObject* source)
Py_XDECREF(objType);
}
-char* getTypeName(PyObject* type)
+QByteArray getTypeName(PyObject *type)
{
if (PyType_Check(type)) {
- char* typeName = NULL;
if (PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(type),
reinterpret_cast<PyTypeObject*>(SbkObject_TypeF()))) {
SbkObjectType* objType = reinterpret_cast<SbkObjectType*>(type);
- typeName = strdup(Shiboken::ObjectType::getOriginalName(objType));
- } else {
- // Translate python types to Qt names
- PyTypeObject* objType = reinterpret_cast<PyTypeObject*>(type);
- if (Shiboken::String::checkType(objType))
- typeName = strdup("QString");
- else if (objType == &PyInt_Type)
- typeName = strdup("int");
- else if (objType == &PyLong_Type)
- typeName = strdup("long");
- else if (objType == &PyFloat_Type)
- typeName = strdup("double");
- else if (objType == &PyBool_Type)
- typeName = strdup("bool");
- else if (Py_TYPE(objType) == SbkEnumType_TypeF())
- typeName = strdup(Shiboken::Enum::getCppName(objType));
- else
- typeName = strdup("PyObject");
+ return Shiboken::ObjectType::getOriginalName(objType);
}
- return typeName;
+ // Translate python types to Qt names
+ PyTypeObject* objType = reinterpret_cast<PyTypeObject*>(type);
+ if (Shiboken::String::checkType(objType))
+ return QByteArrayLiteral("QString");
+ if (objType == &PyInt_Type)
+ return QByteArrayLiteral("int");
+ if (objType == &PyLong_Type)
+ return QByteArrayLiteral("long");
+ if (objType == &PyFloat_Type)
+ return QByteArrayLiteral("double");
+ if (objType == &PyBool_Type)
+ return QByteArrayLiteral("bool");
+ if (Py_TYPE(objType) == SbkEnumType_TypeF())
+ return Shiboken::Enum::getCppName(objType);
+ return QByteArrayLiteral("PyObject");
}
if (type == Py_None) // Must be checked before as Shiboken::String::check accepts Py_None
- return strdup("void");
+ return voidType();
if (Shiboken::String::check(type)) {
- const char *result = Shiboken::String::toCString(type);
- if (!strcmp(result, "qreal"))
+ QByteArray result = Shiboken::String::toCString(type);
+ if (result == "qreal")
result = sizeof(qreal) == sizeof(double) ? "double" : "float";
- return strdup(result);
+ return result;
}
- return 0;
+ return QByteArray();
}
-char* buildSignature(const char* name, const char* signature)
+QByteArray buildSignature(const QByteArray &name, const QByteArray &signature)
{
- QByteArray signal(name);
- signal += '(';
- signal += signature;
- signal += ')';
- return strdup(QMetaObject::normalizedSignature(signal));
+ return QMetaObject::normalizedSignature(name + '(' + signature + ')');
}
-char* parseSignature(PyObject* args)
+QByteArray parseSignature(PyObject* args)
{
- char* signature = 0;
if (args && (Shiboken::String::check(args) || !PySequence_Check(args)))
return getTypeName(args);
+ QByteArray signature;
for (Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) {
Shiboken::AutoDecRef arg(PySequence_GetItem(args, i));
- char* typeName = getTypeName(arg);
- if (typeName) {
- if (signature) {
- signature = reinterpret_cast<char*>(realloc(signature, (strlen(signature) + 1 + strlen(typeName)) * sizeof(char*)));
- signature = strcat(signature, ",");
- signature = strcat(signature, typeName);
- free(typeName);
- } else {
- signature = typeName;
- }
+ const auto typeName = getTypeName(arg);
+ if (!typeName.isEmpty()) {
+ if (!signature.isEmpty())
+ signature += ',';
+ signature += typeName;
}
}
return signature;
@@ -713,17 +682,7 @@ char* parseSignature(PyObject* args)
void appendSignature(PySideSignal* self, const SignalSignature &signature)
{
- self->signaturesSize++;
-
- if (self->signaturesSize > 1) {
- self->signatures = reinterpret_cast<char **>(realloc(self->signatures, sizeof(char *) * self->signaturesSize));
- self->signatureAttributes = reinterpret_cast<int *>(realloc(self->signatureAttributes, sizeof(int) * self->signaturesSize));
- } else {
- self->signatures = reinterpret_cast<char **>(malloc(sizeof(char *)));
- self->signatureAttributes = reinterpret_cast<int *>(malloc(sizeof(int)));
- }
- self->signatures[self->signaturesSize - 1] = strdup(signature.m_parameterTypes);
- self->signatureAttributes[self->signaturesSize - 1] = signature.m_attributes;
+ self->data->signatures.append({signature.m_parameterTypes, signature.m_attributes});
}
PySideSignalInstance* initialize(PySideSignal* self, PyObject* name, PyObject* object)
@@ -740,17 +699,15 @@ void instanceInitialize(PySideSignalInstance* self, PyObject* name, PySideSignal
{
self->d = new PySideSignalInstancePrivate;
PySideSignalInstancePrivate* selfPvt = self->d;
- selfPvt->next = 0;
- if (data->signalName)
- selfPvt->signalName = strdup(data->signalName);
- else {
- selfPvt->signalName = strdup(Shiboken::String::toCString(name));
- data->signalName = strdup(selfPvt->signalName);
- }
+ selfPvt->next = nullptr;
+ if (data->data->signalName.isEmpty())
+ data->data->signalName = Shiboken::String::toCString(name);
+ selfPvt->signalName = data->data->signalName;
selfPvt->source = source;
- selfPvt->signature = buildSignature(self->d->signalName, data->signatures[index]);
- selfPvt->attributes = data->signatureAttributes[index];
+ const auto &signature = data->data->signatures.at(index);
+ selfPvt->signature = buildSignature(self->d->signalName, signature.signature);
+ selfPvt->attributes = signature.attributes;
selfPvt->homonymousMethod = 0;
if (data->homonymousMethod) {
selfPvt->homonymousMethod = data->homonymousMethod;
@@ -758,7 +715,7 @@ void instanceInitialize(PySideSignalInstance* self, PyObject* name, PySideSignal
}
index++;
- if (index < data->signaturesSize) {
+ if (index < data->data->signatures.size()) {
selfPvt->next = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF());
instanceInitialize(selfPvt->next, name, data, source, index);
}
@@ -800,8 +757,8 @@ PySideSignalInstance* newObjectFromMethod(PyObject* source, const QList<QMetaMet
QByteArray cppName(m.methodSignature());
cppName.truncate(cppName.indexOf('('));
// separe SignalName
- selfPvt->signalName = strdup(cppName.data());
- selfPvt->signature = strdup(m.methodSignature());
+ selfPvt->signalName = cppName;
+ selfPvt->signature = m.methodSignature();
selfPvt->attributes = m.attributes();
selfPvt->homonymousMethod = 0;
selfPvt->next = 0;
@@ -814,11 +771,8 @@ PySideSignal* newObject(const char* name, ...)
va_list listSignatures;
char* sig = 0;
PySideSignal* self = PyObject_New(PySideSignal, PySideSignalTypeF());
- self->signalName = strdup(name);
- self->signaturesSize = 0;
- self->signatures = 0;
- self->signatureAttributes = 0;
- self->initialized = 0;
+ self->data = new PySideSignalData;
+ self->data->signalName = name;
self->homonymousMethod = 0;
va_start(listSignatures, name);
@@ -897,11 +851,8 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject)
SignalSigMap::Iterator end = signalsFound.end();
for (; it != end; ++it) {
PySideSignal* self = PyObject_New(PySideSignal, PySideSignalTypeF());
- self->signalName = strdup(it.key().constData());
- self->signaturesSize = 0;
- self->signatures = 0;
- self->signatureAttributes = 0;
- self->initialized = false;
+ self->data = new PySideSignalData;
+ self->data->signalName = it.key();
self->homonymousMethod = 0;
// Empty signatures comes first! So they will be the default signal signature
@@ -918,11 +869,9 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject)
}
}
-PyObject* buildQtCompatible(const char* signature)
+PyObject* buildQtCompatible(const QByteArray &signature)
{
- QByteArray ba;
- ba.append(QT_SIGNAL_SENTINEL);
- ba.append(signature);
+ const auto ba = QT_SIGNAL_SENTINEL + signature;
return Shiboken::String::fromStringAndSize(ba, ba.size());
}
@@ -941,13 +890,6 @@ const char* getSignature(PySideSignalInstance* signal)
return signal->d->signature;
}
-const char** getSignatures(PyObject* signal, int* size)
-{
- PySideSignal* self = reinterpret_cast<PySideSignal*>(signal);
- *size = self->signaturesSize;
- return const_cast<const char**>(self->signatures);
-}
-
QStringList getArgsFromSignature(const char* signature, bool* isShortCircuit)
{
const QString qsignature = QLatin1String(signature);
@@ -1058,6 +1000,11 @@ QString codeCallbackName(PyObject* callback, const QString& funcName)
return funcName + QString::number(quint64(callback), 16);
}
+QByteArray voidType()
+{
+ return QByteArrayLiteral("void");
+}
+
} //namespace Signal
} //namespace PySide
diff --git a/sources/pyside2/libpyside/pysidesignal_p.h b/sources/pyside2/libpyside/pysidesignal_p.h
index 24cbde50..a5cd67f6 100644
--- a/sources/pyside2/libpyside/pysidesignal_p.h
+++ b/sources/pyside2/libpyside/pysidesignal_p.h
@@ -42,40 +42,51 @@
#include <sbkpython.h>
+#include <QtCore/QByteArray>
+#include <QtCore/QVector>
+
+struct PySideSignalData
+{
+ struct Signature
+ {
+ QByteArray signature;
+ int attributes;
+ };
+
+ QByteArray signalName;
+ QVector<Signature> signatures;
+};
+
extern "C"
{
extern PyTypeObject *PySideSignalTypeF(void);
struct PySideSignal {
PyObject_HEAD
- bool initialized;
- char* signalName;
- char** signatures;
- int* signatureAttributes;
- int signaturesSize;
+ PySideSignalData *data;
PyObject* homonymousMethod;
};
struct PySideSignalInstance;
- struct PySideSignalInstancePrivate {
- char* signalName;
- char* signature;
- int attributes;
- PyObject* source;
- PyObject* homonymousMethod;
- PySideSignalInstance* next;
- };
-
-
}; //extern "C"
+struct PySideSignalInstancePrivate
+{
+ QByteArray signalName;
+ QByteArray signature;
+ int attributes = 0;
+ PyObject *source = nullptr;
+ PyObject *homonymousMethod = nullptr;
+ PySideSignalInstance *next = nullptr;
+};
+
namespace PySide { namespace Signal {
void init(PyObject* module);
bool connect(PyObject* source, const char* signal, PyObject* callback);
- char* getTypeName(PyObject*);
- const char** getSignatures(PyObject* self, int *size);
+ QByteArray getTypeName(PyObject *);
QString codeCallbackName(PyObject* callback, const QString& funcName);
+ QByteArray voidType();
}} //namespace PySide
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 694b5b59..4104c090 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -48,12 +48,17 @@
#define SLOT_DEC_NAME "Slot"
+struct SlotData
+{
+ QByteArray name;
+ QByteArray args;
+ QByteArray resultType;
+};
+
typedef struct
{
PyObject_HEAD
- char* slotName;
- char* args;
- char* resultType;
+ SlotData *slotData;
} PySideSlot;
extern "C"
@@ -103,31 +108,25 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
}
PySideSlot *data = reinterpret_cast<PySideSlot*>(self);
+ if (!data->slotData)
+ data->slotData = new SlotData;
for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
PyObject *argType = PyTuple_GET_ITEM(args, i);
- char *typeName = PySide::Signal::getTypeName(argType);
- if (typeName) {
- 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, typeName);
- free(typeName);
- } else {
- data->args = typeName;
- }
- } else {
+ const auto typeName = PySide::Signal::getTypeName(argType);
+ if (typeName.isEmpty()) {
PyErr_Format(PyExc_TypeError, "Unknown signal argument type: %s", Py_TYPE(argType)->tp_name);
return -1;
}
+ if (!data->slotData->args.isEmpty())
+ data->slotData->args += ',';
+ data->slotData->args += typeName;
}
if (argName)
- data->slotName = strdup(argName);
+ data->slotData->name = argName;
- if (argResult)
- data->resultType = PySide::Signal::getTypeName(argResult);
- else
- data->resultType = strdup("void");
+ data->slotData->resultType = argResult
+ ? PySide::Signal::getTypeName(argResult) : PySide::Signal::voidType();
return 1;
}
@@ -142,15 +141,15 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
if (PyFunction_Check(callback)) {
PySideSlot *data = reinterpret_cast<PySideSlot*>(self);
- if (!data->slotName) {
- PyObject *funcName = PepFunction_GetName(callback);
- data->slotName = strdup(Shiboken::String::toCString(funcName));
- }
+ if (!data->slotData)
+ data->slotData = new SlotData;
+
+ if (data->slotData->name.isEmpty())
+ data->slotData->name = Shiboken::String::toCString(PepFunction_GetName(callback));
- const QByteArray returnType = QMetaObject::normalizedType(data->resultType);
+ const QByteArray returnType = QMetaObject::normalizedType(data->slotData->resultType);
const QByteArray signature =
- returnType + ' ' + const_cast<const char *>(data->slotName)
- + '(' + const_cast<const char *>(data->args) + ')';
+ returnType + ' ' + data->slotData->name + '(' + data->slotData->args + ')';
if (!pySlotName)
pySlotName = Shiboken::String::fromCString(PYSIDE_SLOT_LIST_ATTR);
@@ -169,12 +168,8 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
Py_DECREF(pySignature);
//clear data
- free(data->slotName);
- data->slotName = 0;
- free(data->resultType);
- data->resultType = 0;
- free(data->args);
- data->args = 0;
+ delete data->slotData;
+ data->slotData = nullptr;
return callback;
}
return callback;