diff options
Diffstat (limited to 'kalyptus/kalyptusCxxToSmoke.pm')
-rw-r--r-- | kalyptus/kalyptusCxxToSmoke.pm | 746 |
1 files changed, 642 insertions, 104 deletions
diff --git a/kalyptus/kalyptusCxxToSmoke.pm b/kalyptus/kalyptusCxxToSmoke.pm index 3a1f53f..8aa6897 100644 --- a/kalyptus/kalyptusCxxToSmoke.pm +++ b/kalyptus/kalyptusCxxToSmoke.pm @@ -35,7 +35,7 @@ no strict "subs"; use vars qw/ $libname $rootnode $outputdir $opt $debug - $methodNumber + $methodNumber $headerSubdirectories %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %skippedClasses /; @@ -69,12 +69,16 @@ BEGIN 'TQCString' => '$', 'TQCString*' => '$', 'TQCString&' => '$', - 'TQByteArray' => '$', - 'TQByteArray&' => '$', - 'TQByteArray*' => '$', 'char*' => '$', 'TQCOORD*' => '?', 'TQRgb*' => '?', + 'Q_UINT64' => '$', + 'Q_INT64' => '$', + 'Q_LLONG' => '$', + 'tquint64' => '$', + 'qint64' => '$', + 'long long' => '$', + 'qulonglong' => '$', ); # Yes some of this is in kalyptusDataDict's ctypemap @@ -111,20 +115,23 @@ BEGIN # 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip # 'const GUID&' => 'void*', # 'TQWidgetMapper*' => 'void*', -# 'MSG*' => 'void*', + 'MSG*' => 'void*', # 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) 'TQPtrCollection::Item' => 'void*', # to avoid a warning + 'void(* )()' => 'void*', + 'void (*)(void* )' => 'void*', 'mode_t' => 'long', 'TQProcess::PID' => 'long', 'size_type' => 'int', # TQSqlRecordInfo 'TQt::ComparisonFlags' => 'uint', - 'TQt::ToolBarDock' => 'int', # compat thing, TQt shouldn't use it + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it 'TQIODevice::Offset' => 'ulong', 'WState' => 'int', 'WId' => 'ulong', 'TQRgb' => 'uint', + 'ksocklen_t' => 'uint', 'TQCOORD' => 'int', 'TQTSMFI' => 'int', 'TQt::WState' => 'int', @@ -133,16 +140,98 @@ BEGIN 'TQEventLoop::ProcessEventsFlags' => 'uint', 'TQStyle::SCFlags' => 'int', 'TQStyle::SFlags' => 'int', - 'TTQ_INT16' => 'short', - 'TTQ_INT32' => 'int', - 'TTQ_INT8' => 'char', - 'TTQ_LONG' => 'long', - 'TTQ_UINT16' => 'ushort', - 'TTQ_UINT32' => 'uint', - 'TTQ_UINT8' => 'uchar', - 'TTQ_ULONG' => 'long', + 'Q_INT16' => 'short', + 'qint16' => 'short', + 'Q_INT32' => 'int', + 'qint32' => 'int', + 'qint32&' => 'int&', + 'Q_INT8' => 'char', + 'qint8' => 'char', + 'Q_LONG' => 'long', + 'Q_UINT16' => 'ushort', + 'tquint16' => 'ushort', + 'Q_UINT32' => 'uint', + 'tquint32' => 'uint', + 'Q_UINT8' => 'uchar', + 'tquint8' => 'uchar', + 'Q_ULONG' => 'long', + 'qreal' => 'double', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'unsigned short int' => 'ushort', + 'TQt::Alignment' => 'int', + 'TQt::Orientations' => 'int', + 'TQt::DockWidgetAreas' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'AutoFormatting' => 'int', + 'DirtyFlags' => 'int', + 'EditTriggers' => 'int', + 'FindFlags' => 'int', + 'Flags' => 'int', + 'FormattingOptions' => 'int', + 'GLenum' => 'int', + 'GLint' => 'int', + 'GLuint' => 'uint', + 'LoadOperator' => 'int', + 'NumberFlags' => 'int', + 'OpenMode' => 'int', + 'Options' => 'int', + 'PaintEngineFeatures' => 'int', + 'Permissions' => 'int', + 'PrintDialogOptions' => 'int', + 'ProcessEventsFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQFile::Permissions' => 'int', + 'TQGL::FormatOptions' => 'int', + 'TQIODevice::OpenMode' => 'int', + 'TQImageReader::ImageReaderError' => 'int', + 'TQItemSelectionModel::SelectionFlags' => 'int', + 'TQPaintEngine::DirtyFlags' => 'int', + 'TQPainter::RenderHints' => 'int', + 'TQSql::ParamType' => 'int', + 'TQTextDocument::FindFlags' => 'int', + 'Q_PID' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'RenderFlags' => 'int', + 'RenderHints' => 'int', + 'SortFlags' => 'int', + 'StepEnabled' => 'int', + 'Sections' => 'int', + 'Filters' => 'int', + 'SortFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQStyle::State' => 'int', + 'TQValidator::State' => 'int', + 'TQAbstractSpinBox::StepEnabled' => 'int', + 'TQDockWidget::DockWidgetFeatures' => 'int', + 'TQStyle::SubControls' => 'int', ); +$headerSubdirectories = "kio/|tdevelop/|kinterfacedesigner/|kontact/|kate/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/|knewstuff/" + } sub writeDoc @@ -156,7 +245,7 @@ sub writeDoc mkpath( $outputdir ) unless -f $outputdir; # Define TQPtrCollection::Item, for resolveType - unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) || $main::qt4 ) { my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); warn "TQPtrCollection not found" if (!$cNode); my $node = Ast::New( 'Item' ); @@ -165,7 +254,7 @@ sub writeDoc kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); $node->AddProp( "Access", "public" ); } - + print STDERR "Preparsing...\n"; # Preparse everything, to prepare some additional data in the classes and methods @@ -224,6 +313,14 @@ sub preParseClass exists $classNode->{Tmpl} || # Don't generate standard bindings for TQString, this class is handled as a native type $className eq 'TQString' || + $className eq 'TQStringData' || + $className eq 'TQLatin1String' || + $className eq 'TQTLWExtra' || + $className eq 'TQWExtra' || + $className eq 'TQBig5Codec' || + $className eq 'TQBig5hkscsCodec' || + $className eq 'TQPtrCollection' || + $className eq 'TQGCache' || $className eq 'TQConstString' || $className eq 'TQCString' || # Don't map classes which are really arrays @@ -232,16 +329,133 @@ sub preParseClass $className eq 'TQWidgetList' || $className eq 'TQObjectList' || $className eq 'TQStrList' || + $className eq 'KCmdLineOptions' || # Those are template related $className eq 'TQTSManip' || # cause compiler errors with several gcc versions $className eq 'TQGDict' || $className eq 'TQGList' || + $className eq 'TQGArray' || $className eq 'TQGVector' || $className eq 'TQStrIList' || $className eq 'TQStrIVec' || - $className eq 'TQByteArray' || $className eq 'TQBitArray' || - $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + $className eq 'TQMapData' || + $className eq 'TQMetaEnum::Item' || + $className eq 'TQWidgetContainerPlugin' || + $className eq 'TQGArray::array_data' || + ($className eq 'TQMenuItem' and $main::qt_embedded) || + ($className eq 'TQSignal' and $main::qt_embedded) || + ($className eq 'TQWSEvent' and $main::qt_embedded) || + ($className eq 'TQMetaObjectInit' and $main::qt_embedded) || + ($className eq 'TQKoi8Codec' and $main::qt_embedded) || + $className eq 'KAccelGen' || + ($className eq 'TQAbstractUndoItem' and $main::qt4) || + ($className eq 'TQAbstractItemDelegate' and $main::qt4) || + ($className eq 'TQDebug' and $main::qt4) || + ($className eq 'TQNoDebug' and $main::qt4) || + ($className eq 'TQObjectData' and $main::qt4) || + ($className eq 'TQSysInfo' and $main::qt4) || + ($className eq 'TQPNGImageWriter' and $main::qt4) || + ($className eq 'TQPNGImagePacker' and $main::qt4) || + ($className eq 'TQTextCodec::ConverterState' and $main::qt4) || + ($className eq 'TQTextLayout::Selection' and $main::qt4) || + ($className eq 'TQTextStreamManipulator' and $main::qt4) || + $className eq 'DCOPArg' || + $className eq 'DCOPReply' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KDE' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KEntry' || + $className eq 'KEntryKey' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::ComponentFactory' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KExtendedSocket' || + $className eq 'KSocket' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KBufferedIO' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'khtml' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className eq 'TQForeachContainerBase' || # Qt4 + $className eq 'TQInputMethodEvent::Attribute' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::PaintContext' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::Selection' || # Qt4 + $className eq 'TQBrushData' || # Qt4 + $className eq 'TQIPv6Address' || # Qt4 + $className eq 'TQImageTextKeyLang' || # Qt4 + $className eq 'TQMap' || # Qt4 + $className eq 'TQMap::const_iterator' || # Qt4 + $className eq 'TQMap::iterator' || # Qt4 + $className eq 'TQMapData' || # Qt4 + $className eq 'TQMapData::Node' || # Qt4 + $className eq 'TQSharedData' || # Qt4 + $className eq 'TQPainterPath::Element' || # Qt4 + $className eq 'TQThreadStorageData' || # Qt4 + $className eq 'TQVFbHeader' || # Qt4 + $className eq 'TQStyleOptionQ3DockWindow' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQStyleOptionQ3ListViewItem' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQUpdateLaterEvent' || # Qt4 + $className eq 'TQVFbKeyData' || # Qt4 + $className eq 'TQVariant::Handler' || # Qt4 + $className eq 'TQVariant::PrivateShared' || # Qt4 + $className eq 'TQVectorData' || # Qt4 + $className eq 'TQWidgetData' || # Qt4 + $className eq 'TQThread' || # Qt4 + $className eq 'TQThreadStorage' || # Qt4 + $className eq 'TQMutex' || # Qt4 + $className eq 'TQMutexLocker' || # Qt4 + $className eq 'TQSemaphore' || # Qt4 + $className eq 'TQWaitCondition' || # Qt4 + $className eq 'TQReadWriteLock' || # Qt4 + $className eq 'TQReadLocker' || # Qt4 + $className eq 'TQWriteLocker' || + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || + $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam ) { print STDERR "Skipping $className\n" if ($debug); print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); @@ -249,7 +463,7 @@ sub preParseClass delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds return; } - + my $signalCount = 0; my $eventHandlerCount = 0; my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. @@ -264,6 +478,9 @@ sub preParseClass my $hasCopyConstructor = 0; my $hasPrivateCopyConstructor = 0; # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + # Hack to fix up KLed constructors in KDE 3.1 + my $kledAmbiguousConstructor = undef; my $doPrivate = $main::doPrivate; $main::doPrivate = 1; @@ -282,8 +499,8 @@ sub preParseClass } print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); - - if ( $name eq $classNode->{astNodeName} ) { + + if ( $name eq $classNode->{astNodeName} ) { if ( $m->{ReturnType} =~ /~/ ) { # A destructor $hasPublicDestructor = 0 if $m->{Access} ne 'public'; @@ -298,8 +515,10 @@ sub preParseClass # Copy constructor? if ( $#{$m->{ParamList}} == 0 ) { my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; - if ($theArgType =~ /$className\s*\&/) { + (my $classNameWithoutNS = $className) =~ s/^.*:://; + if ($theArgType =~ /$classNameWithoutNS\s*\&/) { $hasCopyConstructor = 1; + $m->{Flags} .= "x"; $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); } } @@ -320,7 +539,146 @@ sub preParseClass # All we want from private methods is to check for virtuals, nothing else next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KCModuleLoader' and $name eq 'errorModule') + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'insertActive') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'removeActive') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'moveActive') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileItem' and $name eq 'extraData') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD4' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButtonDelayed') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteClipboard') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteData') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteDataAsync') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'isClipboardEmpty') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'callExt') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'call') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'send') + || ($classNode->{astNodeName} eq 'DOM' and $name eq 'operator<<') # Avoid kdbgstream debugging method + || ($name eq 'qInitJpegIO' and $main::qt4) + || ($name eq 'qInitPngIO' and $main::qt4) + || ($name eq 'virtual_hook') + || ($name eq 'handle') + + # Obsolete + || ($classNode->{astNodeName} eq 'TQTextStream' and $name eq 'TQTextStream' + and @{$m->{ParamList}} == 2 and $m->{ParamList}[0]->{ArgType} eq 'TQString&') + + # Various methods to skip in Qt/E (Qt 2.3.x) + || ($main::qt_embedded + && ( ($classNode->{astNodeName} eq 'TQUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($classNode->{astNodeName} eq 'TQApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/) + || ($classNode->{astNodeName} eq 'TQPrinter' and $name =~ /^setIdle$|^setActive$/) + || ($classNode->{astNodeName} eq 'TQDragObject' and $name eq 'dragLink') + || ($classNode->{astNodeName} eq 'TQFont' and $name eq 'qwsRenderToDisk') + || ($classNode->{astNodeName} eq 'TQFontInfo' and $name eq 'font') + || ($classNode->{astNodeName} eq 'TQLineEdit' and $name eq 'getSelection') + || ($classNode->{astNodeName} eq 'TQMainWindow' and $name eq 'toolBars') + || ($classNode->{astNodeName} eq 'TQMovie' and $name eq 'setDisplayWidget') + || ($classNode->{astNodeName} eq 'TQMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/) + || ($classNode->{astNodeName} eq 'TQPainter' and $name eq 'pos') + || ($classNode->{astNodeName} eq 'TQPixmap' and $name =~ /^allocCell$|^clut$|^freeCell|^hbm|^isMultiCellPixmap|^multiCellPixmap|^multiCellBitmap|^multiCellHandle|^multiCellOffset|^numCols/) + || ($name eq 'handle') + || ($name eq 'resetInputContext') + || ($name eq 'propagateUpdates') + || ($name eq 'bytesPerLine') + || ($name eq 'scanLine') + || ($name eq 'hPal') + || ($name eq 'copyX11Data') + || ($name eq 'getX11Data') + || ($name eq 'setX11Data') + || ($name eq 'realizePal') + || ($name eq 'qwsDisplay') + || ($name eq 'fixport') + || ($name eq 'hack_strrchr') + || ($name eq 'hack_strchr') + || ($name eq 'hack_strstr') ) ) + + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + + || ($main::qt4 + && ( ($classNode->{astNodeName} eq 'TQWidgetListItem' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQColormap' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQListWidget' and $name eq 'setItemPosition') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'TQFontMetricsF' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'const TQFontMetrics&') + || ($classNode->{astNodeName} eq 'TQHttp' and $name eq 'supportedOperations') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setX') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setY') + || ($classNode->{astNodeName} eq 'TQTextObject' and $name eq 'formatType') + || ($classNode->{astNodeName} eq 'TQUrl' and $name eq 'TQUrl' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'TQUrlPrivate&') + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $name eq 'operator<<' and $m->{ParamList}[0]->{ArgType} =~ /TQDebug/) + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $#{$m->{ParamList}} > 0 and $name =~ /operator/ and $m->{ParamList}[1]->{ArgType} =~ /TQVariant::Type/) + || ($#{$m->{ParamList}} > 0 and $m->{ParamList}[0]->{ArgType} =~ /Private/) + || ($classNode->{astNodeName} eq 'TQScrollArea' and $name eq 'alignment') + || ($classNode->{astNodeName} eq 'TQScrollArea' and $name eq 'setAlignment') + || ($m->{ReturnType} =~ /QT3_SUPPORT/) ) ) + + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + # Hack for fixing up KDE 3.1 KLed where the no arg constructor was ambiguous + if ($classNode->{astNodeName} eq 'KLed' and $name eq 'KLed' && $#{$m->{ParamList}} > 0) { + if ($m->{ParamList}[0]->{ArgType} =~ /TQColor/ && defined $m->{ParamList}[0]->{DefaultValue}) { + $m->{ParamList}[0]->{DefaultValue} = undef; + if (defined $kledAmbiguousConstructor) { + $kledAmbiguousConstructor->{ParamList}[0]->{DefaultValue} = undef; + $kledAmbiguousConstructor->{FirstDefaultParam} = 1; + } + } else { + $kledAmbiguousConstructor = $m; + } + } + my $argId = 0; my $firstDefaultParam; foreach my $arg ( @{$m->{ParamList}} ) { @@ -334,16 +692,18 @@ sub preParseClass or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor - or $arg->{ArgType} eq 'TQtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + or $arg->{ArgType} =~ /Node\s*\*/ # ) { $m->{NodeType} = 'deleted'; } else { # Resolve type in full, e.g. for TQSessionManager::RestartHint - # (x_TQSessionManager doesn't inherit TQSessionManager) + # (x_QSessionManager doesn't inherit TQSessionManager) $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); registerType( $arg->{ArgType} ); $argId++; @@ -355,7 +715,14 @@ sub preParseClass } elsif( $m->{NodeType} eq "enum" ) { my $fullEnumName = $className."::".$m->{astNodeName}; - $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName + + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName if $m->{astNodeName} and $m->{Access} ne 'private'; # Define a type for this enum @@ -367,21 +734,60 @@ sub preParseClass #print STDERR "$fullEnumName is an enum\n"; } elsif( $m->{NodeType} eq 'var' ) { + if ( ($classNode->{astNodeName} eq 'TQUuid' and $name eq 'data4') + || ($name eq 'd') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'mIncomingMetaData') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'mOutgoingMetaData') ) + { + $m->{NodeType} = 'deleted'; + next; + } + my $varType = $m->{Type}; - # We are interested in public static vars, like TQColor::blue - if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' ) - { $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/^\s*//; $varType =~ s/\s*$//; - print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); - - # Register the type - registerType( $varType ); - - } else { - # To avoid duplicating the above test, we just get rid of any other var - $m->{NodeType} = 'deleted'; - } + $varType =~ s/static\s+//; + + if ( $m->{Flags} =~ "s" ) { + # We are interested in public static vars, like TQColor::blue + if ( $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + } else { + $m->{NodeType} = 'deleted'; + } + } elsif ($m->{Access} eq 'public') { + # Add a setter method for a public instance variable + my $setMethod = $name; + if ($setMethod =~ /^(\w)(.*)/) { + my $ch = $1; + $ch =~ tr/a-z/A-Z/; + $setMethod = "set$ch$2"; + } + my $node = Ast::New( $setMethod ); + $node->AddProp( "NodeType", "method" ); + # Flags of "=" for a setter method + $node->AddProp( "Flags", "=" ); + $node->AddProp( "ReturnType", "void" ); + $node->AddProp( "Params", $varType ); + + my $param = Ast::New( 1 ); + $param->AddProp( "NodeType", "param" ); + $param->AddProp( "ArgType", $varType ); + $node->AddPropList( "ParamList", $param ); + + kdocAstUtil::attachChild( $classNode, $node ); + + # Register the type + registerType( $varType ); + } else { + $m->{NodeType} = 'deleted'; + } } }, undef @@ -393,7 +799,8 @@ sub preParseClass my $isGlobalSpace = ($className eq $main::globalSpaceClassName); # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. - if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual && !$isGlobalSpace ) { + if ( !$constructorCount && $defaultConstructor eq 'none' + && !$hasPrivatePureVirtual && !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { # Create a method node for the constructor my $methodNode = Ast::New( $classNode->{astNodeName} ); $methodNode->AddProp( "NodeType", "method" ); @@ -411,7 +818,7 @@ sub preParseClass } # Also, if the class has no explicit destructor, generate a default one. - if ( !$hasDestructor && !$hasPrivatePureVirtual && !$isGlobalSpace ) { + if ( !$hasDestructor && !$hasPrivatePureVirtual && !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { my $methodNode = Ast::New( "$classNode->{astNodeName}" ); $methodNode->AddProp( "NodeType", "method" ); $methodNode->AddProp( "Flags", "" ); @@ -462,7 +869,7 @@ sub propagateCanBeCopied($) if ( !$classNode->{HasCopyConstructor} && $classNode->{CanBeCopied} && $classNode->{CanBeInstanciated} ) { my $methodNode = Ast::New( "$classNode->{astNodeName}" ); $methodNode->AddProp( "NodeType", "method" ); - $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Flags", "ix" ); # Only for internal use in marshallers my $argType = "const ".$className."&"; registerType( $argType ); $methodNode->AddProp( "Params", $argType ); @@ -502,7 +909,7 @@ my $fhn =1; # static print $fh "//Auto-generated by $0. DO NOT EDIT.\n"; print $fh "#include <smoke.h>\n"; print $fh "#include <${libname}_smoke.h>\n"; - + my @code; for my $node ( @$nodelist ) { @@ -511,10 +918,40 @@ my $fhn =1; # static my %includes; map { for my $incl (keys %{$_->[2]}){ $includes{$incl}++ } } @code; + # Hack - some Qt/KDE headers need other headers included, but omit suitable #includes + if (defined $includes{"qregexp.h"} || defined $includes{"qcstring.h"}) { + print $fh "#include <qregexp.h>\n"; + delete $includes{"qregexp.h"}; + } + if (defined $includes{"qmime.h"}) { + print $fh "#include <qurl.h>\n"; + delete $includes{"qurl.h"}; + } + if (defined $includes{"kshortcut.h"}) { + print $fh "#include <kshortcut.h>\n"; + delete $includes{"kshortcut.h"}; + } + if (defined $includes{"kshortcutlist.h"}) { + print $fh "#include <kconfigbase.h>\n"; + print $fh "#include <kshortcutlist.h>\n"; + delete $includes{"kconfigbase.h"}; + delete $includes{"kshortcutlist.h"}; + } + if (defined $includes{"kaction.h"}) { + print $fh "#include <kaction.h>\n"; + delete $includes{"kaction.h"}; + } foreach my $incl (keys %includes) { die if $incl eq ''; print $fh "#include <$incl>\n"; } + if ( $main::qt4 + and ( defined $includes{"qtreewidget.h"} + or defined $includes{"qlistwidget.h"} + or defined $includes{"qtablewidget.h"} ) ) + { + print $fh "#include \"qwidgetitemdata_p.h\"\n"; + } print $fh "\n"; for my $c( 0..$#code ) { @@ -707,8 +1144,11 @@ sub addIncludeForClass($$$) { my ( $node, $addInclude, $debugMe ) = @_; my $sourcename = $node->{Source}->{astNodeName}; - $sourcename =~ s!.*/(.*)!$1!m; - die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + if ( $sourcename !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + return if ( $sourcename eq '' ); unless ( defined $addInclude->{$sourcename} ) { print " Including $sourcename\n" if ($debugMe); $addInclude->{$sourcename} = 1; @@ -788,6 +1228,12 @@ sub generateVirtualMethod($$$$$) my $sig = $methodClass->{astNodeName} . "::" . $signature; my $idx = $allMethods{$sig}; + + if ( ! defined $idx ) { + my $class_name = join( "::", kdocAstUtil::heritage($methodClass) ); + $sig = $class_name . "::" . $signature; + $idx = $allMethods{$sig}; + } die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; if($flags =~ "p") { # pure virtual $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; @@ -798,7 +1244,7 @@ sub generateVirtualMethod($$$$$) $returnType = undef if ($returnType eq 'void'); if($returnType) { my $arg = $returnType; - my $it = $arg; + my $it = applyTypeDef( $arg ); my $cast; my $v = "x[0]"; my $indent = ($flags =~ "p") ? "\t" : ""; @@ -811,7 +1257,7 @@ sub generateVirtualMethod($$$$$) if($arg =~ s/&//) { $cast = "*($arg *)"; $methodCode .= "${indent}return $cast$v;\n"; - } elsif($arg !~ /\*/) { + } elsif($arg !~ /\*$/) { unless($flags =~ "p") { $indent = "\t "; $methodCode .= "{\n"; @@ -870,6 +1316,7 @@ sub generateMethod($$$) } my $returnType = $m->{ReturnType}; + $returnType = undef if ($returnType eq 'void'); # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. @@ -919,17 +1366,17 @@ sub generateMethod($$$) my $argType = $arg->{ArgType}; push @argTypeList, $argType; - + # Detect objects passed by value checkIncludesForObject( $argType, $addInclude ); - } + } my @castedArgList = makeCastedArgList( @argTypeList ); my $isStatic = $flags =~ "s"; my $extra = ""; - $extra .= "static " if $isStatic || $isConstructor; + $extra .= "static " if $isStatic || $isConstructor || $classNode->{NodeType} eq 'namespace'; my $attr = ""; $attr .= "const " if $flags =~ "c"; @@ -973,7 +1420,7 @@ sub generateMethod($$$) } else { $switchCode .= "\tcase $methodNumber: "; - if ($flags =~ "s" || $isConstructor) { # static or constructor + if ($flags =~ "s" || $isConstructor || $classNode->{NodeType} eq 'namespace') { # static, namespace or constructor $switchCode .= "$xClassName\::"; } else { $switchCode .= "xself->" @@ -995,7 +1442,11 @@ sub generateMethod($$$) # Now generate the actual constructor for x_className # (Simply a forwarder to the className constructor with the same args - $methodCode .= " $xClassName("; + if ( $flags =~ "t" ) { + $methodCode .= " explicit $xClassName("; + } else { + $methodCode .= " $xClassName("; + } my $i = 0; for my $arg (@argTypeList) { $methodCode .= ", " if $i++; @@ -1015,15 +1466,29 @@ sub generateMethod($$$) } else { $methodCode .= $returnType . " xret = " if $returnType; - $methodCode .= "$this\->" unless $isStatic; + $methodCode .= "$this\->" unless $isStatic || $classNode->{NodeType} eq 'namespace'; if ($className ne $main::globalSpaceClassName) { - $methodCode .= "$className\::$name(@castedArgList[0..$#argTypeList]);\n"; + if ($flags =~ "=") { + # Setter method for a public instance variable + my $varName = $name; + $varName =~ /^set(\w)(.*)/; + my $ch = $1; + $ch =~ tr/A-Z/a-z/; + $varName = $ch . $2; + $methodCode .= "$varName = @castedArgList[0..$#argTypeList];\n"; + } else { + $methodCode .= "$className\::$name(@castedArgList[0..$#argTypeList]);\n"; + } } elsif ($name =~ /^operator\s?\W+/) { ( my $op = $name ) =~ s/^operator(.*)$/$1/; if (scalar(@argTypeList) == 2) { - $methodCode .= "(@castedArgList[0] $op @castedArgList[1]);\n"; # a + b + if( $name =~ /^operator(?:\+\+|--)/ ) { # postfix increment/decrement + $methodCode .= "(@castedArgList[0])$op;\n"; + } else { + $methodCode .= "(@castedArgList[0] $op @castedArgList[1]);\n"; # a + b + } } elsif (scalar(@argTypeList) == 1) { - $methodCode .= "($op@castedArgList[0]);\n"; # -a + $methodCode .= "$op(@castedArgList[0]);\n"; # -a } else { die "shouldn't reach here!"; } @@ -1037,21 +1502,6 @@ sub generateMethod($$$) $methodCode .= " }\n"; } - #} else { - # if ( $m->{Access} =~ /slots/ ) { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ") slot;\n", - # } elsif ( $m->{Access} =~ /signals/ ) { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ") signal;\n", - # } elsif ( $name =~ /operator(.*)/ ) { - # if ( $argId == 2 ) { - # print PIGSOURCE "$extra$returnType operator $1 (", $cplusplusparams, ") : operator $1 (\$0, \$1);\n", - # } else { - # print PIGSOURCE "$extra$returnType operator $1 (", $cplusplusparams, ")", ($m->{Flags} =~ "c" ? " const" : ""), ";\n", - # } - # } else { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ")", ($m->{Flags} =~ "c" ? " const" : ""), ";\n", - # } - #} pop @argTypeList; $methodNumber++; @@ -1062,20 +1512,22 @@ sub generateMethod($$$) } -sub generateEnum($$) +sub generateEnum($$$) { - my( $classNode, $m ) = @_; # input + my( $classNode, $m, $addInclude ) = @_; # input my $methodCode = ''; # output my $switchCode = ''; # output my @heritage = kdocAstUtil::heritage($classNode); my $className = join( "::", @heritage ); my $xClassName = "x_" . join( "__", @heritage ); + + my $fullEnumType = "$className\::". $m->{astNodeName}; + checkIncludesForObject( $fullEnumType, $addInclude ); foreach my $enum ( @{$m->{ParamList}} ) { my $enumName = $enum->{ArgName}; my $fullEnumName = "$className\::$enumName"; - die "Invalid index for $fullEnumName: $classNode->{case}{$fullEnumName} instead of $methodNumber" if $classNode->{case}{$fullEnumName} != $methodNumber; $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; $methodCode .= "\tx[0].s_enum = (long)$fullEnumName;\n"; @@ -1103,14 +1555,23 @@ sub generateVar($$$) $varType =~ s/const\s+(.*)\s*&/$1/; $varType =~ s/\s*$//; my $fullName = "$className\::$name"; + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; checkIncludesForObject( $varType, $addInclude ); die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; - $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; - $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; - $methodCode .= " }\n"; - $switchCode .= "\tcase $methodNumber: $xClassName\::x_$methodNumber(args);\tbreak;\n"; + if ( $m->{Flags} =~ "s" ) { + $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n "; + $methodCode .= coerce_type('x[0]', $fullName, $varType, 1); + $methodCode .= " }\n"; + $switchCode .= "\tcase $methodNumber: $xClassName\::x_$methodNumber(args);\tbreak;\n"; + } else { + $methodCode .= " void x_$methodNumber(Smoke::Stack x) {\n "; + $methodCode .= coerce_type('x[0]', "$this->$name", $varType, 1); + $methodCode .= " }\n"; + $switchCode .= "\tcase $methodNumber: xself->x_$methodNumber(args);\tbreak;\n"; + } + $methodNumber++; return ( $methodCode, $switchCode ); @@ -1124,6 +1585,13 @@ sub generateEnumCast($) $methodCode .= " static void xenum_operation(Smoke::EnumOperation xop, Smoke::Index xtype, void *&xdata, long &xvalue) {\n"; $methodCode .= "\tswitch(xtype) {\n"; for my $enum (values %{$classNode->{enumerations}}) { + + # Hack - this shouldn't be needed here - deprecated enums + next if ($enum eq 'KStatusBar::BarStatus' + or $enum eq 'KMdi::AddWindowFlags' + or $enum eq 'KToolBar::BarStatus' + or $enum eq 'KMimeType::Format:: compression : 4'); + my $type = findTypeEntry($enum); $methodCode .= "\t case $type->{index}: //$enum\n"; $methodCode .= "\t switch(xop) {\n"; @@ -1162,13 +1630,25 @@ sub generateAllMethods my $isGlobalSpace = ($xClassName eq ("x_".$main::globalSpaceClassName)); my $sourcename = $classNode->{Source}->{astNodeName}; - $sourcename =~ s!.*/(.*)!$1!m; + if ( $sourcename !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } die "Empty source name for $classNode->{astNodeName}" if ( $sourcename eq '' ); my %addInclude = ( $sourcename => 1 ); if (!$isGlobalSpace) { - if(! $classNode->{BindingDerives}) { + if($classNode->{NodeType} eq 'namespace') { + $switchCode .= " (void)obj;\n"; + $methodCode .= "public:\n"; + my $s; + for my $sn( @{$classNode->{Sources}} ) { + if ( ($s = $sn->{astNodeName}) !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $s =~ s!.*/(.*)!$1!m; + } + $addInclude{ $s } = 1; + } + } elsif(! $classNode->{BindingDerives}) { $methodCode .= "private:\n"; $methodCode .= " $className *xthis;\n"; $methodCode .= "public:\n"; @@ -1181,7 +1661,9 @@ sub generateAllMethods } else { my $s; for my $sn( @{$classNode->{Sources}} ) { - ($s = $sn->{astNodeName}) =~ s!.*/(.*)!$1!m; + if ( ($s = $sn->{astNodeName}) !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $s =~ s!.*/(.*)!$1!m; + } $addInclude{ $s } = 1; } $methodCode .= "public:\n"; @@ -1194,7 +1676,7 @@ sub generateAllMethods sub { my ($classNode, $methodNode ) = @_; if ( $methodNode->{NodeType} eq 'enum' ) { - my ($meth, $swit) = generateEnum( $classNode, $methodNode ); + my ($meth, $swit) = generateEnum( $classNode, $methodNode, \%addInclude ); $methodCode .= $meth; $switchCode .= $swit; } @@ -1241,7 +1723,7 @@ sub generateAllMethods # $methodCode .= " virtual ~$xClassName() {}\n"; #} # We generate a dtor though, because we might want to add stuff into it - if ( !$isGlobalSpace ) { + if ( !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { $methodCode .= " ~$xClassName() { ${libname}_Smoke->binding->deleted($classNode->{ClassIndex}, (void*)this); }\n"; } @@ -1369,6 +1851,9 @@ sub registerType($$) { $type =~ s/\s+const$//; # for 'char* const' $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as + # 'TQMap<TQCString, DCOPRef>' return if ( $type eq 'void' or $type eq '' or $type eq '~' ); die if ( $type eq '...' ); # ouch @@ -1408,7 +1893,7 @@ sub registerType($$) { } # Apply typedefs, and store the resulting type. - # For instance, if $type was TTQ_UINT16&, realType will be ushort + # For instance, if $type was Q_UINT16&, realType will be ushort $allTypes{$type}{realType} = applyTypeDef( $realType ); # In the first phase we only create entries into allTypes. @@ -1426,6 +1911,9 @@ sub findTypeEntry($) { $type =~ s/\s+const$//; # for 'char* const' $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as + # 'TQMap<TQCString, DCOPRef>' + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); # Enum _value_ -> get corresponding type @@ -1472,7 +1960,7 @@ sub prepareCaseDict($) { } }, undef ); - # Check for static vars + # Check for vars Iter::MembersByType ( $classNode, undef, sub { my ($classNode, $m ) = @_; @@ -1484,6 +1972,20 @@ sub prepareCaseDict($) { }, undef ); + my %const_methods = (); + # Now look at all const methods for this class, in order to use + # them in preference to any otherwise identical non-const method + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my @args = @{ $m->{ParamList} }; + my $sig = methodSignature( $m, $#args ); + if ( $sig =~ /(.*) const$/ ) { + $const_methods{$1} = 1; + } + + }, undef ); # Now look at all methods for this class Iter::MembersByType ( $classNode, undef, @@ -1506,7 +2008,7 @@ sub prepareCaseDict($) { # Don't generate bindings for pure virtuals - we can't call them ;) $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); - # Bugfix for TQt-3.0.4: those methods are NOT implemented (report sent). + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). $ok = 0 if ( $ok && $className eq 'TQLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); $ok = 0 if ( $ok && $className eq 'TQWidgetItem' && $name eq 'widgetSizeHint' ); @@ -1518,11 +2020,18 @@ sub prepareCaseDict($) { } my @args = @{ $m->{ParamList} }; + my $sig = methodSignature( $m, $#args ); + if ( $const_methods{$sig} && $m->{Flags} !~ "v" ) { + # If there is a method which just differs from another by 'constness', + # then ignore the non-const version + $m->{SkipFromSwitch} = 1; + next; + } my $last = $m->{FirstDefaultParam}; $last = scalar @args unless defined $last; my $iterationCount = scalar(@args) - $last; while($iterationCount >= 0) { - my $sig = methodSignature( $m, $#args ); + $sig = methodSignature( $m, $#args ); $classNode->{case}{$sig} = $methodNumber; #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); pop @args; @@ -1555,6 +2064,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = $_[0]; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + push @classlist, $className; $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; $classNode->{ClassIndex} = $#classlist; @@ -1569,9 +2079,14 @@ sub writeSmokeDataFile($) { foreach my $incl (sort{ return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) return -1 if $b=~/qmotif/; + return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top + return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; $a cmp $b } keys %allIncludes) { die if $incl eq ''; + if( $incl eq "kxmlguifactory.h" ) { + print OUT "#include <kxmlguiclient.h>\n"; + } print OUT "#include <$incl>\n"; } @@ -1609,15 +2124,25 @@ sub writeSmokeDataFile($) { push @super, @{$descendants{$className}}; } my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + print OUT " case $cur:\t//$className\n"; print OUT "\tswitch(to) {\n"; $cur = -1; + my %casevalues; for my $s (@super) { - my $superClassName = join( "::", kdocAstUtil::heritage($s) ); - next if !defined $classidx{$superClassName}; # inherits from unknown class, see below - next if $classidx{$superClassName} == $cur; # shouldn't happen in TQt - $cur = $classidx{$superClassName}; - print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + next if !defined $classidx{$superClassName}; # inherits from unknown class, see below + next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt + if (!defined $s) { + die "problem with $className missing parent" + } + next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class + $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) + next if $casevalues{$cur}; # ..so skip any duplicate parents + print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; + $casevalues{$cur} = 1; } print OUT "\t default: return xptr;\n"; print OUT "\t}\n"; @@ -1642,7 +2167,8 @@ sub writeSmokeDataFile($) { print OUT "\t0,\t// 0: (no super class)\n"; Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; - my $className = join( "__", kdocAstUtil::heritage($classNode) ); + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "inheritanceList: looking at $className\n" if ($debug); # Make list of direct ancestors @@ -1709,7 +2235,7 @@ sub writeSmokeDataFile($) { my $firstClass = 1; Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; - my $className = join( "__", kdocAstUtil::heritage($classNode) ); + my $className = join( "::", kdocAstUtil::heritage($classNode) ); if ($firstClass) { $firstClass = 0; @@ -1720,8 +2246,7 @@ sub writeSmokeDataFile($) { my $xcallFunc = "xcall_$c"; my $xenumFunc = "0"; $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; - # %classinherit needs Foo__Bar, not Foo::Bar? - die "problem with $className" unless defined $classinherit{$c}; + die "problem with $className" unless defined $classinherit{$className}; my $xClassFlags = 0; $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? @@ -1729,7 +2254,7 @@ sub writeSmokeDataFile($) { $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode) == 1; # $xClassFlags .= "|Smoke::cf_undefined" if ...; $xClassFlags =~ s/0\|//; # beautify - print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + print OUT "\t{ \"$className\", $classinherit{$className}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; } ); print OUT "};\n\n"; @@ -1751,7 +2276,10 @@ sub writeSmokeDataFile($) { my $typeFlags = $allTypes{$type}{typeFlags}; my $realType = $allTypes{$type}{realType}; die "$type" if !defined $typeFlags; - die "$realType" if $realType =~ /\(/; +# die "$realType" if $realType =~ /\(/; + if ($realType =~ /\(/) { + print "FATAL ERROR $type $realType\n"; + } # First write the name print OUT "\t{ \"$type\", "; # Then write the classId (and find out the typeid at the same time) @@ -1834,10 +2362,8 @@ sub writeSmokeDataFile($) { $methods{$enumName}++; } - } elsif ( $m->{NodeType} eq 'var' ) { - - $methods{$m->{astNodeName}}++; - + } elsif ( $m->{NodeType} eq 'var' ) { + $methods{$m->{astNodeName}}++; } elsif( $m->{NodeType} eq "method" ) { $methods{$methName}++; @@ -1926,6 +2452,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $classIndex = $classidx{$className}; print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); @@ -1942,7 +2469,7 @@ sub writeSmokeDataFile($) { die "'Method index' for enum $sig not found" unless defined $xmethIndex; my $typeId = findTypeEntry( $fullEnumName )->{index}; die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; - print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static|Smoke::mf_enum, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; $allMethods{$sig} = $methodCount; print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); $methods[$methodCount] = { @@ -1969,8 +2496,12 @@ sub writeSmokeDataFile($) { $varType =~ s/\s*$//; my $typeId = findTypeEntry( $varType )->{index}; die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; - print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; - $allMethods{$sig} = $methodCount; + if ( $m->{Flags} =~ "s" ) { + print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + } else { + print OUT "\t{$classIndex, $xmethIndex, 0, 0, 0, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (var)\n"; + } + $allMethods{$sig} = $methodCount; print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); $methods[$methodCount] = { c => $classIndex, @@ -2035,8 +2566,14 @@ sub writeSmokeDataFile($) { } my $argcnt = $last + 1; my $methodFlags = '0'; - $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + # Make no distinction between a static method in an ordinary class, or a method in a namespace + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s" or $classNode->{NodeType} eq 'namespace'; $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags .= "|Smoke::mf_copyctor" if $m->{Flags} =~ "x"; + $methodFlags .= "|Smoke::mf_internal" if $m->{Flags} =~ "i"; + $methodFlags .= "|Smoke::mf_ctor" if $methName eq $className; + $methodFlags .= "|Smoke::mf_dtor" if $m->{ReturnType} eq '~'; + $methodFlags .= "|Smoke::mf_protected" if $m->{Access} =~ /protected/; $methodFlags =~ s/0\|//; # beautify print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; @@ -2064,6 +2601,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $classIndex = $classidx{$className}; print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); |