aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppgenerator.cpp166
-rw-r--r--cppgenerator.h2
-rw-r--r--headergenerator.cpp14
-rw-r--r--libshiboken/pyenum.cpp32
-rw-r--r--libshiboken/pyenum.h8
5 files changed, 87 insertions, 135 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 0ab0b1f20..905b178aa 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -706,7 +706,14 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadDa
if (!implicitConvs.isEmpty())
s << '(';
- s << cpythonCheckFunction(argType, numberType) << '(' << argumentName << ')';
+ if (argType->typeEntry()->isFlags())
+ s << cpythonCheckFunction(((FlagsTypeEntry*) argType->typeEntry())->originator(), true);
+ else if (argType->isEnum())
+ s << cpythonCheckFunction(argType, false, true);
+ else
+ s << cpythonCheckFunction(argType, numberType);
+
+ s << '(' << argumentName << ')';
if (!implicitConvs.isEmpty())
s << " || " << cpythonIsConvertibleFunction(argType) << '(' << argumentName << "))";
@@ -1446,40 +1453,43 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << INDENT << "enum_item = Shiboken::PyEnumObject_New(&";
s << cpythonName << "_Type," << endl;
- s << INDENT << INDENT << INDENT << '\"' << enumValue->name() << "\",";
- s << "(long) ";
- if (cppEnum->enclosingClass())
- s << cppEnum->enclosingClass()->qualifiedCppName() << "::";
- s << enumValue->name() << ");" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "(long) ";
+ if (cppEnum->enclosingClass())
+ s << cppEnum->enclosingClass()->qualifiedCppName() << "::";
+ s << enumValue->name() << ", \"" << enumValue->name() << "\");" << endl;
+ }
s << INDENT << addFunction << endl;
- s << INDENT << INDENT << INDENT << '\"' << enumValue->name() << "\", enum_item);" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << '"' << enumValue->name() << "\", enum_item);" << endl;
+ }
}
s << endl;
}
-void CppGenerator::writeEnumNewMethod(QTextStream& s, const AbstractMetaEnum* cppEnum)
+void CppGenerator::writeFlagsNewMethod(QTextStream& s, const FlagsTypeEntry* cppFlags)
{
- QString cpythonName = cpythonEnumName(cppEnum);
-
+ QString cpythonName = cpythonFlagsName(cppFlags);
s << "static PyObject*" << endl;
s << cpythonName << "_New(PyTypeObject *type, PyObject *args, PyObject *kwds)" << endl;
s << '{' << endl;
-
s << INDENT << "if (!PyType_IsSubtype(type, &" << cpythonName << "_Type))" << endl;
s << INDENT << INDENT << "return 0;" << endl << endl;
-
- s << INDENT << "PyStringObject* item_name;" << endl;
s << INDENT << "int item_value;" << endl;
-
- s << INDENT << "if (!PyArg_ParseTuple(args, \"Si:__new__\", &item_name, &item_value))" << endl;
- s << INDENT << INDENT << "return 0;" << endl << endl;
-
- s << INDENT << "PyObject* self = Shiboken::PyEnumObject_New";
- s << "(type, (PyObject*) item_name, item_value);" << endl;
-
- s << endl << INDENT << "if (!self)" << endl << INDENT << INDENT << "return 0;" << endl;
-
+ s << INDENT << "if (!PyArg_ParseTuple(args, \"i:__new__\", &item_value))" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "return 0;" << endl;
+ }
+ s << INDENT << "PyObject* self = Shiboken::PyEnumObject_New(type, item_value);" << endl << endl;
+ s << INDENT << "if (!self)" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "return 0;" << endl;
+ }
s << INDENT << "return self;" << endl << '}' << endl;
}
@@ -1490,16 +1500,6 @@ void CppGenerator::writeEnumDefinition(QTextStream& s, const AbstractMetaEnum* c
if (cppEnum->typeEntry()->flags())
tp_as_number = QString("&%1_as_number").arg(cpythonName);
- QString newFunc;
-
- if (cppEnum->typeEntry()->isExtensible()) {
- newFunc = QString("(newfunc)") + cpythonName + "_New";
- writeEnumNewMethod(s, cppEnum);
- s << endl;
- } else {
- newFunc = "Shiboken::PyEnumObject_NonExtensibleNew";
- }
-
s << "static PyGetSetDef " << cpythonName << "_getsetlist[] = {" << endl;
s << INDENT << "{const_cast<char*>(\"name\"), (getter)Shiboken::PyEnumObject_name}," << endl;
s << INDENT << "{0} // Sentinel" << endl;
@@ -1544,7 +1544,7 @@ void CppGenerator::writeEnumDefinition(QTextStream& s, const AbstractMetaEnum* c
s << INDENT << "/*tp_dictoffset*/ 0," << endl;
s << INDENT << "/*tp_init*/ 0," << endl;
s << INDENT << "/*tp_alloc*/ 0," << endl;
- s << INDENT << "/*tp_new*/ " << newFunc << ',' << endl;
+ s << INDENT << "/*tp_new*/ Shiboken::PyEnumObject_NonExtensibleNew," << endl;
s << INDENT << "/*tp_free*/ 0," << endl;
s << INDENT << "/*tp_is_gc*/ 0," << endl;
s << INDENT << "/*tp_bases*/ 0," << endl;
@@ -1622,9 +1622,13 @@ void CppGenerator::writeFlagsDefinition(QTextStream& s, const AbstractMetaEnum*
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
if (!flagsEntry)
return;
- QString cpythonName = cpythonFlagsName(cppEnum);
+ QString cpythonName = cpythonFlagsName(flagsEntry);
QString enumName = cpythonEnumName(cppEnum);
+ QString newFunc = QString("(newfunc)") + cpythonName + "_New";
+ writeFlagsNewMethod(s, flagsEntry);
+ s << endl;
+
s << "PyTypeObject " << cpythonName << "_Type = {" << endl;
s << INDENT << "PyObject_HEAD_INIT(&PyType_Type)" << endl;
s << INDENT << "/*ob_size*/ 0," << endl;
@@ -1664,7 +1668,7 @@ void CppGenerator::writeFlagsDefinition(QTextStream& s, const AbstractMetaEnum*
s << INDENT << "/*tp_dictoffset*/ 0," << endl;
s << INDENT << "/*tp_init*/ 0," << endl;
s << INDENT << "/*tp_alloc*/ 0," << endl;
- s << INDENT << "/*tp_new*/ Shiboken::PyEnumObject_NonExtensibleNew," << endl;
+ s << INDENT << "/*tp_new*/ " << newFunc << ',' << endl;
s << INDENT << "/*tp_free*/ 0," << endl;
s << INDENT << "/*tp_is_gc*/ 0," << endl;
s << INDENT << "/*tp_bases*/ 0," << endl;
@@ -1680,39 +1684,18 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEn
{
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
Q_ASSERT(flagsEntry);
- QString cppName = cppEnum->typeEntry()->name();
- QString cpythonName = cpythonEnumName(cppEnum);
- QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
- s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
+ s << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
- s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
+ s << INDENT << "return Shiboken::Converter< " << flagsEntry->originalName() << " >::toPython(" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "py_result = Shiboken::Converter< ";
- s << flagsEntry->originalName() << " >::toPython(" << endl;
- s << INDENT << "((" << flagsEntry->originalName() << ") ((PyEnumObject*)self)->ob_ival) " << cppOpName << endl;
- s << INDENT << "Shiboken::Converter< " << cppEnum->typeEntry()->qualifiedCppName() << " >::toCpp(arg)" << endl;
- s << INDENT << ");" << endl;
- }
- QString typeErrorLabel = QString("%1___%2___TypeError").arg(cpythonName).arg(pyOpName);
- s << INDENT << "} else goto " << typeErrorLabel << ';' << endl << endl;
-
- s << INDENT << "if (PyErr_Occurred() || !py_result)" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "return 0;" << endl;
- }
- s << endl << INDENT << "return py_result;" << endl << endl;
- s << INDENT << typeErrorLabel << ':' << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "PyErr_SetString(PyExc_TypeError, \"'__" << pyOpName;
- s << "__()' called with wrong parameters.\");" << endl;
- s << INDENT << "return 0;" << endl;
+ s << INDENT << "((" << flagsEntry->originalName() << ") ((PyEnumObject*)self)->ob_ival)" << endl;
+ s << INDENT << cppOpName << " Shiboken::Converter< ";
+ s << flagsEntry->originalName() << " >::toCpp(arg)" << endl;
}
+ s << INDENT << ");" << endl;
s << '}' << endl << endl;
}
@@ -1721,38 +1704,16 @@ void CppGenerator::writeFlagsInplaceOperator(QTextStream& s, const AbstractMetaE
{
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
Q_ASSERT(flagsEntry);
- QString cppName = cppEnum->typeEntry()->name();
- QString cpythonName = cpythonEnumName(cppEnum);
- QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
- s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
+ s << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
- s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "((" << flagsEntry->originalName() << ") ((PyEnumObject*)self)->ob_ival) " << cppOpName << endl;
- s << INDENT << "Shiboken::Converter< " << cppEnum->typeEntry()->qualifiedCppName() << " >::toCpp(arg);" << endl;
- }
- QString typeErrorLabel = QString("%1___%2___TypeError").arg(cpythonName).arg(pyOpName);
- s << INDENT << "} else goto " << typeErrorLabel << ';' << endl << endl;
- s << INDENT << "if (PyErr_Occurred() || !py_result)" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "return 0;" << endl;
- }
- s << endl;
+ s << INDENT << "((" << flagsEntry->originalName() << ") ((PyEnumObject*)self)->ob_ival) " << cppOpName << endl;
+ s << INDENT << "Shiboken::Converter< " << flagsEntry->originalName() << " >::toCpp(arg);" << endl;
+
s << INDENT << "Py_INCREF(self);" << endl;
- s << INDENT << "return self;" << endl << endl;
- s << INDENT << typeErrorLabel << ':' << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "PyErr_SetString(PyExc_TypeError, \"'__" << pyOpName;
- s << "__()' called with wrong parameters.\");" << endl;
- s << INDENT << "return 0;" << endl;
- }
+ s << INDENT << "return self;" << endl;
s << '}' << endl << endl;
}
@@ -1761,35 +1722,18 @@ void CppGenerator::writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnu
{
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
Q_ASSERT(flagsEntry);
- QString cppName = cppEnum->typeEntry()->name();
- QString cpythonName = cpythonEnumName(cppEnum);
- QString checkFunction = cpythonCheckFunction(cppEnum->typeEntry());
s << "PyObject*" << endl;
- s << cpythonName << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
+ s << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* self, PyObject* arg)" << endl;
s << '{' << endl;
- s << INDENT << "PyObject* py_result = 0;" << endl;
- s << INDENT << "if (" << checkFunction << "(arg)) {" << endl;
+ s << INDENT << "return Shiboken::Converter< " << (boolResult ? "bool" : flagsEntry->originalName());
+ s << " >::toPython(" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "py_result = Shiboken::Converter< ";
- if (boolResult)
- s << "bool";
- else
- s << flagsEntry->originalName();
- s << " >::toPython(" << endl;
- s << INDENT << ' ' << cppOpName << " Shiboken::Converter< ";
+ s << INDENT << cppOpName << " Shiboken::Converter< ";
s << flagsEntry->originalName() << " >::toCpp(arg)" << endl;
- s << INDENT << ");" << endl;
- }
- s << INDENT << '}' << endl << endl;
-
- s << INDENT << "if (PyErr_Occurred() || !py_result)" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "return 0;" << endl;
}
- s << endl << INDENT << "return py_result;" << endl;
+ s << INDENT << ");" << endl;
s << '}' << endl << endl;
}
diff --git a/cppgenerator.h b/cppgenerator.h
index 3e50d1eb8..91517c6d0 100644
--- a/cppgenerator.h
+++ b/cppgenerator.h
@@ -94,7 +94,7 @@ private:
void writeRichCompareFunction(QTextStream& s, const AbstractMetaClass* metaClass);
- void writeEnumNewMethod(QTextStream& s, const AbstractMetaEnum* metaEnum);
+ void writeFlagsNewMethod(QTextStream& s, const FlagsTypeEntry* cppFlags);
void writeEnumDefinition(QTextStream& s, const AbstractMetaEnum* metaEnum);
void writeEnumInitialization(QTextStream& s, const AbstractMetaEnum* metaEnum);
diff --git a/headergenerator.cpp b/headergenerator.cpp
index ab5e563cf..75d7333ae 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -246,13 +246,7 @@ void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* ty
s << "PyBaseWrapper_New(&" << pyTypeName << ", &" << pyTypeName << ',';
} else {
// Type is enum or flag
- s << "PyEnumObject_New(" << endl;
- {
- Indentation indent1(INDENT);
- Indentation indent2(INDENT);
- s << INDENT << '&' << pyTypeName << ',' << endl;
- s << INDENT << "\"ReturnedValue\", (long)";
- }
+ s << "PyEnumObject_New(&" << pyTypeName << ", (long)";
}
s << " cppobj);" << endl;
s << '}' << endl << endl;
@@ -350,6 +344,9 @@ void HeaderGenerator::finishGeneration()
if (!incFile.isEmpty())
enumIncludes << cppEnum->includeFile();
writeTypeCheckMacro(s_pts, cppEnum->typeEntry());
+ FlagsTypeEntry* flags = cppEnum->typeEntry()->flags();
+ if (flags)
+ writeTypeCheckMacro(s_pts, flags);
s_pts << endl;
writeTypeConverterDecl(convDecl, cppEnum->typeEntry());
writeTypeConverterImpl(convImpl, cppEnum->typeEntry());
@@ -371,14 +368,15 @@ void HeaderGenerator::finishGeneration()
foreach (const AbstractMetaEnum* cppEnum, metaClass->enums()) {
writeTypeCheckMacro(s_pts, cppEnum->typeEntry());
- s_pts << endl;
writeTypeConverterDecl(convDecl, cppEnum->typeEntry());
writeTypeConverterImpl(convImpl, cppEnum->typeEntry());
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
if (flagsEntry) {
+ writeTypeCheckMacro(s_pts, flagsEntry);
writeTypeConverterDecl(convDecl, flagsEntry);
writeTypeConverterImpl(convImpl, flagsEntry);
}
+ s_pts << endl;
convDecl << endl;
}
diff --git a/libshiboken/pyenum.cpp b/libshiboken/pyenum.cpp
index 6af1d168e..be15496a5 100644
--- a/libshiboken/pyenum.cpp
+++ b/libshiboken/pyenum.cpp
@@ -38,8 +38,10 @@ namespace Shiboken
{
PyObject*
-PyEnumObject_New(PyTypeObject *type, PyObject* item_name, long item_value)
+PyEnumObject_New(PyTypeObject *type, long item_value, PyObject* item_name)
{
+ if (!item_name)
+ item_name = PyString_FromString("");
PyEnumObject* enum_obj = (PyEnumObject*) type->tp_alloc(type, 0);
enum_obj->ob_name = item_name;
enum_obj->ob_ival = item_value;
@@ -47,20 +49,27 @@ PyEnumObject_New(PyTypeObject *type, PyObject* item_name, long item_value)
}
PyObject*
-PyEnumObject_New(PyTypeObject *type, const char* item_name, long item_value)
+PyEnumObject_New(PyTypeObject *type, long item_value, const char* item_name)
{
- PyObject* py_item_name = PyString_FromString(item_name);
- PyObject* enum_obj = PyEnumObject_New(type, py_item_name, item_value);
+ PyObject* py_item_name = 0;
+ if (item_name)
+ py_item_name = PyString_FromString(item_name);
+
+ PyObject* enum_obj = PyEnumObject_New(type, item_value, py_item_name);
if (!enum_obj) {
- Py_DECREF(py_item_name);
+ Py_XDECREF(py_item_name);
return 0;
}
- PyObject* values = PyDict_GetItemString(type->tp_dict, const_cast<char*>("values"));
- if (!values) {
- values = PyDict_New();
- PyDict_SetItemString(type->tp_dict, const_cast<char*>("values"), values);
+
+ if (item_name) {
+ PyObject* values = PyDict_GetItemString(type->tp_dict, const_cast<char*>("values"));
+ if (!values) {
+ values = PyDict_New();
+ PyDict_SetItemString(type->tp_dict, const_cast<char*>("values"), values);
+ }
+ PyDict_SetItemString(values, item_name, enum_obj);
}
- PyDict_SetItemString(values, item_name, enum_obj);
+
return enum_obj;
}
@@ -70,7 +79,7 @@ extern "C"
PyObject*
PyEnumObject_NonExtensibleNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyErr_SetString(PyExc_TypeError, "this enum is not extensible");
+ PyErr_SetString(PyExc_TypeError, "enum is not extensible");
return 0;
}
@@ -94,3 +103,4 @@ PyEnumObject_name(PyObject* self)
} // extern "C"
} // namespace Shiboken
+
diff --git a/libshiboken/pyenum.h b/libshiboken/pyenum.h
index 379072ae2..ab32052a4 100644
--- a/libshiboken/pyenum.h
+++ b/libshiboken/pyenum.h
@@ -56,11 +56,11 @@ PyAPI_FUNC(PyObject*) PyEnumObject_NonExtensibleNew(PyTypeObject* type, PyObject
} // extern "C"
PyObject* PyEnumObject_New(PyTypeObject *instanceType,
- const char* item_name,
- long item_value);
+ long item_value,
+ const char* item_name);
PyObject* PyEnumObject_New(PyTypeObject *instanceType,
- PyObject* item_name,
- long item_value);
+ long item_value,
+ PyObject* item_name = 0);
} // namespace Shiboken