Added scripts for Qt generation.

This commit is contained in:
Matthias Koefferlein 2017-02-21 20:32:40 +01:00
parent eea5da4ba6
commit c15179aa19
21 changed files with 43137 additions and 0 deletions

222
scripts/mkqtdecl.sh Executable file
View File

@ -0,0 +1,222 @@
#!/bin/bash -e
#
# A script to produce the Qt declaration files
#
# This script utilizes the extraction framework from mkqtdecl_common. The extraction
# framework is based on a C++ parser and a configuration file that specifies details
# about the translation.
#
# By default, the script will take the Qt headers from /opt/qt/4.6.3 and /opt/qt/5.5.1
# for Qt4 and Qt5 respectively.
#
# Call it from project level as
#
# ./scripts/mkqtdecl.sh -update # Qt4
# ./scripts/mkqtdecl.sh -update -qt5 # Qt5
#
# For more options see
#
# ./scripts/mkqtdecl.sh -h
#
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
dry=0
sync=0
update=0
diff=0
reuse=0
qt="/opt/qt/4.6.3/include"
qt5="/opt/qt/5.5.1/include"
inst_dir_common=`pwd`/scripts/mkqtdecl_common
inst_dir=`pwd`/scripts/mkqtdecl
inst_dir5=`pwd`/scripts/mkqtdecl5
src_dir=`pwd`/src
src_name=gsiqt
src_name5=gsiqt5
while [ "$1" != "" ]; do
a="$1"
shift
case "$a" in
-h)
echo "Produce Qt declaration"
echo "Usage:"
echo " mkqtdecl.sh -update Produce and synchronize"
echo " mkqtdecl.sh -dry Dry run - produce, but don't synchronize"
echo " mkqtdecl.sh -sync Sync only - don't produce, but synchronize"
echo " mkqtdecl.sh -diff Show differences - don't produce and don't synchronize"
echo " mkqtdecl.sh -qt path_to_include Use the specified include path"
echo " mkqtdecl.sh -qt5 Use setup for Qt 5.x (use before -qt)"
echo " mkqtdecl.sh -reuse Don't parse C++ container again"
exit 0
;;
-dry)
dry=1
;;
-sync)
sync=1
;;
-update)
update=1
;;
-diff)
diff=1
;;
-reuse)
reuse=1
;;
-qt)
qt="$1"
shift
;;
-qt5)
qt="$qt5"
inst_dir="$inst_dir5"
src_name="$src_name5"
;;
*)
echo "*** ERROR: unknown command option $a"
exit 1
;;
esac
done
if [ `expr $update + $sync + $dry + $diff` != 1 ]; then
echo "*** ERROR: either -update, -diff, -dry or -sync must be given"
exit 1
fi
# Production flags
# -diff -> update=0, dry=1
# -dry -> update=1, dry=1
# -sync -> update=0, dry=0
# -update -> update=1, dry=0
if [ $diff != 0 ]; then
dry=1
elif [ $dry != 0 ]; then
update=1
fi
if [ ! -e $src_dir ]; then
echo "*** ERROR: Source directory ($src_dir) not found - run script in repository root"
exit 1
fi
if [ ! -e $inst_dir ]; then
echo "*** ERROR: Installation path ($inst_dir) not found - run script in repository root"
exit 1
fi
if [ ! -e $inst_dir_common ]; then
echo "*** ERROR: Installation path ($inst_dir_common) not found - run script in repository root"
exit 1
fi
if ! ruby -v >/dev/null 2>&1; then
echo "*** ERROR: ruby not installed"
exit 1
fi
if ! ruby -e "require 'oj'" 2>&1; then
echo "*** ERROR: ruby gem 'oj' not installed"
exit 1
fi
if ! ruby -e "require 'treetop'" 2>&1; then
echo "*** ERROR: ruby gem 'treetop' not installed"
exit 1
fi
work_dir="./mkqtdecl.tmp"
if [ $update != 0 ]; then
if [ -e $work_dir ] && [ $reuse == 0 ]; then
rm -rf $work_dir
fi
mkdir -p $work_dir
cd $work_dir
cp $inst_dir/{allofqt.cpp,mkqtdecl.conf,mkqtdecl.properties,mkqtdecl.events} .
cp $inst_dir_common/{cpp_parser_classes.rb,cpp_classes.rb,c++.treetop,parse.rb,reader_ext.rb,produce.rb} .
if [ $reuse == 0 ]; then
echo "Running gcc preprocessor .."
# By using -D_GCC_LIMITS_H_ we make the gcc not include constants such as ULONG_MAX which will
# remain as such. This way the generated code is more generic.
gcc -I$qt -fPIC -D_GCC_LIMITS_H_ -E -o allofqt.x allofqt.cpp
echo "Stripping hash lines .."
egrep -v '^#' <allofqt.x >allofqt.e
rm allofqt.x
echo "Parsing and producing db .."
./parse.rb -i allofqt.e -o allofqt.db
fi
mkdir -p generated
echo "Producing code .."
./produce.rb -i allofqt.db
else
cd $work_dir
fi
if [ ! -e generated ]; then
echo "*** ERROR: production output ("`pwd`"/generated) does not exist - production failed?"
exit 1
fi
cd generated
if [ $dry != 0 ]; then
echo "Synchronizing dry run .."
else
echo "Synchronizing .."
fi
count=0
for f in {*.cc,*.h} qtdecl.pro; do
needs_update=0
if ! [ -e $src_dir/$src_name/$f ]; then
echo "# INFO: creating new file $src_dir/$src_name/$f"
needs_update=1
elif ! cmp -s $f $src_dir/$src_name/$f; then
echo "# INFO: out of date: syncing file $src_dir/$src_name/$f"
needs_update=1
fi
if [ $needs_update != 0 ]; then
count=`expr $count + 1`
if [ $dry != 0 ]; then
echo cp $f $src_dir/$src_name/$f
else
echo === cp $f $src_dir/$src_name/$f
cp $f $src_dir/$src_name/$f
fi
fi
done
if [ $dry != 0 ]; then
echo "# INFO: $count files to synchronize"
else
echo "# INFO: $count files synchronized"
fi

View File

@ -0,0 +1,504 @@
#include "QtGui/QAbstractButton"
#include "QtGui/QAbstractGraphicsShapeItem"
#include "QtGui/QAbstractItemDelegate"
#include "QtGui/QAbstractItemView"
#include "QtGui/QAbstractPrintDialog"
#include "QtGui/QAbstractProxyModel"
#include "QtGui/QAbstractScrollArea"
#include "QtGui/QAbstractSlider"
#include "QtGui/QAbstractSpinBox"
#include "QtGui/QAbstractTextDocumentLayout"
#include "QtGui/QAccessibleEvent"
#include "QtGui/QAccessibleInterface"
#include "QtGui/QAccessibleObject"
#include "QtGui/QAccessibleWidget"
#include "QtGui/QAction"
#include "QtGui/QActionEvent"
#include "QtGui/QActionGroup"
#include "QtGui/QApplication"
#include "QtGui/QBitmap"
#include "QtGui/QBoxLayout"
#include "QtGui/QBrush"
#include "QtGui/QButtonGroup"
#include "QtGui/QCDEStyle"
#include "QtGui/QCalendarWidget"
#include "QtGui/QCheckBox"
#include "QtGui/QCleanlooksStyle"
#include "QtGui/QClipboard"
#include "QtGui/QCloseEvent"
#include "QtGui/QColor"
#include "QtGui/QColorDialog"
#include "QtGui/QColorGroup"
#include "QtGui/QColormap"
#include "QtGui/QColumnView"
#include "QtGui/QComboBox"
#include "QtGui/QCommandLinkButton"
#include "QtGui/QCommonStyle"
#include "QtGui/QCompleter"
#include "QtGui/QConicalGradient"
#include "QtGui/QContextMenuEvent"
#include "QtGui/QCursor"
#include "QtGui/QDataWidgetMapper"
#include "QtGui/QDateEdit"
#include "QtGui/QDateTimeEdit"
#include "QtGui/QDesktopServices"
#include "QtGui/QDesktopWidget"
#include "QtGui/QDial"
#include "QtGui/QDialog"
#include "QtGui/QDialogButtonBox"
#include "QtGui/QDirModel"
#include "QtGui/QDockWidget"
#include "QtGui/QDoubleSpinBox"
#include "QtGui/QDoubleValidator"
#include "QtGui/QDrag"
#include "QtGui/QDragEnterEvent"
#include "QtGui/QDragLeaveEvent"
#include "QtGui/QDragMoveEvent"
#include "QtGui/QDropEvent"
#include "QtGui/QErrorMessage"
#include "QtGui/QFileDialog"
#include "QtGui/QFileIconProvider"
#include "QtGui/QFileOpenEvent"
#include "QtGui/QFileSystemModel"
#include "QtGui/QFocusEvent"
#include "QtGui/QFocusFrame"
#include "QtGui/QFont"
#include "QtGui/QFontComboBox"
#include "QtGui/QFontDatabase"
#include "QtGui/QFontDialog"
#include "QtGui/QFontInfo"
#include "QtGui/QFontMetrics"
#include "QtGui/QFontMetricsF"
#include "QtGui/QFormLayout"
#include "QtGui/QFrame"
#include "QtGui/QGesture"
#include "QtGui/QGestureEvent"
#include "QtGui/QGestureRecognizer"
#include "QtGui/QGradient"
#include "QtGui/QGraphicsAnchor"
#include "QtGui/QGraphicsAnchorLayout"
#include "QtGui/QGraphicsBlurEffect"
#include "QtGui/QGraphicsColorizeEffect"
#include "QtGui/QGraphicsDropShadowEffect"
#include "QtGui/QGraphicsEffect"
#include "QtGui/QGraphicsEllipseItem"
#include "QtGui/QGraphicsGridLayout"
#include "QtGui/QGraphicsItem"
#include "QtGui/QGraphicsItemAnimation"
#include "QtGui/QGraphicsItemGroup"
#include "QtGui/QGraphicsLayout"
#include "QtGui/QGraphicsLayoutItem"
#include "QtGui/QGraphicsLinearLayout"
#include "QtGui/QGraphicsLineItem"
#include "QtGui/QGraphicsObject"
#include "QtGui/QGraphicsOpacityEffect"
#include "QtGui/QGraphicsPathItem"
#include "QtGui/QGraphicsPixmapItem"
#include "QtGui/QGraphicsPolygonItem"
#include "QtGui/QGraphicsProxyWidget"
#include "QtGui/QGraphicsRectItem"
#include "QtGui/QGraphicsRotation"
#include "QtGui/QGraphicsScale"
#include "QtGui/QGraphicsScene"
#include "QtGui/QGraphicsSceneContextMenuEvent"
#include "QtGui/QGraphicsSceneDragDropEvent"
#include "QtGui/QGraphicsSceneEvent"
#include "QtGui/QGraphicsSceneHelpEvent"
#include "QtGui/QGraphicsSceneHoverEvent"
#include "QtGui/QGraphicsSceneMouseEvent"
#include "QtGui/QGraphicsSceneMoveEvent"
#include "QtGui/QGraphicsSceneResizeEvent"
#include "QtGui/QGraphicsSceneWheelEvent"
#include "QtGui/QGraphicsSimpleTextItem"
#include "QtGui/QGraphicsTextItem"
#include "QtGui/QGraphicsTransform"
#include "QtGui/QGraphicsView"
#include "QtGui/QGraphicsWidget"
#include "QtGui/QGridLayout"
#include "QtGui/QGroupBox"
#include "QtGui/QHBoxLayout"
#include "QtGui/QHeaderView"
#include "QtGui/QHelpEvent"
#include "QtGui/QHideEvent"
#include "QtGui/QHoverEvent"
#include "QtGui/QIcon"
#include "QtGui/QIconDragEvent"
#include "QtGui/QIconEngine"
#include "QtGui/QIconEnginePlugin"
#include "QtGui/QIconEnginePluginV2"
#include "QtGui/QIconEngineV2"
#include "QtGui/QImage"
#include "QtGui/QImageTextKeyLang"
#include "QtGui/QImageIOHandler"
#include "QtGui/QImageIOPlugin"
#include "QtGui/QImageReader"
#include "QtGui/QImageWriter"
#include "QtGui/QInputContext"
#include "QtGui/QInputContextFactory"
#include "QtGui/QInputContextPlugin"
#include "QtGui/QInputDialog"
#include "QtGui/QInputEvent"
#include "QtGui/QInputMethodEvent"
#include "QtGui/QIntValidator"
#include "QtGui/QItemDelegate"
#include "QtGui/QItemEditorCreatorBase"
#include "QtGui/QItemEditorFactory"
#include "QtGui/QItemSelection"
#include "QtGui/QItemSelectionModel"
#include "QtGui/QItemSelectionRange"
#include "QtGui/QKeyEvent"
#include "QtGui/QKeySequence"
#include "QtGui/QLCDNumber"
#include "QtGui/QLabel"
#include "QtGui/QLayout"
#include "QtGui/QLayoutItem"
#include "QtGui/QLineEdit"
#include "QtGui/QLinearGradient"
#include "QtGui/QListView"
#include "QtGui/QListWidget"
#include "QtGui/QListWidgetItem"
#include "QtGui/QMacPasteboardMime"
#include "QtGui/QMainWindow"
#include "QtGui/QMatrix4x4"
#include "QtGui/QMatrix"
#include "QtGui/QMdiArea"
#include "QtGui/QMdiSubWindow"
#include "QtGui/QMenu"
#include "QtGui/QMenuBar"
#include "QtGui/QMenuItem"
#include "QtGui/QMessageBox"
#include "QtGui/QMimeSource"
#include "QtGui/QMotifStyle"
#include "QtGui/QMouseEvent"
#include "QtGui/QMoveEvent"
#include "QtGui/QMovie"
#include "QtGui/QPageSetupDialog"
#include "QtGui/QPaintDevice"
#include "QtGui/QPaintEngine"
#include "QtGui/QPaintEngineState"
#include "QtGui/QPaintEvent"
#include "QtGui/QPainter"
#include "QtGui/QPainterPath"
#include "QtGui/QPainterPathStroker"
#include "QtGui/QPalette"
#include "QtGui/QPanGesture"
#include "QtGui/QPen"
#include "QtGui/QPicture"
#include "QtGui/QPinchGesture"
#include "QtGui/QPixmap"
#include "QtGui/QPixmapCache"
#include "QtGui/QPlainTextDocumentLayout"
#include "QtGui/QPlainTextEdit"
#include "QtGui/QPlastiqueStyle"
#include "QtGui/QPolygon"
#include "QtGui/QPolygonF"
#include "QtGui/QPrintDialog"
#include "QtGui/QPrintEngine"
#include "QtGui/QPrintPreviewDialog"
#include "QtGui/QPrintPreviewWidget"
#include "QtGui/QPrinterInfo"
#include "QtGui/QProgressBar"
#include "QtGui/QProgressDialog"
#include "QtGui/QPushButton"
#include "QtGui/QQuaternion"
#include "QtGui/QRadialGradient"
#include "QtGui/QRadioButton"
#include "QtGui/QRegExpValidator"
#include "QtGui/QRegion"
#include "QtGui/QResizeEvent"
#include "QtGui/QRubberBand"
#include "QtGui/QScrollArea"
#include "QtGui/QScrollBar"
#include "QtGui/QShortcut"
#include "QtGui/QShortcutEvent"
#include "QtGui/QShowEvent"
#include "QtGui/QSizeGrip"
#include "QtGui/QSizePolicy"
#include "QtGui/QSlider"
#include "QtGui/QSortFilterProxyModel"
#include "QtGui/QSound"
#include "QtGui/QSpacerItem"
#include "QtGui/QSpinBox"
#include "QtGui/QSplashScreen"
#include "QtGui/QSplitter"
#include "QtGui/QSplitterHandle"
#include "QtGui/QStackedLayout"
#include "QtGui/QStackedWidget"
#include "QtGui/QStandardItem"
#include "QtGui/QStandardItemModel"
#include "QtGui/QStatusBar"
#include "QtGui/QStatusTipEvent"
#include "QtGui/QStringListModel"
#include "QtGui/QStyle"
#include "QtGui/QStyleFactory"
#include "QtGui/QStyleHintReturn"
#include "QtGui/QStyleHintReturnMask"
#include "QtGui/QStyleHintReturnVariant"
#include "QtGui/QStyleOption"
#include "QtGui/QStyleOptionButton"
#include "QtGui/QStyleOptionComboBox"
#include "QtGui/QStyleOptionComplex"
#include "QtGui/QStyleOptionDockWidget"
#include "QtGui/QStyleOptionFocusRect"
#include "QtGui/QStyleOptionFrame"
#include "QtGui/QStyleOptionFrameV2"
#include "QtGui/QStyleOptionFrameV3"
#include "QtGui/QStyleOptionGraphicsItem"
#include "QtGui/QStyleOptionGroupBox"
#include "QtGui/QStyleOptionHeader"
#include "QtGui/QStyleOptionMenuItem"
#include "QtGui/QStyleOptionProgressBar"
#include "QtGui/QStyleOptionProgressBarV2"
#include "QtGui/QStyleOptionQ3DockWindow"
#include "QtGui/QStyleOptionQ3ListView"
#include "QtGui/QStyleOptionQ3ListViewItem"
#include "QtGui/QStyleOptionRubberBand"
#include "QtGui/QStyleOptionSizeGrip"
#include "QtGui/QStyleOptionSlider"
#include "QtGui/QStyleOptionSpinBox"
#include "QtGui/QStyleOptionTab"
#include "QtGui/QStyleOptionTabBarBase"
#include "QtGui/QStyleOptionTabBarBaseV2"
#include "QtGui/QStyleOptionTabV2"
#include "QtGui/QStyleOptionTabV3"
#include "QtGui/QStyleOptionTabWidgetFrame"
#include "QtGui/QStyleOptionTitleBar"
#include "QtGui/QStyleOptionToolBar"
#include "QtGui/QStyleOptionToolBox"
#include "QtGui/QStyleOptionToolBoxV2"
#include "QtGui/QStyleOptionToolButton"
#include "QtGui/QStyleOptionViewItem"
#include "QtGui/QStyleOptionViewItemV2"
#include "QtGui/QStyleOptionViewItemV3"
#include "QtGui/QStyleOptionViewItemV4"
#include "QtGui/QStylePainter"
#include "QtGui/QStylePlugin"
#include "QtGui/QStyledItemDelegate"
#include "QtGui/QSwipeGesture"
#include "QtGui/QSyntaxHighlighter"
#include "QtGui/QSystemTrayIcon"
#include "QtGui/QTabBar"
#include "QtGui/QTabWidget"
#include "QtGui/QTableView"
#include "QtGui/QTableWidget"
#include "QtGui/QTableWidgetItem"
#include "QtGui/QTableWidgetSelectionRange"
#include "QtGui/QTabletEvent"
#include "QtGui/QTapAndHoldGesture"
#include "QtGui/QTapGesture"
#include "QtGui/QTextBlock"
#include "QtGui/QTextBlockFormat"
#include "QtGui/QTextBlockGroup"
#include "QtGui/QTextBlockUserData"
#include "QtGui/QTextBrowser"
#include "QtGui/QTextCharFormat"
#include "QtGui/QTextCursor"
#include "QtGui/QTextDocument"
#include "QtGui/QTextDocumentFragment"
#include "QtGui/QTextDocumentWriter"
#include "QtGui/QTextEdit"
#include "QtGui/QTextFormat"
#include "QtGui/QTextFragment"
#include "QtGui/QTextFrame"
#include "QtGui/QTextFrameFormat"
#include "QtGui/QTextImageFormat"
#include "QtGui/QTextInlineObject"
#include "QtGui/QTextItem"
#include "QtGui/QTextLayout"
#include "QtGui/QTextLength"
#include "QtGui/QTextLine"
#include "QtGui/QTextList"
#include "QtGui/QTextListFormat"
#include "QtGui/QTextObject"
#include "QtGui/QTextObjectInterface"
#include "QtGui/QTextOption"
#include "QtGui/QTextTable"
#include "QtGui/QTextTableCell"
#include "QtGui/QTextTableCellFormat"
#include "QtGui/QTextTableFormat"
#include "QtGui/QTimeEdit"
#include "QtGui/QToolBar"
#include "QtGui/QToolBox"
#include "QtGui/QToolButton"
#include "QtGui/QToolTip"
#include "QtGui/QTouchEvent"
#include "QtGui/QTransform"
#include "QtGui/QTreeView"
#include "QtGui/QTreeWidget"
#include "QtGui/QTreeWidgetItem"
#include "QtGui/QTreeWidgetItemIterator"
#include "QtGui/QUndoCommand"
#include "QtGui/QUndoGroup"
#include "QtGui/QUndoStack"
#include "QtGui/QUndoView"
#include "QtGui/QVBoxLayout"
#include "QtGui/QValidator"
#include "QtGui/QVector2D"
#include "QtGui/QVector3D"
#include "QtGui/QVector4D"
#include "QtGui/QWhatsThis"
#include "QtGui/QWhatsThisClickedEvent"
#include "QtGui/QWheelEvent"
#include "QtGui/QWidget"
#include "QtGui/QWidgetAction"
#include "QtGui/QWidgetItem"
#include "QtGui/QWindowStateChangeEvent"
#include "QtGui/QWindowsMime"
#include "QtGui/QWindowsStyle"
#include "QtGui/QWizard"
#include "QtGui/QWizardPage"
#include "QtGui/QPrinter"
#include "QtGui/QAccessible"
#include "QtCore/QTextStream"
#include "QtCore/QAbstractItemModel"
#include "QtCore/QAbstractListModel"
#include "QtCore/QAbstractTableModel"
#include "QtCore/QBasicTimer"
#include "QtCore/QByteArrayMatcher"
#include "QtCore/QChildEvent"
#include "QtCore/QCoreApplication"
#include "QtCore/QCryptographicHash"
#include "QtCore/QCustomEvent"
#include "QtCore/QDataStream"
#include "QtCore/QDate"
#include "QtCore/QDateTime"
#include "QtCore/QDir"
#include "QtCore/QDynamicPropertyChangeEvent"
#include "QtCore/QEasingCurve"
#include "QtCore/QEvent"
#include "QtCore/QEventLoop"
#include "QtCore/QFactoryInterface"
#include "QtCore/QFile"
#include "QtCore/QFileInfo"
#include "QtCore/QFileSystemWatcher"
#include "QtCore/QIODevice"
#include "QtCore/QLibrary"
#include "QtCore/QLibraryInfo"
#include "QtCore/QLine"
#include "QtCore/QLineF"
#include "QtCore/QLocale"
#include "QtCore/QMargins"
#include "QtCore/QMetaClassInfo"
#include "QtCore/QMetaEnum"
#include "QtCore/QMetaMethod"
#include "QtCore/QMetaObject"
#include "QtCore/QMetaProperty"
#include "QtCore/QMetaType"
#include "QtCore/QMimeData"
#include "QtCore/QModelIndex"
#include "QtCore/QMutex"
#include "QtCore/QObject"
#include "QtCore/QPersistentModelIndex"
#include "QtCore/QPluginLoader"
#include "QtCore/QPoint"
#include "QtCore/QPointF"
#include "QtCore/QProcess"
#include "QtCore/QProcessEnvironment"
#include "QtCore/QReadLocker"
#include "QtCore/QReadWriteLock"
#include "QtCore/QRect"
#include "QtCore/QRectF"
#include "QtCore/QRegExp"
#include "QtCore/QResource"
#include "QtCore/QSemaphore"
#include "QtCore/QSettings"
#include "QtCore/QSignalMapper"
#include "QtCore/QSize"
#include "QtCore/QSizeF"
#include "QtCore/QSocketNotifier"
#include "QtCore/QStringMatcher"
#include "QtCore/QSysInfo"
#include "QtCore/QSystemLocale"
#include "QtCore/QTemporaryFile"
#include "QtCore/QThread"
#include "QtCore/QTime"
#include "QtCore/QTimeLine"
#include "QtCore/QTimer"
#include "QtCore/QTimerEvent"
#include "QtCore/QTranslator"
#include "QtCore/QUrl"
#include "QtCore/QVariant"
#include "QtCore/QWaitCondition"
#include "QtCore/QWriteLocker"
#include "QtCore/QTextCodec"
#include "QtCore/QTextDecoder"
#include "QtCore/QTextEncoder"
#include "QtCore/QBuffer"
#include "QtXml/QDomNode"
#include "QtXml/QDomNodeList"
#include "QtXml/QDomCharacterData"
#include "QtXml/QDomText"
#include "QtXml/QDomAttr"
#include "QtXml/QDomCDATASection"
#include "QtXml/QDomComment"
#include "QtXml/QDomDocument"
#include "QtXml/QDomDocumentFragment"
#include "QtXml/QDomDocumentType"
#include "QtXml/QDomElement"
#include "QtXml/QDomEntity"
#include "QtXml/QDomEntityReference"
#include "QtXml/QDomImplementation"
#include "QtXml/QDomNamedNodeMap"
#include "QtXml/QDomNotation"
#include "QtXml/QDomProcessingInstruction"
#include "QtXml/QXmlAttributes"
#include "QtXml/QXmlContentHandler"
#include "QtXml/QXmlDeclHandler"
#include "QtXml/QXmlDefaultHandler"
#include "QtXml/QXmlDTDHandler"
#include "QtXml/QXmlEntityResolver"
#include "QtXml/QXmlErrorHandler"
#include "QtXml/QXmlInputSource"
#include "QtXml/QXmlLexicalHandler"
#include "QtXml/QXmlLocator"
#include "QtXml/QXmlNamespaceSupport"
#include "QtXml/QXmlParseException"
#include "QtXml/QXmlReader"
#include "QtXml/QXmlSimpleReader"
#include "QtNetwork/QAbstractNetworkCache"
#include "QtNetwork/QAuthenticator"
#include "QtNetwork/QFtp"
#include "QtNetwork/QHostAddress"
#include "QtNetwork/QHostInfo"
#include "QtNetwork/QLocalServer"
#include "QtNetwork/QLocalSocket"
#include "QtNetwork/QNetworkAccessManager"
#include "QtNetwork/QNetworkAddressEntry"
#include "QtNetwork/QNetworkCacheMetaData"
#include "QtNetwork/QNetworkCookie"
#include "QtNetwork/QNetworkCookieJar"
#include "QtNetwork/QNetworkDiskCache"
#include "QtNetwork/QNetworkInterface"
#include "QtNetwork/QNetworkProxy"
#include "QtNetwork/QNetworkProxyFactory"
#include "QtNetwork/QNetworkProxyQuery"
#include "QtNetwork/QNetworkReply"
#include "QtNetwork/QNetworkRequest"
#include "QtNetwork/QSslCertificate"
#include "QtNetwork/QSslCipher"
#include "QtNetwork/QSslConfiguration"
#include "QtNetwork/QSslError"
#include "QtNetwork/QSslKey"
#include "QtNetwork/QSslSocket"
#include "QtNetwork/QTcpServer"
#include "QtNetwork/QTcpSocket"
#include "QtNetwork/QUdpSocket"
#include "QtNetwork/QUrlInfo"
#include "QtNetwork/QAbstractSocket"
#include "QtSql/QSqlDatabase"
#include "QtSql/QSqlDriver"
#include "QtSql/QSqlDriverCreatorBase"
#include "QtSql/QSqlError"
#include "QtSql/QSqlField"
#include "QtSql/QSqlIndex"
#include "QtSql/QSqlQuery"
#include "QtSql/QSqlQueryModel"
#include "QtSql/QSqlRecord"
#include "QtSql/QSqlRelation"
#include "QtSql/QSqlRelationalDelegate"
#include "QtSql/QSqlRelationalTableModel"
#include "QtSql/QSqlResult"
#include "QtSql/QSqlTableModel"
#include "QtDesigner/QAbstractFormBuilder"
#include "QtDesigner/QFormBuilder"
#include "QtCore/Qt"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,414 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
require "cpp_classes.rb"
require "cpp_parser_classes.rb"
grammar CPP
rule s
[ \t\n\r]*
end
rule sp
[ \t\n\r]+
end
rule string_const
'"' ( [^\\"] / "\\" . )* '"'
end
rule char_const
"'" ( [^\\'] / "\\" . )* "'"
end
rule numeric_const
"-"? ( [0-9]+ ( "." [0-9]* )? / "." [0-9]+ ) ( [eE] "-"? [0-9]+ )?
end
rule hex_const
"0x" [0-9a-fA-F]+
end
rule attribute_value
"(" ( s ( "," s )? attribute_value )* s ")" / numeric_const / string_const / id
end
rule a
s ( "__attribute__" s attribute_value s / "__asm" s attribute_value s / "__extension__" s )*
end
rule unary_op
"~" / "!" / "-" / "*" / "&"
end
rule bin_op_wo_gt
"+=" / "++" / "+" / "->" / "-=" / "--" / "-" / "()" / "[]" / "&&" / "&=" / "&" / "||" / "|=" / "|" /
"==" / "=" / "!=" / "*=" / "*" / "/=" / "/" / "%=" / "%" / "<=" / "<<=" / "<<" / "<" /
"~=" / "^=" / "^" / "~=" / ">=" / ">>="
end
rule bin_op
bin_op_wo_gt / ">>" / ">"
end
rule id
"operator" s "," /
"operator" s ( bin_op / unary_op / "," ) /
"operator" sp [a-zA-Z\*\& \t\n\r]+ &( s "(" ) /
"~"? [a-zA-Z_] [a-zA-Z_0-9]*
end
rule template_arg_part_any
block_wo_gt <PConst>
end
rule template_arg_part
qualified_id &( ( s ">" / "," ) ) / template_arg_part_any
end
rule template_args
template_arg_part ( s "," s template_arg_part )* <PTemplateArgs>
end
rule id_with_template_args
id:id taspec:( s "<" s ta:template_args s ">" )? <PId>
end
rule qualified_id
globalspec:( "::" s )? id_with_template_args ( s "::" id_with_template_args )* <PQualifiedId>
end
rule int_type_attr
"signed" ![a-zA-Z0-9_] / "unsigned" ![a-zA-Z0-9_] / "long" ( sp "long" )? ![a-zA-Z0-9_] / "short" ![a-zA-Z0-9_]
end
rule int_type
(
( int_type_attr s )* "int" ![a-zA-Z0-9_] /
int_type_attr ( s int_type_attr )* !"char" ( s "int" ![a-zA-Z0-9_] )?
) <PIntType>
end
rule char_type
( "signed" sp / "unsigned" sp )? s !"int" "char" ![a-zA-Z0-9_] <PCharType>
end
rule bool_type
"bool" <PBoolType>
end
rule void_type
"void" <PVoidType>
end
rule float_type
( "long" sp )? ( "double" / "float" ) ![a-zA-Z0-9_] <PFloatType>
end
rule enum_spec
id:id initspec:( s "=" s init:block_wo_comma )? <PEnumSpec>
end
rule enum_body
enum_spec ( s "," s enum_spec )*
end
rule enum_type
"enum" ![a-zA-Z0-9_] a s id:id? bodyspec:( s "{" s body:enum_body s "}" )? <PEnumType>
end
rule virtual_spec
"virtual" <PVirtual>
end
rule member_declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( "explicit" / "mutable" / storage_class / inline_spec / virtual_spec ) s )*
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
a
(
"{" s block s "}" /
";"?
) <PDeclaration>
end
rule member_declaration_w_semicolon
template:( d:template_decl s )?
attr:( ( "explicit" / "mutable" / storage_class / inline_spec / virtual_spec ) s )*
t:type
# opposite case (member_see declaration_wo_semicolon)
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
a
(
"{" s block s "}" /
";"
) <PDeclaration>
end
rule member_declaration
a ( member_declaration_wo_semicolon / member_declaration_w_semicolon )
end
rule friend_decl
a template:( d:template_decl s )? "friend" ![a-zA-Z0-9_] s t:member_declaration <PFriendDecl>
end
rule class_struct_body_declarations
( s ";" / s friend_decl / s using / s typedef / s !( "public" / "private" / "protected" ) member_declaration )*
end
rule class_struct_body
class_struct_body_declarations
(
s "public" s ":" d:class_struct_body_declarations <PPublicClassStructBodyDeclarations> /
s "private" s ":" d:class_struct_body_declarations <PPrivateClassStructBodyDeclarations> /
s "protected" s ":" d:class_struct_body_declarations <PProtectedClassStructBodyDeclarations>
)*
end
rule class_id
# In order to easily distinguish between constructor methods without
# a return type and class or typedef names we assume that all "name("
# constructs are considered constructor names but "name (*func_ptr) ()" is not.
qualified_id s !( "(" !( s "*" ) )
end
rule typeof
"__typeof" s "(" s qid:qualified_id s ")" <PTypeOf>
end
rule base_class
attr:( "public" ![a-zA-Z0-9_] s / "private" ![a-zA-Z0-9_] s / "protected" ![a-zA-Z0-9_] s / "virtual" ![a-zA-Z0-9_] s )* a cid:class_id <PBaseClass>
end
rule base_classes
base_class ( s "," s base_classes )?
end
rule class_or_struct_type
stype:( "union" ![a-zA-Z0-9_] / "struct" ![a-zA-Z0-9_] / "class" ![a-zA-Z0-9_] ) a idspec:( s id:class_id )? bcspec:( s ":" s bc:base_classes )? bodyspec:( s "{" s body:class_struct_body s "}" )? <PStructOrClassType>
end
rule concrete_type
( class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
end
rule cv
( "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
end
rule pointer
cvspec:( cv:cv s )? "*" itspec:( s it:inner_type )? <PPointer>
end
rule reference
cvspec:( cv:cv s )? "&" itspec:( s it:inner_type )? <PReference>
end
rule array_spec
"[" s block_wo_comma s "]" <PArraySpec>
end
rule func_arg_part
t:type_wo_comma !"..." <PFuncArgPart>
end
rule ellipsis
"..." <PEllipsis>
end
rule func_args
&")" /
func_arg_part ( s "," s func_arg_part )* ( s "," s ellipsis )? /
ellipsis
end
rule func_spec
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? ( s "throw" s "(" s ( type_wo_comma s )? ")" )* a <PFuncSpec>
end
rule member_pointer
cspec:( qid:qualified_id s "::*" s ) itspec:( it:inner_type )? cvspec:( s cv:cv )? <PMemberPointer>
end
rule inner_type_with_cv
cvspec:cv s it:inner_type <PInnerTypeWithCV>
end
rule inner_type
it:(
"(" s inner_type s ")" /
inner_type_with_cv /
pointer /
reference /
member_pointer /
( "__restrict" ![a-zA-Z0-9_] s )? qualified_id
)
pfx:( s spec:( array_spec / func_spec ) )*
<PInnerType>
end
rule type
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
ct:concrete_type
a
il:( s t1:inner_type i1:(s "=" s is1:block_wo_comma)? tt:( s "," s t2:inner_type i2:(s "=" s is2:block_wo_comma)? )* )?
# alternative initialization if only a concrete type is given:
pi:( s "=" s is:block_wo_comma )?
<PType>
end
rule type_wo_comma
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
ct:concrete_type
il:( s t:inner_type i:(s "=" s is:block_wo_comma)? )?
# alternative initialization if only a concrete type is given:
pi:( s "=" s is:block_wo_comma )?
<PTypeWoComma>
end
rule type_for_template
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
ct:concrete_type
il:( s t:inner_type )?
<PTypeForTemplate>
end
rule storage_class
( "static" ![a-zA-Z0-9_] / "extern" ![a-zA-Z0-9_] ( s '"C"' / s '"C++"' / s '"Pascal"' )? ) <PStorageClass>
end
rule inline_spec
"inline" ![a-zA-Z0-9_] <PInline>
end
# parse over blocks as gracefully as possible ...
rule block_atom_wo_gt
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op_wo_gt / "?" / "::" / "." / ":" / ";"
end
rule block_wo_gt
( s block_atom_wo_gt / s "{" s block s "}" )*
end
# parse over blocks as gracefully as possible ...
rule block_atom
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op / "?" / "::" / "." / ":"
end
rule block
( s block_atom / s ";" / s "," / s "{" s block s "}" )*
end
rule block_wo_curly_braces
( s block_atom / s "," )*
end
rule block_wo_comma
( s block_atom / s "{" s block s "}" )*
end
rule using
"using" ![a-zA-Z0-9_] ( s "namespace" )? ![a-zA-Z0-9_] s id:qualified_id a ";" <PUsing>
end
rule typedef
a "typedef" ![a-zA-Z0-9_] s t:type a ";" <PTypedef>
end
rule template_decl_arg
( "class" / "typename" ) ![a-zA-Z0-9_] s id:id dtspec:( s "=" s dt:type_for_template )? <PClassTemplateArg> /
t:type_for_template initspec:( s "=" s init:block_wo_gt )? <PDirectTemplateArg>
end
rule template_decl
"template" s "<" s ( !">" template_decl_arg s ( "," s template_decl_arg )* )? s ">" <PTemplateDecl>
end
rule declaration_w_semicolon
template:( d:template_decl s )?
template_member:( d_member:template_decl s )?
attr:( ( storage_class / inline_spec ) s )*
a
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
a
(
"{" s block s "}" /
";"
) <PDeclaration>
end
rule declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( storage_class / inline_spec ) s )*
a
t:type
# opposite case (see declaration_wo_semicolon)
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
a
(
"{" s block s "}" /
";"?
) <PDeclaration>
end
rule declaration
declaration_w_semicolon / declaration_wo_semicolon
end
rule namespace
"namespace" ![a-zA-Z0-9_] s n:id
a "{" decls:( a ( ";" / using / typedef / namespace / declaration ) )* s "}" <PNamespace>
end
rule extern_decl
"extern" s n:( '"C"' / '"C++"' / '"Pascal"' ) s
a "{" decls:( a ( ";" / typedef / namespace / extern_decl / declaration ) )* s "}" <PExternBlock>
end
rule module
( a ( ";" / using / typedef / namespace / extern_decl / declaration ) )* s <PModule>
end
end

View File

@ -0,0 +1,654 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
class Module
def def_initializer(*args)
self.class_eval <<END
def initialize(#{args.join(", ")})
#{args.map { |arg| "@#{arg} = #{arg}" }.join("\n")}
end
def initialize_copy(other)
# TODO: is there a better way to check whether dup can be used?
# Implement Hash?
#{args.map { |arg| "a = other.#{arg}\n"+
"if a.is_a?(TrueClass) || a.is_a?(FalseClass) || a.is_a?(NilClass) || a.is_a?(Fixnum) || a.is_a?(Float) || a.is_a?(Symbol)\n"+
" @#{arg} = a\n"+
"elsif a.is_a?(Array)\n"+
" @#{arg} = a.collect { |aa| aa.dup }\n"+
"else\n"+
" @#{arg} = a.dup\n"+
"end"
}.join("\n")}
end
END
end
end
# @brief The base class for all CPP objects
class CPPObject
end
# @brief Denotes type nesting wrappers
# Type nesting provide a modification the renders a different type
# for the inner "user" of the type. For example:
# "int **x" starts with "int", adds a pointer, adds another pointer and
# ends at "x" (the symbol). "int" is the "concrete type", the two
# pointers are type wrappers and "x" is the innermost elements.
# The type s read from the inside out: "x" is a pointer to a pointer to an int.
class CPPOuterType < CPPObject
end
# @brief An array specification
# @attribute inner The inner type (the type which makes use of the array)
# "inner" is either another CPPOuterType or a CPPQualifiedId (the innermost)
# part.
class CPPArray < CPPOuterType
attr_accessor :inner
def_initializer :inner
def to_s
if self.inner.is_a?(CPPPointer)
"(" + self.inner.to_s + ") []"
else
self.inner.to_s + " []"
end
end
def dump(i)
i + "CPPArray\n" + i + " inner:\n" + self.inner.dump(i + " ")
end
end
# @brief A function specification
# @attribute inner The inner type (which makes use of the function)
# @attribute args The function arguments
# @attribute cv A const/voilatile specification if the function is a method (:const, :volatile)
# "inner" is either another CPPOuterType or a CPPQualifiedId (the innermost)
# part.
# "args" is an array of CPPType or CPPInitializedType objects, optionally terminated with
# a CPPEllipsis.
# "cv" is a CPPCV object.
class CPPFunc < CPPOuterType
attr_accessor :inner, :args, :cv
def_initializer :inner, :args, :cv
def to_s
a = self.args
a ||= []
if !a.is_a?(Array)
a = [a]
end
self.inner.to_s + " (" + a.join(", ") + ")" + (self.cv ? " " + self.cv.to_s : "")
end
def dump(i)
i + "CPPFunc\n" + i + " inner:\n" + self.inner.dump(i + " ") + "\n" +
i + " cv: " + self.cv.to_s + "\n" +
i + " args:\n" + (self.args || []).collect { |f| f.dump(i + " ") }.join("\n")
end
end
# @brief A pointer declaration
# @attribute inner The inner type which sees the outer type converted into a pointer
# "inner" is either another CPPOuterType or a CPPQualifiedId (the innermost)
# part.
class CPPPointer < CPPOuterType
attr_accessor :inner
def_initializer :inner
def to_s
"* " + self.inner.to_s
end
def dump(i)
i + "CPPPointer\n" + i + " inner:\n" + self.inner.dump(i + " ")
end
end
# @brief A reference declaration
# @attribute inner The inner type which sees the outer type converted into a reference
# "inner" is either another CPPOuterType or a CPPQualifiedId (the innermost)
# part.
class CPPReference < CPPOuterType
attr_accessor :inner
def_initializer :inner
def to_s
"& " + self.inner.to_s
end
def dump(i)
i + "CPPReference\n" + i + " inner:\n" + self.inner.dump(i + " ")
end
end
# @brief A member/method pointer declaration
# @attribute qid The class of which a member/method is addressed (a CPPQualifiedId object)
# @attribute inner The inner type which sees the outer type converted into a member/method pointer
# @attribute cv A CPPCV object describing whether the method is a const or volatile one
# Functions are converted to method pointers, plain type into member pointers.
# "inner" is either another CPPOuterType or a CPPQualifiedId (the innermost)
# part.
class CPPMemberPointer < CPPOuterType
attr_accessor :qid, :inner, :cv
def_initializer :qid, :inner, :cv
def to_s
self.qid.to_s + "::* " + self.inner.to_s + (self.cv ? " " + self.cv.to_s : "")
end
def dump(i)
i + "CPPMemberPointer\n" + i + " inner:\n" + self.inner.dump(i + " ") +
i + " cv:\n" + self.cv.dump(i + " ") +
i + " qid: " + self.qid.to_s
end
end
# @param Adds const or volatile declaration
# @attribute cv :const or :volatile
# @attribute inner The inner expression which sees the const/volatile declaration
class CPPCV < CPPOuterType
attr_accessor :cv, :inner
def_initializer :cv, :inner
def to_s
(self.cv ? (self.cv.to_s + " ") : "") + self.inner.to_s
end
def dump(i)
i + "CPPCV\n" +
i + " cv: " + self.cv.to_s + "\n" +
i + " inner:\n" + self.inner.dump(i + " ")
end
end
def CPPCV::wrap(cv, inner)
cv ? CPPCV::new(cv, inner) : inner
end
# @brief A constant uses as a template instance argument
# @attribute value A string giving the value
class CPPConst < CPPObject
attr_accessor :value
def_initializer :value
def to_s
self.value
end
def dump(i)
i + "CPPConst\n" + i + " value: " + self.value.to_s
end
end
# @brief A class the template instance arguments
# @attribute args An array of CPPConst (for constants) or CPPType objects (for types)
# This class is used for both template instances or declarations.
class CPPTemplateArgs < CPPObject
attr_accessor :args
def_initializer :args
def to_s
self.args.collect { |a| a.to_s }.join(", ")
end
def dump(i)
i + "CPPTemplateArgs\n" +
i + " args:\n" + (self.args || []).collect { |a| a.dump(i + " ") }.join("\n")
end
end
# @brief An class or namespace name, optionally with template arguments
# @attribute id The basic id (a string)
# @attribute template_args A CPPTemplateArgs object describing the template arguments or nil, if it does not describe a template instance or declaration
class CPPId < CPPObject
attr_accessor :id, :template_args
def_initializer :id, :template_args
def to_s
ta = self.template_args.to_s
if ta =~ />$/
ta += " "
end
self.id + (self.template_args ? ( "<" + ta + ">" ) : "")
end
def dump(i)
i + "CPPId\n" +
i + " id: " + self.id.to_s +
i + " template_args:\n" + self.template_args.dump(i + " ")
end
end
# @brief An anonymous ID
# This object is used in place of CPPQualifiedId if no name is given
class CPPAnonymousId < CPPObject
def to_s
""
end
def dump(i)
i + "CPPAnonymousId"
end
end
# @brief An id, optionally qualified by a namespace
# @attribute global If true, the Id is rooted in the global namespace
# @attribute parts A sequence of CPPId objects forming the namespace sequence
class CPPQualifiedId < CPPObject
attr_accessor :global, :parts
def_initializer :global, :parts
def to_s
(self.global ? "::" : "") + (self.parts || []).collect { |p| p.to_s }.join("::")
end
def dump(i)
n = (self.global ? "::" : "") + (self.parts || []).collect { |p| "[" + p.to_s + "]" }.join("::")
i + "CPPQualifiedId (" + n + ")"
end
end
# @brief A "plain old type" (double, float, int, char, ...)
# @attribute signed Is nil, :signed or :unsigned (for the types supporting that)
# @attribute length Is nil, :short, :long or :longlong for the types supporting that
# @attribute type The basic type (:int, :char, :bool, :float, :double)
class CPPPOD < CPPObject
attr_accessor :signed, :length, :type
def_initializer :signed, :length, :type
def to_s
s = ""
if self.signed == :signed
s += "signed "
elsif self.signed == :unsigned
s += "unsigned "
end
if self.length == :short
s += "short "
elsif self.length == :long
s += "long "
elsif self.length == :longlong
s += "long long "
end
s + self.type.to_s
end
def dump(i)
i + "CPPPOD (" + self.to_s + ")"
end
end
# @brief A base class declarations
# @attribute visibility :default, :public, :private or :protected
# @attribute virtual Is true, if the class is a virtual base class
# @attribute class_id A CPPQualifiedId object pointing to the base class
class CPPBaseClass < CPPObject
attr_accessor :visibility, :virtual, :class_id
def_initializer :visibility, :virtual, :class_id
def to_s
(self.visibility ? self.visibility.to_s + " " : "") + (self.virtual ? "virtual " : "") + self.class_id.to_s
end
def dump(i)
i + "CPPBaseClass\n" +
i + " visibility: " + self.visibility.to_s +
i + " virtual:\n" + self.virtual.to_s +
i + " class_id:\n" + self.class_id.to_s
end
end
# @brief Describes a structure, class or union
# @attribute kind :struct, :class or :union
# @attribute id The name of the struct, class or union
# @attribute base_classes The base class declarations (an array of CPPBaseClass objects)
# @attribute body_decl An array or CPPUsingSpec, CPPFriendDecl, CPPTypedef, CPPEnumDeclaration, CPPStructDeclaration or CPPDeclaration objects
# "body_decl" forms the body of the class. It contains friend declarations, using specs, typedef's, enum's,
# nested struct's or method and member declarations.
class CPPStruct < CPPObject
attr_accessor :kind, :id, :base_classes, :body_decl
def_initializer :kind, :id, :base_classes, :body_decl
def to_s
self.kind.to_s + " " + self.id.to_s
end
def dump(i)
l = i + self.kind.to_s + ": " + self.id.to_s + "\n"
l += (self.base_classes || []).collect { |b| i + " < " + b.to_s + "\n" }.join("")
l += (self.body_decl || []).collect { |b| b.dump(i + " ") }.join("\n")
end
end
# @param Describes a type derived with "__typeof"
# @attribute what The object from which the type is derived (a CPPQualifiedId)
class CPPTypeOf < CPPObject
attr_accessor :what
def_initializer :what
def to_s
"__typeof(" + what.to_s + ")"
end
def dump(i)
i + "CPPTypeOf\n" +
i + " what: " + self.what.to_s
end
end
# @param Describes an ellipsis inside a function argument list
class CPPEllipsis < CPPObject
def to_s
"..."
end
def dump(i)
i + "CPPEllipsis"
end
end
# @brief A general type definition
# @attribute concrete The concrete part of the type: a CPPPOD, CPPStruct, CPPEnum, CPPTypeof or CPPQualifiedId object)
# @attribute inner The "inner part": one of the CPPOuterType-derived classes or CPPQualifiedId
# @attribute init A string indicating the initialization expression
# If the concrete type is a class, struct, union, enum or typedef, a CPPQualifiedId is used for the
# attribute, describing the initial type (which can be complex already in the case of a typedef).
# The "inner" declarations add pointers, references, arrays of functions and finally the identifier.
# Without any further qualification, "inner" is a CPPQualifiedId object.
class CPPType < CPPObject
attr_accessor :concrete, :inner, :init
def_initializer :concrete, :inner, :init
def to_s
i = self.inner.to_s
s = self.concrete.to_s + " " + i
# nicen:
s.gsub(/\s+/, " ").sub(/^\s*/, "").sub(/\s*$/, "").gsub(/ \(/, "(").gsub(/\* /, "*").gsub(/& /, "&")
end
def dump(i)
i + "CPPType\n" +
i + " init: " + (self.init ? self.init.to_s : "nil") + "\n" +
i + " concrete:\n" + (self.concrete ? self.concrete.dump(i + " ") : i + " nil") + "\n" +
i + " inner:\n" + self.inner.dump(i + " ")
end
end
# @brief A "using" instruction
# @attribute qid The qualified Id of the using specification
# @attribute visibility :default, :public, :private or :protected
class CPPUsingSpec < CPPObject
attr_accessor :qid, :visibility
def_initializer :qid, :visibility
def dump(i)
i + "using [" + self.visibility.to_s + "]: " + self.qid.to_s
end
end
# @brief A typedef instruction
# @attribute type The declared type (a CPPType object, the inner name is the name of the defined type)
# @attribute visibility :default, :public, :private or :protected
class CPPTypedef < CPPObject
attr_accessor :type, :visibility
def_initializer :type, :visibility
def dump(i)
i + "typedef [" + self.visibility.to_s + "]: " + self.type.to_s
end
end
# @brief A friend declaration
# @attribute decl An array of friend types (an array of CPPType objects)
class CPPFriendDecl < CPPObject
attr_accessor :decl
def_initializer :decl
def dump(i)
self.decl.collect { |d| i + "friend: " + d.to_s }.join("\n")
end
end
# @brief A type template argument (with an optional initializer)
# @attribute id The name of the argument (a string)
# @attribute def_type The default type (nil or a CPPType object)
class CPPClassTemplateArg < CPPObject
attr_accessor :id, :def_type
def_initializer :id, :def_type
def to_s
self.id + (self.def_type ? ("=" + self.def_type.to_s) : "")
end
end
# @brief A value template argument (with an optional initializer)
# @attribute type A CPPType object describing the type
# @attribute def_expr The initializer expression (a string) or nil if no initializer is given
class CPPDirectTemplateArg < CPPObject
attr_accessor :type, :def_expr
def_initializer :type, :def_expr
def to_s
self.type.to_s + (self.def_expr ? ("=" + self.def_expr.to_s) : "")
end
end
# @brief A template declaration
# @attribute parts An array of CPPClassTemplateArg or CPPDirectTemplateArg objects
# CPPClassTemplateArg objects describe type arguments while CPPDirectTemplateArg objects
# describe value arguments (i.e. int).
class CPPTemplateDecl < CPPObject
attr_accessor :parts
def_initializer :parts
def to_s
(self.parts || []).collect { |p| p.to_s }.join(", ")
end
end
# @brief An internal object, does not appear in the final parsed tree
class CPPAttr < CPPObject
attr_accessor :attr
def_initializer :attr
end
# @brief An struct/class/union declaration inside a namespace or class
# @attribute struct The CPPStruct object describing the class, struct or union
# @attribute template_decl nil or a CPPTemplateDecl object if the declaration is a template declaration
# @attribute visibility :default, :public, :private or :protected
class CPPStructDeclaration < CPPObject
attr_accessor :struct, :template_decl, :visibility
def_initializer :struct, :template_decl, :visibility
def dump(i)
l = i + self.struct.kind.to_s + "_decl [" + self.visibility.to_s + "]: "
if self.template_decl
l += "template<" + self.template_decl.to_s + ">"
end
l += "\n"
l += self.struct.dump(i + " ")
end
end
# @brief An enum declaration inside a namespace or class
# @attribute enum The CPPEnum object describing the enum
# @attribute visibility :default, :public, :private or :protected
class CPPEnumDeclaration < CPPObject
attr_accessor :enum, :visibility
def_initializer :enum, :visibility
def dump(i)
i + "enum_decl [" + self.visibility.to_s + "]:\n" + self.enum.dump(i + " ")
end
end
# @brief A declaration of either a function, a type, a member or a method
# @attribute type the declared type: a CPPType object
# @attribute template_decl nil or a CPPTemplateDecl object if the declaration is a template declaration
# @attribute visibility :default, :public, :private or :protected
# @attribute storage_class nil, :extern or :static
# @attribute virtual Is true for virtual methods
# @attribute inline Is true for inline declarations
class CPPDeclaration < CPPObject
attr_accessor :type, :template_decl, :visibility, :storage_class, :virtual, :inline
def_initializer :type, :template_decl, :visibility, :storage_class, :virtual, :inline
def dump(i)
l = i
l += "decl [" + self.visibility.to_s + "]: "
if self.storage_class
l += self.storage_class.to_s + " "
end
if self.virtual
l += "virtual "
end
if self.inline
l += "inline "
end
if self.template_decl
l += "template<" + self.template_decl.to_s + "> "
end
if self.type.respond_to?(:to_s)
l += self.type.to_s
else
l += self.type.dump(i + " ")
end
l += " #" + self.myself.to_s
l
end
end
# @brief A namespace
# @attribute name The namespace name (a string)
# @attribute members The content of the namespace: an array of CPPTypedef, CPPNamespace (nested namespaces), CPPStructDeclaration, CPPEnumDeclaration or CPPDeclaration objects
class CPPNamespace < CPPObject
attr_accessor :name, :members
def_initializer :name, :members
def dump(i)
l = i + "namespace #{self.name} {\n"
l += (self.members || []).collect { |m| m.dump(i + " ") }.join("\n")
l += i + "}"
end
end
# @brief Describes a single enum constant
# @attribute name The name of the enum constant
# @attribute init The initalizer (not parsed - just a string)
class CPPEnumSpec < CPPObject
attr_accessor :name, :init
def_initializer :name, :init
def to_s
self.name + (self.init ? "=" + self.init : "")
end
end
# @brief Describes an enum declaration
# @attribute name The name of the enum (a string)
# @attribute specs the enum members (an array of CPPEnumSpec objects)
class CPPEnum < CPPObject
attr_accessor :name, :specs
def_initializer :name, :specs
def to_s
"enum " + (self.name || "")
end
def dump(i)
l = i + self.to_s + " {\n"
l += (self.specs || []).collect { |s| i + " " + s.to_s + "\n" }.join("")
l += i + "}"
end
end
# @brief The root object of the declaration tree
# @attribute decls The content of the module: an array of CPPTypedef, CPPNamespace (nested namespaces), CPPStructDeclaration, CPPEnumDeclaration or CPPDeclaration objects
class CPPModule < CPPObject
attr_accessor :decls
def_initializer :decls
def dump
(self.decls || []).collect { |d| d.dump("") }.join("\n")
end
end

View File

@ -0,0 +1,474 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
class Treetop::Runtime::SyntaxNode
# An alias which can be used inside a derived cpp implementation
# The default implementation collects all objects emitted by the subnodes.
def get_cpp
a = elements && elements.collect { |e| e.cpp }.select { |e| e }.flatten
(a && !a.empty?) ? a : nil
end
# Returns the CPP objects emitted by this node.
# This method delivers CPP objects or arrays of CPP objects.
def cpp
get_cpp
end
# Returns the single CPP object or nil
def cpp_reduced
a = self.cpp
if a.is_a?(Array)
a.size == 1 || raise("Internal error: more than one syntax tree node")
a = a[0]
end
a
end
# Note: this method is required because curly braces cannot be put
# into parser conditions (treetop syntax flaw?)
def text_value_ends_with_curly_brace
text_value =~ /\}$/
end
end
# These are a couple of emitter extensions to SyntaxNode which produce the definition syntax tree
# through the "cpp" method:
module PTypeOf
def cpp
CPPTypeOf::new(qid.cpp)
end
end
def extract_signed(t)
if t =~ /unsigned/
:unsigned
elsif t =~ /signed/
:signed
else
nil
end
end
def extract_length(t)
if t =~ /long long/
:longlong
elsif t =~ /long/
:long
elsif t =~ /short/
:short
else
nil
end
end
module PIntType
def cpp
CPPPOD::new(extract_signed(text_value), extract_length(text_value), :int)
end
end
module PCharType
def cpp
CPPPOD::new(extract_signed(text_value), nil, :char)
end
end
module PBoolType
def cpp
CPPPOD::new(nil, nil, :bool)
end
end
module PSpecialType
def cpp
# the special type produces an ID
CPPQualifiedId::new(false, [ CPPId::new(id.text_value, nil) ])
end
end
module PFloatType
def cpp
kind = text_value =~ /double/ ? :double : :float
CPPPOD::new(nil, extract_length(text_value), kind)
end
end
module PVoidType
def cpp
CPPPOD::new(nil, nil, :void)
end
end
module PEnumSpec
def cpp
CPPEnumSpec::new(id.text_value, initspec.nonterminal? ? initspec.init.text_value : nil)
end
end
module PEnumType
def cpp
name = id ? id.text_value : nil
specs = bodyspec.nonterminal? ? bodyspec.body.cpp : nil
CPPEnum::new(name, specs)
end
end
module PConst
def cpp
CPPConst::new(text_value)
end
end
module PTemplateArgs
def cpp
decl = self.get_cpp
decl ? CPPTemplateArgs::new(decl) : nil
end
end
module PId
def cpp
CPPId::new(id.text_value, taspec.nonterminal? ? taspec.ta.cpp_reduced : nil)
end
end
module PQualifiedId
def cpp
CPPQualifiedId::new(globalspec.nonterminal?, self.get_cpp)
end
end
module PBaseClass
def cpp
visibility = nil
virtual = false
at = attr.text_value
if at =~ /private/
visibility = :private
elsif at =~ /public/
visibility = :public
elsif at =~ /protected/
visibility = :protected
end
if at =~ /virtual/
virtual = true
end
CPPBaseClass::new(visibility, virtual, cid.cpp_reduced)
end
end
module PStructOrClassType
def cpp
kind = :class
if stype.text_value == "struct"
kind = :struct
elsif stype.text_value == "union"
kind = :union
end
id = idspec.nonterminal? ? idspec.id.cpp_reduced : nil
base_classes = bcspec.nonterminal? ? bcspec.bc.cpp : nil
body_decl = bodyspec.nonterminal? ? bodyspec.body.cpp : nil
CPPStruct::new(kind, id, base_classes, body_decl)
end
end
module PCV
def to_symbol
return self.text_value == "const" ? :const : :volatile
end
end
module PFriendDecl
def cpp
CPPFriendDecl::new(t.cpp)
end
end
module PPointer
def cpp
CPPCV::wrap(cvspec.nonterminal? && cvspec.cv.to_symbol, CPPPointer::new(itspec.nonterminal? ? itspec.it.cpp_reduced : CPPAnonymousId::new))
end
end
module PReference
def cpp
CPPCV::wrap(cvspec.nonterminal? && cvspec.cv.to_symbol, CPPReference::new(itspec.nonterminal? ? itspec.it.cpp_reduced : CPPAnonymousId::new))
end
end
module PMemberPointer
def cpp
CPPMemberPointer::new(cspec.qid.cpp, itspec.nonterminal? ? itspec.it.cpp_reduced : CPPAnonymousId::new, cvspec.nonterminal? && cvspec.cv.to_symbol)
end
end
module PArraySpec
def cpp
CPPArray::new(nil)
end
end
module PFuncArgPart
def cpp
t.cpp_reduced
end
end
module PFuncSpec
def cpp
CPPFunc::new(nil, (fa.nonterminal? && fa.text_value != "void") ? (fa.a.cpp || []) : [], cvspec.nonterminal? && cvspec.cv.to_symbol)
end
end
module PInnerTypeWithCV
def cpp
CPPCV::wrap(cvspec.to_symbol, it.cpp_reduced)
end
end
module PInnerType
def cpp
if pfx.nonterminal?
pfx.elements.inject(it.cpp_reduced) do |r,e|
ee = e.spec.cpp_reduced
ee.inner = r
ee
end
else
it.cpp
end
end
end
module PStorageClass
def cpp
if text_value =~ /^static/
return CPPAttr::new(:static)
elsif text_value =~ /^extern/
return CPPAttr::new(:extern)
else
return nil
end
end
end
module PVirtual
def cpp
return CPPAttr::new(:virtual)
end
end
module PInline
def cpp
return CPPAttr::new(:inline)
end
end
module PType
def cpp
# This is the class/struct/union/enum declaration if there is one
d = ct.cpp
if d.is_a?(Array)
r = d.select { |i| i.is_a?(CPPStruct) || i.is_a?(CPPEnum) }
elsif d.is_a?(CPPStruct) || d.is_a?(CPPEnum)
r = [d]
else
r = []
end
# Create each declaration
ot = CPPCV::wrap(cvspec.nonterminal? && cvspec.cv.to_symbol, ct.cpp_reduced)
if il.nonterminal?
r << CPPType::new(ot, il.t1.cpp_reduced, il.i1.nonterminal? ? il.i1.is1.text_value : nil)
il.tt.elements.each do |t|
r << CPPType::new(ot, t.t2.cpp_reduced, t.i2.nonterminal? ? t.i2.is2.text_value : nil)
end
else
r << CPPType::new(ot, CPPAnonymousId::new, pi.nonterminal? ? pi.is.text_value : nil)
end
r
end
end
module PEllipsis
def cpp
CPPEllipsis::new
end
end
module PTypeWoComma
def cpp
ot = CPPCV::wrap(cvspec.nonterminal? && cvspec.cv.to_symbol, ct.cpp_reduced)
if il.nonterminal?
CPPType::new(ot, il.t.cpp_reduced, il.i.nonterminal? ? il.i.is.text_value : nil)
else
CPPType::new(ot, CPPAnonymousId::new, pi.nonterminal? ? pi.is.text_value : nil)
end
end
end
module PTypeForTemplate
def cpp
ot = CPPCV::wrap(cvspec.nonterminal? && cvspec.cv.to_symbol, ct.cpp_reduced)
CPPType::new(ot, il.nonterminal? ? il.t.cpp_reduced : CPPAnonymousId::new, nil)
end
end
module PUsing
def cpp
CPPUsingSpec::new(id.cpp_reduced, :default)
end
end
module PTypedef
def cpp
t.cpp.collect do |d|
if d.is_a?(CPPStruct)
CPPStructDeclaration::new(d, nil, :default)
elsif d.is_a?(CPPEnum)
CPPEnumDeclaration::new(d, :default)
else
CPPTypedef::new(d, :default)
end
end
end
end
module PPrivateClassStructBodyDeclarations
def cpp
decl = d.cpp
decl && decl.collect do |d|
if d.respond_to?(:visibility)
d.visibility = :private
end
d
end
end
end
module PProtectedClassStructBodyDeclarations
def cpp
decl = d.cpp
decl && decl.collect do |d|
if d.respond_to?(:visibility)
d.visibility = :protected
end
d
end
end
end
module PPublicClassStructBodyDeclarations
def cpp
decl = d.cpp
decl && decl.collect do |d|
if d.respond_to?(:visibility)
d.visibility = :public
end
d
end
end
end
module PTemplateDecl
def cpp
CPPTemplateDecl::new(self.get_cpp)
end
end
module PClassTemplateArg
def cpp
CPPClassTemplateArg::new(id.text_value, dtspec.nonterminal? ? dtspec.cpp : nil)
end
end
module PDirectTemplateArg
def cpp
CPPDirectTemplateArg::new(t.cpp, initspec.nonterminal? ? initspec.text_value : nil)
end
end
module PDeclaration
def cpp
td = nil
if template.nonterminal?
td = template.d.cpp
end
storage_class = nil
virtual = nil
inline = nil
if attr.nonterminal? && attr.cpp
attr.cpp.each do |d|
if d.attr == :virtual
virtual = true
elsif d.attr == :inline
inline = true
elsif d.attr == :static
storage_class = :static
elsif d.attr == :extern
storage_class = :extern
end
end
end
# TODO: abstract declaration determination should be based on initializers on the
# inner types
t.cpp.collect do |d|
if d.is_a?(CPPStruct)
CPPStructDeclaration::new(d, td, :default)
elsif d.is_a?(CPPEnum)
CPPEnumDeclaration::new(d, :default)
else
CPPDeclaration::new(d, td, :default, storage_class, virtual, inline)
end
end
end
end
module PExternBlock
def cpp
self.get_cpp.collect do |d|
if d.is_a?(CPPDeclaration)
d.storage_class = :extern
end
d
end
end
end
module PNamespace
def cpp
CPPNamespace::new(n.text_value, decls.cpp || [])
end
end
module PModule
def cpp
CPPModule::new(self.get_cpp)
end
end

51
scripts/mkqtdecl_common/dump.rb Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env ruby
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
$:.push(File.dirname($0))
require 'oj'
require 'cpp_classes.rb'
require 'reader_ext.rb'
input_file = "all.db"
conf_file = "mkqtdecl.conf"
cls_list = nil
$gen_dir = "generated"
while ARGV.size > 0
o = ARGV.shift
if o == "-i"
input_file = ARGV.shift
else
raise("Invalid option #{o} - usage is 'dump.rb -i all.db'")
end
end
File.open(input_file, "r") do |file|
json = file.read
@root = Oj.load(json)
puts "Reading done."
puts @root.dump
end

View File

@ -0,0 +1,141 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# A helper script to detect ambiguous methods
# run with
# klayout -r mkqtdecl_extract_ambigous_methods.rb -z s
events = {}
classes = {}
RBA::Class::each_class do |cls|
classes[cls.name] = true
end
RBA::Class::each_class do |cls|
tc = {
RBA::ArgType.t_void => "",
RBA::ArgType.t_bool => "b",
RBA::ArgType.t_char => "i",
RBA::ArgType.t_schar => "i",
RBA::ArgType.t_uchar => "i",
RBA::ArgType.t_short => "i",
RBA::ArgType.t_ushort => "i",
RBA::ArgType.t_int => "i",
RBA::ArgType.t_uint => "i",
RBA::ArgType.t_long => "i",
RBA::ArgType.t_ulong => "i",
RBA::ArgType.t_longlong => "i",
RBA::ArgType.t_ulonglong => "i",
RBA::ArgType.t_double => "d",
RBA::ArgType.t_float => "d",
RBA::ArgType.t_var => "v",
RBA::ArgType.t_string => "s",
RBA::ArgType.t_qstring => "s",
RBA::ArgType.t_string_ccptr => "s",
}
uc = {
RBA::ArgType.t_void => "",
RBA::ArgType.t_bool => "b",
RBA::ArgType.t_char => "c",
RBA::ArgType.t_schar => "c",
RBA::ArgType.t_uchar => "uc",
RBA::ArgType.t_short => "s",
RBA::ArgType.t_ushort => "us",
RBA::ArgType.t_int => "i",
RBA::ArgType.t_uint => "ui",
RBA::ArgType.t_long => "l",
RBA::ArgType.t_ulong => "ul",
RBA::ArgType.t_longlong => "w",
RBA::ArgType.t_ulonglong => "uw",
RBA::ArgType.t_double => "d",
RBA::ArgType.t_float => "f",
RBA::ArgType.t_var => "v",
RBA::ArgType.t_string => "s",
RBA::ArgType.t_qstring => "qs",
RBA::ArgType.t_string_ccptr => "t",
}
if cls.name =~ /_Native$/ || !classes[cls.name + "_Native"]
m = {}
cls.each_method do |meth|
m[meth.name] ||= {}
csig = ""
if meth.is_static?
csig += "s"
end
if meth.is_const?
csig += "c"
end
if csig != ""
csig += "#"
end
meth.each_argument do |a|
if a.is_ptr? || a.is_cptr?
csig += "p"
end
if a.type == RBA::ArgType::t_vector
csig += "a"
csig += tc[a.inner.type].to_s
elsif a.type == RBA::ArgType::t_object || a.type == RBA::ArgType::t_object_new
csig += "x"
csig += a.cls.name
else
csig += tc[a.type]
end
end
((m[meth.name] ||= {})[csig] ||= []).push(meth)
end
m.each do |n,cs|
cs.each do |csig,m|
if m.size > 1
puts "Ambigous: #{cls.name}::#{n}_#{csig}"
usigs = []
m.each do |mm|
usig = ""
mm.each_argument do |a|
if a.is_ptr? || a.is_cptr?
usig += "p"
end
if a.type == RBA::ArgType::t_vector
usig += "a"
usig += uc[a.inner.type].to_s
elsif a.type == RBA::ArgType::t_object || a.type == RBA::ArgType::t_object_new
usig += "x"
usig += a.cls.name
else
usig += uc[a.type]
end
end
usigs.push(usig)
end
puts "-> #{usigs.join(',')}"
end
end
end
end
end

View File

@ -0,0 +1,102 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# A helper script to detect non-const pointers
# (those indicate ownership issues).
# run with
# klayout -r mkqtdecl_extract_nc_pointers.rb -z s
events = {}
classes = {}
RBA::Class::each_class do |cls|
classes[cls.name] = true
end
RBA::Class::each_class do |cls|
uc = {
RBA::ArgType.t_void => "",
RBA::ArgType.t_bool => "b",
RBA::ArgType.t_char => "c",
RBA::ArgType.t_schar => "c",
RBA::ArgType.t_uchar => "uc",
RBA::ArgType.t_short => "s",
RBA::ArgType.t_ushort => "us",
RBA::ArgType.t_int => "i",
RBA::ArgType.t_uint => "ui",
RBA::ArgType.t_long => "l",
RBA::ArgType.t_ulong => "ul",
RBA::ArgType.t_longlong => "w",
RBA::ArgType.t_ulonglong => "uw",
RBA::ArgType.t_double => "d",
RBA::ArgType.t_float => "f",
RBA::ArgType.t_var => "v",
RBA::ArgType.t_string => "s",
RBA::ArgType.t_qstring => "qs",
RBA::ArgType.t_string_ccptr => "t",
}
if cls.name =~ /_Native$/ || !classes[cls.name + "_Native"]
m = {}
cls.each_method do |meth|
m[meth.name] ||= {}
has_ptr = false
has_int = false
csig = ""
if meth.is_static?
csig += "s"
end
if meth.is_const?
csig += "c"
end
if csig != ""
csig += "#"
end
meth.each_argument do |a|
if a.is_ptr? || a.is_cptr?
has_ptr = true
csig += "p"
end
if a.type == RBA::ArgType::t_vector
csig += "a"
c = uc[a.inner.type].to_s
csig += c
elsif a.type == RBA::ArgType::t_object || a.type == RBA::ArgType::t_object_new
csig += "x"
csig += a.cls.name
else
c = uc[a.type]
if c == "i" || c == "ui" || c == "l" || c == "ul"
has_int = true
end
csig += c
end
end
if has_ptr && has_int
puts "#{cls.name}::#{meth.name}_#{csig}"
end
end
end
end

View File

@ -0,0 +1,40 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# A helper script to detect potential factory methods
# run with
# klayout -r mkqtdecl_extract_potential_factories.rb -z s
events = {}
RBA::Class::each_class do |cls|
if cls.name =~ /_Native$/
cls.each_method do |meth|
if meth.ret_type.is_ptr?
if meth.name =~ /create/i || meth.name =~ /make/i || meth.name =~ /build/i
puts "#{cls.name}::#{meth.name} -> #{meth.ret_type.to_s}"
end
end
end
end
end

View File

@ -0,0 +1,163 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# A helper script to create or update the .properties configuration file.
# This file will specify the methods that will be turned into properties
# with a getter/setter pair or single getter/setter function.
# run with
# klayout -r mkqtdecl_extract_props.rb -b >mkqtdecl.properties
classes = {}
RBA::Class::each_class do |cls|
classes[cls.name] = true
end
puts "# Properties from Qt meta objects:"
setters_sig = {}
getters_sig = {}
RBA::Class::each_class do |cls|
if cls.name =~ /^Q/ && (cls.name =~ /_Native$/ || !classes[cls.name + "_Native"])
b = cls.base
while b && b.name != "QObject_Native"
b = b.base
end
if b
mo = eval("RBA::#{cls.name}.staticMetaObject")
c = cls.name.sub(/_Native$/, "")
valid_sig = {}
(0..(mo.propertyCount-1)).each do |i|
pr = mo.property(i)
ucname = pr.name[0..0].upcase + pr.name[1..-1]
if pr.isReadable
puts "property_reader(\"#{c}\", /::(#{pr.name}|is#{ucname}|has#{ucname})\\s*\\(/, \"#{pr.name}\")"
getters_sig["#{cls.name}##{pr.name}"] = true
getters_sig["#{cls.name}#is#{ucname}"] = true
getters_sig["#{cls.name}#has#{ucname}"] = true
end
if pr.isWritable
puts "property_writer(\"#{c}\", /::set#{ucname}\\s*\\(/, \"#{pr.name}\")"
setters_sig["#{cls.name}#set#{ucname}"] = true
end
end
end
end
end
puts ""
puts "# Synthetic properties"
# strip const and references from types
def normalize_type(s)
if s =~ /^const\s+(.*)$/
s = $1
end
if s =~ /^(.*?)\s*&/
s = $1
end
s
end
RBA::Class::each_class do |cls|
if cls.name =~ /^Q/ && (cls.name =~ /_Native$/ || !classes[cls.name + "_Native"])
# make all methods into properties with the following signatures
# setX(x) + x() -> "setX|x=" + ":x"
# setX(x) + isX() -> "setX|x=" + "isX|:x"
# setX(x) + hasX() -> "setX|x=" + "hasX|:x"
#
getters = {}
setters = {}
c = cls
while c != nil
c.each_method do |m|
is_setter = false
is_getter = false
m.each_overload do |ov|
is_setter ||= setters_sig["#{c.name}##{ov.name}"]
is_getter ||= getters_sig["#{c.name}##{ov.name}"]
end
if ! is_setter && m.accepts_num_args(1) && m.ret_type.to_s == "void"
m.each_overload do |ov|
if ov.name =~ /^set([A-Z])(\w*)$/
pn = $1.downcase + $2
setters[pn] ||= [ ov, c, m ]
end
end
end
if ! is_getter && m.accepts_num_args(0)
m.each_overload do |ov|
if ov.name =~ /^is([A-Z])(\w*)$/ || ov.name =~ /^has([A-Z])(\w*)$/ || ov.name =~ /^([a-z])(\w*)$/
pn = $1.downcase + $2
getters[pn] ||= [ ov, c, m ]
end
end
end
end
c = c.base
end
setters.keys.sort.each do |pn|
s = setters[pn]
g = getters[pn]
if g && (s[1] == cls || g[1] == cls)
a = nil
s[2].each_argument { |aa| a ||= aa }
setter_type = normalize_type(a.to_s)
getter_type = normalize_type(g[2].ret_type.to_s)
if setter_type == getter_type
puts "# Property #{pn} (#{setter_type})"
gc = g[1].name.sub(/_Native$/, "")
sc = s[1].name.sub(/_Native$/, "")
puts "property_reader(\"#{gc}\", /::#{g[0].name}\\s*\\(/, \"#{pn}\")"
puts "property_writer(\"#{sc}\", /::#{s[0].name}\\s*\\(/, \"#{pn}\")"
end
end
end
end
end

View File

@ -0,0 +1,175 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# A helper script to extract the signals from the Qt declarations
# It can be used to write the .events configuration file which will
# declare the signals of objects.
# run with
# klayout -r mkqtdecl_extract_signals.rb -z >mkqtdecl.events
classes = {}
RBA::Class::each_class do |cls|
classes[cls.name] = true
end
RBA::Class::each_class do |cls|
if cls.name =~ /^Q/ && (cls.name =~ /_Native$/ || !classes[cls.name + "_Native"])
b = cls.base
while b && b.name != "QObject_Native"
b = b.base
end
if b
mo = eval("RBA::#{cls.name}.staticMetaObject")
c = cls.name.sub(/_Native/, "")
valid_sig = {}
(0..(mo.methodCount-1)).each do |i|
mm = mo.method(i)
if mm.methodType == RBA::QMetaMethod::Signal
n = mm.methodSignature.sub(/\(.*/, "")
s = mm.parameterTypes.join(", ")
valid_sig[n] ||= []
found = false
valid_sig[n] = valid_sig[n].select do |vs|
ret = true
if s.index(vs) == 0
ret = false
elsif vs.index(s) == 0
found = true
end
ret
end
if !found
valid_sig[n].push(s)
end
end
end
valid_sig.each do |n,ss|
ss.each do |s|
match = "::#{n}\\s*\\("
renamed = nil
aliased = nil
if c == "QTabWidget"
if n == "currentChanged" && s =~ /QWidget/
match += ".*QWidget"
renamed = "currentChanged_qw"
elsif n == "currentChanged" && s =~ /int/
match += ".*int"
end
elsif c == "QSignalMapper"
if n == "mapped" && s =~ /QWidget/
renamed = "mapped_qw"
match += ".*QWidget"
elsif n == "mapped" && s =~ /int/
match += ".*int"
elsif n == "mapped" && s =~ /QString/
renamed = "mapped_qs"
match += ".*QString"
elsif n == "mapped" && s =~ /QObject/
renamed = "mapped_qo"
match += ".*QObject"
end
elsif c == "QComboBox" || c == "QFontComboBox"
if n == "activated" && s =~ /QString/
renamed = "activated_qs"
match += ".*QString"
elsif n == "activated" && s =~ /int/
match += ".*int"
elsif n == "currentIndexChanged" && s =~ /QString/
renamed = "currentIndexChanged_qs"
match += ".*QString"
elsif n == "currentIndexChanged" && s =~ /int/
match += ".*int"
elsif n == "highlighted" && s =~ /QString/
renamed = "highlighted_qs"
match += ".*QString"
elsif n == "highlighted" && s =~ /int/
match += ".*int"
end
elsif c == "QCompleter"
if n == "activated" && s =~ /QString/
renamed = "activated_qs"
match += ".*QString"
elsif n == "activated" && s =~ /QModelIndex/
match += ".*QModelIndex"
elsif n == "highlighted" && s =~ /QString/
renamed = "highlighted_qs"
match += ".*QString"
elsif n == "highlighted" && s =~ /QModelIndex/
match += ".*QModelIndex"
end
elsif c == "QTextBrowser"
if n == "highlighted" && s =~ /QString/
renamed = "highlighted_qs"
match += ".*QString"
elsif n == "highlighted" && s =~ /QUrl/
match += ".*QUrl"
end
elsif c == "QDoubleSpinBox"
if n == "valueChanged" && s =~ /QString/
renamed = "valueChanged_qs"
match += ".*QString"
elsif n == "valueChanged" && s =~ /double/
match += ".*double"
end
elsif c == "QSpinBox"
if n == "valueChanged" && s =~ /QString/
renamed = "valueChanged_qs"
match += ".*QString"
elsif n == "valueChanged" && s =~ /int/
match += ".*int"
end
elsif c == "QButtonGroup"
if n == "buttonClicked" && s =~ /QAbstractButton/
renamed = "buttonClicked_qab"
match += ".*QAbstractButton"
elsif n == "buttonClicked" && s =~ /int/
match += ".*int"
elsif n == "buttonPressed" && s =~ /QAbstractButton/
renamed = "buttonPressed_qab"
match += ".*QAbstractButton"
elsif n == "buttonPressed" && s =~ /int/
match += ".*int"
elsif n == "buttonReleased" && s =~ /QAbstractButton/
renamed = "buttonReleased_qab"
match += ".*QAbstractButton"
elsif n == "buttonReleased" && s =~ /int/
match += ".*int"
end
end
puts "event(\"#{c}\", /#{match}/, \"#{s}\")"
if renamed
puts "rename(\"#{c}\", /#{match}/, \"#{renamed}\")"
end
end
end
end
end
end

View File

@ -0,0 +1,70 @@
#!/usr/bin/env ruby
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Usage
# parse.rb -i prep.cpp -o dump.json
#
# prep.cpp: preprocessed .cpp file
# dump.json: output dump
$:.push(File.dirname($0))
require 'oj'
require 'treetop'
Treetop.load "c++"
input="all.e"
output="all.db"
while ARGV.size > 0
o = ARGV.shift
if o == "-i"
input = ARGV.shift
elsif o == "-o"
output = ARGV.shift
else
raise("Invalid option #{o} - usage is 'parse.rb -i prep.cpp -o dump.json'")
end
end
input || raise("No input given (use -i)")
output || raise("No output given (use -o)")
text = nil
File.open(input, "r") do |file|
text = file.read
end
parser = CPPParser.new
parser.root = :module
p = parser.parse(text)
if p
puts "Input #{input} successfully read."
File.open(output, "w") do |file|
file.puts(Oj.dump(p.cpp, :mode => :object))
end
puts "Output file #{output} written."
else
puts "Failure in line: "+parser.failure_line.to_s
puts parser.failure_reason
end

3059
scripts/mkqtdecl_common/produce.rb Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,521 @@
#
# Copyright (C) 2006-2017 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
class CPPObject
# Propagate setting of the visibility down to the children
# (set_visibility will replace the default visibility with public or private)
def set_visibility
end
# Inject scoped objects (like "class A::B { ... };") into their target
# scope.
def inject_scoped
end
# delivers a string representation of the name or nil if the object does not have a name
# to contribute
def myself
nil
end
# delivers a CPPQualifiedId representation of the object's location or nil if the object
# does not have a location to contribute
def myid
nil
end
# sets the CPPQualifiedId
def setid(id)
end
# supposed to establish the parent link
def set_parent(p)
end
# removes a child from our members
def remove(d)
end
# inserts a child into our members
def insert(d)
end
end
class CPPType
def func
i = self
while i.respond_to?(:inner)
if i.is_a?(CPPFunc) && (i.inner.is_a?(CPPQualifiedId) || i.inner.is_a?(CPPAnonymousId))
return i
end
i = i.inner
end
nil
end
def return_type
rt = self.dup
f = self.func
if f
i = self
idup = rt
while i.respond_to?(:inner)
i = i.inner
if i == f
idup.inner = CPPAnonymousId::new
break
end
idup.inner = i.dup
idup = idup.inner
end
end
rt
end
def name_substituted_type(sub)
rt = self.dup
i = self
idup = rt
while i.respond_to?(:inner)
ii = i.inner
if ii.is_a?(CPPQualifiedId) || ii.is_a?(CPPAnonymousId)
idup.inner = sub
break
end
i = ii
idup.inner = i.dup
idup = idup.inner
end
rt
end
def anonymous_type
name_substituted_type(CPPAnonymousId::new)
end
def renamed_type(name)
name_substituted_type(CPPQualifiedId::new(false, [name]))
end
def name
i = self
while i.respond_to?(:inner)
ii = i.inner
if ii.is_a?(CPPQualifiedId)
return ii.to_s
end
i = ii
end
nil
end
def is_void?
self.concrete.is_a?(CPPPOD) && self.concrete.to_s == "void" && (self.inner.is_a?(CPPAnonymousId) || self.inner.is_a?(CPPQualifiedId))
end
end
module QualifiedNameResolver
attr_accessor :parent
def global_scope
o = self
while o.myself && o.parent
o = o.parent
end
o
end
# requirements
# - children -> must deliver a list of child objects
# - myself -> must deliver my name
def set_parent(parent = nil)
self.parent = parent
@id2obj = {}
self.children.each do |d|
d.myself && (@id2obj[d.myself] = d)
d.set_parent(self)
end
# Add other children, for example contributed by base classes
if self.respond_to?(:other_children)
self.other_children.each do |d|
d.myself && (@id2obj[d.myself] = d)
end
end
end
def dump_ids
@id2obj.keys.sort.each do |k|
puts("--> #{k}")
end
end
# returns a list of names of child objects
def ids
(@id2obj || {}).keys.sort
end
def id2obj(id)
@id2obj && @id2obj[id]
end
def resolve_qid(qid)
qid.is_a?(CPPQualifiedId) || raise("Argument of resolve_qid must be a CPPQualifiedId object")
obj = nil
if qid.global && self.parent
root = self
while root.parent
root = root.parent
end
obj = root.resolve_qid(qid)
else
obj = id2obj(qid.parts[0].id)
if obj && qid.parts.size > 1
# The part may be a typedef: resolve it in that case before we proceed
while obj && obj.is_a?(CPPTypedef)
obj = obj.type.concrete.is_a?(CPPQualifiedId) && self.resolve_qid(obj.type.concrete)
end
if obj
qid_new = qid.dup
qid_new.parts = qid.parts[1 .. -1]
obj = obj.respond_to?(:resolve_qid) && obj.resolve_qid(qid_new)
end
end
if ! obj && self.parent
obj = self.parent.resolve_qid(qid)
end
end
obj
end
def inject_scoped
self.children.each do |d|
d.inject_scoped
qid = d.myid
if qid
qid.is_a?(CPPQualifiedId) || raise("Argument of resolve_qid must be a CPPQualifiedId object")
if qid.parts.size > 1
qid = qid.dup
while qid.parts.size > 1
obj = id2obj(qid.parts[0].id)
if obj
qid.parts = qid.parts[1 .. -1]
else
break
end
end
if obj && qid.parts.size == 1
# This copies the visibility which is not quite correct, since the injection case
# is usually used for providing an implementation outside a class. That does not
# mean the outside implementation will provide the visibility. Instead a forward
# declaration inside the target scope will do. Since that is lost in our implementation
# currently that is not possible.
self.remove(d)
d.setid(qid)
obj.insert(d)
end
end
end
end
end
end
class CPPDeclaration
include QualifiedNameResolver
def children
[]
end
def myself
self.type.name
end
end
class CPPEnumDeclaration
include QualifiedNameResolver
def children
[]
end
def myself
self.enum.name.to_s
end
end
class CPPEnumSpec
include QualifiedNameResolver
def children
[]
end
def myself
self.name.to_s
end
end
class CPPStruct
attr_accessor :parent
def global_scope
self.parent && self.parent.global_scope
end
def set_visibility
(self.body_decl || []).each do |bd|
if bd.respond_to?(:visibility) && bd.visibility == :default
if self.kind == :struct || self.kind == :union
bd.visibility = :public
else
bd.visibility = :private
end
end
bd.set_visibility
end
end
end
class CPPTypedef
include QualifiedNameResolver
def myself
self.type.name
end
def children
[]
end
end
class CPPStructDeclaration
include QualifiedNameResolver
def children
# take this chance to set the parent to struct
self.struct.parent = self
c = self.struct.body_decl || []
# add enum constants (CPPEnumSpec)
(self.struct.body_decl || []).each do |bd|
if bd.is_a?(CPPEnumDeclaration) && bd.enum && bd.enum.specs
c += bd.enum.specs
end
end
c
end
def remove(d)
self.struct.body_decl.delete(d)
end
def insert(d)
self.struct.body_decl << d
end
def other_children
# add base classes both as sub-namespace and individual parts
# and add self so scoping is possible into ourself
c = [ self ]
(self.struct.base_classes || []).each do |bc|
bc_obj = self.parent.resolve_qid(bc.class_id)
# NOTE: it may look strange to test whether the base class is the class itself but
# since we do a half-hearted job of resolving template variants, this may happen
# if we derive a template specialization from another one (specifically
# "template<class T> struct is_default_constructible : is_default_constructible<> { .. }"
if bc_obj != self && bc_obj.is_a?(CPPStructDeclaration)
c << bc_obj
c += bc_obj.children
c += bc_obj.other_children
end
end
c
end
def myself
# forward declarations (struct.body_decl == nil and no base classes) don't produce a name and
# will therefore not contribute
(self.struct.body_decl || self.struct.base_classes) && self.struct.id.to_s
end
def myid
# forward declarations (struct.body_decl == nil and no base classes) don't produce a name and
# will therefore not contribute
(self.struct.body_decl || self.struct.base_classes) && self.struct.id
end
def setid(id)
self.struct.id = id
end
def set_visibility
self.struct && self.struct.set_visibility
end
end
class CPPNamespace
include QualifiedNameResolver
def children
# take this opportunity to join identical namespaces
if self.members
new_members = []
ns = {}
self.members.each do |d|
if d.is_a?(CPPNamespace)
if !ns[d.myself]
ns[d.myself] = d
new_members << d
else
ns[d.myself].members += d.members
end
else
new_members << d
end
end
self.members = new_members
end
self.members || []
end
def other_children
# add self so scoping is possible into ourself
[ self ]
end
def myself
self.name.to_s
end
def remove(d)
self.members.delete(d)
end
def insert(d)
self.members << d
end
def set_visibility
(self.members || []).each do |m|
if m.respond_to?(:visibility) && m.visibility == :default
m.visibility = :public
end
m.set_visibility
end
end
end
class CPPModule
include QualifiedNameResolver
def children
# take this opportunity to join identical namespaces
new_decls = []
ns = {}
self.decls.each do |d|
if d.is_a?(CPPNamespace)
if !ns[d.myself]
ns[d.myself] = d
new_decls << d
else
ns[d.myself].members += d.members
end
else
new_decls << d
end
end
self.decls = new_decls
end
def remove(d)
self.decls.delete(d)
end
def insert(d)
self.decls << d
end
def myself
nil
end
def set_visibility
(self.decls || []).each do |d|
if d.respond_to?(:visibility) && d.visibility == :default
d.visibility = :public
end
d.set_visibility
end
end
end