aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/sbkenum.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/sbkenum.cpp')
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp193
1 files changed, 95 insertions, 98 deletions
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index d129e6380..26b40c3cb 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -47,9 +47,11 @@
#include <string.h>
#include <cstring>
-#include <list>
+#include <vector>
#define SBK_ENUM(ENUM) reinterpret_cast<SbkEnumObject*>(ENUM)
+#define SBK_TYPE_CHECK(o) (strcmp(Py_TYPE(Py_TYPE(o))->tp_name, "Shiboken.EnumType") == 0)
+typedef PyObject* (*enum_func)(PyObject*, PyObject*);
extern "C"
{
@@ -75,7 +77,7 @@ struct SbkEnumObject
static PyObject* SbkEnumObject_repr(PyObject* self)
{
- const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
+ const SbkEnumObject *enumObj = SBK_ENUM(self);
if (enumObj->ob_name)
return Shiboken::String::fromFormat("%s.%s", (Py_TYPE(self))->tp_name, PyBytes_AS_STRING(enumObj->ob_name));
else
@@ -84,7 +86,7 @@ static PyObject* SbkEnumObject_repr(PyObject* self)
static PyObject* SbkEnumObject_name(PyObject* self, void*)
{
- SbkEnumObject *enum_self = reinterpret_cast<SbkEnumObject *>(self);
+ SbkEnumObject *enum_self = SBK_ENUM(self);
if (enum_self->ob_name == NULL)
Py_RETURN_NONE;
@@ -113,6 +115,43 @@ static PyObject* SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
return reinterpret_cast<PyObject*>(self);
}
+static PyObject* enum_op(enum_func f, PyObject *a, PyObject *b) {
+ PyObject *valA = a;
+ PyObject *valB = b;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB = true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ } else {
+ result = f(valA, valB);
+ }
+
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
+}
+
/* Notes:
* On Py3k land we use long type when using integer numbers. However, on older
* versions of Python (version 2) we need to convert it to int type,
@@ -126,48 +165,19 @@ static PyObject* enum_int(PyObject* v)
return PyInt_FromLong(SBK_ENUM(v)->ob_value);
}
-static long getNumberValue(PyObject* v)
-{
- PyObject* number = PyNumber_Long(v);
- long result = PyLong_AsLong(number);
- Py_XDECREF(number);
- return result;
-}
-
static PyObject* enum_and(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA & valB);
+ return enum_op(PyNumber_And, self, b);
}
static PyObject* enum_or(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA | valB);
+return enum_op(PyNumber_Or, self, b);
}
static PyObject* enum_xor(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA ^ valB);
+ return enum_op(PyNumber_Xor, self, b);
}
static int enum_bool(PyObject* v)
@@ -177,72 +187,63 @@ static int enum_bool(PyObject* v)
static PyObject* enum_add(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA + valB);
+ return enum_op(PyNumber_Add, self, v);
}
static PyObject* enum_subtract(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA - valB);
+ return enum_op(PyNumber_Subtract, self, v);
}
static PyObject* enum_multiply(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA * valB);
+return enum_op(PyNumber_Multiply, self, v);
}
#ifndef IS_PY3K
static PyObject* enum_divide(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyLong_FromLong(valA / valB);
+ return enum_op(PyNumber_Divide, self, v);
}
#endif
static PyObject* enum_richcompare(PyObject* self, PyObject* other, int op)
{
- int result = 0;
- if (!PyNumber_Check(other)) {
+ PyObject *valA = self;
+ PyObject *valB = other;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB =true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
+ } else {
+ result = PyObject_RichCompare(valA, valB, op);
}
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(other);
-
- switch (op) {
- case Py_EQ:
- result = (valA == valB);
- break;
- case Py_NE:
- result = (valA != valB);
- break;
- case Py_LE:
- result = (valA <= valB);
- break;
- case Py_GE:
- result = (valA >= valB);
- break;
- case Py_LT:
- result = (valA < valB);
- break;
- case Py_GT:
- result = (valA > valB);
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
- if (result)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
}
static Py_hash_t enum_hash(PyObject* pyObj)
@@ -339,15 +340,18 @@ namespace Shiboken {
class DeclaredEnumTypes
{
public:
+ DeclaredEnumTypes(const DeclaredEnumTypes&) = delete;
+ DeclaredEnumTypes(DeclaredEnumTypes&&) = delete;
+ DeclaredEnumTypes& operator=(const DeclaredEnumTypes&) = delete;
+ DeclaredEnumTypes& operator=(DeclaredEnumTypes&&) = delete;
+
DeclaredEnumTypes();
~DeclaredEnumTypes();
static DeclaredEnumTypes& instance();
void addEnumType(PyTypeObject* type);
private:
- DeclaredEnumTypes(const DeclaredEnumTypes&);
- DeclaredEnumTypes& operator=(const DeclaredEnumTypes&);
- std::list<PyTypeObject*> m_enumTypes;
+ std::vector<PyTypeObject *> m_enumTypes;
};
namespace Enum {
@@ -373,7 +377,9 @@ PyObject* getEnumItemFromValue(PyTypeObject* enumType, long itemValue)
return 0;
}
-static PyTypeObject* createEnum(const char* fullName, const char* cppName, const char* shortName, PyTypeObject* flagsType)
+static PyTypeObject* createEnum(const char* fullName, const char* cppName,
+ const char* /* shortName */,
+ PyTypeObject* flagsType)
{
PyTypeObject* enumType = newTypeWithName(fullName, cppName, flagsType);
if (PyType_Ready(enumType) < 0)
@@ -524,13 +530,8 @@ copyNumberMethods(PyTypeObject *flagsType,
int *pidx)
{
int idx = *pidx;
-#ifdef IS_PY3K
-# define SLOT slot
-#else
-# define SLOT slot_
-#endif
#define PUT_SLOT(name) \
- number_slots[idx].SLOT = (name); \
+ number_slots[idx].slot = (name); \
number_slots[idx].pfunc = PyType_GetSlot(flagsType, (name)); \
++idx;
@@ -593,8 +594,8 @@ newTypeWithName(const char* name,
newspec->flags = SbkNewType_spec.flags;
// we must append all the number methods, so rebuild everything:
int idx = 0;
- while (SbkNewType_slots[idx].SLOT) {
- newslots[idx].SLOT = SbkNewType_slots[idx].SLOT;
+ while (SbkNewType_slots[idx].slot) {
+ newslots[idx].slot = SbkNewType_slots[idx].slot;
newslots[idx].pfunc = SbkNewType_slots[idx].pfunc;
++idx;
}
@@ -644,14 +645,10 @@ DeclaredEnumTypes& DeclaredEnumTypes::instance()
return me;
}
-DeclaredEnumTypes::DeclaredEnumTypes()
-{
-}
+DeclaredEnumTypes::DeclaredEnumTypes() = default;
DeclaredEnumTypes::~DeclaredEnumTypes()
{
- std::list<PyTypeObject*>::const_iterator it = m_enumTypes.begin();
- for (; it != m_enumTypes.end(); ++it) {
/*
* PYSIDE-595: This was "delete *it;" before introducing 'PyType_FromSpec'.
* XXX what should I do now?
@@ -660,8 +657,8 @@ DeclaredEnumTypes::~DeclaredEnumTypes()
* So right now I am doing nothing. Surely wrong but no crash.
* See also the comment in function 'createGlobalEnumItem'.
*/
- //fprintf(stderr, "ttt %d %s\n", Py_REFCNT(*it), *it->tp_name);
- }
+ // for (PyTypeObject *o : m_enumTypes)
+ // fprintf(stderr, "ttt %d %s\n", Py_REFCNT(o), o->tp_name);
m_enumTypes.clear();
}