summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-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.pro2
-rw-r--r--tools/configure/configureapp.cpp2
-rw-r--r--tools/configure/main.cpp2
-rw-r--r--tools/designer/src/components/propertyeditor/designerpropertymanager.cpp7
-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/uifile.icnsbin0 -> 123696 bytes
-rw-r--r--tools/designer/src/lib/shared/widgetfactory.cpp6
-rw-r--r--tools/linguist/lconvert/main.cpp17
-rw-r--r--tools/linguist/linguist/linguist.rc31
-rw-r--r--tools/linguist/linguist/messagemodel.cpp2
-rw-r--r--tools/linguist/lrelease/main.cpp1
-rw-r--r--tools/linguist/lupdate/main.cpp5
-rw-r--r--tools/linguist/shared/abstractproitemvisitor.h24
-rw-r--r--tools/linguist/shared/po.cpp5
-rw-r--r--tools/linguist/shared/profileevaluator.cpp886
-rw-r--r--tools/linguist/shared/profileevaluator.h3
-rw-r--r--tools/linguist/shared/proitems.cpp84
-rw-r--r--tools/linguist/shared/proitems.h33
-rw-r--r--tools/linguist/shared/qm.cpp3
-rw-r--r--tools/linguist/shared/translator.cpp42
-rw-r--r--tools/linguist/shared/translator.h7
-rw-r--r--tools/linguist/shared/ts.cpp4
-rw-r--r--tools/linguist/shared/xliff.cpp14
-rw-r--r--tools/qdoc3/cppcodeparser.cpp22
-rw-r--r--tools/qdoc3/htmlgenerator.cpp80
-rw-r--r--tools/qdoc3/htmlgenerator.h3
-rw-r--r--tools/qdoc3/qdoc3.pro2
-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-inc.qdocconf2
-rw-r--r--tools/qdoc3/test/qt.qdocconf4
-rw-r--r--tools/qtestlib/wince/cetest/bootstrapped.pri3
-rw-r--r--tools/tools.pro2
-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
50 files changed, 1269 insertions, 465 deletions
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 fdeab29..eeec62a 100644
--- a/tools/configure/configure.pro
+++ b/tools/configure/configure.pro
@@ -32,6 +32,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 \
@@ -64,6 +65,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 0a8880d..728527d 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -3121,6 +3121,7 @@ void Configure::buildQmake()
void Configure::buildHostTools()
{
+ dictionary[ "DONE" ] = "yes";
if (!dictionary.contains("XQMAKESPEC"))
return;
@@ -3344,7 +3345,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/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/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/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/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/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/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp
index 4bed02f..1381595 100644
--- a/tools/linguist/lconvert/main.cpp
+++ b/tools/linguist/lconvert/main.cpp
@@ -81,8 +81,11 @@ 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 XLIFF files.\n"
" May be specified repeatedly.\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/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/main.cpp b/tools/linguist/lrelease/main.cpp
index d3b9937..5cb9e1a 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -121,6 +121,7 @@ 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;
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 7cf7b54..e2acbbb 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -203,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;
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 0ce27af..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>
@@ -171,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;
@@ -191,6 +193,7 @@ public:
bool isActiveConfig(const QString &config, bool regex = false);
QStringList expandVariableReferences(const QString &value);
+ void doVariableReplace(QString *str);
QStringList evaluateExpandFunction(const QString &function, const QString &arguments);
QString format(const char *format) const;
@@ -198,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;
@@ -217,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
@@ -228,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_)
{
@@ -244,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)
@@ -560,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()) {
@@ -662,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"));
@@ -684,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 {
@@ -694,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;
}
@@ -706,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,
@@ -733,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();
@@ -804,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;
@@ -840,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(')'));
@@ -853,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;
}
@@ -988,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;
@@ -1202,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);
@@ -1216,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;
@@ -1401,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)) {
@@ -1475,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));
@@ -1557,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());
@@ -1610,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);
@@ -1624,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]);
@@ -1717,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 {
@@ -1727,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();
@@ -1870,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,
@@ -2039,27 +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 = pro->Accept(this);
+ 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;
}
-
- 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()) {
@@ -2078,7 +2430,7 @@ 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;
}
@@ -2190,14 +2542,14 @@ 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;
diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h
index 688022b..f3498c1 100644
--- a/tools/linguist/shared/profileevaluator.h
+++ b/tools/linguist/shared/profileevaluator.h
@@ -95,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/qm.cpp b/tools/linguist/shared/qm.cpp
index 9523fde..638e997 100644
--- a/tools/linguist/shared/qm.cpp
+++ b/tools/linguist/shared/qm.cpp
@@ -552,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");
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 fb17fd1..d0903a9 100644
--- a/tools/linguist/shared/translator.h
+++ b/tools/linguist/shared/translator.h
@@ -84,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;
@@ -158,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/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/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index 6d703fb..4563f65 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -854,21 +854,25 @@ 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
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index 8726665..bb96d55 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -316,6 +316,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
nonCompatClasses.clear();
mainClasses.clear();
compatClasses.clear();
+ obsoleteClasses.clear();
moduleClassMap.clear();
moduleNamespaceMap.clear();
funcIndex.clear();
@@ -403,7 +404,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);
@@ -590,6 +591,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);
}
@@ -671,11 +675,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;
}
@@ -3421,6 +3426,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)
@@ -3609,10 +3617,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:")
@@ -3636,40 +3644,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 e4a3ec1..a330d0c 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -221,7 +221,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);
@@ -275,6 +275,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/qdoc3.pro b/tools/qdoc3/qdoc3.pro
index 6c1cfd2..49a16e6 100644
--- a/tools/qdoc3/qdoc3.pro
+++ b/tools/qdoc3/qdoc3.pro
@@ -7,9 +7,11 @@ 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/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 79bcb80..4225a1b 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 d427a86..6c7a828 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-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf
index bba8e39..3c8be8c 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 \
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index 9c43b4f..3ce323c 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/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/tools.pro b/tools/tools.pro
index 6cf1760..ecdbcd1 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -26,7 +26,7 @@ embedded:SUBDIRS += kmap2qmap
contains(QT_CONFIG, declarative):SUBDIRS += qmlviewer
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/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)