Property *RClass::property(const char *name) const { Property *prop; SEXP rprop = findVarInFrame(properties(), install(name)); if (rprop != R_UnboundValue) { SEXP rtype = VECTOR_ELT(rprop, R_PROP_TYPE); SmokeType type; if (rtype == R_NilValue) type = SmokeType(smokeBase()->smoke(), (Smoke::Index)0); else type = SmokeType(smokeBase()->smoke(), CHAR(asChar(rtype))); prop = new RProperty(name, type, VECTOR_ELT(rprop, R_PROP_READER), VECTOR_ELT(rprop, R_PROP_WRITER)); } else prop = parent()->property(name); return prop; }
QVariant MocProperty::stackItemToQVariant(const Smoke::StackItem &item, Smoke *s) const { QVector<SmokeType> types; types += SmokeType(s, _property.typeName()); MocStack mocStack(SmokeStack(const_cast<Smoke::Stack>(&item), 1), types); QVariant(_property.type(), mocStack.items()[0]); }
Smoke::StackItem MocProperty::stackItemFromQVariant(QVariant variant, Smoke *s) const { void *ptr = const_cast<void *>(variant.constData()); // undocumented MocStack mocStack(&ptr, 1); QVector<SmokeType> types; types += SmokeType(s, variant.typeName()); return mocStack.toSmoke(types).ret(); }
bool matches_arg(Smoke *smoke, Smoke::Index meth, Smoke::Index argidx, const char *argtype) { Smoke::Index *arg = smoke->argumentList + smoke->methods[meth].args + argidx; SmokeType type = SmokeType(smoke, *arg); if (type.name() && qstrcmp(type.name(), argtype) == 0) { return true; } return false; }
/* Sometimes, an element only exists in a collection (as a value). But Smoke will include a type for it in pointer (*) form. */ SmokeType findElementType(Smoke *smoke, const char *name) { SmokeType elementType(smoke, name); if (elementType.isVoid()) { QByteArray typeName(name); typeName.append("*"); elementType = SmokeType(smoke, typeName.constData()); if (elementType.isVoid()) error("Cannot type for element: %s", name); } return elementType; }
/* We catch all qt_metacall invocations */ extern "C" SEXP qt_qmetacall(SEXP x, SEXP s_call, SEXP s_id, SEXP s_args) { SmokeObject *so = SmokeObject::fromSexp(x); QMetaObject::Call call = enum_from_sexp<QMetaObject::Call>(s_call, SmokeType()); int id = from_sexp<int>(s_id); void **args = reinterpret_cast<void **>(from_sexp<void *>(s_args)); // Assume the target slot is a C++ one Smoke::StackItem i[4]; i[1].s_enum = call; i[2].s_int = id; i[3].s_voidp = args; so->invokeMethod("qt_metacall$$?", i); int ret = i[0].s_int; if (ret < 0) { return ScalarInteger(ret); } if (call != QMetaObject::InvokeMetaMethod) return ScalarInteger(id); QObject * qobj = reinterpret_cast<QObject *>(so->castPtr("QObject")); // get obj metaobject with a virtual call const QMetaObject *metaobject = qobj->metaObject(); // get method count int count = metaobject->methodCount(); QMetaMethod method = metaobject->method(id); if (method.methodType() == QMetaMethod::Signal) { // FIXME: this override of 'activate' is obsolete metaobject->activate(qobj, id, (void**) args); return ScalarInteger(id - count); } DynamicBinding binding(MocMethod(so->smoke(), metaobject, id)); QVector<SmokeType> stackTypes = binding.types(); MocStack mocStack = MocStack(args, stackTypes.size()); SmokeStack smokeStack = mocStack.toSmoke(stackTypes); binding.invoke(so, smokeStack.items()); mocStack.returnFromSmoke(smokeStack, stackTypes[0]); if (binding.lastError() == Method::NoError) warning("Slot invocation failed for %s::%s", so->klass()->name(), binding.name()); return ScalarInteger(id - count); }
QList<MocArgument*> PHPQt::QtToMoc( Smoke* smoke, void** a, const QList<QByteArray> methodTypes ) { static QRegExp * rx = 0; if( rx == 0 ) rx = new QRegExp("^(bool|int|uint|long|ulong|double|char\\*|QString)&?$"); QList<MocArgument*> result; foreach( QByteArray typeName, methodTypes ) { MocArgument* arg = new MocArgument; Smoke::Index typeId = 0; if( typeName.isEmpty() ) { arg->argType = xmoc_void; result.append( arg ); } else { typeName.replace( "const ", "" ); QString staticType = ( rx->indexIn(typeName) != -1 ? rx->cap(1) : "ptr" ); if ( staticType == "ptr" ) { arg->argType = xmoc_ptr; QByteArray targetType = typeName; typeId = smoke->idType(targetType.constData()); if (typeId == 0 && !typeName.contains('*')) { if (!typeName.contains("&")) { targetType += "&"; } typeId = smoke->idType(targetType.constData()); } } else if ( staticType == "bool" ) { arg->argType = xmoc_bool; } else if ( staticType == "int" ) { arg->argType = xmoc_int; } else if ( staticType == "uint" ) { arg->argType = xmoc_uint; } else if ( staticType == "long" ) { arg->argType = xmoc_long; } else if ( staticType == "ulong" ) { arg->argType = xmoc_ulong; } else if ( staticType == "double" ) { arg->argType = xmoc_double; } else if ( staticType == "char*" ) { arg->argType = xmoc_charstar; } else if ( staticType == "QString" ) { arg->argType = xmoc_QString; typeName += "*"; } typeId = smoke->idType( typeName.constData() ); smoke = qt_Smoke; if( typeId == 0 ) { pNotice() << "Cannot handle " << typeName << " as slot argument"; return result; } arg->st.set( smoke, typeId ); result.append( arg ); } #ifdef THOMAS_MAYBE_TO_BE_REMOVED { smokephp_object *o = PHPQt::getSmokePHPObjectFromQt(a[i]); mocStack[i].st = SmokeType(PHPQt::smoke(),o->classId()); mocStack[i].argType = xmoc_void; } #endif }
// time critical QByteArray PHPQt::getSignature(const int argc, zval **argv, MocArgument* mocStack) { mocStack[0].argType = xmoc_bool; // the return type mocStack[0].st = SmokeType( PHPQt::smoke(), PHPQt::smoke()->idType("bool") ); QByteArray signature( "(" ); for(int i=0; i<argc; i++) { const uint type = static_cast< int >( argv[i]->type ); mocStack[ i+1 ].st = SmokeType( PHPQt::smoke(), 0 ); switch( type ) { case IS_RESOURCE: // @TODO add resource type break; case IS_ARRAY: // @TODO xmoc_ptr, php_error( E_WARNING, "Array given as signal argument" ); break; case IS_BOOL: mocStack[i+1].argType = xmoc_bool; mocStack[i+1].st = SmokeType( PHPQt::smoke(), PHPQt::smoke()->idType("bool") ); signature.append( "bool" ); break; case IS_LONG: mocStack[i+1].argType = xmoc_int; mocStack[i+1].st = SmokeType( PHPQt::smoke(), PHPQt::smoke()->idType("int") ); signature.append( "int" ); break; case IS_DOUBLE: mocStack[i+1].argType = xmoc_double; mocStack[i+1].st = SmokeType( PHPQt::smoke(), PHPQt::smoke()->idType("double") ); signature.append( "double" ); break; case IS_STRING: mocStack[i+1].argType = xmoc_charstar; mocStack[i+1].st = SmokeType( PHPQt::smoke(), PHPQt::smoke()->idType("char*") ); signature.append( "string" ); break; case IS_OBJECT: if(Z_OBJCE_P( argv[i] ) == qstring_ce) mocStack[i+1].argType = xmoc_QString; else { smokephp_object *o = PHPQt::getSmokePHPObjectFromZval( argv[i] ); mocStack[i+1].st = SmokeType( PHPQt::smoke(), o->classId() ); mocStack[i+1].argType = xmoc_void; } signature.append( "object" ); default: php_error( E_ERROR,"Unknown argument or unsupported argument type %d, type %d, exit\n", i, type ); exit(FAILURE); break; } // switch } signature.append( ")" ); return signature; }
SmokeType MethodCallBase::type() { return SmokeType(_smoke, _args[_cur]); }
int MethodCall::scoreArg(SEXP arg, Smoke *smoke, Smoke::Index type) { return scoreArg(arg, SmokeType(smoke, type)); }
SEXP to_sexp(QSignalSpy *signalSpy) { return to_sexp(*static_cast<QList<QList<QVariant> > *>(signalSpy), SmokeType(qt_Smoke, "QSignalSpy")); }
SEXP to_sexp(QTestEventList eventList) { return to_sexp(static_cast<QList<QTestEvent*> >(eventList), SmokeType(qt_Smoke, "QTestEventList")); }
SEXP to_sexp(QItemSelection selection) { return to_sexp(static_cast<QList<QItemSelectionRange> >(selection), SmokeType(qt_Smoke, "QItemSelection")); }
SEXP to_sexp(QVariant variant) { SEXP ans = NULL; switch(variant.type()) { case QMetaType::Void: ans = R_NilValue; break; case QMetaType::UChar: ans = ScalarRaw(variant.value<unsigned char>()); break; case QMetaType::Bool: ans = ScalarLogical(variant.value<bool>()); break; case QMetaType::Int: case QMetaType::UInt: case QMetaType::Long: case QMetaType::Short: case QMetaType::UShort: ans = ScalarInteger(variant.value<int>()); break; case QMetaType::Double: case QMetaType::LongLong: case QMetaType::ULong: case QMetaType::ULongLong: case QMetaType::Float: ans = ScalarReal(variant.value<double>()); break; case QMetaType::QChar: case QMetaType::Char: case QMetaType::QString: ans = qstring2sexp(variant.value<QString>()); break; case QMetaType::QByteArray: ans = to_sexp(variant.value<QByteArray>()); break; case QMetaType::VoidStar: ans = wrapPointer(variant.value<void *>()); break; case QMetaType::QObjectStar: ans = ptr_to_sexp(variant.value<QObject *>(), SmokeType(qt_Smoke, "QObject")); break; case QMetaType::QWidgetStar: ans = ptr_to_sexp(variant.value<QWidget *>(), SmokeType(qt_Smoke, "QWidget")); break; case QMetaType::QCursor: ans = QVARIANT_TO_SEXP(variant, QCursor); break; case QMetaType::QDate: ans = QVARIANT_TO_SEXP(variant, QDate); break; case QMetaType::QSize: ans = QVARIANT_TO_SEXP(variant, QSize); case QMetaType::QSizeF: ans = QVARIANT_TO_SEXP(variant, QSizeF); break; case QMetaType::QTime: ans = QVARIANT_TO_SEXP(variant, QTime); break; case QMetaType::QVariantList: ans = to_sexp(variant.value<QVariantList>(), SmokeType(qt_Smoke, "QList<QVariant>")); break; case QMetaType::QPolygon: ans = QVARIANT_TO_SEXP(variant, QPolygon); break; case QMetaType::QColor: ans = QVARIANT_TO_SEXP(variant, QColor); break; case QMetaType::QRectF: ans = QVARIANT_TO_SEXP(variant, QRectF); break; case QMetaType::QRect: ans = QVARIANT_TO_SEXP(variant, QRect); break; case QMetaType::QLine: ans = QVARIANT_TO_SEXP(variant, QLine); break; case QMetaType::QTextLength: ans = QVARIANT_TO_SEXP(variant, QTextLength); break; case QMetaType::QStringList: ans = to_sexp(variant.value<QStringList>(), SmokeType(qt_Smoke, "QStringList")); break; case QMetaType::QVariantMap: ans = to_sexp(variant.value<QVariantMap>(), SmokeType(qt_Smoke, "QMap<QString,QVariant>")); break; case QMetaType::QVariantHash: ans = to_sexp(variant.value<QVariantHash>(), SmokeType(qt_Smoke, "QHash<QString,QVariant>")); break; case QMetaType::QIcon: ans = QVARIANT_TO_SEXP(variant, QIcon); break; case QMetaType::QPen: ans = QVARIANT_TO_SEXP(variant, QPen); break; case QMetaType::QLineF: ans = QVARIANT_TO_SEXP(variant, QLineF); break; case QMetaType::QTextFormat: ans = QVARIANT_TO_SEXP(variant, QTextFormat); break; case QMetaType::QPoint: ans = QVARIANT_TO_SEXP(variant, QPoint); break; case QMetaType::QPointF: ans = QVARIANT_TO_SEXP(variant, QPointF); break; case QMetaType::QUrl: ans = QVARIANT_TO_SEXP(variant, QUrl); break; case QMetaType::QRegExp: ans = QVARIANT_TO_SEXP(variant, QRegExp); break; case QMetaType::QDateTime: ans = QVARIANT_TO_SEXP(variant, QDateTime); break; case QMetaType::QPalette: ans = QVARIANT_TO_SEXP(variant, QPalette); break; case QMetaType::QFont: ans = QVARIANT_TO_SEXP(variant, QFont); break; case QMetaType::QBrush: ans = QVARIANT_TO_SEXP(variant, QBrush); break; case QMetaType::QRegion: ans = QVARIANT_TO_SEXP(variant, QRegion); break; case QMetaType::QBitArray: ans = QVARIANT_TO_SEXP(variant, QBitArray); break; case QMetaType::QImage: ans = QVARIANT_TO_SEXP(variant, QImage); break; case QMetaType::QKeySequence: ans = QVARIANT_TO_SEXP(variant, QKeySequence); break; case QMetaType::QSizePolicy: ans = QVARIANT_TO_SEXP(variant, QSizePolicy); break; case QMetaType::QPixmap: ans = QVARIANT_TO_SEXP(variant, QPixmap); break; case QMetaType::QLocale: ans = QVARIANT_TO_SEXP(variant, QLocale); break; case QMetaType::QBitmap: ans = QVARIANT_TO_SEXP(variant, QBitmap); break; case QMetaType::QMatrix: /* obsolete */ ans = QVARIANT_TO_SEXP(variant, QMatrix); break; #if QT_VERSION >= 0x40300 case QMetaType::QTransform: ans = QVARIANT_TO_SEXP(variant, QTransform); break; #endif #if QT_VERSION >= 0x40600 case QMetaType::QMatrix4x4: ans = QVARIANT_TO_SEXP(variant, QMatrix4x4); break; case QMetaType::QVector2D: ans = QVARIANT_TO_SEXP(variant, QVector2D); break; case QMetaType::QVector3D: ans = QVARIANT_TO_SEXP(variant, QVector3D); break; case QMetaType::QVector4D: ans = QVARIANT_TO_SEXP(variant, QVector4D); break; case QMetaType::QQuaternion: ans = QVARIANT_TO_SEXP(variant, QQuaternion); break; #endif case QMetaType::User: break; default: error("Converting from QVariant: unhandled Qt type"); } if (!ans) error("Converting from QVariant: Qt type not yet implemented"); return ans; }