diff options
-rw-r--r-- | cppgenerator.cpp | 166 | ||||
-rw-r--r-- | cppgenerator.h | 2 | ||||
-rw-r--r-- | headergenerator.cpp | 14 | ||||
-rw-r--r-- | libshiboken/pyenum.cpp | 32 | ||||
-rw-r--r-- | libshiboken/pyenum.h | 8 |
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 |