/Doc/templates/

l='alternate' title='Atom feed' href='http://service.techsat.com/oss-git/Qt.git/atom/tools?h=v4.8.6' type='application/atom+xml'/>
summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2011-06-01 15:08:39 (GMT)
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2011-06-01 19:34:28 (GMT)
commitf1249f94c07654f0b76e7a90fb81ed5b58cd30f7 (patch)
treef8a18a3bbc7b4b0c3bf6f11b3cb2aa39e018adbe /tools
parent9f71cffea1d5cdac94ae7368ffa7f54183ac33a4 (diff)
downloadQt-f1249f94c07654f0b76e7a90fb81ed5b58cd30f7.zip
Qt-f1249f94c07654f0b76e7a90fb81ed5b58cd30f7.tar.gz
Qt-f1249f94c07654f0b76e7a90fb81ed5b58cd30f7.tar.bz2
synchronize qmake project parser with qt creator
qt creator as of ddb918f. not feeling like replaying the whole history ...
Diffstat (limited to 'tools')
-rw-r--r--tools/linguist/lrelease/main.cpp61
-rw-r--r--tools/linguist/lupdate/main.cpp82
-rw-r--r--tools/linguist/shared/abstractproitemvisitor.h74
-rw-r--r--tools/linguist/shared/ioutils.cpp152
-rw-r--r--tools/linguist/shared/ioutils.h65
-rw-r--r--tools/linguist/shared/profileevaluator.cpp4207
-rw-r--r--tools/linguist/shared/profileevaluator.h209
-rw-r--r--tools/linguist/shared/profileparser.cpp1028
-rw-r--r--tools/linguist/shared/profileparser.h186
-rw-r--r--tools/linguist/shared/proitems.cpp485
-rw-r--r--tools/linguist/shared/proitems.h354
-rw-r--r--tools/linguist/shared/proparser.pri13
-rw-r--r--tools/linguist/shared/proparser_global.h48
-rw-r--r--tools/linguist/shared/proparserutils.h324
14 files changed, 4708 insertions, 2580 deletions
diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 96b1926..f9e08a0 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -40,7 +40,9 @@
****************************************************************************/
#include "translator.h"
-#include "profileevaluator.h"
+
+#include <profileparser.h>
+#include <profileevaluator.h>
#ifndef QT_BOOTSTRAPPED
#include <QtCore/QCoreApplication>
@@ -58,6 +60,8 @@
QT_USE_NAMESPACE
#ifdef QT_BOOTSTRAPPED
+static QString binDir;
+
static void initBinaryDir(
#ifndef Q_OS_WIN
const char *argv0
@@ -185,6 +189,40 @@ static bool releaseTsFile(const QString& tsFileName,
return releaseTranslator(tor, qmFileName, cd, removeIdentical);
}
+static void print(const QString &fileName, int lineNo, const QString &msg)
+{
+ if (lineNo)
+ printErr(QString::fromLatin1("%2(%1): %3").arg(lineNo).arg(fileName, msg));
+ else
+ printErr(msg);
+}
+
+class ParseHandler : public ProFileParserHandler {
+public:
+ virtual void parseError(const QString &fileName, int lineNo, const QString &msg)
+ { if (verbose) print(fileName, lineNo, msg); }
+
+ bool verbose;
+};
+
+class EvalHandler : public ProFileEvaluatorHandler {
+public:
+ virtual void configError(const QString &msg)
+ { printErr(msg); }
+ virtual void evalError(const QString &fileName, int lineNo, const QString &msg)
+ { if (verbose) print(fileName, lineNo, msg); }
+ virtual void fileMessage(const QString &msg)
+ { printErr(msg); }
+
+ virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {}
+ virtual void doneWithEval(ProFile *) {}
+
+ bool verbose;
+};
+
+static ParseHandler parseHandler;
+static EvalHandler evalHandler;
+
int main(int argc, char **argv)
{
#ifdef QT_BOOTSTRAPPED
@@ -272,23 +310,32 @@ int main(int argc, char **argv)
if (inputFile.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
|| inputFile.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
QFileInfo fi(inputFile);
- ProFile pro(fi.absoluteFilePath());
- ProFileEvaluator visitor;
- visitor.setVerbose(cd.isVerbose());
+ parseHandler.verbose = evalHandler.verbose = cd.isVerbose();
+ ProFileOption option;
+#ifdef QT_BOOTSTRAPPED
+ option.initProperties(binDir + QLatin1String("/qmake"));
+#else
+ option.initProperties(app.applicationDirPath() + QLatin1String("/qmake"));
+#endif
+ ProFileParser parser(0, &parseHandler);
+ ProFileEvaluator visitor(&option, &parser, &evalHandler);
- if (!visitor.queryProFile(&pro)) {
+ ProFile *pro;
+ if (!(pro = parser.parsedProFile(QDir::cleanPath(fi.absoluteFilePath())))) {
printErr(LR::tr(
"lrelease error: cannot read project file '%1'.\n")
.arg(inputFile));
continue;
}
- if (!visitor.accept(&pro)) {
+ if (!visitor.accept(pro)) {
printErr(LR::tr(
"lrelease error: cannot process project file '%1'.\n")
.arg(inputFile));
+ pro->deref();
continue;
}
+ pro->deref();
QStringList translations = visitor.values(QLatin1String("TRANSLATIONS"));
if (translations.isEmpty()) {
@@ -324,8 +371,6 @@ int main(int argc, char **argv)
# include <windows.h>
#endif
-static QString binDir;
-
static void initBinaryDir(
#ifndef Q_OS_WIN
const char *_argv0
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 737bfd0..34bb792 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -42,6 +42,7 @@
#include "lupdate.h"
#include <translator.h>
+#include <profileparser.h>
#include <profileevaluator.h>
#include <QtCore/QCoreApplication>
@@ -227,6 +228,40 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
}
}
+static void print(const QString &fileName, int lineNo, const QString &msg)
+{
+ if (lineNo)
+ printErr(QString::fromLatin1("%2(%1): %3").arg(lineNo).arg(fileName, msg));
+ else
+ printErr(msg);
+}
+
+class ParseHandler : public ProFileParserHandler {
+public:
+ virtual void parseError(const QString &fileName, int lineNo, const QString &msg)
+ { if (verbose) print(fileName, lineNo, msg); }
+
+ bool verbose;
+};
+
+class EvalHandler : public ProFileEvaluatorHandler {
+public:
+ virtual void configError(const QString &msg)
+ { printErr(msg); }
+ virtual void evalError(const QString &fileName, int lineNo, const QString &msg)
+ { if (verbose) print(fileName, lineNo, msg); }
+ virtual void fileMessage(const QString &msg)
+ { printErr(msg); }
+
+ virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {}
+ virtual void doneWithEval(ProFile *) {}
+
+ bool verbose;
+};
+
+static ParseHandler parseHandler;
+static EvalHandler evalHandler;
+
static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths,
const QString &projectDir, const ProFileEvaluator &visitor)
{
@@ -288,12 +323,14 @@ static void processSources(Translator &fetchedTor,
static void processProjects(
bool topLevel, bool nestComplain, const QStringList &proFiles,
+ ProFileOption *option, ProFileParser *parser,
UpdateOptions options, const QByteArray &codecForSource,
const QString &targetLanguage, const QString &sourceLanguage,
Translator *parentTor, bool *fail);
static void processProject(
- bool nestComplain, const QFileInfo &pfi, ProFileEvaluator &visitor,
+ bool nestComplain, const QFileInfo &pfi,
+ ProFileOption *option, ProFileParser *parser, ProFileEvaluator &visitor,
UpdateOptions options, const QByteArray &_codecForSource,
const QString &targetLanguage, const QString &sourceLanguage,
Translator *fetchedTor, bool *fail)
@@ -321,7 +358,7 @@ static void processProject(
else
subProFiles << subPro;
}
- processProjects(false, nestComplain, subProFiles, options, codecForSource,
+ processProjects(false, nestComplain, subProFiles, option, parser, options, codecForSource,
targetLanguage, sourceLanguage, fetchedTor, fail);
} else {
ConversionData cd;
@@ -347,23 +384,25 @@ static void processProject(
static void processProjects(
bool topLevel, bool nestComplain, const QStringList &proFiles,
+ ProFileOption *option, ProFileParser *parser,
UpdateOptions options, const QByteArray &codecForSource,
const QString &targetLanguage, const QString &sourceLanguage,
Translator *parentTor, bool *fail)
{
foreach (const QString &proFile, proFiles) {
- ProFileEvaluator visitor;
- visitor.setVerbose(options & Verbose);
-
- QHash<QString, QStringList> lupdateConfig;
- lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run")));
- visitor.addVariables(lupdateConfig);
-
QFileInfo pfi(proFile);
- ProFile pro(pfi.absoluteFilePath());
- if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) {
+
+ ProFileEvaluator visitor(option, parser, &evalHandler);
+ ProFile *pro;
+ if (!(pro = parser->parsedProFile(QDir::cleanPath(pfi.absoluteFilePath())))) {
+ if (topLevel)
+ *fail = true;
+ continue;
+ }
+ if (!visitor.accept(pro)) {
if (topLevel)
*fail = true;
+ pro->deref();
continue;
}
@@ -376,6 +415,7 @@ static void processProjects(
} else if (nestComplain) {
printErr(LU::tr("lupdate warning: TS files from command line "
"prevent recursing into %1.\n").arg(proFile));
+ pro->deref();
continue;
}
}
@@ -387,6 +427,7 @@ static void processProjects(
// This might mean either a buggy PRO file or an intentional detach -
// we can't know without seeing the actual RHS of the assignment ...
// Just assume correctness and be silent.
+ pro->deref();
continue;
}
Translator tor;
@@ -398,9 +439,10 @@ static void processProjects(
tor.setCodecName(tmp.last().toLatin1());
setCodec = true;
}
- processProject(false, pfi, visitor, options, codecForSource,
+ processProject(false, pfi, option, parser, visitor, options, codecForSource,
targetLanguage, sourceLanguage, &tor, fail);
updateTsFiles(tor, tsFiles, setCodec, sourceLanguage, targetLanguage, options, fail);
+ pro->deref();
continue;
}
noTrans:
@@ -409,12 +451,13 @@ static void processProjects(
printErr(LU::tr("lupdate warning: no TS files specified. Only diagnostics "
"will be produced for '%1'.\n").arg(proFile));
Translator tor;
- processProject(nestComplain, pfi, visitor, options, codecForSource,
+ processProject(nestComplain, pfi, option, parser, visitor, options, codecForSource,
targetLanguage, sourceLanguage, &tor, fail);
} else {
- processProject(nestComplain, pfi, visitor, options, codecForSource,
+ processProject(nestComplain, pfi, option, parser, visitor, options, codecForSource,
targetLanguage, sourceLanguage, parentTor, fail);
}
+ pro->deref();
}
}
@@ -714,15 +757,22 @@ int main(int argc, char **argv)
" Both project and source files / include paths specified.\n"));
return 1;
}
+
+ parseHandler.verbose = evalHandler.verbose = !!(options & Verbose);
+ ProFileOption option;
+ option.initProperties(app.applicationDirPath() + QLatin1String("/qmake"));
+ option.setCommandLineArguments(QStringList() << QLatin1String("CONFIG+=lupdate_run"));
+ ProFileParser parser(0, &parseHandler);
+
if (!tsFileNames.isEmpty()) {
Translator fetchedTor;
fetchedTor.setCodecName(codecForTr);
- processProjects(true, true, proFiles, options, QByteArray(),
+ processProjects(true, true, proFiles, &option, &parser, options, QByteArray(),
targetLanguage, sourceLanguage, &fetchedTor, &fail);
updateTsFiles(fetchedTor, tsFileNames, !codecForTr.isEmpty(),
sourceLanguage, targetLanguage, options, &fail);
} else {
- processProjects(true, false, proFiles, options, QByteArray(),
+ processProjects(true, false, proFiles, &option, &parser, options, QByteArray(),
targetLanguage, sourceLanguage, 0, &fail);
}
}
diff --git a/tools/linguist/shared/abstractproitemvisitor.h b/tools/linguist/shared/abstractproitemvisitor.h
deleted file mode 100644
index 73614c5..0000000
--- a/tools/linguist/shared/abstractproitemvisitor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Linguist of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.1, 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef ABSTRACTPROITEMVISITOR
-#define ABSTRACTPROITEMVISITOR
-
-#include "proitems.h"
-
-QT_BEGIN_NAMESPACE
-
-struct AbstractProItemVisitor
-{
- virtual ~AbstractProItemVisitor() {}
-
- virtual ProItem::ProItemReturn visitBeginProBlock(ProBlock *block) = 0;
- virtual void visitEndProBlock(ProBlock *block) = 0;
-
- virtual ProItem::ProItemReturn visitProLoopIteration() = 0;
- virtual void visitProLoopCleanup() = 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
-
-#endif // ABSTRACTPROITEMVISITOR
-
diff --git a/tools/linguist/shared/ioutils.cpp b/tools/linguist/shared/ioutils.cpp
new file mode 100644
index 0000000..fbee8fc
--- /dev/null
+++ b/tools/linguist/shared/ioutils.cpp
@@ -0,0 +1,152 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "ioutils.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+#else
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <unistd.h>
+#endif
+
+using namespace ProFileEvaluatorInternal;
+
+IoUtils::FileType IoUtils::fileType(const QString &fileName)
+{
+ Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName));
+#ifdef Q_OS_WIN
+ DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16());
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return FileNotFound;
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular;
+#else
+ struct ::stat st;
+ if (::stat(fileName.toLocal8Bit().constData(), &st))
+ return FileNotFound;
+ return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular;
+#endif
+}
+
+bool IoUtils::isRelativePath(const QString &path)
+{
+ if (path.startsWith(QLatin1Char('/')))
+ return false;
+#ifdef Q_OS_WIN
+ if (path.startsWith(QLatin1Char('\\')))
+ return false;
+ // Unlike QFileInfo, this won't accept a relative path with a drive letter.
+ // Such paths result in a royal mess anyway ...
+ if (path.length() >= 3 && path.at(1) == QLatin1Char(':') && path.at(0).isLetter()
+ && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\')))
+ return false;
+#endif
+ return true;
+}
+
+QStringRef IoUtils::fileName(const QString &fileName)
+{
+ return fileName.midRef(fileName.lastIndexOf(QLatin1Char('/')) + 1);
+}
+
+QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
+{
+ if (fileName.isEmpty())
+ return QString();
+ if (isAbsolutePath(fileName))
+ return QDir::cleanPath(fileName);
+ return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
+}
+
+#ifdef QT_BOOTSTRAPPED
+inline static bool isSpecialChar(ushort c)
+{
+ // Chars that should be quoted (TM). This includes:
+#ifdef Q_OS_WIN
+ // - control chars & space
+ // - the shell meta chars "&()<>^|
+ // - the potential separators ,;=
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
+ };
+#else
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
+ 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
+ }; // 0-32 \'"$`<>|;&(){}*?#!~[]
+#endif
+
+ return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
+}
+
+inline static bool hasSpecialChars(const QString &arg)
+{
+ for (int x = arg.length() - 1; x >= 0; --x)
+ if (isSpecialChar(arg.unicode()[x].unicode()))
+ return true;
+ return false;
+}
+
+QString IoUtils::shellQuote(const QString &arg)
+{
+ if (!arg.length())
+ return QString::fromLatin1("\"\"");
+
+ QString ret(arg);
+ if (hasSpecialChars(ret)) {
+#ifdef Q_OS_WIN
+ // Quotes are escaped and their preceding backslashes are doubled.
+ // It's impossible to escape anything inside a quoted string on cmd
+ // level, so the outer quoting must be "suspended".
+ ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
+ // The argument must not end with a \ since this would be interpreted
+ // as escaping the quote -- rather put the \ behind the quote: e.g.
+ // rather use "foo"\ than "foo\"
+ int i = ret.length();
+ while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
+ --i;
+ ret.insert(i, QLatin1Char('"'));
+ ret.prepend(QLatin1Char('"'));
+#else // Q_OS_WIN
+ ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
+ ret.prepend(QLatin1Char('\''));
+ ret.append(QLatin1Char('\''));
+#endif // Q_OS_WIN
+ }
+ return ret;
+}
+#endif
diff --git a/tools/linguist/shared/ioutils.h b/tools/linguist/shared/ioutils.h
new file mode 100644