summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-07-24 09:45:33 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-07-27 13:04:30 (GMT)
commit3643028959f0b38350e57e60ba4000435b75e592 (patch)
treec129e4dee11487abd437ab8ebd993ba261e06fa6 /tools
parentcf66c667a97c0079141eb3f2d9e997b7378ae792 (diff)
parentc36139c665e61866aff4bf8572890a735167a7d0 (diff)
downloadQt-3643028959f0b38350e57e60ba4000435b75e592.zip
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.gz
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: configure.exe qmake/Makefile.unix qmake/generators/makefile.cpp src/corelib/global/qglobal.h src/corelib/kernel/kernel.pri src/corelib/kernel/qcoreevent.cpp src/corelib/kernel/qsharedmemory_unix.cpp src/gui/graphicsview/qgraphicsscene.cpp src/gui/kernel/qaction.cpp src/gui/kernel/qaction.h src/gui/kernel/qaction_p.h src/gui/kernel/qapplication.cpp src/gui/kernel/qapplication.h src/gui/kernel/qwidget.cpp src/gui/kernel/qwidget.h src/gui/kernel/qwidget_mac.mm src/gui/painting/qgraphicssystemfactory.cpp src/gui/styles/qwindowsstyle.cpp src/gui/text/qfontengine_qpf.cpp src/gui/widgets/qabstractscrollarea_p.h src/network/access/qnetworkaccessdebugpipebackend.cpp src/network/socket/qlocalsocket_unix.cpp src/network/socket/qnativesocketengine_p.h src/network/socket/qnativesocketengine_unix.cpp src/openvg/qpaintengine_vg.cpp tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp tests/auto/qcssparser/qcssparser.pro tests/auto/qdir/tst_qdir.cpp tests/auto/qfile/tst_qfile.cpp tests/auto/qobject/tst_qobject.cpp tests/auto/qpathclipper/qpathclipper.pro tests/auto/qprocess/tst_qprocess.cpp tests/auto/qsettings/tst_qsettings.cpp tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qsqlquerymodel/qsqlquerymodel.pro tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro tests/auto/qsqltablemodel/qsqltablemodel.pro tests/auto/qsqlthread/qsqlthread.pro tests/auto/qwidget/tst_qwidget.cpp
Diffstat (limited to 'tools')
-rw-r--r--tools/activeqt/dumpcpp/main.cpp6
-rw-r--r--tools/assistant/lib/qhelpprojectdata.cpp22
-rw-r--r--tools/assistant/tools/assistant/assistant.rc31
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp11
-rw-r--r--tools/checksdk/cesdkhandler.cpp7
-rw-r--r--tools/checksdk/cesdkhandler.h4
-rw-r--r--tools/checksdk/checksdk.pro39
-rw-r--r--tools/checksdk/main.cpp42
-rw-r--r--tools/configure/configure.pro4
-rw-r--r--tools/configure/configureapp.cpp107
-rw-r--r--tools/configure/configureapp.h4
-rw-r--r--tools/configure/environment.cpp218
-rw-r--r--tools/configure/main.cpp2
-rw-r--r--tools/configure/tools.cpp4
-rw-r--r--tools/designer/data/generate_shared.xsl4
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.cpp6
-rw-r--r--tools/designer/src/components/propertyeditor/designerpropertymanager.cpp7
-rw-r--r--tools/designer/src/components/signalsloteditor/connectdialog.ui8
-rw-r--r--tools/designer/src/designer/Info_mac.plist2
-rw-r--r--tools/designer/src/designer/designer.pro3
-rw-r--r--tools/designer/src/designer/designer.rc30
-rw-r--r--tools/designer/src/designer/mainwindow.cpp2
-rw-r--r--tools/designer/src/designer/qdesigner_workbench.cpp13
-rw-r--r--tools/designer/src/designer/uifile.icnsbin0 -> 123696 bytes
-rw-r--r--tools/designer/src/lib/sdk/abstractformwindow.cpp14
-rw-r--r--tools/designer/src/lib/sdk/script.cpp6
-rw-r--r--tools/designer/src/lib/shared/widgetfactory.cpp6
-rw-r--r--tools/designer/src/lib/uilib/abstractformbuilder.cpp14
-rw-r--r--tools/designer/src/lib/uilib/formbuilder.cpp4
-rw-r--r--tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp2
-rw-r--r--tools/designer/src/uitools/quiloader.cpp8
-rw-r--r--tools/linguist/lconvert/main.cpp23
-rw-r--r--tools/linguist/linguist/linguist.rc31
-rw-r--r--tools/linguist/linguist/mainwindow.cpp22
-rw-r--r--tools/linguist/linguist/mainwindow.h6
-rw-r--r--tools/linguist/linguist/mainwindow.ui2
-rw-r--r--tools/linguist/linguist/messagemodel.cpp2
-rw-r--r--tools/linguist/lrelease/lrelease.112
-rw-r--r--tools/linguist/lrelease/main.cpp32
-rw-r--r--tools/linguist/lupdate/cpp.cpp120
-rw-r--r--tools/linguist/lupdate/lupdate.114
-rw-r--r--tools/linguist/lupdate/main.cpp19
-rw-r--r--tools/linguist/phrasebooks/french.qph227
-rw-r--r--tools/linguist/shared/abstractproitemvisitor.h24
-rw-r--r--tools/linguist/shared/po.cpp5
-rw-r--r--tools/linguist/shared/profileevaluator.cpp1119
-rw-r--r--tools/linguist/shared/profileevaluator.h13
-rw-r--r--tools/linguist/shared/proitems.cpp84
-rw-r--r--tools/linguist/shared/proitems.h33
-rw-r--r--tools/linguist/shared/proparser.pri2
-rw-r--r--tools/linguist/shared/proreader.cpp131
-rw-r--r--tools/linguist/shared/proreader.h57
-rw-r--r--tools/linguist/shared/qm.cpp57
-rw-r--r--tools/linguist/shared/translator.cpp42
-rw-r--r--tools/linguist/shared/translator.h9
-rw-r--r--tools/linguist/shared/ts.cpp4
-rw-r--r--tools/linguist/shared/ts.dtd8
-rw-r--r--tools/linguist/shared/xliff.cpp14
-rw-r--r--tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp11
-rw-r--r--tools/qdoc3/cppcodeparser.cpp25
-rw-r--r--tools/qdoc3/doc.cpp3
-rw-r--r--tools/qdoc3/generator.cpp212
-rw-r--r--tools/qdoc3/generator.h8
-rw-r--r--tools/qdoc3/htmlgenerator.cpp83
-rw-r--r--tools/qdoc3/htmlgenerator.h3
-rw-r--r--tools/qdoc3/javadocgenerator.cpp3
-rw-r--r--tools/qdoc3/javadocgenerator.h2
-rw-r--r--tools/qdoc3/main.cpp2
-rw-r--r--tools/qdoc3/node.cpp12
-rw-r--r--tools/qdoc3/node.h4
-rw-r--r--tools/qdoc3/qdoc3.pro3
-rw-r--r--tools/qdoc3/separator.cpp36
-rw-r--r--tools/qdoc3/separator.h1
-rw-r--r--tools/qdoc3/test/assistant.qdocconf4
-rw-r--r--tools/qdoc3/test/classic.css2
-rw-r--r--tools/qdoc3/test/designer.qdocconf4
-rw-r--r--tools/qdoc3/test/linguist.qdocconf4
-rw-r--r--tools/qdoc3/test/macros.qdocconf5
-rw-r--r--tools/qdoc3/test/qmake.qdocconf4
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf4
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf3
-rw-r--r--tools/qdoc3/test/qt-inc.qdocconf5
-rw-r--r--tools/qdoc3/test/qt.qdocconf4
-rw-r--r--tools/qtconfig/paletteeditoradvanced.cpp2
-rw-r--r--tools/qtestlib/wince/cetest/activesyncconnection.cpp42
-rw-r--r--tools/qtestlib/wince/cetest/bootstrapped.pri3
-rw-r--r--tools/qtestlib/wince/cetest/deployment.cpp34
-rw-r--r--tools/qtestlib/wince/cetest/main.cpp1
-rw-r--r--tools/qtestlib/wince/cetest/remoteconnection.cpp32
-rw-r--r--tools/qtestlib/wince/cetest/remoteconnection.h2
-rw-r--r--tools/qtestlib/wince/remotelib/commands.cpp10
-rw-r--r--tools/qtestlib/wince/remotelib/commands.h2
-rw-r--r--tools/tools.pro2
-rw-r--r--tools/xmlpatterns/main.cpp2
-rw-r--r--tools/xmlpatterns/qcoloringmessagehandler.cpp12
-rw-r--r--tools/xmlpatternsvalidator/main.cpp133
-rw-r--r--tools/xmlpatternsvalidator/main.h76
-rw-r--r--tools/xmlpatternsvalidator/xmlpatternsvalidator.pro19
98 files changed, 2477 insertions, 1084 deletions
diff --git a/tools/activeqt/dumpcpp/main.cpp b/tools/activeqt/dumpcpp/main.cpp
index 0a4aa06..de3ec57 100644
--- a/tools/activeqt/dumpcpp/main.cpp
+++ b/tools/activeqt/dumpcpp/main.cpp
@@ -969,7 +969,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
QString libName;
BSTR nameString;
typelib->GetDocumentation(-1, &nameString, 0, 0, 0);
- libName = QString::fromUtf16((const ushort *)nameString);
+ libName = QString::fromWCharArray(nameString);
SysFreeString(nameString);
if (!nameSpace.isEmpty())
libName = QString(nameSpace);
@@ -1086,7 +1086,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
BSTR bstr;
if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0))
break;
- className = QString::fromUtf16((const ushort *)bstr).toLatin1();
+ className = QString::fromWCharArray(bstr).toLatin1();
SysFreeString(bstr);
switch (typekind) {
case TKIND_RECORD:
@@ -1227,7 +1227,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
BSTR bstr;
if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0))
break;
- className = QString::fromUtf16((const ushort *)bstr).toLatin1();
+ className = QString::fromWCharArray(bstr).toLatin1();
SysFreeString(bstr);
declOut << "// stub for vtable-only interface" << endl;
diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp
index 8947a36..55b4ea7 100644
--- a/tools/assistant/lib/qhelpprojectdata.cpp
+++ b/tools/assistant/lib/qhelpprojectdata.cpp
@@ -41,6 +41,7 @@
#include "qhelpprojectdata_p.h"
+#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QStack>
#include <QtCore/QMap>
@@ -73,6 +74,7 @@ private:
void readKeywords();
void readFiles();
void raiseUnknownTokenError();
+ void addMatchingFiles(const QString &pattern);
};
void QHelpProjectDataPrivate::raiseUnknownTokenError()
@@ -161,7 +163,7 @@ void QHelpProjectDataPrivate::readFilterSection()
readNext();
if (isStartElement()) {
if (name() == QLatin1String("filterAttribute"))
- filterSectionList.last().addFilterAttribute(readElementText());
+ filterSectionList.last().addFilterAttribute(readElementText());
else if (name() == QLatin1String("toc"))
readTOC();
else if (name() == QLatin1String("keywords"))
@@ -244,7 +246,7 @@ void QHelpProjectDataPrivate::readFiles()
readNext();
if (isStartElement()) {
if (name() == QLatin1String("file"))
- filterSectionList.last().addFile(readElementText());
+ addMatchingFiles(readElementText());
else
raiseUnknownTokenError();
} else if (isEndElement()) {
@@ -258,7 +260,21 @@ void QHelpProjectDataPrivate::readFiles()
}
}
-
+// Expand file pattern and add matches into list. If the pattern does not match
+// any files, insert the pattern itself so the QHelpGenerator will emit a
+// meaningful warning later.
+void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
+{
+ QFileInfo fileInfo(rootPath + '/' + pattern);
+ const QStringList &matches =
+ fileInfo.dir().entryList(QStringList(fileInfo.fileName()));
+ for (QStringList::ConstIterator it = matches.constBegin();
+ it != matches.constEnd();
+ ++it)
+ filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it);
+ if (matches.empty())
+ filterSectionList.last().addFile(pattern);
+}
/*!
\internal
diff --git a/tools/assistant/tools/assistant/assistant.rc b/tools/assistant/tools/assistant/assistant.rc
index b4786ce..deaf40c 100644
--- a/tools/assistant/tools/assistant/assistant.rc
+++ b/tools/assistant/tools/assistant/assistant.rc
@@ -1 +1,32 @@
+#include "winver.h"
+
IDI_ICON1 ICON DISCARDABLE "assistant.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Assistant"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "assistant.exe"
+ VALUE "OriginalFilename", "assistant.exe"
+ VALUE "ProductName", "Qt Assistant"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
index 617ac4d..7926020 100644
--- a/tools/assistant/tools/assistant/mainwindow.cpp
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -93,6 +93,8 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
, m_qtDocInstaller(0)
, m_connectedInitSignals(false)
{
+ setToolButtonStyle(Qt::ToolButtonFollowStyle);
+
if (usesDefaultCollection()) {
MainWindow::collectionFileDirectory(true);
m_helpEngine = new QHelpEngine(MainWindow::defaultHelpCollectionFileName(),
@@ -429,6 +431,7 @@ void MainWindow::setupActions()
SLOT(printPreview()));
m_printAction = menu->addAction(tr("&Print..."), m_centralWidget, SLOT(print()));
+ m_printAction->setPriority(QAction::LowPriority);
m_printAction->setIcon(QIcon(resourcePath + QLatin1String("/print.png")));
m_printAction->setShortcut(QKeySequence::Print);
@@ -448,12 +451,15 @@ void MainWindow::setupActions()
menu = menuBar()->addMenu(tr("&Edit"));
m_copyAction = menu->addAction(tr("&Copy selected Text"), m_centralWidget,
SLOT(copySelection()));
+ m_copyAction->setPriority(QAction::LowPriority);
+ m_copyAction->setIconText("&Copy");
m_copyAction->setIcon(QIcon(resourcePath + QLatin1String("/editcopy.png")));
m_copyAction->setShortcuts(QKeySequence::Copy);
m_copyAction->setEnabled(false);
m_findAction = menu->addAction(tr("&Find in Text..."), m_centralWidget,
SLOT(showTextSearch()));
+ m_findAction->setIconText("&Find");
m_findAction->setIcon(QIcon(resourcePath + QLatin1String("/find.png")));
m_findAction->setShortcuts(QKeySequence::Find);
@@ -472,16 +478,19 @@ void MainWindow::setupActions()
m_viewMenu = menuBar()->addMenu(tr("&View"));
m_zoomInAction = m_viewMenu->addAction(tr("Zoom &in"), m_centralWidget,
SLOT(zoomIn()));
+ m_zoomInAction->setPriority(QAction::LowPriority);
m_zoomInAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomin.png")));
m_zoomInAction->setShortcut(QKeySequence::ZoomIn);
m_zoomOutAction = m_viewMenu->addAction(tr("Zoom &out"), m_centralWidget,
SLOT(zoomOut()));
+ m_zoomOutAction->setPriority(QAction::LowPriority);
m_zoomOutAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomout.png")));
m_zoomOutAction->setShortcut(QKeySequence::ZoomOut);
m_resetZoomAction = m_viewMenu->addAction(tr("Normal &Size"), m_centralWidget,
SLOT(resetZoom()));
+ m_resetZoomAction->setPriority(QAction::LowPriority);
m_resetZoomAction->setIcon(QIcon(resourcePath + QLatin1String("/resetzoom.png")));
m_resetZoomAction->setShortcut(tr("Ctrl+0"));
@@ -507,12 +516,14 @@ void MainWindow::setupActions()
m_backAction->setIcon(QIcon(resourcePath + QLatin1String("/previous.png")));
m_nextAction = menu->addAction(tr("&Forward"), m_centralWidget, SLOT(forward()));
+ m_nextAction->setPriority(QAction::LowPriority);
m_nextAction->setEnabled(false);
m_nextAction->setShortcuts(QKeySequence::Forward);
m_nextAction->setIcon(QIcon(resourcePath + QLatin1String("/next.png")));
m_syncAction = menu->addAction(tr("Sync with Table of Contents"), this,
SLOT(syncContents()));
+ m_syncAction->setIconText("Sync");
m_syncAction->setIcon(QIcon(resourcePath + QLatin1String("/synctoc.png")));
menu->addSeparator();
diff --git a/tools/checksdk/cesdkhandler.cpp b/tools/checksdk/cesdkhandler.cpp
index 48452a3..677d003 100644
--- a/tools/checksdk/cesdkhandler.cpp
+++ b/tools/checksdk/cesdkhandler.cpp
@@ -71,15 +71,15 @@ bool CeSdkHandler::parse()
// look at the file at %VCInstallDir%/vcpackages/WCE.VCPlatform.config
// and scan through all installed sdks...
m_list.clear();
- VCInstallDir = qgetenv("VCInstallDir");
+ VCInstallDir = QString::fromLatin1(qgetenv("VCInstallDir"));
VCInstallDir += QLatin1String("\\");
- VSInstallDir = qgetenv("VSInstallDir");
+ VSInstallDir = QString::fromLatin1(qgetenv("VSInstallDir"));
VSInstallDir += QLatin1String("\\");
if (VCInstallDir.isEmpty() || VSInstallDir.isEmpty())
return false;
QDir vStudioDir(VCInstallDir);
- if (!vStudioDir.cd("vcpackages"))
+ if (!vStudioDir.cd(QLatin1String("vcpackages")))
return false;
QFile configFile(vStudioDir.absoluteFilePath(QLatin1String("WCE.VCPlatform.config")));
@@ -118,6 +118,7 @@ bool CeSdkHandler::parse()
qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
return false;
}
+
return m_list.size() > 0 ? true : false;
}
diff --git a/tools/checksdk/cesdkhandler.h b/tools/checksdk/cesdkhandler.h
index 04d3bdf..6ec26db 100644
--- a/tools/checksdk/cesdkhandler.h
+++ b/tools/checksdk/cesdkhandler.h
@@ -102,8 +102,8 @@ inline QList<CeSdkInfo> CeSdkHandler::listAll() const
inline QString CeSdkHandler::fixPaths(QString path) const
{
- QString str = QDir::toNativeSeparators(QDir::cleanPath(path.replace(VCINSTALL_MACRO, VCInstallDir).replace(VSINSTALL_MACRO, VSInstallDir).replace(QLatin1String("$(PATH)"), QLatin1String("%PATH%"))));
- if (str.endsWith(';'))
+ QString str = QDir::toNativeSeparators(QDir::cleanPath(path.replace(QLatin1String(VCINSTALL_MACRO), VCInstallDir).replace(QLatin1String(VSINSTALL_MACRO), VSInstallDir).replace(QLatin1String("$(PATH)"), QLatin1String("%PATH%"))));
+ if (str.endsWith(QLatin1Char(';')))
str.truncate(str.length() - 1);
return str;
}
diff --git a/tools/checksdk/checksdk.pro b/tools/checksdk/checksdk.pro
index e364f26..a513981 100644
--- a/tools/checksdk/checksdk.pro
+++ b/tools/checksdk/checksdk.pro
@@ -32,40 +32,5 @@ SOURCES += \
HEADERS += \
cesdkhandler.h
-# Bootstrapped Input
-SOURCES += \
- $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \
- $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qstring.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_win.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qbuffer.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qurl.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qlocale.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qbytearray.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qbytearraymatcher.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qvector.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qvsnprintf.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qlistdata.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qhash.cpp \
- $$QT_SOURCE_TREE/src/corelib/global/qglobal.cpp \
- $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \
- $$QT_SOURCE_TREE/src/corelib/global/qnumeric.cpp \
- $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.cpp \
- $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qregexp.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \
- $$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \
- $$QT_BUILD_TREE/src/corelib/global/qconfig.cpp
+include(../../src/tools/bootstrap/bootstrap.pri)
+
diff --git a/tools/checksdk/main.cpp b/tools/checksdk/main.cpp
index 2dd7214..6322eb7 100644
--- a/tools/checksdk/main.cpp
+++ b/tools/checksdk/main.cpp
@@ -46,17 +46,17 @@
void usage()
{
- qDebug() << "SDK Scanner - Convenience Tool to setup your environment";
- qDebug() << " for crosscompilation to Windows CE";
- qDebug() << "Options:";
- qDebug() << "-help This output";
- qDebug() << "-list List all available SDKs";
- qDebug() << "-sdk <name> Select specified SDK.";
- qDebug() << " Note: SDK names with spaces need to be";
- qDebug() << " specified in parenthesis";
- qDebug() << " default: Windows Mobile 5.0 Pocket PC SDK (ARMV4I)";
- qDebug() << "-script <file> Create a script file which can be launched";
- qDebug() << " to setup your environment for specified SDK";
+ printf("SDK Scanner - Convenience Tool to setup your environment\n");
+ printf(" for crosscompilation to Windows CE\n");
+ printf("Options:\n");
+ printf("-help This output\n");
+ printf("-list List all available SDKs\n");
+ printf("-sdk <name> Select specified SDK.\n");
+ printf(" Note: SDK names with spaces need to be\n");
+ printf(" specified in parenthesis\n");
+ printf(" default: Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\n");
+ printf("-script <file> Create a script file which can be launched\n");
+ printf(" to setup your environment for specified SDK\n");
}
int main(int argc, char **argv)
@@ -106,9 +106,12 @@ int main(int argc, char **argv)
QList<CeSdkInfo> list = handler.listAll();
if (operationList) {
- qDebug() << "Available SDKs:";
- for (QList<CeSdkInfo>::iterator it = list.begin(); it != list.end(); ++it)
- qDebug() << "SDK Name:" << it->name();
+ printf("Available SDKs:\n");
+ for (QList<CeSdkInfo>::iterator it = list.begin(); it != list.end(); ++it) {
+ printf("SDK Name: ");
+ printf(qPrintable(it->name()));
+ printf("\n");
+ }
return 0;
}
@@ -132,10 +135,13 @@ int main(int argc, char **argv)
includePath = QString::fromLatin1("INCLUDE=") + it->includePath();
libPath = QString::fromLatin1("LIB=") + it->libPath();
if (scriptFile.isEmpty()) {
- qDebug() << "Please set up your environment with the following paths:";
- qDebug() << qPrintable(binPath);
- qDebug() << qPrintable(includePath);
- qDebug() << qPrintable(libPath);
+ printf("Please set up your environment with the following paths:\n");
+ printf(qPrintable(binPath));
+ printf("\n");
+ printf(qPrintable(includePath));
+ printf("\n");
+ printf(qPrintable(libPath));
+ printf("\n");
return 0;
} else {
QFile file(scriptFile);
diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro
index b82104e..14a5a95 100644
--- a/tools/configure/configure.pro
+++ b/tools/configure/configure.pro
@@ -3,7 +3,7 @@ DESTDIR = ../..
CONFIG += console flat
CONFIG -= moc qt
-DEFINES = QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE
+DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE
win32 : !win32-mwc : LIBS += -lole32 -ladvapi32
@@ -35,6 +35,7 @@ HEADERS = configureapp.h environment.h tools.h\
$$QT_SOURCE_TREE/src/corelib/tools/qlist.h \
$$QT_SOURCE_TREE/src/corelib/tools/qlocale.h \
$$QT_SOURCE_TREE/src/corelib/tools/qvector.h \
+ $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec_p.h \
$$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.h \
$$QT_SOURCE_TREE/src/corelib/global/qglobal.h \
$$QT_SOURCE_TREE/src/corelib/global/qnumeric.h \
@@ -67,6 +68,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qlistdata.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qlocale.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qvector.cpp \
+ $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp \
$$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.cpp \
$$QT_SOURCE_TREE/src/corelib/global/qglobal.cpp \
$$QT_SOURCE_TREE/src/corelib/global/qnumeric.cpp \
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index a50019f..be1ec71 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -116,16 +116,9 @@ Configure::Configure( int& argc, char** argv )
// Get the path to the executable
- QFileInfo sourcePathInfo;
- QT_WA({
- unsigned short module_name[256];
- GetModuleFileNameW(0, reinterpret_cast<wchar_t *>(module_name), sizeof(module_name));
- sourcePathInfo = QString::fromUtf16(module_name);
- }, {
- char module_name[256];
- GetModuleFileNameA(0, module_name, sizeof(module_name));
- sourcePathInfo = QString::fromLocal8Bit(module_name);
- });
+ wchar_t module_name[MAX_PATH];
+ GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t));
+ QFileInfo sourcePathInfo = QString::fromWCharArray(module_name);
sourcePath = sourcePathInfo.absolutePath();
sourceDir = sourcePathInfo.dir();
buildPath = QDir::currentPath();
@@ -615,10 +608,13 @@ void Configure::parseCmdLine()
// cetest ---------------------------------------------------
else if (configCmdLine.at(i) == "-no-cetest") {
dictionary[ "CETEST" ] = "no";
+ dictionary[ "CETEST_REQUESTED" ] = "no";
} else if (configCmdLine.at(i) == "-cetest") {
// although specified to use it, we stay at "auto" state
// this is because checkAvailability() adds variables
- // we need for crosscompilation
+ // we need for crosscompilation; but remember if we asked
+ // for it.
+ dictionary[ "CETEST_REQUESTED" ] = "yes";
}
// Qt/CE - signing tool -------------------------------------
else if( configCmdLine.at(i) == "-signature") {
@@ -1202,6 +1198,10 @@ void Configure::parseCmdLine()
useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++");
+ // Allow tests for private classes to be compiled against internal builds
+ if (dictionary["BUILDDEV"] == "yes")
+ qtConfig += "private_tests";
+
#if !defined(EVAL)
for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) {
@@ -1794,39 +1794,49 @@ bool Configure::displayHelp()
return false;
}
-bool Configure::findFileInPaths(const QString &fileName, const QStringList &paths)
+QString Configure::findFileInPaths(const QString &fileName, const QString &paths)
{
+#if defined(Q_OS_WIN32)
+ QRegExp splitReg("[;,]");
+#else
+ QRegExp splitReg("[:]");
+#endif
+ QStringList pathList = paths.split(splitReg, QString::SkipEmptyParts);
QDir d;
- for( QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) {
+ for( QStringList::ConstIterator it = pathList.begin(); it != pathList.end(); ++it ) {
// Remove any leading or trailing ", this is commonly used in the environment
// variables
QString path = (*it);
- if ( path.startsWith( "\"" ) )
+ if ( path.startsWith( '\"' ) )
path = path.right( path.length() - 1 );
- if ( path.endsWith( "\"" ) )
+ if ( path.endsWith( '\"' ) )
path = path.left( path.length() - 1 );
if( d.exists( path + QDir::separator() + fileName ) )
- return true;
+ return path;
}
- return false;
+ return QString();
}
bool Configure::findFile( const QString &fileName )
{
- QString file = fileName.toLower();
- QStringList paths;
-#if defined(Q_OS_WIN32)
- QRegExp splitReg("[;,]");
-#else
- QRegExp splitReg("[:]");
-#endif
- if (file.endsWith(".h"))
- paths = QString::fromLocal8Bit(getenv("INCLUDE")).split(splitReg, QString::SkipEmptyParts);
- else if ( file.endsWith( ".lib" ) )
- paths = QString::fromLocal8Bit(getenv("LIB")).split(splitReg, QString::SkipEmptyParts);
- else
- paths = QString::fromLocal8Bit(getenv("PATH")).split(splitReg, QString::SkipEmptyParts);
- return findFileInPaths(file, paths);
+ const QString file = fileName.toLower();
+ const QString pathEnvVar = QString::fromLocal8Bit(getenv("PATH"));
+ const QString mingwPath = dictionary["QMAKESPEC"].endsWith("-g++") ?
+ findFileInPaths("mingw32-g++.exe", pathEnvVar) : QString();
+
+ QString paths;
+ if (file.endsWith(".h")) {
+ if (!mingwPath.isNull() && !findFileInPaths(file, mingwPath + QLatin1String("/../include")).isNull())
+ return true;
+ paths = QString::fromLocal8Bit(getenv("INCLUDE"));
+ } else if ( file.endsWith( ".lib" ) || file.endsWith( ".a" ) ) {
+ if (!mingwPath.isNull() && !findFileInPaths(file, mingwPath + QLatin1String("/../lib")).isNull())
+ return true;
+ paths = QString::fromLocal8Bit(getenv("LIB"));
+ } else {
+ paths = pathEnvVar;
+ }
+ return !findFileInPaths(file, paths).isNull();
}
/*!
@@ -1896,7 +1906,7 @@ bool Configure::checkAvailability(const QString &part)
{
bool available = false;
if (part == "STYLE_WINDOWSXP")
- available = (dictionary.value("QMAKESPEC") == "win32-g++" || findFile("uxtheme.h"));
+ available = (findFile("uxtheme.h"));
else if (part == "ZLIB")
available = findFile("zlib.h");
@@ -1971,6 +1981,11 @@ bool Configure::checkAvailability(const QString &part)
dictionary[ "QT_CE_RAPI_INC" ] += QLatin1String("\"") + rapiHeader + QLatin1String("\"");
dictionary[ "QT_CE_RAPI_LIB" ] += QLatin1String("\"") + rapiLib + QLatin1String("\"");
}
+ else if (dictionary[ "CETEST_REQUESTED" ] == "yes") {
+ cout << "cetest could not be enabled: rapi.h and rapi.lib could not be found." << endl;
+ cout << "Make sure the environment is set up for compiling with ActiveSync." << endl;
+ dictionary[ "DONE" ] = "error";
+ }
}
else if (part == "INCREDIBUILD_XGE")
available = findFile("BuildConsole.exe") && findFile("xgConsole.exe");
@@ -1982,13 +1997,22 @@ bool Configure::checkAvailability(const QString &part)
&& dictionary.value("QMAKESPEC") != "win32-msvc2002"
&& dictionary.value("EXCEPTIONS") == "yes";
} else if (part == "PHONON") {
- available = findFile("vmr9.h") && findFile("dshow.h") && findFile("strmiids.lib") &&
- findFile("dmoguids.lib") && findFile("msdmo.lib") && findFile("d3d9.h");
+ available = findFile("vmr9.h") && findFile("dshow.h") && findFile("dmo.h") && findFile("dmodshow.h")
+ && (findFile("strmiids.lib") || findFile("libstrmiids.a"))
+ && (findFile("dmoguids.lib") || findFile("libdmoguids.a"))
+ && (findFile("msdmo.lib") || findFile("libmsdmo.a"))
+ && findFile("d3d9.h");
if (!available) {
cout << "All the required DirectShow/Direct3D files couldn't be found." << endl
- << "Make sure you have either the platform SDK AND the DirectX SDK or the Windows SDK installed." << endl
- << "If you have the DirectX SDK installed, please make sure that you have run the <path to SDK>\\SetEnv.Cmd script." << endl;
+ << "Make sure you have either the platform SDK AND the DirectShow SDK or the Windows SDK installed." << endl
+ << "If you have the DirectShow SDK installed, please make sure that you have run the <path to SDK>\\SetEnv.Cmd script." << endl;
+ if (!findFile("vmr9.h")) cout << "vmr9.h not found" << endl;
+ if (!findFile("dshow.h")) cout << "dshow.h not found" << endl;
+ if (!findFile("strmiids.lib")) cout << "strmiids.lib not found" << endl;
+ if (!findFile("dmoguids.lib")) cout << "dmoguids.lib not found" << endl;
+ if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl;
+ if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl;
}
} else if (part == "WEBKIT") {
available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++");
@@ -2152,7 +2176,6 @@ bool Configure::verifyConfiguration()
no-gif gif
dll staticlib
- internal
nocrosscompiler
GNUmake
largefile
@@ -2928,7 +2951,7 @@ void Configure::generateConfigfiles()
tmpFile.flush();
// Replace old qconfig.h with new one
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL);
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
QFile::remove(outName);
tmpFile.copy(outName);
tmpFile.close();
@@ -2964,7 +2987,7 @@ void Configure::generateConfigfiles()
}
outName = defSpec + "/qmake.conf";
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
QFile qmakeConfFile(outName);
if (qmakeConfFile.open(QFile::Append | QFile::WriteOnly | QFile::Text)) {
QTextStream qmakeConfStream;
@@ -3032,7 +3055,7 @@ void Configure::generateConfigfiles()
tmpFile2.flush();
// Replace old qconfig.cpp with new one
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
QFile::remove( outName );
tmpFile2.copy(outName);
tmpFile2.close();
@@ -3296,6 +3319,9 @@ void Configure::buildQmake()
void Configure::buildHostTools()
{
+ if (dictionary[ "NOPROCESS" ] == "yes")
+ dictionary[ "DONE" ] = "yes";
+
if (!dictionary.contains("XQMAKESPEC"))
return;
@@ -3521,7 +3547,6 @@ void Configure::generateMakefiles()
} else {
cout << "Processing of project files have been disabled." << endl;
cout << "Only use this option if you really know what you're doing." << endl << endl;
- dictionary[ "DONE" ] = "yes";
return;
}
}
diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h
index dc22ac9..03df28e 100644
--- a/tools/configure/configureapp.h
+++ b/tools/configure/configureapp.h
@@ -150,8 +150,8 @@ private:
QString fixSeparators(QString somePath);
bool filesDiffer(const QString &file1, const QString &file2);
- static bool findFile(const QString &fileName);
- static bool findFileInPaths(const QString &fileName, const QStringList &paths);
+ bool findFile(const QString &fileName);
+ static QString findFileInPaths(const QString &fileName, const QString &paths);
#if !defined(EVAL)
void reloadCmdLine();
void saveCmdLine();
diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp
index 6dc8940..b4c61f8 100644
--- a/tools/configure/environment.cpp
+++ b/tools/configure/environment.cpp
@@ -146,26 +146,14 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
QString rSubkeyPath = keyPath(rSubkey);
HKEY handle = 0;
- LONG res;
- QT_WA( {
- res = RegOpenKeyExW(parentHandle, (WCHAR*)rSubkeyPath.utf16(),
- 0, KEY_READ, &handle);
- } , {
- res = RegOpenKeyExA(parentHandle, rSubkeyPath.toLocal8Bit(),
- 0, KEY_READ, &handle);
- } );
-
+ LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle);
if (res != ERROR_SUCCESS)
return QString();
// get the size and type of the value
DWORD dataType;
DWORD dataSize;
- QT_WA( {
- res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
- }, {
- res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, &dataType, 0, &dataSize);
- } );
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
return QString();
@@ -173,13 +161,8 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
// get the value
QByteArray data(dataSize, 0);
- QT_WA( {
- res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, 0,
- reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- }, {
- res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, 0,
- reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- } );
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0,
+ reinterpret_cast<unsigned char*>(data.data()), &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
return QString();
@@ -189,11 +172,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
switch (dataType) {
case REG_EXPAND_SZ:
case REG_SZ: {
- QT_WA( {
- result = QString::fromUtf16(((const ushort*)data.constData()));
- }, {
- result = QString::fromLatin1(data.constData());
- } );
+ result = QString::fromWCharArray(((const wchar_t *)data.constData()));
break;
}
@@ -201,29 +180,20 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
QStringList l;
int i = 0;
for (;;) {
- QString s;
- QT_WA( {
- s = QString::fromUtf16((const ushort*)data.constData() + i);
- }, {
- s = QString::fromLatin1(data.constData() + i);
- } );
+ QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
i += s.length() + 1;
if (s.isEmpty())
break;
l.append(s);
}
- result = l.join(", ");
+ result = l.join(", ");
break;
}
case REG_NONE:
case REG_BINARY: {
- QT_WA( {
- result = QString::fromUtf16((const ushort*)data.constData(), data.size()/2);
- }, {
- result = QString::fromLatin1(data.constData(), data.size());
- } );
+ result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
break;
}
@@ -232,7 +202,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
Q_ASSERT(data.size() == sizeof(int));
int i;
memcpy((char*)&i, data.constData(), sizeof(int));
- result = QString::number(i);
+ result = QString::number(i);
break;
}
@@ -350,29 +320,14 @@ bool Environment::detectExecutable(const QString &executable)
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
- bool couldExecute;
- QT_WA({
- // Unicode version
- STARTUPINFOW startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
-
- couldExecute = CreateProcessW(0, (WCHAR*)executable.utf16(),
- 0, 0, false,
- CREATE_NO_WINDOW | CREATE_SUSPENDED,
- 0, 0, &startInfo, &procInfo);
-
- }, {
- // Ansi version
- STARTUPINFOA startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
+ STARTUPINFO startInfo;
+ memset(&startInfo, 0, sizeof(startInfo));
+ startInfo.cb = sizeof(startInfo);
- couldExecute = CreateProcessA(0, executable.toLocal8Bit().data(),
+ bool couldExecute = CreateProcess(0, (wchar_t*)executable.utf16(),
0, 0, false,
CREATE_NO_WINDOW | CREATE_SUSPENDED,
0, 0, &startInfo, &procInfo);
- })
if (couldExecute) {
CloseHandle(procInfo.hThread);
@@ -421,61 +376,38 @@ static QString qt_create_commandline(const QString &program, const QStringList &
}
/*!
- Creates a QByteArray of the \a environment in either UNICODE or
- ansi representation.
+ Creates a QByteArray of the \a environment.
*/
static QByteArray qt_create_environment(const QStringList &environment)
{
QByteArray envlist;
- if (!environment.isEmpty()) {
- int pos = 0;
- // add PATH if necessary (for DLL loading)
- QByteArray path = qgetenv("PATH");
- QT_WA({
- if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty()
- && !path.isNull()) {
- QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path));
- uint tmpSize = sizeof(TCHAR) * (tmp.length()+1);
- envlist.resize(envlist.size() + tmpSize );
- memcpy(envlist.data()+pos, tmp.utf16(), tmpSize);
- pos += tmpSize;
- }
- // add the user environment
- for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) {
- QString tmp = *it;
- uint tmpSize = sizeof(TCHAR) * (tmp.length()+1);
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.utf16(), tmpSize);
- pos += tmpSize;
- }
- // add the 2 terminating 0 (actually 4, just to be on the safe side)
- envlist.resize( envlist.size()+4 );
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- }, {
- if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) {
- QByteArray tmp = QString("PATH=%1").arg(QString::fromLocal8Bit(path)).toLocal8Bit();
- uint tmpSize = tmp.length() + 1;
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.data(), tmpSize);
- pos += tmpSize;
- }
- // add the user environment
- for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++) {
- QByteArray tmp = (*it).toLocal8Bit();
- uint tmpSize = tmp.length() + 1;
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.data(), tmpSize);
- pos += tmpSize;
- }
- // add the terminating 0 (actually 2, just to be on the safe side)
- envlist.resize(envlist.size()+2);
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- })
+ if (environment.isEmpty())
+ return envlist;
+
+ int pos = 0;
+ // add PATH if necessary (for DLL loading)
+ QByteArray path = qgetenv("PATH");
+ if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) {
+ QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path));
+ uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
+ envlist.resize(envlist.size() + tmpSize);
+ memcpy(envlist.data() + pos, tmp.utf16(), tmpSize);
+ pos += tmpSize;
}
+ // add the user environment
+ for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) {
+ QString tmp = *it;
+ uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
+ envlist.resize(envlist.size() + tmpSize);
+ memcpy(envlist.data() + pos, tmp.utf16(), tmpSize);
+ pos += tmpSize;
+ }
+ // add the 2 terminating 0 (actually 4, just to be on the safe side)
+ envlist.resize(envlist.size() + 4);
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
return envlist;
}
@@ -501,46 +433,24 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
qDebug() << " " << additionalEnv;
qDebug() << " " << removeEnv;
#endif
-// GetEnvironmentStrings is defined to GetEnvironmentStringsW when
-// UNICODE is defined. We cannot use that, since we need to
-// destinguish between unicode and ansi versions of the functions.
-#if defined(UNICODE) && defined(GetEnvironmentStrings)
-#undef GetEnvironmentStrings
-#endif
-
// Create the full environment from the current environment and
// the additionalEnv strings, then remove all variables defined
// in removeEnv
QMap<QString, QString> fullEnvMap;
- QT_WA({
- LPWSTR envStrings = GetEnvironmentStringsW();
- if (envStrings) {
- int strLen = 0;
- for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) {
- strLen = wcslen(envString);
- QString str = QString((const QChar*)envString, strLen);
- if (!str.startsWith("=")) { // These are added by the system
- int sepIndex = str.indexOf('=');
- fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
- }
- }
- }
- FreeEnvironmentStringsW(envStrings);
- }, {
- LPSTR envStrings = GetEnvironmentStrings();
- if (envStrings) {
- int strLen = 0;
- for (LPSTR envString = envStrings; *(envString); envString += strLen + 1) {
- strLen = strlen(envString);
- QString str = QLatin1String(envString);
- if (!str.startsWith("=")) { // These are added by the system
- int sepIndex = str.indexOf('=');
- fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
- }
+ LPWSTR envStrings = GetEnvironmentStrings();
+ if (envStrings) {
+ int strLen = 0;
+ for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) {
+ strLen = wcslen(envString);
+ QString str = QString((const QChar*)envString, strLen);
+ if (!str.startsWith("=")) { // These are added by the system
+ int sepIndex = str.indexOf('=');
+ fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
}
}
- FreeEnvironmentStringsA(envStrings);
- })
+ }
+ FreeEnvironmentStrings(envStrings);
+
// Add additionalEnv variables
for (int i = 0; i < additionalEnv.count(); ++i) {
const QString &str = additionalEnv.at(i);
@@ -569,28 +479,14 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
- bool couldExecute;
- QT_WA({
- // Unicode version
- STARTUPINFOW startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
+ STARTUPINFO startInfo;
+ memset(&startInfo, 0, sizeof(startInfo));
+ startInfo.cb = sizeof(startInfo);
- couldExecute = CreateProcessW(0, (WCHAR*)args.utf16(),
+ bool couldExecute = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, true, CREATE_UNICODE_ENVIRONMENT,
envlist.isEmpty() ? 0 : envlist.data(),
0, &startInfo, &procInfo);
- }, {
- // Ansi version
- STARTUPINFOA startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
-
- couldExecute = CreateProcessA(0, args.toLocal8Bit().data(),
- 0, 0, true, 0,
- envlist.isEmpty() ? 0 : envlist.data(),
- 0, &startInfo, &procInfo);
- })
if (couldExecute) {
WaitForSingleObject(procInfo.hProcess, INFINITE);
@@ -654,7 +550,7 @@ bool Environment::cpdir(const QString &srcDir, const QString &destDir)
#endif
QFile::remove(destFile);
intermediate = QFile::copy(entry.absoluteFilePath(), destFile);
- SetFileAttributesA(destFile.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL);
+ SetFileAttributes((wchar_t*)destFile.utf16(), FILE_ATTRIBUTE_NORMAL);
}
if(!intermediate) {
qDebug() << "cpdir: Failure for " << entry.fileName() << entry.isDir();
diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp
index 0e13c7a..e5c04cc 100644
--- a/tools/configure/main.cpp
+++ b/tools/configure/main.cpp
@@ -95,7 +95,7 @@ int runConfigure( int argc, char** argv )
#endif
if( !app.isDone() )
app.generateMakefiles();
- if( !app.isDone() && app.isOk() )
+ if( !app.isDone() )
app.buildHostTools();
if( !app.isDone() )
app.showSummary();
diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp
index f60f72c..708a537 100644
--- a/tools/configure/tools.cpp
+++ b/tools/configure/tools.cpp
@@ -201,8 +201,8 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString
if (licenseFeatures == '5') //Floating
dictionary["METERED LICENSE"] = "true";
- if (!CopyFileA(QDir::toNativeSeparators(fromLicenseFile).toLocal8Bit(),
- QDir::toNativeSeparators(toLicenseFile).toLocal8Bit(), FALSE)) {
+ if (!CopyFile((wchar_t*)QDir::toNativeSeparators(fromLicenseFile).utf16(),
+ (wchar_t*)QDir::toNativeSeparators(toLicenseFile).utf16(), FALSE)) {
cout << "Failed to copy license file (" << fromLicenseFile << ")";
dictionary["DONE"] = "error";
return;
diff --git a/tools/designer/data/generate_shared.xsl b/tools/designer/data/generate_shared.xsl
index f7859cd..ec95fe2 100644
--- a/tools/designer/data/generate_shared.xsl
+++ b/tools/designer/data/generate_shared.xsl
@@ -6,8 +6,8 @@
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Hack to make names camel case
- All names in ui files are lowercase, while the element names are
- capital case. To make the ui files conforming to the xsd file + keep
+ All names in UI files are lowercase, while the element names are
+ capital case. To make the UI files conforming to the XSD file + keep
the DOM interface we rename them here -->
<xsl:template name="camel-case">
<xsl:param name="text"/>
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
index de4b57b..ac03909 100644
--- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -631,13 +631,13 @@ static bool readUiAttributes(QIODevice *dev, QString *errorMessage,
*language = attributes.value(languageAttribute).toString();
return true;
} else {
- *errorMessage = QCoreApplication::translate("Designer", "Invalid ui file: The root element <ui> is missing.");
+ *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element <ui> is missing.");
return false;
}
}
}
- *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the ui file at line %1, column %2: %3")
+ *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3")
.arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString());
return false;
}
@@ -756,7 +756,7 @@ void QDesignerResource::setSaveRelative(bool relative)
QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
{
// Load extra info extension. This is used by Jambi for preventing
- // C++ ui files from being loaded
+ // C++ UI files from being loaded
if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core())) {
if (!extra->loadUiExtraInfo(ui)) {
const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load.");
diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
index fb1a5bb..ca55b15 100644
--- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
+++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
@@ -254,8 +254,11 @@ void TextEditor::resourceActionActivated()
{
QString oldPath = m_editor->text();
if (oldPath.startsWith(QLatin1String("qrc:")))
- oldPath = oldPath.mid(4);
- const QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
+ oldPath.remove(0, 4);
+ // returns ':/file'
+ QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
+ if (newPath.startsWith(QLatin1Char(':')))
+ newPath.remove(0, 1);
if (newPath.isEmpty() || newPath == oldPath)
return;
const QString newText = QLatin1String("qrc:") + newPath;
diff --git a/tools/designer/src/components/signalsloteditor/connectdialog.ui b/tools/designer/src/components/signalsloteditor/connectdialog.ui
index bd062eb..568516a 100644
--- a/tools/designer/src/components/signalsloteditor/connectdialog.ui
+++ b/tools/designer/src/components/signalsloteditor/connectdialog.ui
@@ -13,7 +13,7 @@
<string>Configure Connection</string>
</property>
<layout class="QGridLayout" >
- <item row="0" column="0" colspan="2" >
+ <item row="0" column="0" >
<widget class="QGroupBox" name="signalGroupBox" >
<property name="title" >
<string>GroupBox</string>
@@ -53,7 +53,7 @@
</layout>
</widget>
</item>
- <item row="0" column="2" >
+ <item row="0" column="1" >
<widget class="QGroupBox" name="slotGroupBox" >
<property name="title" >
<string>GroupBox</string>
@@ -93,14 +93,14 @@
</layout>
</widget>
</item>
- <item row="1" column="0" >
+ <item row="1" column="0" colspan="2" >
<widget class="QCheckBox" name="showAllCheckBox" >
<property name="text" >
<string>Show signals and slots inherited from QWidget</string>
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2" >
+ <item row="2" column="0" colspan="2" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
diff --git a/tools/designer/src/designer/Info_mac.plist b/tools/designer/src/designer/Info_mac.plist
index 8632a6d..f19176f 100644
--- a/tools/designer/src/designer/Info_mac.plist
+++ b/tools/designer/src/designer/Info_mac.plist
@@ -22,7 +22,7 @@
<string>ui</string>
</array>
<key>CFBundleTypeIconFile</key>
- <string>@ICON@</string>
+ <string>uifile.icns</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSIsAppleDefaultForType</key>
diff --git a/tools/designer/src/designer/designer.pro b/tools/designer/src/designer/designer.pro
index e7fa038..aa6850c 100644
--- a/tools/designer/src/designer/designer.pro
+++ b/tools/designer/src/designer/designer.pro
@@ -78,6 +78,9 @@ mac {
ICON = designer.icns
QMAKE_INFO_PLIST = Info_mac.plist
TARGET = Designer
+ FILETYPES.files = uifile.icns
+ FILETYPES.path = Contents/Resources
+ QMAKE_BUNDLE_DATA += FILETYPES
}
target.path=$$[QT_INSTALL_BINS]
diff --git a/tools/designer/src/designer/designer.rc b/tools/designer/src/designer/designer.rc
index 4b6324b..1f8bc0a 100644
--- a/tools/designer/src/designer/designer.rc
+++ b/tools/designer/src/designer/designer.rc
@@ -1,2 +1,32 @@
+#include "winver.h"
+
IDI_ICON1 ICON DISCARDABLE "designer.ico"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Designer"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "designer"
+ VALUE "OriginalFilename", "designer.exe"
+ VALUE "ProductName", "Qt Designer"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/tools/designer/src/designer/mainwindow.cpp b/tools/designer/src/designer/mainwindow.cpp
index b72a790..a3ca234 100644
--- a/tools/designer/src/designer/mainwindow.cpp
+++ b/tools/designer/src/designer/mainwindow.cpp
@@ -155,7 +155,7 @@ DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) :
QStringList DockedMdiArea::uiFiles(const QMimeData *d) const
{
- // Extract dropped ui files from Mime data.
+ // Extract dropped UI files from Mime data.
QStringList rc;
if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
return rc;
diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp
index 923687a2..2ac9e1f 100644
--- a/tools/designer/src/designer/qdesigner_workbench.cpp
+++ b/tools/designer/src/designer/qdesigner_workbench.cpp
@@ -410,6 +410,12 @@ void QDesignerWorkbench::switchToDockedMode()
switchToNeutralMode();
+#ifndef Q_WS_MAC
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ widgetBoxWrapper->action()->setVisible(true);
+ widgetBoxWrapper->setWindowTitle(tr("Widget Box"));
+#endif
+
m_mode = DockedMode;
const QDesignerSettings settings(m_core);
m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows);
@@ -462,8 +468,6 @@ void QDesignerWorkbench::switchToTopLevelMode()
// make sure that the widgetbox is visible if it is different from neutral.
QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
Q_ASSERT(widgetBoxWrapper);
- if (!widgetBoxWrapper->action()->isChecked())
- widgetBoxWrapper->action()->trigger();
switchToNeutralMode();
const QPoint desktopOffset = desktopGeometry().topLeft();
@@ -502,9 +506,6 @@ void QDesignerWorkbench::switchToTopLevelMode()
found_visible_window |= tw->isVisible();
}
- if (!widgetBoxWrapper->action()->isChecked())
- widgetBoxWrapper->action()->trigger();
-
if (!m_toolWindows.isEmpty() && !found_visible_window)
m_toolWindows.first()->show();
@@ -960,7 +961,7 @@ QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName,
removeFormWindow(formWindow);
formWindowManager->removeFormWindow(editor);
m_core->metaDataBase()->remove(editor);
- *errorMessage = tr("The file <b>%1</b> is not a valid Designer ui file.").arg(file.fileName());
+ *errorMessage = tr("The file <b>%1</b> is not a valid Designer UI file.").arg(file.fileName());
return 0;
}
*uic3Converted = editor->fileName().isEmpty();
diff --git a/tools/designer/src/designer/uifile.icns b/tools/designer/src/designer/uifile.icns
new file mode 100644
index 0000000..2473ea4
--- /dev/null
+++ b/tools/designer/src/designer/uifile.icns
Binary files differ
diff --git a/tools/designer/src/lib/sdk/abstractformwindow.cpp b/tools/designer/src/lib/sdk/abstractformwindow.cpp
index 89c1015..313b324 100644
--- a/tools/designer/src/lib/sdk/abstractformwindow.cpp
+++ b/tools/designer/src/lib/sdk/abstractformwindow.cpp
@@ -247,7 +247,7 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
/*!
\fn virtual QString QDesignerFormWindowInterface::fileName() const
- Returns the file name of the .ui file that describes the form
+ Returns the file name of the UI file that describes the form
currently being shown.
\sa setFileName()
@@ -399,11 +399,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
\fn virtual QStringList QDesignerFormWindowInterface::includeHints() const
Returns a list of the header files that will be included in the
- form window's associated \c .ui file.
+ form window's associated UI file.
Header files may be local, i.e. relative to the project's
- directory,\c "mywidget.h", or global, i.e. part of Qt or the
- compilers standard libraries:\c <QtGui/QWidget>.
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
\sa setIncludeHints()
*/
@@ -412,11 +412,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
\fn virtual void QDesignerFormWindowInterface::setIncludeHints(const QStringList &includeHints)
Sets the header files that will be included in the form window's
- associated \c .ui file to the specified \a includeHints.
+ associated UI file to the specified \a includeHints.
Header files may be local, i.e. relative to the project's
- directory,\c "mywidget.h", or global, i.e. part of Qt or the
- compilers standard libraries:\c <QtGui/QWidget>.
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
\sa includeHints()
*/
diff --git a/tools/designer/src/lib/sdk/script.cpp b/tools/designer/src/lib/sdk/script.cpp
index 90b4c73..2eda3d1 100644
--- a/tools/designer/src/lib/sdk/script.cpp
+++ b/tools/designer/src/lib/sdk/script.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
\since 4.3
On saving the form, the extension is queried for a script snippet
- to be associated with the widget while saving the \c .ui file.
+ to be associated with the widget while saving the UI file.
This script is then run after creating the widget by \l uic or
QUiLoader.
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
for which an editor is provided by the QDesignerTaskMenuExtension.
While saving the form, the state is serialized as a QVariantMap of
- \QD-supported properties, which is stored in the \c .ui file. This is
+ \QD-supported properties, which is stored in the UI file. This is
handled by data() and setData().
For item view contents, there might be for example a key that determines
@@ -97,7 +97,7 @@ QDesignerScriptExtension::~QDesignerScriptExtension()
\fn virtual QVariantMap QDesignerScriptExtension::data() const
Returns a map of variants describing the internal state to be
- stored in the \c .ui file.
+ stored in the UI file.
*/
/*!
diff --git a/tools/designer/src/lib/shared/widgetfactory.cpp b/tools/designer/src/lib/shared/widgetfactory.cpp
index 6c45daf..7080ed3 100644
--- a/tools/designer/src/lib/shared/widgetfactory.cpp
+++ b/tools/designer/src/lib/shared/widgetfactory.cpp
@@ -834,9 +834,11 @@ bool WidgetFactory::isPassiveInteractor(QWidget *widget)
if (isTabBarInteractor(tabBar))
m_lastWasAPassiveInteractor = true;
return m_lastWasAPassiveInteractor;
- } else if (qobject_cast<QSizeGrip*>(widget))
+#ifndef QT_NO_SIZEGRIP
+ } else if (qobject_cast<QSizeGrip*>(widget)) {
return (m_lastWasAPassiveInteractor = true);
- else if (qobject_cast<QMdiSubWindow*>(widget))
+#endif
+ } else if (qobject_cast<QMdiSubWindow*>(widget))
return (m_lastWasAPassiveInteractor = true);
else if (qobject_cast<QAbstractButton*>(widget) && (qobject_cast<QTabBar*>(widget->parent()) || qobject_cast<QToolBox*>(widget->parent())))
return (m_lastWasAPassiveInteractor = true);
diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
index 5a6e1f5..1711d43 100644
--- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp
+++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
@@ -135,7 +135,7 @@ public:
QAbstractFormBuilder provides a standard interface and a default
implementation for constructing forms from user interface
files. It is not intended to be instantiated directly. Use the
- QFormBuilder class to create user interfaces from \c{.ui} files at
+ QFormBuilder class to create user interfaces from UI files at
run-time. For example:
\snippet doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp 0
@@ -145,10 +145,10 @@ public:
functions:
\list
- \o load() handles reading of \c{.ui} format files from arbitrary
+ \o load() handles reading of UI format files from arbitrary
QIODevices, and construction of widgets from the XML data
that they contain.
- \o save() handles saving of widget details in \c{.ui} format to
+ \o save() handles saving of widget details in UI format to
arbitrary QIODevices.
\o workingDirectory() and setWorkingDirectory() control the
directory in which forms are held. The form builder looks for
@@ -208,13 +208,13 @@ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget)
}
}
if (reader.hasError()) {
- uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the ui file at line %1, column %2: %3")
+ uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3")
.arg(reader.lineNumber()).arg(reader.columnNumber())
.arg(reader.errorString()));
return 0;
}
if (!initialized) {
- uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid ui file: The root element <ui> is missing."));
+ uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element <ui> is missing."));
return 0;
}
@@ -657,7 +657,7 @@ void QAbstractFormBuilder::layoutInfo(DomLayout *ui_layout, QObject *parent, int
spac = p->elementNumber();
#ifdef Q_OS_MAC
- // here we recognize ui file < 4.3 (no we don't store margin property)
+ // here we recognize UI file < 4.3 (no we don't store margin property)
if (mar != INT_MIN) {
const int defaultMargin = parent->inherits("QLayoutWidget") ? 0 : 9;
if (mar == defaultMargin)
@@ -1202,7 +1202,7 @@ QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QSt
\fn void QAbstractFormBuilder::save(QIODevice *device, QWidget *widget)
Saves an XML representation of the given \a widget to the
- specified \a device in the standard \c{.ui} file format.
+ specified \a device in the standard UI file format.
\sa load()*/
void QAbstractFormBuilder::save(QIODevice *dev, QWidget *widget)
diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp
index 043991e..f737311 100644
--- a/tools/designer/src/lib/uilib/formbuilder.cpp
+++ b/tools/designer/src/lib/uilib/formbuilder.cpp
@@ -57,12 +57,12 @@ namespace QFormInternal {
\class QFormBuilder
\brief The QFormBuilder class is used to dynamically construct
- user interfaces from .ui files at run-time.
+ user interfaces from UI files at run-time.
\inmodule QtDesigner
The QFormBuilder class provides a mechanism for dynamically
- creating user interfaces at run-time, based on \c{.ui} files
+ creating user interfaces at run-time, based on UI files
created with \QD. For example:
\snippet doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp 0
diff --git a/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp b/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
index 1158e35..1cbf1c1 100644
--- a/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
+++ b/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
@@ -162,7 +162,7 @@ void QAxWidgetTaskMenu::setActiveXControl()
tr("The control requires a design-time license"));
clsid = QUuid();
} else {
- key = QString::fromUtf16((ushort *)bKey);
+ key = QString::fromWCharArray(bKey);
}
cf2->Release();
diff --git a/tools/designer/src/uitools/quiloader.cpp b/tools/designer/src/uitools/quiloader.cpp
index 83d3089..260e9bd 100644
--- a/tools/designer/src/uitools/quiloader.cpp
+++ b/tools/designer/src/uitools/quiloader.cpp
@@ -574,20 +574,20 @@ void QUiLoaderPrivate::setupWidgetMap() const
\brief The QUiLoader class enables standalone applications to
dynamically create user interfaces at run-time using the
- information stored in .ui files or specified in plugin paths.
+ information stored in UI files or specified in plugin paths.
In addition, you can customize or create your own user interface by
deriving your own loader class.
If you have a custom component or an application that embeds \QD, you can
also use the QFormBuilder class provided by the QtDesigner module to create
- user interfaces from \c{.ui} files.
+ user interfaces from UI files.
The QUiLoader class provides a collection of functions allowing you to
- create widgets based on the information stored in \c .ui files (created
+ create widgets based on the information stored in UI files (created
with \QD) or available in the specified plugin paths. The specified plugin
paths can be retrieved using the pluginPaths() function. Similarly, the
- contents of a \c{.ui} file can be retrieved using the load() function. For
+ contents of a UI file can be retrieved using the load() function. For
example:
\snippet doc/src/snippets/quiloader/mywidget.cpp 0
diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp
index 534bc11..1381595 100644
--- a/tools/linguist/lconvert/main.cpp
+++ b/tools/linguist/lconvert/main.cpp
@@ -81,10 +81,13 @@ static int usage(const QStringList &args)
" --output-format <outformat>\n"
" Specify output format. See -if.\n\n"
" --input-codec <codec>\n"
- " Specify encoding for .qm input files. Default is 'Latin1'.\n"
- " UTF-8 is always tried as well, corresponding to the trUtf8() function.\n\n"
+ " Specify encoding for QM and PO input files. Default is 'Latin1'\n"
+ " for QM and 'UTF-8' for PO files. UTF-8 is always tried as well for\n"
+ " QM, corresponding to the possible use of the trUtf8() function.\n\n"
+ " --output-codec <codec>\n"
+ " Specify encoding for PO output files. Default is 'UTF-8'.\n\n"
" --drop-tags <regexp>\n"
- " Drop named extra tags when writing 'ts' or 'xlf' files.\n"
+ " Drop named extra tags when writing TS or XLIFF files.\n"
" May be specified repeatedly.\n\n"
" --drop-translations\n"
" Drop existing translations and reset the status to 'unfinished'.\n"
@@ -101,10 +104,10 @@ static int usage(const QStringList &args)
" --no-finished\n"
" Drop finished messages.\n\n"
" --locations {absolute|relative|none}\n"
- " Override how source code references are saved in ts files.\n"
+ " Override how source code references are saved in TS files.\n"
" Default is absolute.\n\n"
" --no-ui-lines\n"
- " Drop line numbers from references to .ui files.\n\n"
+ " Drop line numbers from references to UI files.\n\n"
" --verbose\n"
" be a bit more verbose\n\n"
"Long options can be specified with only one leading dash, too.\n\n"
@@ -141,7 +144,6 @@ int main(int argc, char *argv[])
Translator::LocationsType locations = Translator::DefaultLocations;
ConversionData cd;
- cd.m_codecForSource = "Latin1";
Translator tr;
for (int i = 1; i < args.size(); ++i) {
@@ -174,6 +176,10 @@ int main(int argc, char *argv[])
if (++i >= args.size())
return usage(args);
cd.m_codecForSource = args[i].toLatin1();
+ } else if (args[i] == QLatin1String("-output-codec")) {
+ if (++i >= args.size())
+ return usage(args);
+ cd.m_outputCodec = args[i].toLatin1();
} else if (args[i] == QLatin1String("-drop-tag")) {
if (++i >= args.size())
return usage(args);
@@ -257,6 +263,11 @@ int main(int argc, char *argv[])
if (locations != Translator::DefaultLocations)
tr.setLocationsType(locations);
+ tr.normalizeTranslations(cd);
+ if (!cd.errors().isEmpty()) {
+ qWarning("%s", qPrintable(cd.error()));
+ cd.clearErrors();
+ }
if (!tr.save(outFileName, cd, outFormat)) {
qWarning("%s", qPrintable(cd.error()));
return 3;
diff --git a/tools/linguist/linguist/linguist.rc b/tools/linguist/linguist/linguist.rc
index 865e021..5ff37ca 100644
--- a/tools/linguist/linguist/linguist.rc
+++ b/tools/linguist/linguist/linguist.rc
@@ -1 +1,32 @@
+#include "winver.h"
+
IDI_ICON1 ICON DISCARDABLE "linguist.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Linguist"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "linguist"
+ VALUE "OriginalFilename", "linguist.exe"
+ VALUE "ProductName", "Qt Linguist"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp
index 2b1df39..bb79b19 100644
--- a/tools/linguist/linguist/mainwindow.cpp
+++ b/tools/linguist/linguist/mainwindow.cpp
@@ -82,6 +82,7 @@
#include <QMenuBar>
#include <QMessageBox>
#include <QPrintDialog>
+#include <QPrinter>
#include <QProcess>
#include <QRegExp>
#include <QSettings>
@@ -257,6 +258,7 @@ bool FocusWatcher::eventFilter(QObject *, QEvent *event)
MainWindow::MainWindow()
: QMainWindow(0, Qt::Window),
m_assistantProcess(0),
+ m_printer(0),
m_findMatchCase(Qt::CaseInsensitive),
m_findIgnoreAccelerators(true),
m_findWhere(DataModel::NoLocation),
@@ -503,6 +505,7 @@ MainWindow::~MainWindow()
qDeleteAll(m_phraseBooks);
delete m_dataModel;
delete m_statistics;
+ delete m_printer;
}
void MainWindow::modelCountChanged()
@@ -870,15 +873,22 @@ void MainWindow::releaseAll()
releaseInternal(i);
}
+QPrinter *MainWindow::printer()
+{
+ if (!m_printer)
+ m_printer = new QPrinter;
+ return m_printer;
+}
+
void MainWindow::print()
{
int pageNum = 0;
- QPrintDialog dlg(&m_printer, this);
+ QPrintDialog dlg(printer(), this);
if (dlg.exec()) {
QApplication::setOverrideCursor(Qt::WaitCursor);
- m_printer.setDocName(m_dataModel->condensedSrcFileNames(true));
+ printer()->setDocName(m_dataModel->condensedSrcFileNames(true));
statusBar()->showMessage(tr("Printing..."));
- PrintOut pout(&m_printer);
+ PrintOut pout(printer());
for (int i = 0; i < m_dataModel->contextCount(); ++i) {
MultiContextItem *mc = m_dataModel->multiContextItem(i);
@@ -1229,11 +1239,11 @@ void MainWindow::printPhraseBook(QAction *action)
int pageNum = 0;
- QPrintDialog dlg(&m_printer, this);
+ QPrintDialog dlg(printer(), this);
if (dlg.exec()) {
- m_printer.setDocName(phraseBook->fileName());
+ printer()->setDocName(phraseBook->fileName());
statusBar()->showMessage(tr("Printing..."));
- PrintOut pout(&m_printer);
+ PrintOut pout(printer());
pout.setRule(PrintOut::ThinRule);
foreach (const Phrase *p, phraseBook->phrases()) {
pout.setGuide(p->source());
diff --git a/tools/linguist/linguist/mainwindow.h b/tools/linguist/linguist/mainwindow.h
index 167dfe4..3dedcb5 100644
--- a/tools/linguist/linguist/mainwindow.h
+++ b/tools/linguist/linguist/mainwindow.h
@@ -51,7 +51,6 @@
#include <QtCore/QLocale>
#include <QtGui/QMainWindow>
-#include <QtGui/QPrinter>
QT_BEGIN_NAMESPACE
@@ -60,6 +59,7 @@ class QAction;
class QDialog;
class QLabel;
class QMenu;
+class QPrinter;
class QProcess;
class QIcon;
class QSortFilterProxyModel;
@@ -200,6 +200,8 @@ private:
void releaseInternal(int model);
void saveInternal(int model);
+ QPrinter *printer();
+
// FIXME: move to DataModel
void updateDanger(const MultiDataIndex &index, bool verbose);
@@ -226,7 +228,7 @@ private:
QList<QHash<QString, QList<Phrase *> > > m_phraseDict;
QList<PhraseBook *> m_phraseBooks;
QMap<QAction *, PhraseBook *> m_phraseBookMenu[3];
- QPrinter m_printer;
+ QPrinter *m_printer;
FindDialog *m_findDialog;
QString m_findText;
diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui
index 4f66f31..613241b 100644
--- a/tools/linguist/linguist/mainwindow.ui
+++ b/tools/linguist/linguist/mainwindow.ui
@@ -747,7 +747,7 @@
<string>Release As...</string>
</property>
<property name="whatsThis">
- <string>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file.</string>
+ <string>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file.</string>
</property>
</action>
<action name="actionFile">
diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp
index 6bbf6f3..9995220 100644
--- a/tools/linguist/linguist/messagemodel.cpp
+++ b/tools/linguist/linguist/messagemodel.cpp
@@ -139,7 +139,7 @@ DataModel::DataModel(QObject *parent)
QStringList DataModel::normalizedTranslations(const MessageItem &m) const
{
- return Translator::normalizedTranslations(m.message(), m_language, m_country);
+ return Translator::normalizedTranslations(m.message(), m_numerusForms.count());
}
ContextItem *DataModel::contextItem(int context) const
diff --git a/tools/linguist/lrelease/lrelease.1 b/tools/linguist/lrelease/lrelease.1
index 9e77504..8dd14b2 100644
--- a/tools/linguist/lrelease/lrelease.1
+++ b/tools/linguist/lrelease/lrelease.1
@@ -51,10 +51,10 @@ This page documents the
tool for the Qt GUI toolkit.
.B Lrelease
reads a qmake/tmake project file (.pro file) and converts the
-translation files (.ts files) specified in it into Qt message files
-(.qm files) used by the application to translate.
+translation files (TS files) specified in it into Qt message files
+(QM files) used by the application to translate.
.PP
-The .qm file format is a compact binary format that provides
+The QM file format is a compact binary format that provides
extremely fast lookups for translations and that is used by Qt.
.SH OPTIONS
.TP
@@ -62,7 +62,7 @@ extremely fast lookups for translations and that is used by Qt.
Display the usage and exit.
.TP
.I "-compress"
-Compress the .qm files.
+Compress the QM files.
.TP
.I "-nounfinished"
Do not include unfinished translations.
@@ -72,7 +72,7 @@ If the translated text is the same as
the source text, do not include the message.
.TP
.I "-silent"
-Don't explain what is being done.
+Do not explain what is being done.
.TP
.I "-version"
Display the version of
@@ -105,7 +105,7 @@ generated from gnomovision_dk.ts, gnomovision_fi.ts,
gnomovision_no.ts and gnomovision_se.ts, respectively.
.PP
.B Lrelease
-can also be invoked with a list of .ts files to convert:
+can also be invoked with a list of TS files to convert:
.PP
.in +4
.nf
diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 86b7866..5cb9e1a 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "translator.h"
-#include "profileevaluator.h"
+#include "proreader.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -66,19 +66,21 @@ static void printUsage()
" lrelease [options] project-file\n"
" lrelease [options] ts-files [-qm qm-file]\n\n"
"lrelease is part of Qt's Linguist tool chain. It can be used as a\n"
- "stand-alone tool to convert XML based translations files in the .ts\n"
- "format into the 'compiled' .qm format used by QTranslator objects.\n\n"
+ "stand-alone tool to convert XML-based translations files in the TS\n"
+ "format into the 'compiled' QM format used by QTranslator objects.\n\n"
"Options:\n"
" -help Display this information and exit\n"
+ " -idbased\n"
+ " Use IDs instead of source strings for message keying\n"
" -compress\n"
- " Compress the .qm files\n"
+ " Compress the QM files\n"
" -nounfinished\n"
" Do not include unfinished translations\n"
" -removeidentical\n"
" If the translated text is the same as\n"
" the source text, do not include the message\n"
" -silent\n"
- " Don't explain what is being done\n"
+ " Do not explain what is being done\n"
" -version\n"
" Display the version of lrelease and exit\n"
));
@@ -99,7 +101,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo
static bool releaseTranslator(Translator &tor, const QString &qmFileName,
bool verbose, bool ignoreUnfinished,
- bool removeIdentical, TranslatorSaveMode mode)
+ bool removeIdentical, bool idBased, TranslatorSaveMode mode)
{
Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose);
@@ -119,8 +121,10 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
}
ConversionData cd;
+ tor.normalizeTranslations(cd);
cd.m_verbose = verbose;
cd.m_ignoreUnfinished = ignoreUnfinished;
+ cd.m_idBased = idBased;
cd.m_saveMode = mode;
bool ok = tor.release(&file, cd);
file.close();
@@ -136,7 +140,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
}
static bool releaseTsFile(const QString& tsFileName, bool verbose,
- bool ignoreUnfinished, bool removeIdentical, TranslatorSaveMode mode)
+ bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode)
{
Translator tor;
if (!loadTsFile(tor, tsFileName, verbose))
@@ -151,7 +155,7 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose,
}
qmFileName += QLatin1String(".qm");
- return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, mode);
+ return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode);
}
int main(int argc, char **argv)
@@ -164,6 +168,7 @@ int main(int argc, char **argv)
bool verbose = true; // the default is true starting with Qt 4.2
bool ignoreUnfinished = false;
+ bool idBased = false;
// the default mode is SaveEverything starting with Qt 4.2
TranslatorSaveMode mode = SaveEverything;
bool removeIdentical = false;
@@ -175,6 +180,9 @@ int main(int argc, char **argv)
if (args[i] == QLatin1String("-compress")) {
mode = SaveStripped;
continue;
+ } else if (args[i] == QLatin1String("-idbased")) {
+ idBased = true;
+ continue;
} else if (args[i] == QLatin1String("-nocompress")) {
mode = SaveEverything;
continue;
@@ -232,18 +240,18 @@ int main(int argc, char **argv)
qPrintable(args[i]));
} else {
foreach (const QString &trans, translations)
- if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, mode))
+ if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode))
return 1;
}
} else {
qWarning("error: lrelease encountered project file functionality that is currently not supported.\n"
- "You might want to consider using .ts files as input instead of a project file.\n"
+ "You might want to consider using TS files as input instead of a project file.\n"
"Try the following syntax:\n"
" lrelease [options] ts-files [-qm qm-file]\n");
}
} else {
if (outputFile.isEmpty()) {
- if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, mode))
+ if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode))
return 1;
} else {
if (!loadTsFile(tor, args[i], verbose))
@@ -254,7 +262,7 @@ int main(int argc, char **argv)
if (!outputFile.isEmpty())
return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished,
- removeIdentical, mode) ? 0 : 1;
+ removeIdentical, idBased, mode) ? 0 : 1;
return 0;
}
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
index eb743c2..58e094b 100644
--- a/tools/linguist/lupdate/cpp.cpp
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -58,10 +58,6 @@ QT_BEGIN_NAMESPACE
static const char MagicComment[] = "TRANSLATOR ";
-static const int yyIdentMaxLen = 128;
-static const int yyCommentMaxLen = 65536;
-static const int yyStringMaxLen = 65536;
-
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s)))
@@ -180,7 +176,8 @@ private:
QString transcode(const QString &str, bool utf8);
void recordMessage(
int line, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool utf8, bool plural);
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural);
void processInclude(const QString &file, ConversionData &cd,
QSet<QString> &inclusions);
@@ -202,7 +199,7 @@ private:
enum {
Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
- Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8,
+ Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid,
Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS,
Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
Tok_Equals,
@@ -556,6 +553,8 @@ uint CppParser::getToken()
return Tok_Q_DECLARE_TR_FUNCTIONS;
if (yyIdent == QLatin1String("QT_TR_NOOP"))
return Tok_tr;
+ if (yyIdent == QLatin1String("QT_TRID_NOOP"))
+ return Tok_trid;
if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP"))
return Tok_translate;
if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3"))
@@ -591,6 +590,10 @@ uint CppParser::getToken()
if (yyIdent == QLatin1String("namespace"))
return Tok_namespace;
break;
+ case 'q':
+ if (yyIdent == QLatin1String("qtTrId"))
+ return Tok_trid;
+ break;
case 'r':
if (yyIdent == QLatin1String("return"))
return Tok_return;
@@ -667,14 +670,9 @@ uint CppParser::getToken()
yyCh = getChar();
if (yyCh == EOF || yyCh == '\n')
break;
- if (yyString.size() < yyStringMaxLen) {
- yyString.append(QLatin1Char('\\'));
- yyString.append(yyCh);
- }
- } else {
- if (yyString.size() < yyStringMaxLen)
- yyString.append(yyCh);
+ yyString.append(QLatin1Char('\\'));
}
+ yyString.append(yyCh);
yyCh = getChar();
}
@@ -1299,13 +1297,16 @@ QString CppParser::transcode(const QString &str, bool utf8)
void CppParser::recordMessage(
int line, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool utf8, bool plural)
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural)
{
TranslatorMessage msg(
transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(),
yyFileName, line, QStringList(),
TranslatorMessage::Unfinished, plural);
msg.setExtraComment(transcode(extracomment.simplified(), utf8));
+ msg.setId(msgid);
+ msg.setExtras(extra);
if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit())
msg.setUtf8(true);
results->tor->append(msg);
@@ -1332,6 +1333,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
QString text;
QString comment;
QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
QString prefix;
#ifdef DIAGNOSE_RETRANSLATABILITY
QString functionName;
@@ -1517,6 +1521,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
case Tok_trUtf8:
if (!results->tor)
goto case_default;
+ if (!sourcetext.isEmpty())
+ qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
utf8 = (yyTok == Tok_trUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1604,14 +1611,19 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
prefix.clear();
}
- recordMessage(line, context, text, comment, extracomment, utf8, plural);
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
extracomment.clear();
+ msgid.clear();
+ extra.clear();
break;
case Tok_translateUtf8:
case Tok_translate:
if (!results->tor)
goto case_default;
+ if (!sourcetext.isEmpty())
+ qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
utf8 = (yyTok == Tok_translateUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1655,9 +1667,32 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
break;
}
}
- recordMessage(line, context, text, comment, extracomment, utf8, plural);
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_trid:
+ if (!results->tor)
+ goto case_default;
+ if (!sourcetext.isEmpty()) {
+ if (!msgid.isEmpty())
+ qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
+ //utf8 = false; // Maybe use //%% or something like that
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) {
+ bool plural = match(Tok_Comma);
+ recordMessage(line, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, false, plural);
+ }
+ sourcetext.clear();
+ }
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
break;
case Tok_Q_DECLARE_TR_FUNCTIONS:
case Tok_Q_OBJECT:
@@ -1679,6 +1714,49 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (yyComment.startsWith(QLatin1Char(':'))) {
yyComment.remove(0, 1);
extracomment.append(yyComment);
+ } else if (yyComment.startsWith(QLatin1Char('='))) {
+ yyComment.remove(0, 1);
+ msgid = yyComment.simplified();
+ } else if (yyComment.startsWith(QLatin1Char('~'))) {
+ yyComment.remove(0, 1);
+ yyComment = yyComment.trimmed();
+ int k = yyComment.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed());
+ } else if (yyComment.startsWith(QLatin1Char('%'))) {
+ int p = 1, c;
+ forever {
+ if (p >= yyComment.length())
+ break;
+ c = yyComment.unicode()[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ qWarning("%s:%d: Unexpected character in meta string\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ forever {
+ if (p >= yyComment.length()) {
+ whoops:
+ qWarning("%s:%d: Unterminated meta string\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ c = yyComment.unicode()[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= yyComment.length())
+ goto whoops;
+ c = yyComment.unicode()[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ sourcetext.append(QLatin1Char('\\'));
+ }
+ sourcetext.append(c);
+ }
+ }
} else {
comment = yyComment.simplified();
if (comment.startsWith(QLatin1String(MagicComment))) {
@@ -1689,7 +1767,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
} else {
context = comment.left(k);
comment.remove(0, k + 1);
- recordMessage(yyLineNo, context, QString(), comment, extracomment, false, false);
+ recordMessage(yyLineNo, context, QString(), comment, extracomment,
+ QString(), TranslatorMessage::ExtraData(), false, false);
+ extracomment.clear();
+ results->tor->setExtras(extra);
+ extra.clear();
}
}
}
@@ -1739,6 +1821,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
prospectiveContext.clear();
prefix.clear();
extracomment.clear();
+ msgid.clear();
+ extra.clear();
yyTokColonSeen = false;
yyTok = getToken();
break;
@@ -1799,7 +1883,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
? translator.codecName() : cd.m_codecForSource;
QTextCodec *codec = QTextCodec::codecForName(codecName);
- foreach (const QString filename, filenames) {
+ foreach (const QString &filename, filenames) {
if (CppFiles::getResults(filename) || CppFiles::isBlacklisted(filename))
continue;
diff --git a/tools/linguist/lupdate/lupdate.1 b/tools/linguist/lupdate/lupdate.1
index 68958b9..b37e7b3 100644
--- a/tools/linguist/lupdate/lupdate.1
+++ b/tools/linguist/lupdate/lupdate.1
@@ -52,12 +52,12 @@ tool for the Qt GUI toolkit.
.B Lupdate
reads a qmake/tmake project file (.pro file), finds the translatable
strings in the specified source, header and interface files, and
-updates the translation files (.ts files) specified in it. The
+updates the translation files (TS files) specified in it. The
translation files are given to the translator who uses
.B Qt Linguist
to read the files and insert the translations.
.PP
-The .ts file format is a simple human-readable XML format that can be
+The TS file format is a simple human-readable XML format that can be
used with version control systems if required.
.PP
.SH OPTIONS
@@ -74,7 +74,7 @@ Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'.
Display the usage and exit.
.TP
.I "-locations {absolute|relative|none}"
-Specify/override how source code references are saved in ts files.
+Specify/override how source code references are saved in TS files.
Default is absolute.
.TP
.I "-no-obsolete"
@@ -84,7 +84,7 @@ Drop all obsolete strings.
Do not recursively scan the following directories.
.TP
.I "-no-sort"
-Do not sort contexts in .ts files.
+Do not sort contexts in TS files.
.TP
.I "-pluralonly"
Only include plural form messages.
@@ -97,7 +97,7 @@ file syntax but different file suffix
Recursively scan the following directories.
.TP
.I "-silent"
-Don't explain what is being done.
+Do not explain what is being done.
.TP
.I "-source-language <language>[_<region>]"
Specify/override the language of the source strings. Defaults to
@@ -139,8 +139,8 @@ translations will be reused as far as possible, and translated
strings that have vanished from the source files are marked obsolete.
.PP
.B lupdate
-can also be invoked with a list of C++ source files, .ui files
-and .ts files:
+can also be invoked with a list of C++ source files, UI files
+and TS files:
.PP
.in +4
.nf
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 18c8932..6a1edc4 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -43,6 +43,7 @@
#include <translator.h>
#include <profileevaluator.h>
+#include <proreader.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -103,7 +104,7 @@ static void printUsage()
" -silent\n"
" Do not explain what is being done.\n"
" -no-sort\n"
- " Do not sort contexts in .ts files.\n"
+ " Do not sort contexts in TS files.\n"
" -no-recursive\n"
" Do not recursively scan the following directories.\n"
" -recursive\n"
@@ -112,10 +113,10 @@ static void printUsage()
" Additional location to look for include files.\n"
" May be specified multiple times.\n"
" -locations {absolute|relative|none}\n"
- " Specify/override how source code references are saved in ts files.\n"
+ " Specify/override how source code references are saved in TS files.\n"
" Default is absolute.\n"
" -no-ui-lines\n"
- " Do not record line numbers in references to .ui files.\n"
+ " Do not record line numbers in references to UI files.\n"
" -disable-heuristic {sametext|similartext|number}\n"
" Disable the named merge heuristic. Can be specified multiple times.\n"
" -pro <filename>\n"
@@ -182,9 +183,10 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
if (options & Verbose)
printOut(QObject::tr("Updating '%1'...\n").arg(fn));
+ UpdateOptions theseOptions = options;
if (tor.locationsType() == Translator::NoLocations) // Could be set from file
- options |= NoLocations;
- Translator out = merge(tor, fetchedTor, options, err);
+ theseOptions |= NoLocations;
+ Translator out = merge(tor, fetchedTor, theseOptions, err);
if (!codecForTr.isEmpty())
out.setCodecName(codecForTr);
@@ -201,6 +203,11 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
out.stripObsoleteMessages();
out.stripEmptyContexts();
+ out.normalizeTranslations(cd);
+ if (!cd.errors().isEmpty()) {
+ printOut(cd.error());
+ cd.clearErrors();
+ }
if (!out.save(fileName, cd, QLatin1String("auto"))) {
printOut(cd.error());
*fail = true;
@@ -487,7 +494,7 @@ int main(int argc, char **argv)
cd.m_includePath += visitor.values(QLatin1String("INCLUDEPATH"));
- evaluateProFile(visitor, &variables);
+ evaluateProFile(visitor, &variables, pfi.absolutePath());
sourceFiles = variables.value("SOURCES");
diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph
index f244013..d38da5a 100644
--- a/tools/linguist/phrasebooks/french.qph
+++ b/tools/linguist/phrasebooks/french.qph
@@ -1,4 +1,5 @@
-<!DOCTYPE QPH><QPH language="fr">
+<!DOCTYPE QPH>
+<QPH language="fr">
<phrase>
<source>About</source>
<target>A propos</target>
@@ -1101,4 +1102,228 @@
<source>Yes</source>
<target>Oui</target>
</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Scinder</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <target>&amp;Édition</target>
+</phrase>
+<phrase>
+ <source>&amp;Redo</source>
+ <target>Re&amp;faire</target>
+</phrase>
+<phrase>
+ <source>debugger</source>
+ <target>débogueur</target>
+</phrase>
+<phrase>
+ <source>Start Debugger</source>
+ <target>Lancer le débogueur</target>
+</phrase>
+<phrase>
+ <source>Executable:</source>
+ <target>Exécutable:</target>
+</phrase>
+<phrase>
+ <source>Filter:</source>
+ <target>Filtre:</target>
+</phrase>
+<phrase>
+ <source>Clear</source>
+ <target>Effacer</target>
+</phrase>
+<phrase>
+ <source>Host and port:</source>
+ <target>Hôte et port:</target>
+</phrase>
+<phrase>
+ <source>Architecture:</source>
+ <target>Architecture:</target>
+</phrase>
+<phrase>
+ <source>Server start script:</source>
+ <target>Script de démarrage du serveur:</target>
+</phrase>
+<phrase>
+ <source>&amp;Undo</source>
+ <target>Annu&amp;ler</target>
+</phrase>
+<phrase>
+ <source>Add Bookmark</source>
+ <target>Ajouter un signet</target>
+</phrase>
+<phrase>
+ <source>Bookmark:</source>
+ <target>Signet:</target>
+</phrase>
+<phrase>
+ <source>Add in Folder:</source>
+ <target>Ajouter dans le dossier:</target>
+</phrase>
+<phrase>
+ <source>+</source>
+ <target>+</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Nouveau dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Signets</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Renommer le dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Signet</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Retirer</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Supprimer le dossier</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Ajouter</target>
+</phrase>
+<phrase>
+ <source>Move Up</source>
+ <target>Vers le Haut</target>
+</phrase>
+<phrase>
+ <source>Move Down</source>
+ <target>Vers le Bas</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark</source>
+ <target>Afficher le signet</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark in New Tab</source>
+ <target>Afficher le signet dans un nouvel onglet</target>
+</phrase>
+<phrase>
+ <source>Delete Bookmark</source>
+ <target>Supprimer le signet</target>
+</phrase>
+<phrase>
+ <source>Rename Bookmark</source>
+ <target>Renommer le signet</target>
+</phrase>
+<phrase>
+ <source>Previous Bookmark</source>
+ <target>Signet précédent</target>
+</phrase>
+<phrase>
+ <source>Next Bookmark</source>
+ <target>Signet suivant</target>
+</phrase>
+<phrase>
+ <source>Condition:</source>
+ <target>Condition:</target>
+</phrase>
+<phrase>
+ <source>Working Directory:</source>
+ <target>Répertoire de travail:</target>
+</phrase>
+<phrase>
+ <source>Environment</source>
+ <target>Environnement</target>
+</phrase>
+<phrase>
+ <source>Arguments</source>
+ <target>Arguments</target>
+</phrase>
+<phrase>
+ <source>Build directory:</source>
+ <target>Répertoire de compilation:</target>
+</phrase>
+<phrase>
+ <source>Path:</source>
+ <target>Chemin:</target>
+</phrase>
+<phrase>
+ <source>General</source>
+ <target>Général</target>
+</phrase>
+<phrase>
+ <source>Username:</source>
+ <target>Nom d&apos;utilisateur:</target>
+</phrase>
+<phrase>
+ <source>User interface</source>
+ <target>Interface utilisateur</target>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Ouvrir le lien</target>
+</phrase>
+<phrase>
+ <source> [read only]</source>
+ <target> [lecture seule]</target>
+</phrase>
+<phrase>
+ <source> [directory]</source>
+ <target> [répertoire]</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Fermer tout</target>
+</phrase>
+<phrase>
+ <source>Failed!</source>
+ <target>Échec!</target>
+</phrase>
+<phrase>
+ <source>Proceed</source>
+ <target>Continuer</target>
+</phrase>
+<phrase>
+ <source>Make writable</source>
+ <target>Rendre inscriptible</target>
+</phrase>
+<phrase>
+ <source>Qt Creator</source>
+ <target>Qt Creator</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fichier</target>
+</phrase>
+<phrase>
+ <source>Activate %1</source>
+ <target>Activer %1</target>
+</phrase>
+<phrase>
+ <source>New Project</source>
+ <target>Nouveau projet</target>
+</phrase>
+<phrase>
+ <source>Close %1</source>
+ <target>Fermer %1</target>
+</phrase>
+<phrase>
+ <source>*</source>
+ <target>*</target>
+</phrase>
+<phrase>
+ <source>&amp;Change</source>
+ <target>&amp;Modifier</target>
+</phrase>
+<phrase>
+ <source>Close Other Editors</source>
+ <target>Fermer les autres éditeurs</target>
+</phrase>
+<phrase>
+ <source>Close All Except %1</source>
+ <target>Fermer tout sauf %1</target>
+</phrase>
</QPH>
diff --git a/tools/linguist/shared/abstractproitemvisitor.h b/tools/linguist/shared/abstractproitemvisitor.h
index 0691fdc..43e79e0 100644
--- a/tools/linguist/shared/abstractproitemvisitor.h
+++ b/tools/linguist/shared/abstractproitemvisitor.h
@@ -49,19 +49,23 @@ QT_BEGIN_NAMESPACE
struct AbstractProItemVisitor
{
virtual ~AbstractProItemVisitor() {}
- virtual bool visitBeginProBlock(ProBlock *block) = 0;
- virtual bool visitEndProBlock(ProBlock *block) = 0;
- virtual bool visitBeginProVariable(ProVariable *variable) = 0;
- virtual bool visitEndProVariable(ProVariable *variable) = 0;
+ virtual ProItem::ProItemReturn visitBeginProBlock(ProBlock *block) = 0;
+ virtual void visitEndProBlock(ProBlock *block) = 0;
- virtual bool visitBeginProFile(ProFile *value) = 0;
- virtual bool visitEndProFile(ProFile *value) = 0;
+ virtual ProItem::ProItemReturn visitProLoopIteration() = 0;
+ virtual void visitProLoopCleanup() = 0;
- virtual bool visitProValue(ProValue *value) = 0;
- virtual bool visitProFunction(ProFunction *function) = 0;
- virtual bool visitProOperator(ProOperator *function) = 0;
- virtual bool visitProCondition(ProCondition *function) = 0;
+ virtual void visitBeginProVariable(ProVariable *variable) = 0;
+ virtual void visitEndProVariable(ProVariable *variable) = 0;
+
+ virtual ProItem::ProItemReturn visitBeginProFile(ProFile *value) = 0;
+ virtual ProItem::ProItemReturn visitEndProFile(ProFile *value) = 0;
+
+ virtual void visitProValue(ProValue *value) = 0;
+ virtual ProItem::ProItemReturn visitProFunction(ProFunction *function) = 0;
+ virtual void visitProOperator(ProOperator *function) = 0;
+ virtual void visitProCondition(ProCondition *function) = 0;
};
QT_END_NAMESPACE
diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp
index e22aa7d..796d012 100644
--- a/tools/linguist/shared/po.cpp
+++ b/tools/linguist/shared/po.cpp
@@ -359,6 +359,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
const QChar quote = QLatin1Char('"');
const QChar newline = QLatin1Char('\n');
QTextStream in(&dev);
+ in.setCodec(cd.m_codecForSource.isEmpty() ? "UTF-8" : cd.m_codecForSource);
bool error = false;
// format of a .po file entry:
@@ -554,7 +555,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
{
bool ok = true;
QTextStream out(&dev);
- //qDebug() << "OUT CODEC: " << out.codec()->name();
+ out.setCodec(cd.m_outputCodec.isEmpty() ? "UTF-8" : cd.m_outputCodec);
bool first = true;
if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) {
@@ -636,7 +637,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
if (plural.isEmpty())
plural = msg.sourceText();
out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
- QStringList translations = translator.normalizedTranslations(msg, cd, &ok);
+ const QStringList &translations = msg.translations();
for (int i = 0; i != translations.size(); ++i) {
QString str = translations.at(i);
str.replace(QChar(Translator::BinaryVariantSeparator),
diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp
index ef59543..5a9095a 100644
--- a/tools/linguist/shared/profileevaluator.cpp
+++ b/tools/linguist/shared/profileevaluator.cpp
@@ -60,7 +60,7 @@
#ifdef Q_OS_UNIX
#include <unistd.h>
#include <sys/utsname.h>
-#elif defined(Q_OS_WIN32)
+#else
#include <Windows.h>
#endif
#include <stdio.h>
@@ -68,8 +68,10 @@
#ifdef Q_OS_WIN32
#define QT_POPEN _popen
+#define QT_PCLOSE _pclose
#else
#define QT_POPEN popen
+#define QT_PCLOSE pclose
#endif
QT_BEGIN_NAMESPACE
@@ -169,16 +171,18 @@ public:
/////////////// Evaluating pro file contents
// implementation of AbstractProItemVisitor
- bool visitBeginProBlock(ProBlock *block);
- bool visitEndProBlock(ProBlock *block);
- bool visitBeginProVariable(ProVariable *variable);
- bool visitEndProVariable(ProVariable *variable);
- bool visitBeginProFile(ProFile *value);
- bool visitEndProFile(ProFile *value);
- bool visitProValue(ProValue *value);
- bool visitProFunction(ProFunction *function);
- bool visitProOperator(ProOperator *oper);
- bool visitProCondition(ProCondition *condition);
+ ProItem::ProItemReturn visitBeginProBlock(ProBlock *block);
+ void visitEndProBlock(ProBlock *block);
+ ProItem::ProItemReturn visitProLoopIteration();
+ void visitProLoopCleanup();
+ void visitBeginProVariable(ProVariable *variable);
+ void visitEndProVariable(ProVariable *variable);
+ ProItem::ProItemReturn visitBeginProFile(ProFile *value);
+ ProItem::ProItemReturn visitEndProFile(ProFile *value);
+ void visitProValue(ProValue *value);
+ ProItem::ProItemReturn visitProFunction(ProFunction *function);
+ void visitProOperator(ProOperator *oper);
+ void visitProCondition(ProCondition *condition);
QStringList valuesDirect(const QString &variableName) const { return m_valuemap[variableName]; }
QStringList values(const QString &variableName) const;
@@ -188,10 +192,8 @@ public:
QString propertyValue(const QString &val) const;
bool isActiveConfig(const QString &config, bool regex = false);
- QStringList expandPattern(const QString &pattern);
- void expandPatternHelper(const QString &relName, const QString &absName,
- QStringList &sources_out);
QStringList expandVariableReferences(const QString &value);
+ void doVariableReplace(QString *str);
QStringList evaluateExpandFunction(const QString &function, const QString &arguments);
QString format(const char *format) const;
@@ -199,17 +201,22 @@ public:
QString currentDirectory() const;
ProFile *currentProFile() const;
- bool evaluateConditionalFunction(const QString &function, const QString &arguments, bool *result);
- bool evaluateFile(const QString &fileName, bool *result);
- bool evaluateFeatureFile(const QString &fileName, bool *result);
+ ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments);
+ bool evaluateFile(const QString &fileName);
+ bool evaluateFeatureFile(const QString &fileName);
+
+ static inline ProItem::ProItemReturn returnBool(bool b)
+ { return b ? ProItem::ReturnTrue : ProItem::ReturnFalse; }
+
+ QStringList evaluateFunction(ProBlock *funcPtr, const QStringList &argumentsList, bool *ok);
QStringList qmakeFeaturePaths();
- enum { ConditionTrue, ConditionFalse, ConditionElse };
- int m_condition;
- int m_prevCondition;
- bool m_updateCondition;
- bool m_invertNext;
+ struct State {
+ bool condition;
+ bool prevCondition;
+ } m_sts;
+ bool m_invertNext; // Short-lived, so not in State
int m_skipLevel;
bool m_cumulative;
bool m_isFirstVariableValue;
@@ -218,6 +225,14 @@ public:
QString m_origfile;
QString m_oldPath; // To restore the current path to the path
QStack<ProFile*> m_profileStack; // To handle 'include(a.pri), so we can track back to 'a.pro' when finished with 'a.pri'
+ struct ProLoop {
+ QString variable;
+ QStringList oldVarVal;
+ QStringList list;
+ int index;
+ bool infinite;
+ };
+ QStack<ProLoop> m_loopStack;
// we need the following two variables for handling
// CONFIG = foo bar $$CONFIG
@@ -229,10 +244,23 @@ public:
QHash<QString, QString> m_properties;
QString m_outputDir;
+ bool m_definingTest;
+ QString m_definingFunc;
+ QHash<QString, ProBlock *> m_testFunctions;
+ QHash<QString, ProBlock *> m_replaceFunctions;
+ QStringList m_returnValue;
+ QStack<QHash<QString, QStringList> > m_valuemapStack;
+ QStack<QHash<const ProFile*, QHash<QString, QStringList> > > m_filevaluemapStack;
+
int m_prevLineNo; // Checking whether we're assigning the same TARGET
ProFile *m_prevProFile; // See m_prevLineNo
};
+#if (!defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) && !defined(__SUNPRO_CC)
+Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::State, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::ProLoop, Q_MOVABLE_TYPE);
+#endif
+
ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
: q(q_)
{
@@ -245,11 +273,12 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
m_cumulative = true;
// Evaluator state
- m_updateCondition = false;
- m_condition = ConditionFalse;
+ m_sts.condition = false;
+ m_sts.prevCondition = false;
m_invertNext = false;
m_skipLevel = 0;
m_isFirstVariableValue = true;
+ m_definingFunc.clear();
}
bool ProFileEvaluator::Private::read(ProFile *pro)
@@ -561,91 +590,125 @@ void ProFileEvaluator::Private::updateItem()
}
-bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
+ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
{
- if (block->blockKind() == ProBlock::ScopeKind) {
- m_updateCondition = true;
+ if (block->blockKind() & ProBlock::ScopeContentsKind) {
+ if (!m_definingFunc.isEmpty()) {
+ if (!m_skipLevel || m_cumulative) {
+ QHash<QString, ProBlock *> *hash =
+ (m_definingTest ? &m_testFunctions : &m_replaceFunctions);
+ if (ProBlock *def = hash->value(m_definingFunc))
+ def->deref();
+ hash->insert(m_definingFunc, block);
+ block->ref();
+ block->setBlockKind(block->blockKind() | ProBlock::FunctionBodyKind);
+ }
+ m_definingFunc.clear();
+ return ProItem::ReturnSkip;
+ } else if (!(block->blockKind() & ProBlock::FunctionBodyKind)) {
+ if (!m_sts.condition)
+ ++m_skipLevel;
+ else
+ Q_ASSERT(!m_skipLevel);
+ }
+ } else {
if (!m_skipLevel) {
- m_prevCondition = m_condition;
- m_condition = ConditionFalse;
+ if (m_sts.condition) {
+ m_sts.prevCondition = true;
+ m_sts.condition = false;
+ }
} else {
- Q_ASSERT(m_condition != ConditionTrue);
+ Q_ASSERT(!m_sts.condition);
}
- } else if (block->blockKind() & ProBlock::ScopeContentsKind) {
- m_updateCondition = false;
- if (m_condition != ConditionTrue)
- ++m_skipLevel;
- else
- Q_ASSERT(!m_skipLevel);
}
- return true;
+ return ProItem::ReturnTrue;
}
-bool ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
+void ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
{
- if (block->blockKind() & ProBlock::ScopeContentsKind) {
+ if ((block->blockKind() & ProBlock::ScopeContentsKind)
+ && !(block->blockKind() & ProBlock::FunctionBodyKind)) {
if (m_skipLevel) {
- Q_ASSERT(m_condition != ConditionTrue);
+ Q_ASSERT(!m_sts.condition);
--m_skipLevel;
- } else {
+ } else if (!(block->blockKind() & ProBlock::SingleLine)) {
// Conditionals contained inside this block may have changed the state.
// So we reset it here to make an else following us do the right thing.
- m_condition = ConditionTrue;
+ m_sts.condition = true;
}
}
- return true;
}
-bool ProFileEvaluator::Private::visitBeginProVariable(ProVariable *variable)
+ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoopIteration()
+{
+ ProLoop &loop = m_loopStack.top();
+
+ if (loop.infinite) {
+ if (!loop.variable.isEmpty())
+ m_valuemap[loop.variable] = QStringList(QString::number(loop.index++));
+ if (loop.index > 1000) {
+ q->errorMessage(format("ran into infinite loop (> 1000 iterations)."));
+ return ProItem::ReturnFalse;
+ }
+ } else {
+ QString val;
+ do {
+ if (loop.index >= loop.list.count())
+ return ProItem::ReturnFalse;
+ val = loop.list.at(loop.index++);
+ } while (val.isEmpty()); // stupid, but qmake is like that
+ m_valuemap[loop.variable] = QStringList(val);
+ }
+ return ProItem::ReturnTrue;
+}
+
+void ProFileEvaluator::Private::visitProLoopCleanup()
+{
+ ProLoop &loop = m_loopStack.top();
+ m_valuemap[loop.variable] = loop.oldVarVal;
+ m_loopStack.pop_back();
+}
+
+void ProFileEvaluator::Private::visitBeginProVariable(ProVariable *variable)
{
m_lastVarName = variable->variable();
m_variableOperator = variable->variableOperator();
m_isFirstVariableValue = true;
m_tempValuemap = m_valuemap;
m_tempFilevaluemap = m_filevaluemap;
- return true;
}
-bool ProFileEvaluator::Private::visitEndProVariable(ProVariable *variable)
+void ProFileEvaluator::Private::visitEndProVariable(ProVariable *variable)
{
Q_UNUSED(variable);
m_valuemap = m_tempValuemap;
m_filevaluemap = m_tempFilevaluemap;
m_lastVarName.clear();
- return true;
}
-bool ProFileEvaluator::Private::visitProOperator(ProOperator *oper)
+void ProFileEvaluator::Private::visitProOperator(ProOperator *oper)
{
m_invertNext = (oper->operatorKind() == ProOperator::NotOperator);
- return true;
}
-bool ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
+void ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
{
if (!m_skipLevel) {
- if (cond->text().toLower() == QLatin1String("else")) {
- // The state ConditionElse makes sure that subsequential elses are ignored.
- // That's braindead, but qmake is like that.
- if (m_prevCondition == ConditionTrue)
- m_condition = ConditionElse;
- else if (m_prevCondition == ConditionFalse)
- m_condition = ConditionTrue;
- } else if (m_condition == ConditionFalse) {
- if (isActiveConfig(cond->text(), true) ^ m_invertNext)
- m_condition = ConditionTrue;
+ if (!cond->text().compare(QLatin1String("else"), Qt::CaseInsensitive)) {
+ m_sts.condition = !m_sts.prevCondition;
+ } else {
+ m_sts.prevCondition = false;
+ if (!m_sts.condition && isActiveConfig(cond->text(), true) ^ m_invertNext)
+ m_sts.condition = true;
}
}
m_invertNext = false;
- return true;
}
-bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
+ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
{
PRE(pro);
- bool ok = true;
m_lineNo = pro->lineNumber();
-
if (m_origfile.isEmpty())
m_origfile = pro->fileName();
if (m_oldPath.isEmpty()) {
@@ -663,21 +726,20 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
m_cumulative = false;
// This is what qmake does, everything set in the mkspec is also set
// But this also creates a lot of problems
- evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok);
- evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok);
+ evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"));
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"));
m_cumulative = cumulative;
}
- ok = QDir::setCurrent(pro->directoryName());
+ return returnBool(QDir::setCurrent(pro->directoryName()));
}
- return ok;
+ return ProItem::ReturnTrue;
}
-bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
+ProItem::ProItemReturn ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
{
PRE(pro);
- bool ok = true;
m_lineNo = pro->lineNumber();
if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) {
const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
@@ -685,7 +747,7 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
bool cumulative = m_cumulative;
m_cumulative = false;
- evaluateFile(mkspecDirectory + QLatin1String("/features/default_post.prf"), &ok);
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_post.prf"));
QSet<QString> processed;
forever {
@@ -695,9 +757,8 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
const QString config = configs[i].toLower();
if (!processed.contains(config)) {
processed.insert(config);
- evaluateFile(mkspecDirectory + QLatin1String("/features/")
- + config + QLatin1String(".prf"), &ok);
- if (ok) {
+ if (evaluateFile(mkspecDirectory + QLatin1String("/features/")
+ + config + QLatin1String(".prf"))) {
finished = false;
break;
}
@@ -707,13 +768,21 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
break;
}
+ foreach (ProBlock *itm, m_replaceFunctions)
+ itm->deref();
+ m_replaceFunctions.clear();
+ foreach (ProBlock *itm, m_testFunctions)
+ itm->deref();
+ m_testFunctions.clear();
+
m_cumulative = cumulative;
}
m_profileStack.pop();
- ok = QDir::setCurrent(m_oldPath);
+ return returnBool(QDir::setCurrent(m_oldPath));
}
- return ok;
+
+ return ProItem::ReturnTrue;
}
static void replaceInList(QStringList *varlist,
@@ -734,7 +803,7 @@ static void replaceInList(QStringList *varlist,
}
}
-bool ProFileEvaluator::Private::visitProValue(ProValue *value)
+void ProFileEvaluator::Private::visitProValue(ProValue *value)
{
PRE(value);
m_lineNo = value->lineNumber();
@@ -761,29 +830,6 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
m_prevLineNo = m_lineNo;
m_prevProFile = currentProFile();
- // The following two blocks fix bug 180128 by making all "interesting"
- // file name absolute in each .pro file, not just the top most one
- if (varName == QLatin1String("SOURCES")
- || varName == QLatin1String("HEADERS")
- || varName == QLatin1String("INTERFACES")
- || varName == QLatin1String("FORMS")
- || varName == QLatin1String("FORMS3")
- || varName == QLatin1String("RESOURCES")) {
- // matches only existent files, expand certain(?) patterns
- QStringList vv;
- for (int i = v.count(); --i >= 0; )
- vv << expandPattern(v[i]);
- v = vv;
- }
-
- if (varName == QLatin1String("TRANSLATIONS")) {
- // also matches non-existent files, but does not expand pattern
- QString dir = QFileInfo(currentFileName()).absolutePath();
- dir += QLatin1Char('/');
- for (int i = v.count(); --i >= 0; )
- v[i] = QFileInfo(dir, v[i]).absoluteFilePath();
- }
-
switch (m_variableOperator) {
case ProVariable::SetOperator: // =
if (!m_cumulative) {
@@ -828,16 +874,16 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
{
// DEFINES ~= s/a/b/?[gqi]
- // FIXME: qmake variable-expands val first.
+ doVariableReplace(&val);
if (val.length() < 4 || val[0] != QLatin1Char('s')) {
q->logMessage(format("the ~= operator can handle only the s/// function."));
- return false;
+ break;
}
QChar sep = val.at(1);
QStringList func = val.split(sep);
if (func.count() < 3 || func.count() > 4) {
q->logMessage(format("the s/// function expects 3 or 4 arguments."));
- return false;
+ break;
}
bool global = false, quote = false, case_sense = false;
@@ -864,12 +910,16 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
}
m_isFirstVariableValue = false;
- return true;
}
-bool ProFileEvaluator::Private::visitProFunction(ProFunction *func)
+ProItem::ProItemReturn ProFileEvaluator::Private::visitProFunction(ProFunction *func)
{
- if (!m_updateCondition || m_condition == ConditionFalse) {
+ // Make sure that called subblocks don't inherit & destroy the state
+ bool invertThis = m_invertNext;
+ m_invertNext = false;
+ if (!m_skipLevel)
+ m_sts.prevCondition = false;
+ if (m_cumulative || !m_sts.condition) {
QString text = func->text();
int lparen = text.indexOf(QLatin1Char('('));
int rparen = text.lastIndexOf(QLatin1Char(')'));
@@ -877,16 +927,13 @@ bool ProFileEvaluator::Private::visitProFunction(ProFunction *func)
QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
QString funcName = text.left(lparen);
m_lineNo = func->lineNumber();
- bool result;
- if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result)) {
- m_invertNext = false;
- return false;
- }
- if (!m_skipLevel && (result ^ m_invertNext))
- m_condition = ConditionTrue;
+ ProItem::ProItemReturn result = evaluateConditionalFunction(funcName.trimmed(), arguments);
+ if (result != ProItem::ReturnFalse && result != ProItem::ReturnTrue)
+ return result;
+ if (!m_skipLevel && ((result == ProItem::ReturnTrue) ^ invertThis))
+ m_sts.condition = true;
}
- m_invertNext = false;
- return true;
+ return ProItem::ReturnTrue;
}
@@ -1012,6 +1059,11 @@ QString ProFileEvaluator::Private::currentDirectory() const
return cur->directoryName();
}
+void ProFileEvaluator::Private::doVariableReplace(QString *str)
+{
+ *str = expandVariableReferences(*str).join(QString(Option::field_sep));
+}
+
QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &str)
{
QStringList ret;
@@ -1226,10 +1278,49 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
return false;
}
+QStringList ProFileEvaluator::Private::evaluateFunction(
+ ProBlock *funcPtr, const QStringList &argumentsList, bool *ok)
+{
+ bool oki;
+ QStringList ret;
+
+ if (m_valuemapStack.count() >= 100) {
+ q->errorMessage(format("ran into infinite recursion (depth > 100)."));
+ oki = false;
+ } else {
+ State sts = m_sts;
+ m_valuemapStack.push(m_valuemap);
+ m_filevaluemapStack.push(m_filevaluemap);
+
+ QStringList args;
+ for (int i = 0; i < argumentsList.count(); ++i) {
+ QStringList theArgs = expandVariableReferences(argumentsList[i]);
+ args += theArgs;
+ m_valuemap[QString::number(i+1)] = theArgs;
+ }
+ m_valuemap[QLatin1String("ARGS")] = args;
+ oki = (funcPtr->Accept(this) != ProItem::ReturnFalse); // True || Return
+ ret = m_returnValue;
+ m_returnValue.clear();
+
+ m_valuemap = m_valuemapStack.pop();
+ m_filevaluemap = m_filevaluemapStack.pop();
+ m_sts = sts;
+ }
+ if (ok)
+ *ok = oki;
+ if (oki)
+ return ret;
+ return QStringList();
+}
+
QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
{
QStringList argumentsList = split_arg_list(arguments);
+ if (ProBlock *funcPtr = m_replaceFunctions.value(func, 0))
+ return evaluateFunction(funcPtr, argumentsList, 0);
+
QStringList args;
for (int i = 0; i < argumentsList.count(); ++i)
args += expandVariableReferences(argumentsList[i]).join(Option::field_sep);
@@ -1240,35 +1331,34 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE,
E_REPLACE };
- static QHash<QString, int> *expands = 0;
- if (!expands) {
- expands = new QHash<QString, int>;
- expands->insert(QLatin1String("member"), E_MEMBER);
- expands->insert(QLatin1String("first"), E_FIRST);
- expands->insert(QLatin1String("last"), E_LAST);
- expands->insert(QLatin1String("cat"), E_CAT);
- expands->insert(QLatin1String("fromfile"), E_FROMFILE); // implementation disabled (see comment below)
- expands->insert(QLatin1String("eval"), E_EVAL);
- expands->insert(QLatin1String("list"), E_LIST);
- expands->insert(QLatin1String("sprintf"), E_SPRINTF);
- expands->insert(QLatin1String("join"), E_JOIN);
- expands->insert(QLatin1String("split"), E_SPLIT);
- expands->insert(QLatin1String("basename"), E_BASENAME);
- expands->insert(QLatin1String("dirname"), E_DIRNAME);
- expands->insert(QLatin1String("section"), E_SECTION);
- expands->insert(QLatin1String("find"), E_FIND);
- expands->insert(QLatin1String("system"), E_SYSTEM);
- expands->insert(QLatin1String("unique"), E_UNIQUE);
- expands->insert(QLatin1String("quote"), E_QUOTE);
- expands->insert(QLatin1String("escape_expand"), E_ESCAPE_EXPAND);
- expands->insert(QLatin1String("upper"), E_UPPER);
- expands->insert(QLatin1String("lower"), E_LOWER);
- expands->insert(QLatin1String("re_escape"), E_RE_ESCAPE);
- expands->insert(QLatin1String("files"), E_FILES);
- expands->insert(QLatin1String("prompt"), E_PROMPT); // interactive, so cannot be implemented
- expands->insert(QLatin1String("replace"), E_REPLACE);
+ static QHash<QString, int> expands;
+ if (expands.isEmpty()) {
+ expands.insert(QLatin1String("member"), E_MEMBER);
+ expands.insert(QLatin1String("first"), E_FIRST);
+ expands.insert(QLatin1String("last"), E_LAST);
+ expands.insert(QLatin1String("cat"), E_CAT);
+ expands.insert(QLatin1String("fromfile"), E_FROMFILE); // implementation disabled (see comment below)
+ expands.insert(QLatin1String("eval"), E_EVAL);
+ expands.insert(QLatin1String("list"), E_LIST);
+ expands.insert(QLatin1String("sprintf"), E_SPRINTF);
+ expands.insert(QLatin1String("join"), E_JOIN);
+ expands.insert(QLatin1String("split"), E_SPLIT);
+ expands.insert(QLatin1String("basename"), E_BASENAME);
+ expands.insert(QLatin1String("dirname"), E_DIRNAME);
+ expands.insert(QLatin1String("section"), E_SECTION);
+ expands.insert(QLatin1String("find"), E_FIND);
+ expands.insert(QLatin1String("system"), E_SYSTEM);
+ expands.insert(QLatin1String("unique"), E_UNIQUE);
+ expands.insert(QLatin1String("quote"), E_QUOTE);
+ expands.insert(QLatin1String("escape_expand"), E_ESCAPE_EXPAND);
+ expands.insert(QLatin1String("upper"), E_UPPER);
+ expands.insert(QLatin1String("lower"), E_LOWER);
+ expands.insert(QLatin1String("re_escape"), E_RE_ESCAPE);
+ expands.insert(QLatin1String("files"), E_FILES);
+ expands.insert(QLatin1String("prompt"), E_PROMPT); // interactive, so cannot be implemented
+ expands.insert(QLatin1String("replace"), E_REPLACE);
}
- ExpandFunc func_t = ExpandFunc(expands->value(func.toLower()));
+ ExpandFunc func_t = ExpandFunc(expands.value(func.toLower()));
QStringList ret;
@@ -1425,7 +1515,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
bool singleLine = true;
if (args.count() > 1)
- singleLine = (args[1].toLower() == QLatin1String("true"));
+ singleLine = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive));
QFile qfile(file);
if (qfile.open(QIODevice::ReadOnly)) {
@@ -1499,7 +1589,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
FILE *proc = QT_POPEN(args[0].toLatin1(), "r");
bool singleLine = true;
if (args.count() > 1)
- singleLine = (args[1].toLower() == QLatin1String("true"));
+ singleLine = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive));
QString output;
while (proc && !feof(proc)) {
int read_in = int(fread(buff, 1, 255, proc));
@@ -1513,6 +1603,8 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
output += QLatin1String(buff);
}
ret += split_value_list(output);
+ if (proc)
+ QT_PCLOSE(proc);
}
}
break;
@@ -1579,7 +1671,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
} else {
bool recursive = false;
if (args.count() == 2)
- recursive = (args[1].toLower() == QLatin1String("true") || args[1].toInt());
+ recursive = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive) || args[1].toInt());
QStringList dirs;
QString r = Option::fixPathToLocalOS(args[0]);
int slash = r.lastIndexOf(QDir::separator());
@@ -1632,13 +1724,40 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
return ret;
}
-bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &function,
- const QString &arguments, bool *result)
+ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
+ const QString &function, const QString &arguments)
{
QStringList argumentsList = split_arg_list(arguments);
+
+ if (ProBlock *funcPtr = m_testFunctions.value(function, 0)) {
+ bool ok;
+ QStringList ret = evaluateFunction(funcPtr, argumentsList, &ok);
+ if (ok) {
+ if (ret.isEmpty()) {
+ return ProItem::ReturnTrue;
+ } else {
+ if (ret.first() != QLatin1String("false")) {
+ if (ret.first() == QLatin1String("true")) {
+ return ProItem::ReturnTrue;
+ } else {
+ bool ok;
+ int val = ret.first().toInt(&ok);
+ if (ok) {
+ if (val)
+ return ProItem::ReturnTrue;
+ } else {
+ q->logMessage(format("Unexpected return value from test '%1': %2")
+ .arg(function).arg(ret.join(QLatin1String(" :: "))));
+ }
+ }
+ }
+ }
+ }
+ return ProItem::ReturnFalse;
+ }
+
QString sep;
sep.append(Option::field_sep);
-
QStringList args;
for (int i = 0; i < argumentsList.count(); ++i)
args += expandVariableReferences(argumentsList[i]).join(sep);
@@ -1646,91 +1765,282 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
- T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF };
-
- static QHash<QString, int> *functions = 0;
- if (!functions) {
- functions = new QHash<QString, int>;
- functions->insert(QLatin1String("requires"), T_REQUIRES);
- functions->insert(QLatin1String("greaterThan"), T_GREATERTHAN);
- functions->insert(QLatin1String("lessThan"), T_LESSTHAN);
- functions->insert(QLatin1String("equals"), T_EQUALS);
- functions->insert(QLatin1String("isEqual"), T_EQUALS);
- functions->insert(QLatin1String("exists"), T_EXISTS);
- functions->insert(QLatin1String("export"), T_EXPORT);
- functions->insert(QLatin1String("clear"), T_CLEAR);
- functions->insert(QLatin1String("unset"), T_UNSET);
- functions->insert(QLatin1String("eval"), T_EVAL);
- functions->insert(QLatin1String("CONFIG"), T_CONFIG);
- functions->insert(QLatin1String("if"), T_IF);
- functions->insert(QLatin1String("isActiveConfig"), T_CONFIG);
- functions->insert(QLatin1String("system"), T_SYSTEM);
- functions->insert(QLatin1String("return"), T_RETURN);
- functions->insert(QLatin1String("break"), T_BREAK);
- functions->insert(QLatin1String("next"), T_NEXT);
- functions->insert(QLatin1String("defined"), T_DEFINED);
- functions->insert(QLatin1String("contains"), T_CONTAINS);
- functions->insert(QLatin1String("infile"), T_INFILE);
- functions->insert(QLatin1String("count"), T_COUNT);
- functions->insert(QLatin1String("isEmpty"), T_ISEMPTY);
- functions->insert(QLatin1String("load"), T_LOAD); //v
- functions->insert(QLatin1String("include"), T_INCLUDE); //v
- functions->insert(QLatin1String("debug"), T_DEBUG);
- functions->insert(QLatin1String("message"), T_MESSAGE); //v
- functions->insert(QLatin1String("warning"), T_MESSAGE); //v
- functions->insert(QLatin1String("error"), T_MESSAGE); //v
+ T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF,
+ T_FOR, T_DEFINE_TEST, T_DEFINE_REPLACE };
+
+ static QHash<QString, int> functions;
+ if (functions.isEmpty()) {
+ functions.insert(QLatin1String("requires"), T_REQUIRES);
+ functions.insert(QLatin1String("greaterThan"), T_GREATERTHAN);
+ functions.insert(QLatin1String("lessThan"), T_LESSTHAN);
+ functions.insert(QLatin1String("equals"), T_EQUALS);
+ functions.insert(QLatin1String("isEqual"), T_EQUALS);
+ functions.insert(QLatin1String("exists"), T_EXISTS);
+ functions.insert(QLatin1String("export"), T_EXPORT);
+ functions.insert(QLatin1String("clear"), T_CLEAR);
+ functions.insert(QLatin1String("unset"), T_UNSET);
+ functions.insert(QLatin1String("eval"), T_EVAL);
+ functions.insert(QLatin1String("CONFIG"), T_CONFIG);
+ functions.insert(QLatin1String("if"), T_IF);
+ functions.insert(QLatin1String("isActiveConfig"), T_CONFIG);
+ functions.insert(QLatin1String("system"), T_SYSTEM);
+ functions.insert(QLatin1String("return"), T_RETURN);
+ functions.insert(QLatin1String("break"), T_BREAK);
+ functions.insert(QLatin1String("next"), T_NEXT);
+ functions.insert(QLatin1String("defined"), T_DEFINED);
+ functions.insert(QLatin1String("contains"), T_CONTAINS);
+ functions.insert(QLatin1String("infile"), T_INFILE);
+ functions.insert(QLatin1String("count"), T_COUNT);
+ functions.insert(QLatin1String("isEmpty"), T_ISEMPTY);
+ functions.insert(QLatin1String("load"), T_LOAD); //v
+ functions.insert(QLatin1String("include"), T_INCLUDE); //v
+ functions.insert(QLatin1String("debug"), T_DEBUG);
+ functions.insert(QLatin1String("message"), T_MESSAGE); //v
+ functions.insert(QLatin1String("warning"), T_MESSAGE); //v
+ functions.insert(QLatin1String("error"), T_MESSAGE); //v
+ functions.insert(QLatin1String("for"), T_FOR); //v
+ functions.insert(QLatin1String("defineTest"), T_DEFINE_TEST); //v
+ functions.insert(QLatin1String("defineReplace"), T_DEFINE_REPLACE); //v
}
- bool cond = false;
- bool ok = true;
-
- TestFunc func_t = (TestFunc)functions->value(function);
+ TestFunc func_t = (TestFunc)functions.value(function);
switch (func_t) {
+ case T_DEFINE_TEST:
+ m_definingTest = true;
+ goto defineFunc;
+ case T_DEFINE_REPLACE:
+ m_definingTest = false;
+ defineFunc:
+ if (args.count() != 1) {
+ q->logMessage(format("%s(function) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ m_definingFunc = args.first();
+ return ProItem::ReturnTrue;
+ case T_DEFINED:
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("defined(function, [\"test\"|\"replace\"])"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ if (args.count() > 1) {
+ if (args[1] == QLatin1String("test"))
+ return returnBool(m_testFunctions.contains(args[0]));
+ else if (args[1] == QLatin1String("replace"))
+ return returnBool(m_replaceFunctions.contains(args[0]));
+ q->logMessage(format("defined(function, type):"
+ " unexpected type [%1].\n").arg(args[1]));
+ return ProItem::ReturnFalse;
+ }
+ return returnBool(m_replaceFunctions.contains(args[0])
+ || m_testFunctions.contains(args[0]));
+ case T_RETURN:
+ m_returnValue = args;
+ // It is "safe" to ignore returns - due to qmake brokeness
+ // they cannot be used to terminate loops anyway.
+ if (m_skipLevel || m_cumulative)
+ return ProItem::ReturnTrue;
+ if (m_valuemapStack.isEmpty()) {
+ q->logMessage(format("unexpected return()."));
+ return ProItem::ReturnFalse;
+ }
+ return ProItem::ReturnReturn;
+ case T_EXPORT:
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnTrue;
+ if (args.count() != 1) {
+ q->logMessage(format("export(variable) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ for (int i = 0; i < m_valuemapStack.size(); ++i) {
+ m_valuemapStack[i][args[0]] = m_valuemap[args[0]];
+ m_filevaluemapStack[i][currentProFile()][args[0]] =
+ m_filevaluemap[currentProFile()][args[0]];
+ }
+ return ProItem::ReturnTrue;
#if 0
case T_INFILE:
case T_REQUIRES:
- case T_GREATERTHAN:
- case T_LESSTHAN:
- case T_EQUALS:
- case T_EXPORT:
- case T_CLEAR:
- case T_UNSET:
case T_EVAL:
- case T_IF:
- case T_RETURN:
+#endif
+ case T_FOR: {
+ if (m_cumulative) // This is a no-win situation, so just pretend it's no loop
+ return ProItem::ReturnTrue;
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (args.count() > 2 || args.count() < 1) {
+ q->logMessage(format("for({var, list|var, forever|ever})"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ ProLoop loop;
+ loop.infinite = false;
+ loop.index = 0;
+ QString it_list;
+ if (args.count() == 1) {
+ doVariableReplace(&args[0]);
+ it_list = args[0];
+ if (args[0] != QLatin1String("ever")) {
+ q->logMessage(format("for({var, list|var, forever|ever})"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ it_list = QLatin1String("forever");
+ } else {
+ loop.variable = args[0];
+ loop.oldVarVal = m_valuemap.value(loop.variable);
+ doVariableReplace(&args[1]);
+ it_list = args[1];
+ }
+ loop.list = m_valuemap[it_list];
+ if (loop.list.isEmpty()) {
+ if (it_list == QLatin1String("forever")) {
+ loop.infinite = true;
+ } else {
+ int dotdot = it_list.indexOf(QLatin1String(".."));
+ if (dotdot != -1) {
+ bool ok;
+ int start = it_list.left(dotdot).toInt(&ok);
+ if (ok) {
+ int end = it_list.mid(dotdot+2).toInt(&ok);
+ if (ok) {
+ if (start < end) {
+ for (int i = start; i <= end; i++)
+ loop.list << QString::number(i);
+ } else {
+ for (int i = start; i >= end; i--)
+ loop.list << QString::number(i);
+ }
+ }
+ }
+ }
+ }
+ }
+ m_loopStack.push(loop);
+ m_sts.condition = true;
+ return ProItem::ReturnLoop;
+ }
case T_BREAK:
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (!m_loopStack.isEmpty())
+ return ProItem::ReturnBreak;
+ // ### missing: breaking out of multiline blocks
+ q->logMessage(format("unexpected break()."));
+ return ProItem::ReturnFalse;
case T_NEXT:
- case T_DEFINED:
-#endif
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (!m_loopStack.isEmpty())
+ return ProItem::ReturnNext;
+ q->logMessage(format("unexpected next()."));
+ return ProItem::ReturnFalse;
+ case T_IF: {
+ if (args.count() != 1) {
+ q->logMessage(format("if(condition) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ QString cond = args.first();
+ bool escaped = false; // This is more than qmake does
+ bool quoted = false;
+ bool ret = true;
+ bool orOp = false;
+ bool invert = false;
+ bool isFunc = false;
+ int parens = 0;
+ QString test;
+ test.reserve(20);
+ QString args;
+ args.reserve(50);
+ const QChar *d = cond.unicode();
+ const QChar *ed = d + cond.length();
+ while (d < ed) {
+ ushort c = (d++)->unicode();
+ if (!escaped) {
+ if (c == '\\') {
+ escaped = true;
+ args += c; // Assume no-one quotes the test name
+ continue;
+ } else if (c == '"') {
+ quoted = !quoted;
+ args += c; // Ditto
+ continue;
+ }
+ } else {
+ escaped = false;
+ }
+ if (quoted) {
+ args += c; // Ditto
+ } else {
+ bool isOp = false;
+ if (c == '(') {
+ isFunc = true;
+ if (parens)
+ args += c;
+ ++parens;
+ } else if (c == ')') {
+ --parens;
+ if (parens)
+ args += c;
+ } else if (!parens) {
+ if (c == ':' || c == '|')
+ isOp = true;
+ else if (c == '!')
+ invert = true;
+ else
+ test += c;
+ } else {
+ args += c;
+ }
+ if (!parens && (isOp || d == ed)) {
+ // Yes, qmake doesn't shortcut evaluations here. We can't, either,
+ // as some test functions have side effects.
+ bool success;
+ if (isFunc) {
+ success = evaluateConditionalFunction(test, args);
+ } else {
+ success = isActiveConfig(test, true);
+ }
+ success ^= invert;
+ if (orOp)
+ ret |= success;
+ else
+ ret &= success;
+ orOp = (c == '|');
+ invert = false;
+ isFunc = false;
+ test.clear();
+ args.clear();
+ }
+ }
+ }
+ return returnBool(ret);
+ }
case T_CONFIG: {
if (args.count() < 1 || args.count() > 2) {
q->logMessage(format("CONFIG(config) requires one or two arguments."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
if (args.count() == 1) {
//cond = isActiveConfig(args.first()); XXX
- break;
+ return ProItem::ReturnFalse;
}
const QStringList mutuals = args[1].split(QLatin1Char('|'));
const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
for (int i = configs.size() - 1; i >= 0; i--) {
for (int mut = 0; mut < mutuals.count(); mut++) {
if (configs[i] == mutuals[mut].trimmed()) {
- cond = (configs[i] == args[0]);
- goto done_T_CONFIG;
+ return returnBool(configs[i] == args[0]);
}
}
}
- done_T_CONFIG:
- break;
+ return ProItem::ReturnFalse;
}
case T_CONTAINS: {
if (args.count() < 2 || args.count() > 3) {
q->logMessage(format("contains(var, val) requires two or three arguments."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
QRegExp regx(args[1]);
@@ -1739,8 +2049,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
for (int i = 0; i < l.size(); ++i) {
const QString val = l[i];
if (regx.exactMatch(val) || val == args[1]) {
- cond = true;
- break;
+ return ProItem::ReturnTrue;
}
}
} else {
@@ -1749,140 +2058,172 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
const QString val = l[i];
for (int mut = 0; mut < mutuals.count(); mut++) {
if (val == mutuals[mut].trimmed()) {
- cond = (regx.exactMatch(val) || val == args[1]);
- goto done_T_CONTAINS;
+ return returnBool(regx.exactMatch(val) || val == args[1]);
}
}
}
}
- done_T_CONTAINS:
- break;
+ return ProItem::ReturnFalse;
}
case T_COUNT: {
if (args.count() != 2 && args.count() != 3) {
q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
if (args.count() == 3) {
QString comp = args[2];
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
- cond = values(args.first()).count() > args[1].toInt();
+ return returnBool(values(args.first()).count() > args[1].toInt());
} else if (comp == QLatin1String(">=")) {
- cond = values(args.first()).count() >= args[1].toInt();
+ return returnBool(values(args.first()).count() >= args[1].toInt());
} else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
- cond = values(args.first()).count() < args[1].toInt();
+ return returnBool(values(args.first()).count() < args[1].toInt());
} else if (comp == QLatin1String("<=")) {
- cond = values(args.first()).count() <= args[1].toInt();
- } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual") || comp == QLatin1String("=") || comp == QLatin1String("==")) {
- cond = values(args.first()).count() == args[1].toInt();
+ return returnBool(values(args.first()).count() <= args[1].toInt());
+ } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
+ || comp == QLatin1String("=") || comp == QLatin1String("==")) {
+ return returnBool(values(args.first()).count() == args[1].toInt());
} else {
- ok = false;
q->logMessage(format("unexpected modifier to count(%2)").arg(comp));
+ return ProItem::ReturnFalse;
}
- break;
}
- cond = values(args.first()).count() == args[1].toInt();
- break;
+ return returnBool(values(args.first()).count() == args[1].toInt());
+ }
+ case T_GREATERTHAN:
+ case T_LESSTHAN: {
+ if (args.count() != 2) {
+ q->logMessage(format("%1(variable, value) requires two arguments.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QString rhs(args[1]), lhs(values(args[0]).join(QString(Option::field_sep)));
+ bool ok;
+ int rhs_int = rhs.toInt(&ok);
+ if (ok) { // do integer compare
+ int lhs_int = lhs.toInt(&ok);
+ if (ok) {
+ if (func_t == T_GREATERTHAN)
+ return returnBool(lhs_int > rhs_int);
+ return returnBool(lhs_int < rhs_int);
+ }
+ }
+ if (func_t == T_GREATERTHAN)
+ return returnBool(lhs > rhs);
+ return returnBool(lhs < rhs);
+ }
+ case T_EQUALS:
+ if (args.count() != 2) {
+ q->logMessage(format("%1(variable, value) requires two arguments.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ return returnBool(values(args[0]).join(QString(Option::field_sep)) == args[1]);
+ case T_CLEAR: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ if (args.count() != 1) {
+ q->logMessage(format("%1(variable) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
+ if (it == m_valuemap.end())
+ return ProItem::ReturnFalse;
+ it->clear();
+ return ProItem::ReturnTrue;
+ }
+ case T_UNSET: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ if (args.count() != 1) {
+ q->logMessage(format("%1(variable) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
+ if (it == m_valuemap.end())
+ return ProItem::ReturnFalse;
+ m_valuemap.erase(it);
+ return ProItem::ReturnTrue;
}
case T_INCLUDE: {
if (m_skipLevel && !m_cumulative)
- break;
+ return ProItem::ReturnFalse;
QString parseInto;
if (args.count() == 2) {
parseInto = args[1];
} else if (args.count() != 1) {
q->logMessage(format("include(file) requires one or two arguments."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
QString fileName = args.first();
// ### this breaks if we have include(c:/reallystupid.pri) but IMHO that's really bad style.
QDir currentProPath(currentDirectory());
fileName = QDir::cleanPath(currentProPath.absoluteFilePath(fileName));
- ok = evaluateFile(fileName, &ok);
- break;
+ State sts = m_sts;
+ bool ok = evaluateFile(fileName);
+ m_sts = sts;
+ return returnBool(ok);
}
case T_LOAD: {
if (m_skipLevel && !m_cumulative)
- break;
+ return ProItem::ReturnFalse;
QString parseInto;
bool ignore_error = false;
if (args.count() == 2) {
QString sarg = args[1];
- ignore_error = (sarg.toLower() == QLatin1String("true") || sarg.toInt());
+ ignore_error = (!sarg.compare(QLatin1String("true"), Qt::CaseInsensitive) || sarg.toInt());
} else if (args.count() != 1) {
q->logMessage(format("load(feature) requires one or two arguments."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
- ok = evaluateFeatureFile( args.first(), &cond);
- break;
+ // XXX ignore_error unused
+ return returnBool(evaluateFeatureFile(args.first()));
}
case T_DEBUG:
// Yup - do nothing. Nothing is going to enable debug output anyway.
- break;
+ return ProItem::ReturnFalse;
case T_MESSAGE: {
if (args.count() != 1) {
q->logMessage(format("%1(message) requires one argument.").arg(function));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
QString msg = fixEnvVariables(args.first());
- if (function == QLatin1String("error")) {
- QStringList parents;
- foreach (ProFile *proFile, m_profileStack)
- parents.append(proFile->fileName());
- if (!parents.isEmpty())
- parents.takeLast();
- if (parents.isEmpty())
- q->fileMessage(format("Project ERROR: %1").arg(msg));
- else
- q->fileMessage(format("Project ERROR: %1. File was included from: '%2'")
- .arg(msg).arg(parents.join(QLatin1String("', '"))));
- } else {
- q->fileMessage(format("Project MESSAGE: %1").arg(msg));
- }
- break;
+ q->fileMessage(QString::fromLatin1("Project %1: %2").arg(function.toUpper(), msg));
+ // ### Consider real termination in non-cumulative mode
+ return returnBool(function != QLatin1String("error"));
}
#if 0 // Way too dangerous to enable.
case T_SYSTEM: {
if (args.count() != 1) {
q->logMessage(format("system(exec) requires one argument."));
- ok = false;
- break;
+ ProItem::ReturnFalse;
}
- ok = system(args.first().toLatin1().constData()) == 0;
- break;
+ return returnBool(system(args.first().toLatin1().constData()) == 0);
}
#endif
case T_ISEMPTY: {
if (args.count() != 1) {
q->logMessage(format("isEmpty(var) requires one argument."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
QStringList sl = values(args.first());
if (sl.count() == 0) {
- cond = true;
+ return ProItem::ReturnTrue;
} else if (sl.count() > 0) {
QString var = sl.first();
- cond = (var.isEmpty());
+ if (var.isEmpty())
+ return ProItem::ReturnTrue;
}
- break;
+ return ProItem::ReturnFalse;
}
case T_EXISTS: {
if (args.count() != 1) {
q->logMessage(format("exists(file) requires one argument."));
- ok = false;
- break;
+ return ProItem::ReturnFalse;
}
QString file = args.first();
file = Option::fixPathToLocalOS(file);
if (QFile::exists(file)) {
- cond = true;
- break;
+ return ProItem::ReturnTrue;
}
//regular expression I guess
QString dirstr = currentDirectory();
@@ -1892,23 +2233,18 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
file = file.right(file.length() - slsh - 1);
}
if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
- cond = QDir(dirstr).entryList(QStringList(file)).count();
+ if (!QDir(dirstr).entryList(QStringList(file)).isEmpty())
+ return ProItem::ReturnTrue;
- break;
+ return ProItem::ReturnFalse;
}
case 0:
- // This is too chatty currently (missing defineTest and defineReplace)
- //q->logMessage(format("'%1' is not a recognized test function").arg(function));
- break;
+ q->logMessage(format("'%1' is not a recognized test function").arg(function));
+ return ProItem::ReturnFalse;
default:
q->logMessage(format("Function '%1' is not implemented").arg(function));
- break;
+ return ProItem::ReturnFalse;
}
-
- if (result)
- *result = cond;
-
- return ok;
}
QStringList ProFileEvaluator::Private::values(const QString &variableName,
@@ -1949,9 +2285,9 @@ QStringList ProFileEvaluator::Private::values(const QString &variableName,
ret = QLatin1String("Windows");
} else if (type == QLatin1String("name")) {
DWORD name_length = 1024;
- TCHAR name[1024];
+ wchar_t name[1024];
if (GetComputerName(name, &name_length))
- ret = QString::fromUtf16((ushort*)name, name_length);
+ ret = QString::fromWCharArray(name);
} else if (type == QLatin1String("version") || type == QLatin1String("version_string")) {
QSysInfo::WinVersion ver = QSysInfo::WindowsVersion;
if (type == QLatin1String("version"))
@@ -2061,37 +2397,21 @@ void ProFileEvaluator::releaseParsedProFile(ProFile *proFile)
delete proFile;
}
-bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *result)
+bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
{
- bool ok = true;
ProFile *pro = q->parsedProFile(fileName);
if (pro) {
m_profileStack.push(pro);
- ok = (currentProFile() ? pro->Accept(this) : false);
+ bool ok = (pro->Accept(this) == ProItem::ReturnTrue);
m_profileStack.pop();
q->releaseParsedProFile(pro);
-
- if (result)
- *result = true;
+ return ok;
} else {
- if (result)
- *result = false;
+ return false;
}
-/* if (ok && readFeatures) {
- QStringList configs = values("CONFIG");
- QSet<QString> processed;
- foreach (const QString &fn, configs) {
- if (!processed.contains(fn)) {
- processed.insert(fn);
- evaluateFeatureFile(fn, 0);
- }
- }
- } */
-
- return ok;
}
-bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, bool *result)
+bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName)
{
QString fn;
foreach (const QString &path, qmakeFeaturePaths()) {
@@ -2110,87 +2430,11 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, boo
return false;
bool cumulative = m_cumulative;
m_cumulative = false;
- bool ok = evaluateFile(fn, result);
+ bool ok = evaluateFile(fn);
m_cumulative = cumulative;
return ok;
}
-void ProFileEvaluator::Private::expandPatternHelper(const QString &relName, const QString &absName,
- QStringList &sources_out)
-{
- const QStringList vpaths = values(QLatin1String("VPATH"))
- + values(QLatin1String("QMAKE_ABSOLUTE_SOURCE_PATH"))
- + values(QLatin1String("DEPENDPATH"))
- + values(QLatin1String("VPATH_SOURCES"));
-
- QFileInfo fi(absName);
- bool found = fi.exists();
- // Search in all vpaths
- if (!found) {
- foreach (const QString &vpath, vpaths) {
- fi.setFile(vpath + QDir::separator() + relName);
- if (fi.exists()) {
- found = true;
- break;
- }
- }
- }
-
- if (found) {
- sources_out += fi.absoluteFilePath(); // Not resolving symlinks
- } else {
- QString val = relName;
- QString dir;
- QString wildcard = val;
- QString real_dir;
- if (wildcard.lastIndexOf(QLatin1Char('/')) != -1) {
- dir = wildcard.left(wildcard.lastIndexOf(QLatin1Char('/')) + 1);
- real_dir = dir;
- wildcard = wildcard.right(wildcard.length() - dir.length());
- }
-
- if (real_dir.isEmpty() || QFileInfo(real_dir).exists()) {
- QStringList files = QDir(real_dir).entryList(QStringList(wildcard));
- if (files.isEmpty()) {
- q->logMessage(format("Failure to find %1").arg(val));
- } else {
- QString a;
- for (int i = files.count() - 1; i >= 0; --i) {
- if (files[i] == QLatin1String(".") || files[i] == QLatin1String(".."))
- continue;
- a = dir + files[i];
- sources_out += a;
- }
- }
- } else {
- q->logMessage(format("Cannot match %1/%2, as %3 does not exist.")
- .arg(real_dir).arg(wildcard).arg(real_dir));
- }
- }
-}
-
-
-/*
- * Lookup of files are done in this order:
- * 1. look in pwd
- * 2. look in vpaths
- * 3. expand wild card files relative from the profiles folder
- **/
-
-// FIXME: This code supports something that I'd consider a flaw in .pro file syntax
-// which is not even documented. So arguably this can be ditched completely...
-QStringList ProFileEvaluator::Private::expandPattern(const QString& pattern)
-{
- if (!currentProFile())
- return QStringList();
-
- QStringList sources_out;
- const QString absName = QDir::cleanPath(QDir::current().absoluteFilePath(pattern));
-
- expandPatternHelper(pattern, absName, sources_out);
- return sources_out;
-}
-
QString ProFileEvaluator::Private::format(const char *fmt) const
{
ProFile *pro = currentProFile();
@@ -2241,18 +2485,71 @@ QStringList ProFileEvaluator::values(const QString &variableName, const ProFile
return fixEnvVariables(d->values(variableName, pro));
}
+QStringList ProFileEvaluator::absolutePathValues(
+ const QString &variable, const QString &baseDirectory) const
+{
+ QStringList result;
+ foreach (const QString &el, values(variable)) {
+ const QFileInfo info = QFileInfo(baseDirectory, el);
+ if (info.isDir())
+ result << QDir::cleanPath(info.absoluteFilePath());
+ }
+ return result;
+}
+
+QStringList ProFileEvaluator::absoluteFileValues(
+ const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
+ const ProFile *pro) const
+{
+ QStringList result;
+ foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
+ QFileInfo info(el);
+ if (info.isAbsolute()) {
+ if (info.exists()) {
+ result << QDir::cleanPath(el);
+ goto next;
+ }
+ } else {
+ foreach (const QString &dir, searchDirs) {
+ QFileInfo info(dir, el);
+ if (info.isFile()) {
+ result << QDir::cleanPath(info.filePath());
+ goto next;
+ }
+ }
+ if (baseDirectory.isEmpty())
+ goto next;
+ info = QFileInfo(baseDirectory, el);
+ }
+ {
+ QFileInfo baseInfo(info.absolutePath());
+ if (baseInfo.exists()) {
+ QString wildcard = info.fileName();
+ if (wildcard.contains(QLatin1Char('*')) || wildcard.contains(QLatin1Char('?'))) {
+ QDir theDir(QDir::cleanPath(baseInfo.filePath()));
+ foreach (const QString &fn, theDir.entryList(QStringList(wildcard)))
+ if (fn != QLatin1String(".") && fn != QLatin1String(".."))
+ result << theDir.absoluteFilePath(fn);
+ }
+ }
+ }
+ next: ;
+ }
+ return result;
+}
+
ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
{
QStringList templ = values(QLatin1String("TEMPLATE"));
if (templ.count() >= 1) {
- QString t = templ.last().toLower();
- if (t == QLatin1String("app"))
+ const QString &t = templ.last();
+ if (!t.compare(QLatin1String("app"), Qt::CaseInsensitive))
return TT_Application;
- if (t == QLatin1String("lib"))
+ if (!t.compare(QLatin1String("lib"), Qt::CaseInsensitive))
return TT_Library;
- if (t == QLatin1String("script"))
+ if (!t.compare(QLatin1String("script"), Qt::CaseInsensitive))
return TT_Script;
- if (t == QLatin1String("subdirs"))
+ if (!t.compare(QLatin1String("subdirs"), Qt::CaseInsensitive))
return TT_Subdirs;
}
return TT_Unknown;
@@ -2327,64 +2624,4 @@ void ProFileEvaluator::setOutputDir(const QString &dir)
d->m_outputDir = dir;
}
-void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap)
-{
- QStringList sourceFiles;
- QString codecForTr;
- QString codecForSource;
- QStringList tsFileNames;
-
- // app/lib template
- sourceFiles += visitor.values(QLatin1String("SOURCES"));
- sourceFiles += visitor.values(QLatin1String("HEADERS"));
- tsFileNames = visitor.values(QLatin1String("TRANSLATIONS"));
-
- QStringList trcodec = visitor.values(QLatin1String("CODEC"))
- + visitor.values(QLatin1String("DEFAULTCODEC"))
- + visitor.values(QLatin1String("CODECFORTR"));
- if (!trcodec.isEmpty())
- codecForTr = trcodec.last();
-
- QStringList srccodec = visitor.values(QLatin1String("CODECFORSRC"));
- if (!srccodec.isEmpty())
- codecForSource = srccodec.last();
-
- QStringList forms = visitor.values(QLatin1String("INTERFACES"))
- + visitor.values(QLatin1String("FORMS"))
- + visitor.values(QLatin1String("FORMS3"));
- sourceFiles << forms;
-
- sourceFiles.sort();
- sourceFiles.removeDuplicates();
- tsFileNames.sort();
- tsFileNames.removeDuplicates();
-
- varMap->insert("SOURCES", sourceFiles);
- varMap->insert("CODECFORTR", QStringList() << codecForTr);
- varMap->insert("CODECFORSRC", QStringList() << codecForSource);
- varMap->insert("TRANSLATIONS", tsFileNames);
-}
-
-bool evaluateProFile(const QString &fileName, bool verbose, QHash<QByteArray, QStringList> *varMap)
-{
- QFileInfo fi(fileName);
- if (!fi.exists())
- return false;
-
- ProFile pro(fi.absoluteFilePath());
-
- ProFileEvaluator visitor;
- visitor.setVerbose(verbose);
-
- if (!visitor.queryProFile(&pro))
- return false;
-
- if (!visitor.accept(&pro))
- return false;
-
- evaluateProFile(visitor, varMap);
-
- return true;
-}
-
QT_END_NAMESPACE
diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h
index 69f47f5..f3498c1 100644
--- a/tools/linguist/shared/profileevaluator.h
+++ b/tools/linguist/shared/profileevaluator.h
@@ -52,12 +52,6 @@
QT_BEGIN_NAMESPACE
-class ProFile;
-class ProFileEvaluator;
-
-void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap);
-bool evaluateProFile(const QString &fileName, bool verbose, QHash<QByteArray, QStringList> *varMap);
-
class ProFileEvaluator
{
public:
@@ -85,6 +79,10 @@ public:
void addProperties(const QHash<QString, QString> &properties);
QStringList values(const QString &variableName) const;
QStringList values(const QString &variableName, const ProFile *pro) const;
+ QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const;
+ QStringList absoluteFileValues(
+ const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
+ const ProFile *pro) const;
QString propertyValue(const QString &val) const;
// for our descendents
@@ -97,6 +95,9 @@ public:
private:
class Private;
Private *d;
+
+ // This doesn't help gcc 3.3 and sunpro ...
+ template<typename T> friend class QTypeInfo;
};
QT_END_NAMESPACE
diff --git a/tools/linguist/shared/proitems.cpp b/tools/linguist/shared/proitems.cpp
index 471417e..905c67e 100644
--- a/tools/linguist/shared/proitems.cpp
+++ b/tools/linguist/shared/proitems.cpp
@@ -58,15 +58,21 @@ QString ProItem::comment() const
}
// --------------- ProBlock ----------------
+
ProBlock::ProBlock(ProBlock *parent)
{
m_blockKind = 0;
m_parent = parent;
+ m_refCount = 1;
}
ProBlock::~ProBlock()
{
- qDeleteAll(m_proitems);
+ foreach (ProItem *itm, m_proitems)
+ if (itm->kind() == BlockKind)
+ static_cast<ProBlock *>(itm)->deref();
+ else
+ delete itm;
}
void ProBlock::appendItem(ProItem *proitem)
@@ -109,14 +115,37 @@ ProItem::ProItemKind ProBlock::kind() const
return ProItem::BlockKind;
}
-bool ProBlock::Accept(AbstractProItemVisitor *visitor)
-{
- visitor->visitBeginProBlock(this);
- foreach (ProItem *item, m_proitems) {
- if (!item->Accept(visitor))
- return false;
+ProItem::ProItemReturn ProBlock::Accept(AbstractProItemVisitor *visitor)
+{
+ if (visitor->visitBeginProBlock(this) == ReturnSkip)
+ return ReturnTrue;
+ ProItemReturn rt = ReturnTrue;
+ for (int i = 0; i < m_proitems.count(); ++i) {
+ rt = m_proitems.at(i)->Accept(visitor);
+ if (rt != ReturnTrue && rt != ReturnFalse) {
+ if (rt == ReturnLoop) {
+ rt = ReturnTrue;
+ while (visitor->visitProLoopIteration())
+ for (int j = i; ++j < m_proitems.count(); ) {
+ rt = m_proitems.at(j)->Accept(visitor);
+ if (rt != ReturnTrue && rt != ReturnFalse) {
+ if (rt == ReturnNext) {
+ rt = ReturnTrue;
+ break;
+ }
+ if (rt == ReturnBreak)
+ rt = ReturnTrue;
+ goto do_break;
+ }
+ }
+ do_break:
+ visitor->visitProLoopCleanup();
+ }
+ break;
+ }
}
- return visitor->visitEndProBlock(this);
+ visitor->visitEndProBlock(this);
+ return rt;
}
// --------------- ProVariable ----------------
@@ -148,14 +177,13 @@ QString ProVariable::variable() const
return m_variable;
}
-bool ProVariable::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProVariable::Accept(AbstractProItemVisitor *visitor)
{
visitor->visitBeginProVariable(this);
- foreach (ProItem *item, m_proitems) {
- if (!item->Accept(visitor))
- return false;
- }
- return visitor->visitEndProVariable(this);
+ foreach (ProItem *item, m_proitems)
+ item->Accept(visitor); // cannot fail
+ visitor->visitEndProVariable(this);
+ return ReturnTrue;
}
// --------------- ProValue ----------------
@@ -190,9 +218,10 @@ ProItem::ProItemKind ProValue::kind() const
return ProItem::ValueKind;
}
-bool ProValue::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProValue::Accept(AbstractProItemVisitor *visitor)
{
- return visitor->visitProValue(this);
+ visitor->visitProValue(this);
+ return ReturnTrue;
}
// --------------- ProFunction ----------------
@@ -216,7 +245,7 @@ ProItem::ProItemKind ProFunction::kind() const
return ProItem::FunctionKind;
}
-bool ProFunction::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProFunction::Accept(AbstractProItemVisitor *visitor)
{
return visitor->visitProFunction(this);
}
@@ -242,9 +271,10 @@ ProItem::ProItemKind ProCondition::kind() const
return ProItem::ConditionKind;
}
-bool ProCondition::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProCondition::Accept(AbstractProItemVisitor *visitor)
{
- return visitor->visitProCondition(this);
+ visitor->visitProCondition(this);
+ return ReturnTrue;
}
// --------------- ProOperator ----------------
@@ -268,9 +298,10 @@ ProItem::ProItemKind ProOperator::kind() const
return ProItem::OperatorKind;
}
-bool ProOperator::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProOperator::Accept(AbstractProItemVisitor *visitor)
{
- return visitor->visitProOperator(this);
+ visitor->visitProOperator(this);
+ return ReturnTrue;
}
// --------------- ProFile ----------------
@@ -315,13 +346,12 @@ bool ProFile::isModified() const
return m_modified;
}
-bool ProFile::Accept(AbstractProItemVisitor *visitor)
+ProItem::ProItemReturn ProFile::Accept(AbstractProItemVisitor *visitor)
{
- visitor->visitBeginProFile(this);
- foreach (ProItem *item, m_proitems) {
- if (!item->Accept(visitor))
- return false;
- }
+ ProItemReturn rt;
+ if ((rt = visitor->visitBeginProFile(this)) != ReturnTrue)
+ return rt;
+ ProBlock::Accept(visitor); // cannot fail
return visitor->visitEndProFile(this);
}
diff --git a/tools/linguist/shared/proitems.h b/tools/linguist/shared/proitems.h
index aad0ba2..7833be1 100644
--- a/tools/linguist/shared/proitems.h
+++ b/tools/linguist/shared/proitems.h
@@ -60,6 +60,16 @@ public:
BlockKind
};
+ enum ProItemReturn {
+ ReturnFalse,
+ ReturnTrue,
+ ReturnBreak,
+ ReturnNext,
+ ReturnLoop,
+ ReturnSkip,
+ ReturnReturn
+ };
+
ProItem() : m_lineNumber(0) {}
virtual ~ProItem() {}
@@ -68,7 +78,7 @@ public:
void setComment(const QString &comment);
QString comment() const;
- virtual bool Accept(AbstractProItemVisitor *visitor) = 0;
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor) = 0;
int lineNumber() const { return m_lineNumber; }
void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
@@ -86,7 +96,8 @@ public:
ScopeContentsKind = 0x02,
VariableKind = 0x04,
ProFileKind = 0x08,
- SingleLine = 0x10
+ FunctionBodyKind = 0x10,
+ SingleLine = 0x80
};
ProBlock(ProBlock *parent);
@@ -102,14 +113,18 @@ public:
void setParent(ProBlock *parent);
ProBlock *parent() const;
+ void ref() { ++m_refCount; }
+ void deref() { if (!--m_refCount) delete this; }
+
ProItem::ProItemKind kind() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
protected:
QList<ProItem *> m_proitems;
private:
ProBlock *m_parent;
int m_blockKind;
+ int m_refCount;
};
class ProVariable : public ProBlock
@@ -131,7 +146,7 @@ public:
void setVariable(const QString &name);
QString variable() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
VariableOperator m_variableKind;
QString m_variable;
@@ -150,7 +165,7 @@ public:
ProItem::ProItemKind kind() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
QString m_value;
ProVariable *m_variable;
@@ -166,7 +181,7 @@ public:
ProItem::ProItemKind kind() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
QString m_text;
};
@@ -181,7 +196,7 @@ public:
ProItem::ProItemKind kind() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
QString m_text;
};
@@ -201,7 +216,7 @@ public:
ProItem::ProItemKind kind() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
OperatorKind m_operatorKind;
};
@@ -219,7 +234,7 @@ public:
void setModified(bool modified);
bool isModified() const;
- virtual bool Accept(AbstractProItemVisitor *visitor);
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
private:
QString m_fileName;
diff --git a/tools/linguist/shared/proparser.pri b/tools/linguist/shared/proparser.pri
index 372247e..99d32e7 100644
--- a/tools/linguist/shared/proparser.pri
+++ b/tools/linguist/shared/proparser.pri
@@ -2,11 +2,13 @@
INCLUDEPATH *= $$PWD
HEADERS += \
+ $$PWD/proreader.h \
$$PWD/abstractproitemvisitor.h \
$$PWD/proitems.h \
$$PWD/profileevaluator.h \
$$PWD/proparserutils.h
SOURCES += \
+ $$PWD/proreader.cpp \
$$PWD/proitems.cpp \
$$PWD/profileevaluator.cpp
diff --git a/tools/linguist/shared/proreader.cpp b/tools/linguist/shared/proreader.cpp
new file mode 100644
index 0000000..3400f20
--- /dev/null
+++ b/tools/linguist/shared/proreader.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "profileevaluator.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths,
+ const QString &projectDir, const ProFileEvaluator &visitor)
+{
+ QStringList vPaths =
+ visitor.absolutePathValues(QLatin1String(vvar), projectDir);
+ vPaths += baseVPaths;
+ vPaths.removeDuplicates();
+ return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0);
+}
+
+void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap,
+ const QString &projectDir)
+{
+ QStringList baseVPaths;
+ baseVPaths += visitor.absolutePathValues(QLatin1String("VPATH"), projectDir);
+ baseVPaths << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH
+ baseVPaths += visitor.absolutePathValues(QLatin1String("DEPENDPATH"), projectDir);
+ baseVPaths.removeDuplicates();
+
+ QStringList sourceFiles;
+ QString codecForTr;
+ QString codecForSource;
+ QStringList tsFileNames;
+
+ // app/lib template
+ sourceFiles += getSources("SOURCES", "VPATH_SOURCES", baseVPaths, projectDir, visitor);
+
+ sourceFiles += getSources("FORMS", "VPATH_FORMS", baseVPaths, projectDir, visitor);
+ sourceFiles += getSources("FORMS3", "VPATH_FORMS3", baseVPaths, projectDir, visitor);
+
+ QStringList vPathsInc = baseVPaths;
+ vPathsInc += visitor.absolutePathValues(QLatin1String("INCLUDEPATH"), projectDir);
+ vPathsInc.removeDuplicates();
+ sourceFiles += visitor.absoluteFileValues(QLatin1String("HEADERS"), projectDir, vPathsInc, 0);
+
+ QDir proDir(projectDir);
+ foreach (const QString &tsFile, visitor.values(QLatin1String("TRANSLATIONS")))
+ tsFileNames << QFileInfo(proDir, tsFile).filePath();
+
+ QStringList trcodec = visitor.values(QLatin1String("CODEC"))
+ + visitor.values(QLatin1String("DEFAULTCODEC"))
+ + visitor.values(QLatin1String("CODECFORTR"));
+ if (!trcodec.isEmpty())
+ codecForTr = trcodec.last();
+
+ QStringList srccodec = visitor.values(QLatin1String("CODECFORSRC"));
+ if (!srccodec.isEmpty())
+ codecForSource = srccodec.last();
+
+ sourceFiles.sort();
+ sourceFiles.removeDuplicates();
+ tsFileNames.sort();
+ tsFileNames.removeDuplicates();
+
+ varMap->insert("SOURCES", sourceFiles);
+ varMap->insert("CODECFORTR", QStringList() << codecForTr);
+ varMap->insert("CODECFORSRC", QStringList() << codecForSource);
+ varMap->insert("TRANSLATIONS", tsFileNames);
+}
+
+bool evaluateProFile(const QString &fileName, bool verbose, QHash<QByteArray, QStringList> *varMap)
+{
+ QFileInfo fi(fileName);
+ if (!fi.exists())
+ return false;
+
+ ProFile pro(fi.absoluteFilePath());
+
+ ProFileEvaluator visitor;
+ visitor.setVerbose(verbose);
+
+ if (!visitor.queryProFile(&pro))
+ return false;
+
+ if (!visitor.accept(&pro))
+ return false;
+
+ evaluateProFile(visitor, varMap, fi.absolutePath());
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/linguist/shared/proreader.h b/tools/linguist/shared/proreader.h
new file mode 100644
index 0000000..f663e23
--- /dev/null
+++ b/tools/linguist/shared/proreader.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROREADER_H
+#define PROREADER_H
+
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class ProFileEvaluator;
+
+void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap,
+ const QString &projectDir);
+bool evaluateProFile(const QString &fileName, bool verbose, QHash<QByteArray, QStringList> *varMap);
+
+QT_END_NAMESPACE
+
+#endif // PROREADER_H
diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp
index ec61cb6..638e997 100644
--- a/tools/linguist/shared/qm.cpp
+++ b/tools/linguist/shared/qm.cpp
@@ -173,6 +173,7 @@ public:
bool save(QIODevice *iod);
void insert(const TranslatorMessage &msg, bool forceComment);
+ void insertIdBased(const TranslatorMessage &message);
void squeeze(TranslatorSaveMode mode);
@@ -244,7 +245,7 @@ void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &strea
if (mode == SaveEverything)
prefix = HashContextSourceTextComment;
- // lrelease produces "wrong" .qm files for QByteArrays that are .isNull().
+ // lrelease produces "wrong" QM files for QByteArrays that are .isNull().
switch (prefix) {
default:
case HashContextSourceTextComment:
@@ -436,6 +437,16 @@ void Releaser::insert(const TranslatorMessage &message, bool forceComment)
insertInternal(message, forceComment, false);
}
+void Releaser::insertIdBased(const TranslatorMessage &message)
+{
+ QStringList tlns = message.translations();
+ for (int i = 0; i < tlns.size(); ++i)
+ if (tlns.at(i).isEmpty())
+ tlns[i] = message.sourceText();
+ ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns);
+ m_messages.insert(bmsg, 0);
+}
+
void Releaser::setNumerusRules(const QByteArray &rules)
{
m_numerusRules = rules;
@@ -541,7 +552,8 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
size_t numItems = offsetLength / (2 * sizeof(quint32));
//qDebug() << "NUMITEMS: " << numItems;
- QTextCodec *codec = QTextCodec::codecForName(cd.m_codecForSource);
+ QTextCodec *codec = QTextCodec::codecForName(
+ cd.m_codecForSource.isEmpty() ? "Latin1" : cd.m_codecForSource);
QTextCodec *utf8Codec = 0;
if (codec->name() != "UTF-8")
utf8Codec = QTextCodec::codecForName("UTF-8");
@@ -689,11 +701,17 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
int finished = 0;
int unfinished = 0;
int untranslated = 0;
+ int missingIds = 0;
+ int droppedData = 0;
for (int i = 0; i != translator.messageCount(); ++i) {
const TranslatorMessage &msg = translator.message(i);
TranslatorMessage::Type typ = msg.type();
if (typ != TranslatorMessage::Obsolete) {
+ if (cd.m_idBased && msg.id().isEmpty()) {
+ ++missingIds;
+ continue;
+ }
if (typ == TranslatorMessage::Unfinished) {
if (msg.translation().isEmpty()) {
++untranslated;
@@ -706,19 +724,34 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
} else {
++finished;
}
- // Drop the comment in (context, sourceText, comment),
- // unless the context is empty,
- // unless (context, sourceText, "") already exists or
- // unless we already dropped the comment of (context,
- // sourceText, comment0).
- bool forceComment =
- msg.comment().isEmpty()
- || msg.context().isEmpty()
- || translator.contains(msg.context(), msg.sourceText(), QString());
- releaser.insert(msg, forceComment);
+ if (cd.m_idBased) {
+ if (!msg.context().isEmpty() || !msg.comment().isEmpty())
+ ++droppedData;
+ releaser.insertIdBased(msg);
+ } else {
+ // Drop the comment in (context, sourceText, comment),
+ // unless the context is empty,
+ // unless (context, sourceText, "") already exists or
+ // unless we already dropped the comment of (context,
+ // sourceText, comment0).
+ bool forceComment =
+ msg.comment().isEmpty()
+ || msg.context().isEmpty()
+ || translator.contains(msg.context(), msg.sourceText(), QString());
+ releaser.insert(msg, forceComment);
+ }
}
}
+ if (missingIds)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Dropped %n message(s) which had no ID.", 0,
+ QCoreApplication::CodecForTr, missingIds));
+ if (droppedData)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Excess context/disambiguation dropped from %n message(s).", 0,
+ QCoreApplication::CodecForTr, droppedData));
+
releaser.squeeze(cd.m_saveMode);
bool saved = releaser.save(&dev);
if (saved && cd.isVerbose()) {
diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp
index 305681d..62f4d10 100644
--- a/tools/linguist/shared/translator.cpp
+++ b/tools/linguist/shared/translator.cpp
@@ -517,16 +517,10 @@ QList<TranslatorMessage> Translator::translatedMessages() const
return result;
}
-QStringList Translator::normalizedTranslations(const TranslatorMessage &msg,
- QLocale::Language language, QLocale::Country country)
+QStringList Translator::normalizedTranslations(const TranslatorMessage &msg, int numPlurals)
{
QStringList translations = msg.translations();
- int numTranslations = 1;
- if (msg.isPlural() && language != QLocale::C) {
- QStringList forms;
- if (getNumerusInfo(language, country, 0, &forms))
- numTranslations = forms.count(); // includes singular
- }
+ int numTranslations = msg.isPlural() ? numPlurals : 1;
// make sure that the stringlist always have the size of the
// language's current numerus, or 1 if its not plural
@@ -540,21 +534,39 @@ QStringList Translator::normalizedTranslations(const TranslatorMessage &msg,
return translations;
}
-QStringList Translator::normalizedTranslations(const TranslatorMessage &msg,
- ConversionData &cd, bool *ok) const
+void Translator::normalizeTranslations(ConversionData &cd)
{
+ bool truncated = false;
QLocale::Language l;
QLocale::Country c;
languageAndCountry(languageCode(), &l, &c);
- QStringList translns = normalizedTranslations(msg, l, c);
- if (msg.translations().size() > translns.size() && ok) {
+ int numPlurals = 1;
+ if (l != QLocale::C) {
+ QStringList forms;
+ if (getNumerusInfo(l, c, 0, &forms))
+ numPlurals = forms.count(); // includes singular
+ }
+ for (int i = 0; i < m_messages.count(); ++i) {
+ const TranslatorMessage &msg = m_messages.at(i);
+ QStringList tlns = msg.translations();
+ int ccnt = msg.isPlural() ? numPlurals : 1;
+ if (tlns.count() != ccnt) {
+ while (tlns.count() < ccnt)
+ tlns.append(QString());
+ while (tlns.count() > ccnt) {
+ tlns.removeLast();
+ truncated = true;
+ }
+ TranslatorMessage msg2(msg);
+ msg2.setTranslations(tlns);
+ m_messages[i] = msg2;
+ }
+ }
+ if (truncated)
cd.appendError(QLatin1String(
"Removed plural forms as the target language has less "
"forms.\nIf this sounds wrong, possibly the target language is "
"not set or recognized.\n"));
- *ok = false;
- }
- return translns;
}
QString Translator::guessLanguageCodeFromFileName(const QString &filename)
diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h
index ac824f3..d0903a9 100644
--- a/tools/linguist/shared/translator.h
+++ b/tools/linguist/shared/translator.h
@@ -65,6 +65,7 @@ public:
m_ignoreUnfinished(false),
m_sortContexts(false),
m_noUiLines(false),
+ m_idBased(false),
m_saveMode(SaveEverything)
{}
@@ -83,7 +84,8 @@ public:
public:
QString m_defaultContext;
- QByteArray m_codecForSource; // CPP specific
+ QByteArray m_codecForSource; // CPP, PO & QM specific
+ QByteArray m_outputCodec; // PO specific
QString m_sourceFileName;
QString m_targetFileName;
QDir m_sourceDir;
@@ -97,6 +99,7 @@ public:
bool m_ignoreUnfinished;
bool m_sortContexts;
bool m_noUiLines;
+ bool m_idBased;
TranslatorSaveMode m_saveMode;
};
@@ -156,8 +159,8 @@ public:
static QString guessLanguageCodeFromFileName(const QString &fileName);
QList<TranslatorMessage> messages() const;
QList<TranslatorMessage> translatedMessages() const;
- static QStringList normalizedTranslations(const TranslatorMessage &m,
- QLocale::Language lang, QLocale::Country country);
+ static QStringList normalizedTranslations(const TranslatorMessage &m, int numPlurals);
+ void normalizeTranslations(ConversionData &cd);
QStringList normalizedTranslations(const TranslatorMessage &m, ConversionData &cd, bool *ok) const;
int messageCount() const { return m_messages.size(); }
diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp
index 3efce15..5884997 100644
--- a/tools/linguist/shared/ts.cpp
+++ b/tools/linguist/shared/ts.cpp
@@ -693,8 +693,8 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd, in
t << " type=\"obsolete\"";
if (msg.isPlural()) {
t << ">";
- QStringList translns = translator.normalizedTranslations(msg, cd, &result);
- for (int j = 0; j < qMax(1, translns.count()); ++j) {
+ const QStringList &translns = msg.translations();
+ for (int j = 0; j < translns.count(); ++j) {
t << "\n <numerusform";
writeVariants(t, " ", translns[j]);
t << "</numerusform>";
diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd
index ab77f64..4d2cdeb 100644
--- a/tools/linguist/shared/ts.dtd
+++ b/tools/linguist/shared/ts.dtd
@@ -34,7 +34,7 @@
version CDATA #IMPLIED
sourcelanguage CDATA #IMPLIED
language CDATA #IMPLIED>
-<!-- The encoding to use in the .qm file by default. Default is ISO-8859-1. -->
+<!-- The encoding to use in the QM file by default. Default is ISO-8859-1. -->
<!ELEMENT defaultcodec (#PCDATA) >
<!ELEMENT context (name?, comment?, (context|message)+) >
<!ATTLIST context
@@ -54,7 +54,7 @@
<!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) >
<!--
! If utf8 is true, the defaultcodec is overridden and the message is encoded
- ! in UTF-8 in the .qm file.
+ ! in UTF-8 in the QM file.
-->
<!ATTLIST message
id CDATA #IMPLIED
@@ -70,7 +70,7 @@
! is omitted, the "current" one is used. For the 1st location in a message,
! "current" is the filename used for the 1st location of the previous message.
! For subsequent locations, it is the filename used for the previous location.
- ! A single .ts file has either all absolute or all relative locations.
+ ! A single TS file has either all absolute or all relative locations.
-->
<!ATTLIST location
filename CDATA #IMPLIED
@@ -106,7 +106,7 @@
<!--
! The translation variants have a priority between 1 ("highest") and 9 ("lowest")
! Typically longer translations get a higher priority.
- ! If omitted, the order of appearance of the variants in the .ts files is used.
+ ! If omitted, the order of appearance of the variants in the TS files is used.
-->
<!ATTLIST lengthvariant
priority (1|2|3|4|5|6|7|8|9) #IMPLIED>
diff --git a/tools/linguist/shared/xliff.cpp b/tools/linguist/shared/xliff.cpp
index 1313172..c222b8d 100644
--- a/tools/linguist/shared/xliff.cpp
+++ b/tools/linguist/shared/xliff.cpp
@@ -243,13 +243,12 @@ static void writeComment(QTextStream &ts, const TranslatorMessage &msg, const QR
}
}
-static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent,
- const Translator &translator, ConversionData &cd, bool *ok)
+static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent)
{
static int msgid;
QString msgidstr = !msg.id().isEmpty() ? msg.id() : QString::fromAscii("_msg%1").arg(++msgid);
- QStringList translns = translator.normalizedTranslations(msg, cd, ok);
+ QStringList translns = msg.translations();
QHash<QString, QString>::const_iterator it;
QString pluralStr;
QStringList sources(msg.sourceText());
@@ -349,8 +348,7 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const
}
}
-static void writeMessage(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent,
- const Translator &translator, ConversionData &cd, bool *ok)
+static void writeMessage(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent)
{
if (msg.isPlural()) {
writeIndent(ts, indent);
@@ -364,12 +362,12 @@ static void writeMessage(QTextStream &ts, const TranslatorMessage &msg, const QR
writeLineNumber(ts, msg, indent);
writeComment(ts, msg, drops, indent);
- writeTransUnits(ts, msg, drops, indent, translator, cd, ok);
+ writeTransUnits(ts, msg, drops, indent);
--indent;
writeIndent(ts, indent);
ts << "</group>\n";
} else {
- writeTransUnits(ts, msg, drops, indent, translator, cd, ok);
+ writeTransUnits(ts, msg, drops, indent);
}
}
@@ -795,7 +793,7 @@ bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd)
}
foreach (const TranslatorMessage &msg, messageOrder[fn][ctx])
- writeMessage(ts, msg, drops, indent, translator, cd, &ok);
+ writeMessage(ts, msg, drops, indent);
if (!ctx.isEmpty()) {
--indent;
diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
index 5d1ac32..b8b9338 100644
--- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -613,18 +613,15 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// getter:
if (property.access != QDBusIntrospection::Property::Write) {
- hs << " inline " << type << " " << getter << "() const" << endl;
- if (type != "QVariant")
- hs << " { return qvariant_cast< " << type << " >(internalPropGet(\""
- << property.name << "\")); }" << endl;
- else
- hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl;
+ hs << " inline " << type << " " << getter << "() const" << endl
+ << " { return qvariant_cast< " << type << " >(property(\""
+ << property.name << "\")); }" << endl;
}
// setter:
if (property.access != QDBusIntrospection::Property::Read) {
hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl
- << " { internalPropSet(\"" << property.name
+ << " { setProperty(\"" << property.name
<< "\", qVariantFromValue(value)); }" << endl;
}
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index 792190d..dd10c1c 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -726,24 +726,29 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
tr("The function either doesn't exist in any base class "
"with the same signature or it exists but isn't virtual."));
}
-#if 0 // Ideally, we would enable this check to warn whenever \reimp is used
- // incorrectly, and only make the node internal if the function is a
- // reimplementation of another function in a base class.
+ /*
+ Ideally, we would enable this check to warn whenever
+ \reimp is used incorrectly, and only make the node
+ internal if the function is a reimplementation of
+ another function in a base class.
+ */
else if (from->access() == Node::Private
|| from->parent()->access() == Node::Private) {
- doc.location().warning(
- tr("Base function for '\\%1' in %2() is private or internal")
+ doc.location().warning(tr("'\\%1' in %2() should be '\\internal' because its base function is private or internal")
.arg(COMMAND_REIMP).arg(node->name()));
}
-#endif
- // Note: Setting the access to Private hides the documentation,
- // but setting the status to Internal makes the node available
- // in the XML output when the WebXMLGenerator is used.
+
#if 0
// Reimplemented functions now reported in separate sections.
+ /*
+ Note: Setting the access to Private hides the documentation,
+ but setting the status to Internal makes the node available
+ in the XML output when the WebXMLGenerator is used.
+ */
func->setAccess(Node::Private);
func->setStatus(Node::Internal);
-#endif
+#endif
+ func->setReimp(true);
}
else {
doc.location().warning(tr("Ignored '\\%1' in %2")
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index 222b9a1..d5aca0e 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -1677,10 +1677,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd)
leavePara();
if (currentSectioningUnit == Doc::Book) {
+#if 0
+ // mws didn't think this was necessary.
if (unit > Doc::Section1)
location().warning(tr("Unexpected '\\%1' without '\\%2'")
.arg(cmdName(cmd))
.arg(cmdName(CMD_SECTION1)));
+#endif
currentSectioningUnit = (Doc::SectioningUnit) (unit - 1);
priv->constructExtra();
priv->extra->sectioningUnit = currentSectioningUnit;
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index fa55b8a..e97b7f2 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -68,10 +68,12 @@ QStringList Generator::imageDirs;
QString Generator::outDir;
QString Generator::project;
-static Text stockLink(const QString &target)
+static void singularPlural(Text& text, const NodeList& nodes)
{
- return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ if (nodes.count() == 1)
+ text << " is";
+ else
+ text << " are";
}
Generator::Generator()
@@ -241,7 +243,7 @@ void Generator::generateFakeNode(const FakeNode * /* fake */,
{
}
-void Generator::generateText(const Text& text,
+bool Generator::generateText(const Text& text,
const Node *relative,
CodeMarker *marker)
{
@@ -254,31 +256,35 @@ void Generator::generateText(const Text& text,
true,
numAtoms);
endText(relative, marker);
+ return true;
}
+ return false;
}
#ifdef QDOC_QML
-void Generator::generateQmlText(const Text& text,
+bool Generator::generateQmlText(const Text& text,
const Node *relative,
CodeMarker *marker)
{
- if (text.firstAtom() != 0) {
- startText(relative, marker);
- const Atom *atom = text.firstAtom();
- while (atom) {
- if (atom->type() != Atom::QmlText)
- atom = atom->next();
- else {
- atom = atom->next();
- while (atom && (atom->type() != Atom::EndQmlText)) {
- int n = 1 + generateAtom(atom, relative, marker);
- while (n-- > 0)
- atom = atom->next();
- }
+ const Atom* atom = text.firstAtom();
+ if (atom == 0)
+ return false;
+
+ startText(relative, marker);
+ while (atom) {
+ if (atom->type() != Atom::QmlText)
+ atom = atom->next();
+ else {
+ atom = atom->next();
+ while (atom && (atom->type() != Atom::EndQmlText)) {
+ int n = 1 + generateAtom(atom, relative, marker);
+ while (n-- > 0)
+ atom = atom->next();
}
}
- endText(relative, marker);
}
+ endText(relative, marker);
+ return true;
}
#endif
@@ -302,7 +308,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
if (node->doc().isEmpty()) {
- if (!quiet) // ### might be unnecessary
+ if (!quiet && !node->isReimp()) // ### might be unnecessary
node->location().warning(tr("No documentation for '%1'")
.arg(marker->plainFullName(node)));
}
@@ -313,7 +319,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
generateReimplementedFrom(func, marker);
}
- generateText(node->doc().body(), node, marker);
+ if (!generateText(node->doc().body(), node, marker))
+ if (node->isReimp())
+ return;
if (node->type() == Node::Enum) {
const EnumNode *enume = (const EnumNode *) node;
@@ -395,7 +403,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
}
- if (needWarning)
+ if (needWarning && !func->isReimp())
node->doc().location().warning(
tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)));
}
@@ -769,64 +777,138 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
{
Text text;
Text theStockLink;
- Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness();
+ Node::ThreadSafeness threadSafeness = node->threadSafeness();
+
+ Text rlink;
+ rlink << Atom(Atom::Link,"reentrant")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "reentrant"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ Text tlink;
+ tlink << Atom(Atom::Link,"thread-safe")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "thread-safe"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- switch (node->threadSafeness()) {
+ switch (threadSafeness) {
case Node::UnspecifiedSafeness:
break;
case Node::NonReentrant:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:"
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This "
- << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight;
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Warning:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " This "
+ << typeString(node)
+ << " is not "
+ << rlink
+ << "."
+ << Atom::ParaRight;
break;
case Node::Reentrant:
case Node::ThreadSafe:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD);
- if (parent == Node::ThreadSafe) {
- text << "Warning:";
- } else {
- text << "Note:";
- }
- text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " ";
-
- if (node->threadSafeness() == Node::ThreadSafe)
- theStockLink = stockLink("thread-safe");
- else
- theStockLink = stockLink("reentrant");
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Note:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " ";
if (node->isInnerNode()) {
- const InnerNode *innerNode = static_cast<const InnerNode *>(node);
- text << "All the functions in this " << typeString(node) << " are "
- << theStockLink;
-
- NodeList except;
+ const InnerNode* innerNode = static_cast<const InnerNode*>(node);
+ text << "All functions in this "
+ << typeString(node)
+ << " are ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+
+ bool exceptions = false;
+ NodeList reentrant;
+ NodeList threadsafe;
+ NodeList nonreentrant;
NodeList::ConstIterator c = innerNode->childNodes().begin();
while (c != innerNode->childNodes().end()) {
- if ((*c)->threadSafeness() != Node::UnspecifiedSafeness)
- except.append(*c);
+ switch ((*c)->threadSafeness()) {
+ case Node::Reentrant:
+ reentrant.append(*c);
+ if (threadSafeness == Node::ThreadSafe)
+ exceptions = true;
+ break;
+ case Node::ThreadSafe:
+ threadsafe.append(*c);
+ if (threadSafeness == Node::Reentrant)
+ exceptions = true;
+ break;
+ case Node::NonReentrant:
+ nonreentrant.append(*c);
+ exceptions = true;
+ break;
+ default:
+ break;
+ }
++c;
}
- if (except.isEmpty()) {
+ if (!exceptions)
text << ".";
+ else if (threadSafeness == Node::Reentrant) {
+ if (nonreentrant.isEmpty()) {
+ if (!threadsafe.isEmpty()) {
+ text << ", but ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " also " << tlink << ".";
+ }
+ else
+ text << ".";
+ }
+ else {
+ text << ", except for ";
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ if (!threadsafe.isEmpty()) {
+ text << " ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " " << tlink << ".";
+ }
+ }
}
- else {
- text << ", except ";
-
- NodeList::ConstIterator e = except.begin();
- int index = 0;
- while (e != except.end()) {
- appendFullName(text, *e, innerNode, marker);
- text << separator(index++, except.count());
- ++e;
+ else { // thread-safe
+ if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
+ text << ", except for ";
+ if (!reentrant.isEmpty()) {
+ appendFullNames(text,reentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,reentrant);
+ text << " only " << rlink;
+ if (!nonreentrant.isEmpty())
+ text << ", and ";
+ }
+ if (!nonreentrant.isEmpty()) {
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ }
+ text << ".";
}
}
}
else {
- text << "This " << typeString(node) << " is " << theStockLink << ".";
+ text << "This " << typeString(node) << " is ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+ text << ".";
}
text << Atom::ParaRight;
}
- generateText(text, node, marker);
+ generateText(text,node,marker);
}
void Generator::generateSince(const Node *node, CodeMarker *marker)
@@ -960,6 +1042,20 @@ void Generator::appendFullName(Text& text,
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
+void Generator::appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator n = nodes.begin();
+ int index = 0;
+ while (n != nodes.end()) {
+ appendFullName(text,*n,relative,marker);
+ text << comma(index++,nodes.count());
+ ++n;
+ }
+}
+
void Generator::appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h
index 75134d2..cdc4c29 100644
--- a/tools/qdoc3/generator.h
+++ b/tools/qdoc3/generator.h
@@ -93,11 +93,11 @@ class Generator
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
- virtual void generateText(const Text& text,
+ virtual bool generateText(const Text& text,
const Node *relative,
CodeMarker *marker);
#ifdef QDOC_QML
- virtual void generateQmlText(const Text& text,
+ virtual bool generateQmlText(const Text& text,
const Node *relative,
CodeMarker *marker);
#endif
@@ -154,6 +154,10 @@ class Generator
const Node *apparentNode,
const QString& fullName,
const Node *actualNode);
+ void appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker);
void appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index c007b9b..d82e9f8 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -294,6 +294,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
nonCompatClasses.clear();
mainClasses.clear();
compatClasses.clear();
+ obsoleteClasses.clear();
moduleClassMap.clear();
moduleNamespaceMap.clear();
funcIndex.clear();
@@ -381,7 +382,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::AutoLink:
if (!inLink && !inContents && !inSectionHeading) {
const Node *node = 0;
- QString link = getLink(atom, relative, marker, node);
+ QString link = getLink(atom, relative, marker, &node);
if (!link.isEmpty()) {
beginLink(link, node, relative, marker);
generateLink(atom, relative, marker);
@@ -567,6 +568,9 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == "compatclasses") {
generateCompactList(relative, marker, compatClasses);
}
+ else if (atom->string() == "obsoleteclasses") {
+ generateCompactList(relative, marker, obsoleteClasses);
+ }
else if (atom->string() == "functionindex") {
generateFunctionIndex(relative, marker);
}
@@ -648,11 +652,12 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, marker, node);
- if (myLink.isEmpty())
+ QString myLink = getLink(atom, relative, marker, &node);
+ if (myLink.isEmpty()) {
relative->doc().location().warning(tr("Cannot link to '%1' in %2")
.arg(atom->string())
.arg(marker->plainFullName(relative)));
+ }
beginLink(myLink, node, relative, marker);
skipAhead = 1;
}
@@ -1843,6 +1848,9 @@ HtmlGenerator::generateAnnotatedList(const Node *relative,
foreach (const QString &name, nodeMap.keys()) {
const Node *node = nodeMap[name];
+ if (node->status() == Node::Obsolete)
+ continue;
+
if (++row % 2 == 1)
out() << "<tr valign=\"top\" class=\"odd\">";
else
@@ -3261,6 +3269,9 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
if ((*c)->status() == Node::Compat) {
compatClasses.insert(className, *c);
}
+ else if ((*c)->status() == Node::Obsolete) {
+ obsoleteClasses.insert(className, *c);
+ }
else {
nonCompatClasses.insert(className, *c);
if ((*c)->status() == Node::Main)
@@ -3457,10 +3468,10 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
QString HtmlGenerator::getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
- const Node *node)
+ const Node** node)
{
QString link;
- node = 0;
+ *node = 0;
if (atom->string().contains(":") &&
(atom->string().startsWith("file:")
@@ -3484,40 +3495,74 @@ QString HtmlGenerator::getLink(const Atom *atom,
QString first = path.first().trimmed();
if (first.isEmpty()) {
- node = relative;
+ *node = relative;
}
else if (first.endsWith(".html")) {
- node = tre->root()->findNode(first, Node::Fake);
+ *node = tre->root()->findNode(first, Node::Fake);
}
else {
- node = marker->resolveTarget(first, tre, relative);
- if (!node)
- node = tre->findFakeNodeByTitle(first);
- if (!node)
- node = tre->findUnambiguousTarget(first, targetAtom);
+ *node = marker->resolveTarget(first, tre, relative);
+ if (!*node)
+ *node = tre->findFakeNodeByTitle(first);
+ if (!*node)
+ *node = tre->findUnambiguousTarget(first, targetAtom);
}
- if (node) {
- if (!node->url().isEmpty())
- return node->url();
+ if (*node) {
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
else
path.removeFirst();
}
else {
- node = relative;
+ *node = relative;
+ }
+
+ if (*node) {
+ if ((*node)->status() == Node::Obsolete) {
+ if (relative) {
+ if (relative->parent() != *node) {
+ if (relative->status() != Node::Obsolete) {
+ relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
+ .arg(atom->string())
+ .arg(marker->plainFullName(relative)));
+#if 0
+ qDebug() << "Link to Obsolete entity"
+ << (*node)->name();
+ qDebug() << " relative entity"
+ << relative->name();
+#endif
+ }
+ }
+ }
+ else {
+ qDebug() << "Link to Obsolete entity"
+ << (*node)->name() << "no relative";
+ }
+ }
+#if 0
+ else if ((*node)->status() == Node::Deprecated) {
+ qDebug() << "Link to Deprecated entity";
+ }
+ else if ((*node)->status() == Node::Internal) {
+ qDebug() << "Link to Internal entity";
+ }
+ //else
+ //qDebug() << "Node Status:" << (*node)->status();
+#endif
}
while (!path.isEmpty()) {
- targetAtom = tre->findTarget(path.first(), node);
+ targetAtom = tre->findTarget(path.first(), *node);
if (targetAtom == 0)
break;
path.removeFirst();
}
if (path.isEmpty()) {
- link = linkForNode(node, relative);
+ link = linkForNode(*node, relative);
if (targetAtom)
- link += "#" + refForAtom(targetAtom, node);
+ link += "#" + refForAtom(targetAtom, *node);
}
}
return link;
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index dc5e5cf..a7f4009 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -202,7 +202,7 @@ class HtmlGenerator : public PageGenerator
virtual QString getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
- const Node *node = 0);
+ const Node** node);
virtual void generateDcf(const QString &fileBase,
const QString &startPage,
const QString &title, DcfSection &dcfRoot);
@@ -256,6 +256,7 @@ class HtmlGenerator : public PageGenerator
QMap<QString, const Node *> nonCompatClasses;
QMap<QString, const Node *> mainClasses;
QMap<QString, const Node *> compatClasses;
+ QMap<QString, const Node *> obsoleteClasses;
QMap<QString, const Node *> namespaceIndex;
QMap<QString, const Node *> serviceClasses;
#ifdef QDOC_QML
diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp
index b32425c..294877b 100644
--- a/tools/qdoc3/javadocgenerator.cpp
+++ b/tools/qdoc3/javadocgenerator.cpp
@@ -272,9 +272,10 @@ void JavadocGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker
HtmlGenerator::generateFakeNode(fake, marker);
}
-void JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
+bool JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
{
HtmlGenerator::generateText(text, relative, marker);
+ return true;
}
void JavadocGenerator::generateBody(const Node *node, CodeMarker *marker)
diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h
index ba9b15d..5431c38 100644
--- a/tools/qdoc3/javadocgenerator.h
+++ b/tools/qdoc3/javadocgenerator.h
@@ -68,7 +68,7 @@ protected:
void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
- void generateText( const Text& text, const Node *relative, CodeMarker *marker );
+ bool generateText( const Text& text, const Node *relative, CodeMarker *marker );
void generateBody( const Node *node, CodeMarker *marker );
void generateAlsoList( const Node *node, CodeMarker *marker );
diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp
index 5a98275..6425765 100644
--- a/tools/qdoc3/main.cpp
+++ b/tools/qdoc3/main.cpp
@@ -128,7 +128,7 @@ static void printHelp()
" -D<name> "
"Define <name> as a macro while parsing sources\n"
" -slow "
- "Turn on features that slow down qdoc"
+ "Turn on features that slow down qdoc\n"
" -showinternal "
"Include stuff marked internal") );
}
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 0f9468a..b2e53ab 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -868,6 +868,18 @@ void FunctionNode::setOverload(bool overlode)
}
/*!
+ Sets the function node's reimplementation flag to \a r.
+ When \a r is true, it is supposed to mean that this function
+ is a reimplementation of a virtual function in a base class,
+ but it really just means the \e reimp command was seen in the
+ qdoc comment.
+ */
+void FunctionNode::setReimp(bool r)
+{
+ reimp = r;
+}
+
+/*!
*/
void FunctionNode::addParameter(const Parameter& parameter)
{
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 0a671b37d..a35bc17 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -123,6 +123,7 @@ class Node
void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; }
virtual bool isInnerNode() const = 0;
+ virtual bool isReimp() const { return false; }
Type type() const { return typ; }
InnerNode *parent() const { return par; }
InnerNode *relates() const { return rel; }
@@ -444,6 +445,7 @@ class FunctionNode : public LeafNode
void setConst(bool conste) { con = conste; }
void setStatic(bool statique) { sta = statique; }
void setOverload(bool overlode);
+ void setReimp(bool r);
void addParameter(const Parameter& parameter);
inline void setParameters(const QList<Parameter>& parameters);
void borrowParameterNames(const FunctionNode *source);
@@ -458,6 +460,7 @@ class FunctionNode : public LeafNode
bool isConst() const { return con; }
bool isStatic() const { return sta; }
bool isOverload() const { return ove; }
+ bool isReimp() const { return reimp; }
int overloadNumber() const;
int numOverloads() const;
const QList<Parameter>& parameters() const { return params; }
@@ -483,6 +486,7 @@ class FunctionNode : public LeafNode
bool con : 1;
bool sta : 1;
bool ove : 1;
+ bool reimp: 1;
QList<Parameter> params;
const FunctionNode *rf;
const PropertyNode *ap;
diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro
index ed27669..49a16e6 100644
--- a/tools/qdoc3/qdoc3.pro
+++ b/tools/qdoc3/qdoc3.pro
@@ -6,9 +6,12 @@ DEFINES += QT_NO_CAST_TO_ASCII
QT = core xml
CONFIG += console
+CONFIG -= debug_and_release_target
+#CONFIG += debug
build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
+# CONFIG += debug
}
mac:CONFIG -= app_bundle
HEADERS += apigenerator.h \
diff --git a/tools/qdoc3/separator.cpp b/tools/qdoc3/separator.cpp
index 8f27f90..60674be 100644
--- a/tools/qdoc3/separator.cpp
+++ b/tools/qdoc3/separator.cpp
@@ -48,22 +48,30 @@
QT_BEGIN_NAMESPACE
-QString separator( int index, int count )
+QString separator(int index, int count)
{
- if ( index == count - 1 )
- return tr( ".", "terminator" );
+ if (index == count - 1)
+ return tr(".", "terminator");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
+}
- if ( count == 2 ) {
- return tr( " and ", "separator when N = 2" );
- } else {
- if ( index == 0 ) {
- return tr( ", ", "first separator when N > 2" );
- } else if ( index < count - 2 ) {
- return tr( ", ", "general separator when N > 2" );
- } else {
- return tr( ", and ", "last separator when N > 2" );
- }
- }
+QString comma(int index, int count)
+{
+ if (index == count - 1)
+ return QString("");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/separator.h b/tools/qdoc3/separator.h
index 70ba624..2336d94 100644
--- a/tools/qdoc3/separator.h
+++ b/tools/qdoc3/separator.h
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
QString separator( int index, int count );
+QString comma( int index, int count );
QT_END_NAMESPACE
diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf
index b82507f..44815ff 100644
--- a/tools/qdoc3/test/assistant.qdocconf
+++ b/tools/qdoc3/test/assistant.qdocconf
@@ -6,14 +6,14 @@ include(qt-defines.qdocconf)
project = Qt Assistant
description = Qt Assistant Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Assistant
qhp.Assistant.file = assistant.qhp
-qhp.Assistant.namespace = com.trolltech.assistant.452
+qhp.Assistant.namespace = com.trolltech.assistant.460
qhp.Assistant.virtualFolder = qdoc
qhp.Assistant.indexTitle = Qt Assistant Manual
qhp.Assistant.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css
index 7f22861..3816164 100644
--- a/tools/qdoc3/test/classic.css
+++ b/tools/qdoc3/test/classic.css
@@ -125,7 +125,7 @@ table.generic, table.annotated
}
table td.memItemLeft {
- width: 160px;
+ width: 180px;
padding: 2px 0px 0px 8px;
margin: 4px;
border-width: 1px;
diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf
index 9c0790e..88f8dc9 100644
--- a/tools/qdoc3/test/designer.qdocconf
+++ b/tools/qdoc3/test/designer.qdocconf
@@ -6,14 +6,14 @@ include(qt-defines.qdocconf)
project = Qt Designer
description = Qt Designer Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Designer
qhp.Designer.file = designer.qhp
-qhp.Designer.namespace = com.trolltech.designer.452
+qhp.Designer.namespace = com.trolltech.designer.460
qhp.Designer.virtualFolder = qdoc
qhp.Designer.indexTitle = Qt Designer Manual
qhp.Designer.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf
index da49abe..1c0a585 100644
--- a/tools/qdoc3/test/linguist.qdocconf
+++ b/tools/qdoc3/test/linguist.qdocconf
@@ -6,14 +6,14 @@ include(qt-defines.qdocconf)
project = Qt Linguist
description = Qt Linguist Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Linguist
qhp.Linguist.file = linguist.qhp
-qhp.Linguist.namespace = com.trolltech.linguist.452
+qhp.Linguist.namespace = com.trolltech.linguist.460
qhp.Linguist.virtualFolder = qdoc
qhp.Linguist.indexTitle = Qt Linguist Manual
qhp.Linguist.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
diff --git a/tools/qdoc3/test/macros.qdocconf b/tools/qdoc3/test/macros.qdocconf
index 85fe1db..f7dcdc0 100644
--- a/tools/qdoc3/test/macros.qdocconf
+++ b/tools/qdoc3/test/macros.qdocconf
@@ -1,14 +1,15 @@
+macro.aacute.HTML = "&aacute;"
macro.Aring.HTML = "&Aring;"
macro.aring.HTML = "&aring;"
macro.Auml.HTML = "&Auml;"
macro.author = "\\bold{Author:}"
macro.br.HTML = "<br />"
macro.BR.HTML = "<br />"
-macro.aacute.HTML = "&aacute;"
+macro.copyright.HTML = "&copy;"
macro.eacute.HTML = "&eacute;"
-macro.iacute.HTML = "&iacute;"
macro.gui = "\\bold"
macro.hr.HTML = "<hr />"
+macro.iacute.HTML = "&iacute;"
macro.key = "\\bold"
macro.menu = "\\bold"
macro.note = "\\bold{Note:}"
diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf
index 5e2cac7..0f98132 100644
--- a/tools/qdoc3/test/qmake.qdocconf
+++ b/tools/qdoc3/test/qmake.qdocconf
@@ -6,14 +6,14 @@ include(qt-defines.qdocconf)
project = QMake
description = QMake Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = qmake
qhp.qmake.file = qmake.qhp
-qhp.qmake.namespace = com.trolltech.qmake.452
+qhp.qmake.namespace = com.trolltech.qmake.460
qhp.qmake.virtualFolder = qdoc
qhp.qmake.indexTitle = QMake Manual
qhp.qmake.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf
index 77b03d2..b4f0c7a 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -6,7 +6,7 @@ include(qt-defines.qdocconf)
project = Qt
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
QtXmlPatterns QtTest
@@ -20,7 +20,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.452
+qhp.Qt.namespace = com.trolltech.qt.460
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index 9a18abe..709e336 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -68,7 +68,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QT_END_NAMESPACE \
QT_END_INCLUDE_NAMESPACE \
PHONON_EXPORT \
- Q_GADGET
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf
index 01b07b3..379511f 100644
--- a/tools/qdoc3/test/qt-inc.qdocconf
+++ b/tools/qdoc3/test/qt-inc.qdocconf
@@ -3,7 +3,7 @@ include(macros.qdocconf)
project = Qt
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console = QtCore QtNetwork QtSql QtXml QtScript QtTest
edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtSvg QtXml QtScript \
@@ -100,7 +100,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_TYPENAME \
Q_XML_EXPORT \
QDBUS_EXPORT \
- Q_GADGET
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index d154254..10e0fcd 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -8,7 +8,7 @@ project = Qt
versionsym =
version = %VERSION%
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
QtXmlPatterns QtTest
@@ -22,7 +22,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.452
+qhp.Qt.namespace = com.trolltech.qt.460
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp
index 45f6a45..36cbd89 100644
--- a/tools/qtconfig/paletteeditoradvanced.cpp
+++ b/tools/qtconfig/paletteeditoradvanced.cpp
@@ -55,7 +55,7 @@ PaletteEditorAdvanced::PaletteEditorAdvanced( QWidget * parent,
const char * name, bool modal, Qt::WindowFlags f )
: PaletteEditorAdvancedBase( parent, name, modal, f ), selectedPalette(0)
{
- // work around buggy ui file
+ // work around buggy UI file
comboEffect->setEnabled(false);
buttonEffect->setEnabled(false);
onToggleBuildEffects(true);
diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
index f047b79..1080477 100644
--- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp
+++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
@@ -113,6 +113,8 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
CeCloseHandle(deviceHandle);
return true;
}
+ } else {
+ qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString()));
}
return false;
}
@@ -120,7 +122,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
deleteFile(deviceDest);
HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (deviceHandle == INVALID_HANDLE_VALUE) {
- debugOutput(QString::fromLatin1(" Could not create target file"), 2);
+ qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
return false;
}
@@ -144,7 +146,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
if (toWrite == 0)
break;
if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) {
- debugOutput(QString::fromLatin1(" Could not write File"), 2);
+ qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
return false;
}
currentPos += written;
@@ -270,8 +272,8 @@ bool ActiveSyncConnection::copyDirectoryFromDevice(const QString &deviceSource,
}
do {
- QString srcFile = deviceSource + "\\" + QString::fromUtf16(data.cFileName);
- QString destFile = localDest + "\\" + QString::fromUtf16(data.cFileName);
+ QString srcFile = deviceSource + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = localDest + "\\" + QString::fromWCharArray(data.cFileName);
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive && !copyDirectoryFromDevice(srcFile, destFile, recursive)) {
wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
@@ -306,8 +308,8 @@ bool ActiveSyncConnection::copyDirectory(const QString &srcDirectory, const QStr
}
do {
- QString srcFile = srcDirectory + "\\" + QString::fromUtf16(data.cFileName);
- QString destFile = destDirectory + "\\" + QString::fromUtf16(data.cFileName);
+ QString srcFile = srcDirectory + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = destDirectory + "\\" + QString::fromWCharArray(data.cFileName);
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive && !copyDirectory(srcFile, destFile, recursive)) {
wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
@@ -341,7 +343,7 @@ bool ActiveSyncConnection::deleteDirectory(const QString &directory, bool recurs
return false;
do {
- QString FileName = directory + "\\" + QString::fromUtf16(FindFileData.cFileName);
+ QString FileName = directory + "\\" + QString::fromWCharArray(FindFileData.cFileName);
if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive)
if (!deleteDirectory(FileName, recursive, failIfContentExists))
@@ -380,12 +382,17 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo
BYTE* output;
IRAPIStream *stream;
int returned = 0;
+ DWORD error = 0;
HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
if (S_OK != res) {
- if (S_OK != CeGetLastError())
- debugOutput(QString::fromLatin1("Error: Could not invoke method on QtRemote"),1);
- else
- debugOutput(QString::fromLatin1("Error: QtRemote return unexpectedly with error Code %1").arg(res), 1);
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
} else {
DWORD written;
int strSize = program.length();
@@ -414,9 +421,18 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo
if (S_OK != stream->Read(&returned, sizeof(returned), &written)) {
qWarning(" Could not access return value of process");
}
- result = true;
- }
+ if (S_OK != stream->Read(&error, sizeof(error), &written)) {
+ qWarning(" Could not access error code");
+ }
+ if (error) {
+ qWarning("Error on target: %s", strwinerror(error).constData());
+ result = false;
+ }
+ else {
+ result = true;
+ }
+ }
if (returnValue)
*returnValue = returned;
diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri
index 39f24c2..a31374e 100644
--- a/tools/qtestlib/wince/cetest/bootstrapped.pri
+++ b/tools/qtestlib/wince/cetest/bootstrapped.pri
@@ -35,4 +35,5 @@ SOURCES += \
$$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \
$$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \
- $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp
+ $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \
+ $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp
diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp
index fec2735..68f0197 100644
--- a/tools/qtestlib/wince/cetest/deployment.cpp
+++ b/tools/qtestlib/wince/cetest/deployment.cpp
@@ -125,13 +125,37 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl
if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) {
QStringList libs = project->values("LIBS");
QStringList qtLibs;
+ QStringList libPaths;
foreach (QString item, libs) {
- if (item.startsWith("-lQt")) {
- qtLibs += project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + item.mid(2) + QLatin1String("4.dll");
+
+ if (item.startsWith("-L")) {
+ // -L -> a directory containing DLLs
+ libPaths << item.mid(2);
+ continue;
+ }
+
+ QStringList libCandidates;
+
+ if (item.startsWith("-l")) {
+ // -l -> a library located within one of the standard library paths
+ QString lib = item.mid(2);
+
+ // Check if it's a Qt library first, then check in all paths given with -L.
+ // Note Qt libraries get a `4' appended to them, others don't.
+ libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll");
+ foreach (QString const& libPath, libPaths) {
+ libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll");
+ }
} else {
- QFileInfo info(item);
- if (info.exists() && info.isAbsolute() && info.fileName().startsWith(QLatin1String("Qt")))
- qtLibs += info.dir().absoluteFilePath(info.fileName().replace(QLatin1String(".lib"), QLatin1String(".dll")));
+ libCandidates << item.replace(".lib",".dll");
+ }
+
+ foreach (QString const& file, libCandidates) {
+ QFileInfo info(file);
+ if (info.exists()) {
+ qtLibs += info.dir().absoluteFilePath(info.fileName());
+ break;
+ }
}
}
for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) {
diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp
index ba3ef8d..782f6d9 100644
--- a/tools/qtestlib/wince/cetest/main.cpp
+++ b/tools/qtestlib/wince/cetest/main.cpp
@@ -320,6 +320,7 @@ int main(int argc, char **argv)
cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl;
if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) {
cout << "Error: Could not execute target file" << endl;
+ return -1;
}
diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp
index 547b211..3d0c3f3 100644
--- a/tools/qtestlib/wince/cetest/remoteconnection.cpp
+++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp
@@ -41,6 +41,38 @@
#include "remoteconnection.h"
+QByteArray strwinerror(DWORD errorcode)
+{
+ QByteArray out(512, 0);
+
+ DWORD ok = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ errorcode,
+ 0,
+ out.data(),
+ out.size(),
+ 0
+ );
+
+ if (!ok) {
+ qsnprintf(out.data(), out.size(),
+ "(error %d; additionally, error %d while looking up error string)",
+ (int)errorcode, (int)GetLastError());
+ }
+ else {
+ out.resize(qstrlen(out.constData()));
+ if (out.endsWith("\r\n"))
+ out.chop(2);
+
+ /* Append error number to error message for good measure */
+ out.append(" (0x");
+ out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0'));
+ out.append(")");
+ }
+ return out;
+}
+
AbstractRemoteConnection::AbstractRemoteConnection()
{
}
diff --git a/tools/qtestlib/wince/cetest/remoteconnection.h b/tools/qtestlib/wince/cetest/remoteconnection.h
index 9c3e63d..f517009 100644
--- a/tools/qtestlib/wince/cetest/remoteconnection.h
+++ b/tools/qtestlib/wince/cetest/remoteconnection.h
@@ -79,4 +79,6 @@ public:
virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0;
};
+QByteArray strwinerror(DWORD);
+
#endif
diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp
index 3aed2d6..f2176dd 100644
--- a/tools/qtestlib/wince/remotelib/commands.cpp
+++ b/tools/qtestlib/wince/remotelib/commands.cpp
@@ -56,6 +56,7 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
wchar_t* arguments = 0;
int timeout = -1;
int returnValue = -2;
+ DWORD error = 0;
if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead))
CLEAN_FAIL(-2);
@@ -74,11 +75,13 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead))
CLEAN_FAIL(-2);
- bool result = qRemoteExecute(appName, arguments, &returnValue, timeout);
+ bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout);
if (timeout != 0) {
if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead))
CLEAN_FAIL(-4);
+ if (S_OK != stream->Write(&error, sizeof(error), &bytesRead))
+ CLEAN_FAIL(-5);
}
delete appName;
delete arguments;
@@ -90,13 +93,16 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
}
-bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, int timeout)
+bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout)
{
+ *error = 0;
+
if (!program)
return false;
PROCESS_INFORMATION pid;
if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) {
+ *error = GetLastError();
wprintf(L"Could not launch: %s\n", program);
return false;
}
diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h
index 9f0b2e3..5275f2c 100644
--- a/tools/qtestlib/wince/remotelib/commands.h
+++ b/tools/qtestlib/wince/remotelib/commands.h
@@ -45,7 +45,7 @@
extern "C" {
int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*);
- bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , int timeout = -1);
+ bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1);
}
#endif
diff --git a/tools/tools.pro b/tools/tools.pro
index d034dcd..eab9d48 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -25,7 +25,7 @@ mac {
embedded:SUBDIRS += kmap2qmap
contains(QT_CONFIG, dbus):SUBDIRS += qdbus
-!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns
+!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator
embedded: SUBDIRS += makeqpf
CONFIG+=ordered
diff --git a/tools/xmlpatterns/main.cpp b/tools/xmlpatterns/main.cpp
index a5c2c41..2405d5d 100644
--- a/tools/xmlpatterns/main.cpp
+++ b/tools/xmlpatterns/main.cpp
@@ -194,7 +194,7 @@ protected:
/* If we don't open stdout in "binary" mode on Windows, it will translate
* 0xA into 0xD 0xA. See Trolltech task 173619, for an example. */
_setmode(_fileno(stdout), _O_BINARY);
- m_stdout = QT_WA_INLINE(_wfdopen(_fileno(stdout), L"wb"),_fdopen(_fileno(stdout), "wb"));
+ m_stdout = _wfdopen(_fileno(stdout), L"wb");
out->open(m_stdout, QIODevice::WriteOnly);
#else
out->open(stdout, QIODevice::WriteOnly);
diff --git a/tools/xmlpatterns/qcoloringmessagehandler.cpp b/tools/xmlpatterns/qcoloringmessagehandler.cpp
index 9616097..0ddb246 100644
--- a/tools/xmlpatterns/qcoloringmessagehandler.cpp
+++ b/tools/xmlpatterns/qcoloringmessagehandler.cpp
@@ -100,12 +100,18 @@ void ColoringMessageHandler::handleMessage(QtMsgType type,
}
case QtFatalMsg:
{
- Q_ASSERT(!sourceLocation.isNull());
const QString errorCode(identifier.fragment());
Q_ASSERT(!errorCode.isEmpty());
QUrl uri(identifier);
uri.setFragment(QString());
+ QString location;
+
+ if(sourceLocation.isNull())
+ location = QXmlPatternistCLI::tr("Unknown location");
+ else
+ location = QString::fromLatin1(sourceLocation.uri().toEncoded());
+
QString errorId;
/* If it's a standard error code, we don't want to output the
* whole URI. */
@@ -117,7 +123,7 @@ void ColoringMessageHandler::handleMessage(QtMsgType type,
if(hasLine)
{
writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode),
- colorify(QString::fromLatin1(sourceLocation.uri().toEncoded()), Location),
+ colorify(location, Location),
colorify(QString::number(sourceLocation.line()), Location),
colorify(QString::number(sourceLocation.column()), Location),
colorifyDescription(description)));
@@ -125,7 +131,7 @@ void ColoringMessageHandler::handleMessage(QtMsgType type,
else
{
writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode),
- colorify(QString::fromLatin1(sourceLocation.uri().toEncoded()), Location),
+ colorify(location, Location),
colorifyDescription(description)));
}
break;
diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp
new file mode 100644
index 0000000..75ea8b4
--- /dev/null
+++ b/tools/xmlpatternsvalidator/main.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Patternist project on Trolltech Labs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "main.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+#include <QtXmlPatterns/QXmlSchema>
+#include <QtXmlPatterns/QXmlSchemaValidator>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ enum ExitCode
+ {
+ Valid = 0,
+ Invalid,
+ ParseError
+ };
+
+ enum ExecutionMode
+ {
+ InvalidMode,
+ SchemaOnlyMode,
+ SchemaAndInstanceMode,
+ InstanceOnlyMode
+ };
+
+ const QCoreApplication app(argc, argv);
+ QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator"));
+
+ if (argc != 2 && argc != 3) {
+ qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator (<schema url> | <instance url> <schema url> | <instance url>)");
+ return ParseError;
+ }
+
+ // parse command line arguments
+ ExecutionMode mode = InvalidMode;
+
+ if (argc == 2) {
+ // either it is a schema or instance document
+
+ QString url = QFile::decodeName(argv[1]);
+ if (url.toLower().endsWith(QLatin1String(".xsd"))) {
+ mode = SchemaOnlyMode;
+ } else {
+ // as we could validate all types of xml documents, don't check the extension here
+ mode = InstanceOnlyMode;
+ }
+ } else if (argc == 3) {
+ mode = SchemaAndInstanceMode;
+ }
+
+ // do validation
+ QXmlSchema schema;
+
+ if (mode == SchemaOnlyMode) {
+ const QString schemaUri = QFile::decodeName(argv[1]);
+
+ schema.load(QUrl(schemaUri));
+
+ if (schema.isValid())
+ return Valid;
+ else
+ return Invalid;
+ } else if (mode == SchemaAndInstanceMode) {
+ const QString instanceUri = QFile::decodeName(argv[1]);
+ const QString schemaUri = QFile::decodeName(argv[2]);
+
+ schema.load(QUrl(schemaUri));
+
+ if (!schema.isValid())
+ return Invalid;
+
+ QXmlSchemaValidator validator(schema);
+ if (validator.validate(QUrl(instanceUri)))
+ return Valid;
+ else
+ return Invalid;
+ } else if (mode == InstanceOnlyMode) {
+ const QString instanceUri = QFile::decodeName(argv[1]);
+
+ QXmlSchemaValidator validator(schema);
+ if (validator.validate(QUrl(instanceUri)))
+ return Valid;
+ else
+ return Invalid;
+ }
+
+ Q_ASSERT(false);
+
+ return Invalid;
+}
diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h
new file mode 100644
index 0000000..a0eff3b
--- /dev/null
+++ b/tools/xmlpatternsvalidator/main.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ ** Contact: Qt Software Information (qt-info@nokia.com)
+ **
+ ** This file is part of the Patternist project on Trolltech Labs. * **
+ ** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+ **
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_main_h
+#define Patternist_main_h
+
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlPatternistCLI
+{
+public:
+ Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI)
+private:
+ inline QXmlPatternistCLI();
+ Q_DISABLE_COPY(QXmlPatternistCLI)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro
new file mode 100644
index 0000000..dd5bd37
--- /dev/null
+++ b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+TARGET = xmlpatternsvalidator
+DESTDIR = ../../bin
+QT -= gui
+QT += xmlpatterns
+
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+
+# This ensures we get stderr and stdout on Windows.
+CONFIG += console
+
+# This ensures that this is a command-line program on OS X and not a GUI application.
+CONFIG -= app_bundle
+
+SOURCES = main.cpp
+HEADERS = main.h
+
+include(../src/common.pri)