diff options
Diffstat (limited to 'src/linguist/shared')
44 files changed, 1080 insertions, 1620 deletions
diff --git a/src/linguist/shared/fmt.h b/src/linguist/shared/fmt.h new file mode 100644 index 000000000..b40cdd308 --- /dev/null +++ b/src/linguist/shared/fmt.h @@ -0,0 +1,17 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef FMT_H +#define FMT_H + +#include <QtCore/qcoreapplication.h> + +QT_BEGIN_NAMESPACE + +class FMT { + Q_DECLARE_TR_FUNCTIONS(Linguist) +}; + +QT_END_NAMESPACE + +#endif // FMT_H diff --git a/src/linguist/shared/ioutils.cpp b/src/linguist/shared/ioutils.cpp index d94348440..71bf0020c 100644 --- a/src/linguist/shared/ioutils.cpp +++ b/src/linguist/shared/ioutils.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "ioutils.h" @@ -33,7 +8,7 @@ #include <qregularexpression.h> #ifdef Q_OS_WIN -# include <windows.h> +# include <qt_windows.h> #else # include <sys/types.h> # include <sys/stat.h> @@ -49,6 +24,40 @@ QT_BEGIN_NAMESPACE using namespace QMakeInternal; +QString IoUtils::binaryAbsLocation(const QString &argv0) +{ + QString ret; + if (!argv0.isEmpty() && isAbsolutePath(argv0)) { + ret = argv0; + } else if (argv0.contains(QLatin1Char('/')) +#ifdef Q_OS_WIN + || argv0.contains(QLatin1Char('\\')) +#endif + ) { // relative PWD + ret = QDir::current().absoluteFilePath(argv0); + } else { // in the PATH + QByteArray pEnv = qgetenv("PATH"); + QDir currentDir = QDir::current(); +#ifdef Q_OS_WIN + QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";")); + paths.prepend(QLatin1String(".")); +#else + QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":")); +#endif + for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { + if ((*p).isEmpty()) + continue; + QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0); + if (QFile::exists(candidate)) { + ret = candidate; + break; + } + } + } + + return QDir::cleanPath(ret); +} + IoUtils::FileType IoUtils::fileType(const QString &fileName) { Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName)); @@ -78,7 +87,12 @@ bool IoUtils::isRelativePath(const QString &path) && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\'))) { return false; } - // (... unless, of course, they're UNC, which qmake fails on anyway) + // ... unless, of course, they're UNC: + if (path.length() >= 2 + && (path.at(0).unicode() == '\\' || path.at(0).unicode() == '/') + && path.at(1) == path.at(0)) { + return false; + } #else if (path.startsWith(QLatin1Char('/'))) return false; @@ -86,14 +100,14 @@ bool IoUtils::isRelativePath(const QString &path) return true; } -QStringView IoUtils::pathName(QStringView fileName) +QStringView IoUtils::pathName(const QString &fileName) { - return fileName.left(fileName.lastIndexOf(QLatin1Char('/')) + 1); + return QStringView{fileName}.left(fileName.lastIndexOf(QLatin1Char('/')) + 1); } -QStringView IoUtils::fileName(QStringView fileName) +QStringView IoUtils::fileName(const QString &fileName) { - return fileName.mid(fileName.lastIndexOf(QLatin1Char('/')) + 1); + return QStringView(fileName).mid(fileName.lastIndexOf(QLatin1Char('/')) + 1); } QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName) @@ -122,7 +136,7 @@ bool isSpecialChar(ushort c, const uchar (&iqm)[16]) inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16]) { - for (int x = arg.length() - 1; x >= 0; --x) { + for (int x = arg.size() - 1; x >= 0; --x) { if (isSpecialChar(arg.unicode()[x].unicode(), iqm)) return true; } @@ -137,7 +151,7 @@ QString IoUtils::shellQuoteUnix(const QString &arg) 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78 }; // 0-32 \'"$`<>|;&(){}*?#!~[] - if (!arg.length()) + if (!arg.size()) return QString::fromLatin1("''"); QString ret(arg); @@ -165,7 +179,7 @@ QString IoUtils::shellQuoteWin(const QString &arg) 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10 }; // &()<>^| - if (!arg.length()) + if (!arg.size()) return QString::fromLatin1("\"\""); QString ret(arg); @@ -181,7 +195,7 @@ QString IoUtils::shellQuoteWin(const QString &arg) // to the called process verbatim. In the unquoted state, the circumflex escapes // meta chars (including itself and quotes), and is removed from the command. bool quoted = true; - for (int i = 0; i < ret.length(); i++) { + for (int i = 0; i < ret.size(); i++) { QChar c = ret.unicode()[i]; if (c.unicode() == '"') quoted = !quoted; diff --git a/src/linguist/shared/ioutils.h b/src/linguist/shared/ioutils.h index 8726a35c3..2f288e543 100644 --- a/src/linguist/shared/ioutils.h +++ b/src/linguist/shared/ioutils.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef IOUTILS_H #define IOUTILS_H @@ -49,12 +24,13 @@ public: FileIsDir = 2 }; + static QString binaryAbsLocation(const QString &argv0); static FileType fileType(const QString &fileName); static bool exists(const QString &fileName) { return fileType(fileName) != FileNotFound; } static bool isRelativePath(const QString &fileName); static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); } - static QStringView pathName(QStringView fileName); // Requires normalized path - static QStringView fileName(QStringView fileName); // Requires normalized path + static QStringView pathName(const QString &fileName); // Requires normalized path + static QStringView fileName(const QString &fileName); // Requires normalized path static QString resolvePath(const QString &baseDir, const QString &fileName); static QString shellQuoteUnix(const QString &arg); static QString shellQuoteWin(const QString &arg); diff --git a/src/linguist/shared/numerus.cpp b/src/linguist/shared/numerus.cpp index 5b4895233..ef52bcdb6 100644 --- a/src/linguist/shared/numerus.cpp +++ b/src/linguist/shared/numerus.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -290,22 +265,22 @@ static const QLocale::Language welshLanguage[] = { QLocale::Welsh, EOL }; static const QLocale::Language arabicLanguage[] = { QLocale::Arabic, EOL }; static const QLocale::Language tagalogLanguage[] = { QLocale::Filipino, EOL }; -static const QLocale::Country frenchStyleCountries[] = { +static const QLocale::Territory frenchStyleCountries[] = { // keep synchronized with frenchStyleLanguages - QLocale::AnyCountry, - QLocale::AnyCountry, - QLocale::AnyCountry, + QLocale::AnyTerritory, + QLocale::AnyTerritory, + QLocale::AnyTerritory, QLocale::Brazil, - QLocale::AnyCountry, - QLocale::AnyCountry, - QLocale::AnyCountry + QLocale::AnyTerritory, + QLocale::AnyTerritory, + QLocale::AnyTerritory }; struct NumerusTableEntry { const uchar *rules; int rulesSize; const char * const *forms; const QLocale::Language *languages; - const QLocale::Country *countries; + const QLocale::Territory *countries; const char * const gettextRules; }; @@ -349,7 +324,7 @@ static const NumerusTableEntry numerusTable[] = { static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]); -bool getNumerusInfo(QLocale::Language language, QLocale::Country country, +bool getNumerusInfo(QLocale::Language language, QLocale::Territory country, QByteArray *rules, QStringList *forms, const char **gettextRules) { while (true) { @@ -357,7 +332,7 @@ bool getNumerusInfo(QLocale::Language language, QLocale::Country country, const NumerusTableEntry &entry = numerusTable[i]; for (int j = 0; entry.languages[j] != EOL; ++j) { if (entry.languages[j] == language - && ((!entry.countries && country == QLocale::AnyCountry) + && ((!entry.countries && country == QLocale::AnyTerritory) || (entry.countries && entry.countries[j] == country))) { if (rules) { *rules = QByteArray::fromRawData(reinterpret_cast<const char *>(entry.rules), @@ -375,9 +350,9 @@ bool getNumerusInfo(QLocale::Language language, QLocale::Country country, } } - if (country == QLocale::AnyCountry) + if (country == QLocale::AnyTerritory) break; - country = QLocale::AnyCountry; + country = QLocale::AnyTerritory; } return false; } @@ -389,14 +364,15 @@ QString getNumerusInfoString() for (int i = 0; i < NumerusTableSize; ++i) { const NumerusTableEntry &entry = numerusTable[i]; for (int j = 0; entry.languages[j] != EOL; ++j) { - QLocale loc(entry.languages[j], entry.countries ? entry.countries[j] : QLocale::AnyCountry); + QLocale loc(entry.languages[j], entry.countries ? entry.countries[j] + : QLocale::AnyTerritory); QString lang = QLocale::languageToString(entry.languages[j]); if (loc.language() == QLocale::C) lang += QLatin1String(" (!!!)"); - else if (entry.countries && entry.countries[j] != QLocale::AnyCountry) - lang += QLatin1String(" (") + QLocale::countryToString(loc.country()) + QLatin1Char(')'); + else if (entry.countries && entry.countries[j] != QLocale::AnyTerritory) + lang += QLatin1String(" (%1)").arg(QLocale::territoryToString(loc.territory())); else - lang += QLatin1String(" [") + QLocale::countryToString(loc.country()) + QLatin1Char(']'); + lang += QLatin1String(" [%1]").arg(QLocale::territoryToString(loc.territory())); langs << QString::fromLatin1("%1 %2 %3\n").arg(lang, -40).arg(loc.name(), -8) .arg(QString::fromLatin1(entry.gettextRules)); } diff --git a/src/linguist/shared/po.cpp b/src/linguist/shared/po.cpp index d9aa24bbd..1da8b95d2 100644 --- a/src/linguist/shared/po.cpp +++ b/src/linguist/shared/po.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -52,7 +27,7 @@ static QString poEscapedString(const QString &prefix, const QString &keyword, QStringList lines; int off = 0; QString res; - while (off < ba.length()) { + while (off < ba.size()) { ushort c = ba[off++].unicode(); switch (c) { case '\n': @@ -88,7 +63,7 @@ static QString poEscapedString(const QString &prefix, const QString &keyword, if (c < 32) { res += QLatin1String("\\x"); res += QString::number(c, 16); - if (off < ba.length() && isxdigit(ba[off].unicode())) + if (off < ba.size() && isxdigit(ba[off].unicode())) res += QLatin1String("\"\""); } else { res += QChar(c); @@ -100,15 +75,15 @@ static QString poEscapedString(const QString &prefix, const QString &keyword, lines.append(res); if (!lines.isEmpty()) { if (!noWrap) { - if (lines.count() != 1 || - lines.first().length() > MAX_LEN - keyword.length() - prefix.length() - 3) + if (lines.size() != 1 || + lines.first().size() > MAX_LEN - keyword.size() - prefix.size() - 3) { const QStringList olines = lines; lines = QStringList(QString()); - const int maxlen = MAX_LEN - prefix.length() - 2; + const int maxlen = MAX_LEN - prefix.size() - 2; for (const QString &line : olines) { int off = 0; - while (off + maxlen < line.length()) { + while (off + maxlen < line.size()) { int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1) + 1; if (idx == off) { #ifdef HARD_WRAP_LONG_WORDS @@ -126,7 +101,7 @@ static QString poEscapedString(const QString &prefix, const QString &keyword, lines.append(line.mid(off)); } } - } else if (lines.count() > 1) { + } else if (lines.size() > 1) { lines.prepend(QString()); } } @@ -158,10 +133,10 @@ static QString poEscapedLines(const QString &prefix, bool addSpace, const QStrin static QString poWrappedEscapedLines(const QString &prefix, bool addSpace, const QString &line) { - const int maxlen = MAX_LEN - prefix.length() - addSpace; + const int maxlen = MAX_LEN - prefix.size() - addSpace; QStringList lines; int off = 0; - while (off + maxlen < line.length()) { + while (off + maxlen < line.size()) { int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1); if (idx < off) { #if 0 //def HARD_WRAP_LONG_WORDS @@ -227,11 +202,11 @@ static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l, break; offset++; forever { - if (offset == line.length()) + if (offset == line.size()) goto premature_eol; uchar c = line[offset++]; if (c == '"') { - if (offset == line.length()) + if (offset == line.size()) break; while (isspace(line[offset])) offset++; @@ -244,7 +219,7 @@ static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l, continue; } if (c == '\\') { - if (offset == line.length()) + if (offset == line.size()) goto premature_eol; c = line[offset++]; switch (c) { @@ -285,14 +260,14 @@ static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l, case '7': stoff = offset - 1; while ((c = line[offset]) >= '0' && c <= '7') - if (++offset == line.length()) + if (++offset == line.size()) goto premature_eol; msg += line.mid(stoff, offset - stoff).toUInt(0, 8); break; case 'x': stoff = offset; while (isxdigit(line[offset])) - if (++offset == line.length()) + if (++offset == line.size()) goto premature_eol; msg += line.mid(stoff, offset - stoff).toUInt(0, 16); break; @@ -435,7 +410,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) bool isObsolete = line.startsWith("#~ msgstr"); const QByteArray prefix = isObsolete ? "#~ " : ""; while (true) { - int idx = line.indexOf(' ', prefix.length()); + int idx = line.indexOf(' ', prefix.size()); QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd); item.msgStr.append(str); if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1))) @@ -476,7 +451,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) .arg(QString::fromLatin1(hdrValue))); error = true; // This will avoid a flood of conversion errors. - toUnicode = QStringConverter::Latin1; + toUnicode = QStringDecoder(QStringConverter::Latin1); } else { QByteArray cod = hdrValue.mid(20); auto enc = QStringConverter::encodingForName(cod); @@ -485,9 +460,9 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) .arg(QString::fromLatin1(cod))); error = true; // This will avoid a flood of conversion errors. - toUnicode = QStringConverter::Latin1; + toUnicode = QStringDecoder(QStringConverter::Latin1); } else { - toUnicode = *enc; + toUnicode = QStringDecoder(*enc); } } } else if (hdrName == "Content-Transfer-Encoding") { @@ -516,7 +491,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) "Plural-Forms", "X-Language", "X-Source-Language", "X-Qt-Contexts" }; uint cdh = 0; - for (int cho = 0; cho < hdrOrder.length(); cho++) { + for (int cho = 0; cho < hdrOrder.size(); cho++) { for (;; cdh++) { if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) { extras[QLatin1String("po-headers")] = @@ -573,7 +548,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) msg.setTranslatorComment(toUnicode(item.translatorComments)); msg.setPlural(item.isPlural || item.msgStr.size() > 1); QStringList translations; - for (const QByteArray &bstr : qAsConst(item.msgStr)) { + for (const QByteArray &bstr : std::as_const(item.msgStr)) { QString str = toUnicode(bstr); str.replace(QChar(Translator::TextVariantSeparator), QChar(Translator::BinaryVariantSeparator)); @@ -754,8 +729,8 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &) addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit")); if (!translator.languageCode().isEmpty()) { QLocale::Language l; - QLocale::Country c; - Translator::languageAndCountry(translator.languageCode(), &l, &c); + QLocale::Territory c; + Translator::languageAndTerritory(translator.languageCode(), &l, &c); const char *gettextRules; if (getNumerusInfo(l, c, 0, 0, &gettextRules)) addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules)); @@ -766,7 +741,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &) if (qtContexts) addPoHeader(headers, hdrOrder, "X-Qt-Contexts", QLatin1String("true")); QString hdrStr; - for (const QString &hdr : qAsConst(hdrOrder)) { + for (const QString &hdr : std::as_const(hdrOrder)) { hdrStr += hdr; hdrStr += QLatin1String(": "); hdrStr += headers.value(makePoHeader(hdr)); @@ -820,7 +795,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &) // This is fuzzy logic, as we don't know whether the string is // actually used with QString::arg(). for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) { - if (++off >= source.length()) + if (++off >= source.size()) break; if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) { flags.append(QLatin1String("qt-format")); diff --git a/src/linguist/shared/profileevaluator.cpp b/src/linguist/shared/profileevaluator.cpp index 77059fa94..a22a45672 100644 --- a/src/linguist/shared/profileevaluator.cpp +++ b/src/linguist/shared/profileevaluator.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "profileevaluator.h" @@ -152,7 +127,7 @@ QStringList ProFileEvaluator::absoluteFileValues( // because no sane project would add generated files by wildcard. if (IoUtils::fileType(absDir) == IoUtils::FileIsDir) { QString wildcard = d->m_tmp2.setRawData(absEl.constData() + nameOff + 1, - absEl.length() - nameOff - 1); + absEl.size() - nameOff - 1); if (wildcard.contains(QLatin1Char('*')) || wildcard.contains(QLatin1Char('?'))) { QDir theDir(absDir); for (const QString &fn : theDir.entryList(QStringList(wildcard))) @@ -169,7 +144,7 @@ QStringList ProFileEvaluator::absoluteFileValues( ProFileEvaluator::TemplateType ProFileEvaluator::templateType() const { const ProStringList &templ = d->values(ProKey("TEMPLATE")); - if (templ.count() >= 1) { + if (templ.size() >= 1) { const QString &t = templ.at(0).toQString(); if (!t.compare(QLatin1String("app"), Qt::CaseInsensitive)) return TT_Application; diff --git a/src/linguist/shared/profileevaluator.h b/src/linguist/shared/profileevaluator.h index 1280d182d..1e8a50205 100644 --- a/src/linguist/shared/profileevaluator.h +++ b/src/linguist/shared/profileevaluator.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PROFILEEVALUATOR_H #define PROFILEEVALUATOR_H diff --git a/src/linguist/shared/profileutils.h b/src/linguist/shared/profileutils.h index a4ffb7389..de4555976 100644 --- a/src/linguist/shared/profileutils.h +++ b/src/linguist/shared/profileutils.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PROFILEUTILS_H #define PROFILEUTILS_H diff --git a/src/linguist/shared/proitems.cpp b/src/linguist/shared/proitems.cpp index 2d8faff73..2edd40a35 100644 --- a/src/linguist/shared/proitems.cpp +++ b/src/linguist/shared/proitems.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "proitems.h" @@ -32,6 +7,7 @@ #include <qset.h> #include <qstringlist.h> #include <qtextstream.h> +#include <private/qduplicatetracker_p.h> QT_BEGIN_NAMESPACE @@ -64,13 +40,13 @@ ProString::ProString(const ProString &other, OmitPreHashing) : } ProString::ProString(const QString &str, DoPreHashing) : - m_string(str), m_offset(0), m_length(str.length()), m_file(0) + m_string(str), m_offset(0), m_length(str.size()), m_file(0) { updatedHash(); } ProString::ProString(const QString &str) : - m_string(str), m_offset(0), m_length(str.length()), m_file(0), m_hash(0x80000000) + m_string(str), m_offset(0), m_length(str.size()), m_file(0), m_hash(0x80000000) { } @@ -108,7 +84,7 @@ ProString::ProString(const QString &str, int offset, int length) : void ProString::setValue(const QString &str) { - m_string = str, m_offset = 0, m_length = str.length(), m_hash = 0x80000000; + m_string = str, m_offset = 0, m_length = str.size(), m_hash = 0x80000000; } size_t ProString::updatedHash() const @@ -145,7 +121,7 @@ ProKey::ProKey(const QString &str, int off, int len, uint hash) : void ProKey::setValue(const QString &str) { - m_string = str, m_offset = 0, m_length = str.length(); + m_string = str, m_offset = 0, m_length = str.size(); updatedHash(); } @@ -160,51 +136,18 @@ QString &ProString::toQString(QString &tmp) const return tmp; } -/*! - * \brief ProString::prepareExtend - * \param extraLen number of new characters to be added - * \param thisTarget offset to which current contents should be moved - * \param extraTarget offset at which new characters will be added - * \return pointer to storage location for new characters - * - * Prepares the string for adding new characters. - * If the string is detached and has enough space, it will be changed in place. - * Otherwise, it will be replaced with a new string object, thus detaching. - * In either case, the hash will be reset. - */ -QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget) -{ - if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) { - m_string.reserve(0); // Prevent the resize() below from reallocating - QChar *ptr = (QChar *)m_string.constData(); - if (m_offset != thisTarget) - memmove(ptr + thisTarget, ptr + m_offset, m_length * 2); - ptr += extraTarget; - m_offset = 0; - m_length += extraLen; - m_string.resize(m_length); - m_hash = 0x80000000; - return ptr; - } else { - QString neu(m_length + extraLen, Qt::Uninitialized); - QChar *ptr = (QChar *)neu.constData(); - memcpy(ptr + thisTarget, m_string.constData() + m_offset, m_length * 2); - ptr += extraTarget; - *this = ProString(neu); - return ptr; - } -} - ProString &ProString::prepend(const ProString &other) { if (other.m_length) { if (!m_length) { *this = other; } else { - QChar *ptr = prepareExtend(other.m_length, other.m_length, 0); - memcpy(ptr, other.constData(), other.m_length * 2); + m_string = other.toQStringView() + toQStringView(); + m_offset = 0; + m_length = m_string.size(); if (!m_file) m_file = other.m_file; + m_hash = 0x80000000; } } return *this; @@ -212,20 +155,33 @@ ProString &ProString::prepend(const ProString &other) ProString &ProString::append(const QLatin1String other) { - const char *latin1 = other.latin1(); - int size = other.size(); - if (size) { - QChar *ptr = prepareExtend(size, 0, m_length); - for (int i = 0; i < size; i++) - *ptr++ = QLatin1Char(latin1[i]); + if (other.size()) { + if (m_length != m_string.size()) { + m_string = toQStringView() + other; + m_offset = 0; + m_length = m_string.size(); + } else { + Q_ASSERT(m_offset == 0); + m_string.append(other); + m_length += other.size(); + } + m_hash = 0x80000000; } return *this; } ProString &ProString::append(QChar other) { - QChar *ptr = prepareExtend(1, 0, m_length); - *ptr = other; + if (m_length != m_string.size()) { + m_string = toQStringView() + other; + m_offset = 0; + m_length = m_string.size(); + } else { + Q_ASSERT(m_offset == 0); + m_string.append(other); + ++m_length; + } + m_hash = 0x80000000; return *this; } @@ -236,16 +192,18 @@ ProString &ProString::append(const ProString &other, bool *pending) if (!m_length) { *this = other; } else { - QChar *ptr; + if (m_length != m_string.size()) + m_string = toQString(); if (pending && !*pending) { - ptr = prepareExtend(1 + other.m_length, 0, m_length); - *ptr++ = u' '; + m_string += QLatin1Char(' ') + other.toQStringView(); } else { - ptr = prepareExtend(other.m_length, 0, m_length); + m_string += other.toQStringView(); } - memcpy(ptr, other.m_string.constData() + other.m_offset, other.m_length * 2); + m_length = m_string.size(); + m_offset = 0; if (other.m_file) m_file = other.m_file; + m_hash = 0x80000000; } if (pending) *pending = true; @@ -265,27 +223,24 @@ ProString &ProString::append(const ProStringList &other, bool *pending, bool ski if (!m_length && sz == startIdx + 1) { *this = other.at(startIdx); } else { - int totalLength = sz - startIdx; - for (int i = startIdx; i < sz; ++i) - totalLength += other.at(i).size(); bool putSpace = false; if (pending && !*pending && m_length) putSpace = true; - else - totalLength--; - QChar *ptr = prepareExtend(totalLength, 0, m_length); + m_string = toQString(); + m_offset = 0; for (int i = startIdx; i < sz; ++i) { if (putSpace) - *ptr++ = u' '; + m_string += QLatin1Char(' '); else putSpace = true; const ProString &str = other.at(i); - memcpy(ptr, str.m_string.constData() + str.m_offset, str.m_length * 2); - ptr += str.m_length; + m_string += str.toQStringView(); } + m_length = m_string.size(); if (other.last().m_file) m_file = other.last().m_file; + m_hash = 0x80000000; } if (pending) *pending = true; @@ -419,21 +374,8 @@ void ProStringList::removeEmpty() void ProStringList::removeDuplicates() { - int n = size(); - int j = 0; - QSet<ProString> seen; - seen.reserve(n); - for (int i = 0; i < n; ++i) { - const ProString &s = at(i); - if (seen.contains(s)) - continue; - seen.insert(s); - if (j != i) - (*this)[j] = s; - ++j; - } - if (n != j) - erase(begin() + j, end()); + QDuplicateTracker<ProString> seen(size()); + removeIf([&](const ProString &s) { return seen.hasSeen(s); }); } void ProStringList::insertUnique(const ProStringList &value) @@ -518,4 +460,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr) return ret; } +QDebug operator<<(QDebug debug, const ProString &str) +{ + return debug << str.toQString(); +} + QT_END_NAMESPACE diff --git a/src/linguist/shared/proitems.h b/src/linguist/shared/proitems.h index 218d02a79..23339a145 100644 --- a/src/linguist/shared/proitems.h +++ b/src/linguist/shared/proitems.h @@ -1,36 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PROITEMS_H #define PROITEMS_H #include "qmake_global.h" +#include <qdebug.h> #include <qhash.h> #include <qlist.h> #include <qmap.h> @@ -69,9 +45,16 @@ public: ProString(); ProString(const ProString &other); ProString &operator=(const ProString &) = default; - PROITEM_EXPLICIT ProString(const QString &str); + template<typename A, typename B> + ProString &operator=(const QStringBuilder<A, B> &str) + { return *this = QString(str); } + ProString(const QString &str); PROITEM_EXPLICIT ProString(QStringView str); PROITEM_EXPLICIT ProString(const char *str); + template<typename A, typename B> + ProString(const QStringBuilder<A, B> &str) + : ProString(QString(str)) + {} ProString(const QString &str, int offset, int length); void setValue(const QString &str); void clear() { m_string.clear(); m_length = 0; } @@ -82,12 +65,16 @@ public: ProString &prepend(const ProString &other); ProString &append(const ProString &other, bool *pending = nullptr); ProString &append(const QString &other) { return append(ProString(other)); } + template<typename A, typename B> + ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); } ProString &append(const QLatin1String other); ProString &append(const char *other) { return append(QLatin1String(other)); } ProString &append(QChar other); ProString &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false); ProString &operator+=(const ProString &other) { return append(other); } ProString &operator+=(const QString &other) { return append(other); } + template<typename A, typename B> + ProString &operator+=(const QStringBuilder<A, B> &other) { return append(QString(other)); } ProString &operator+=(const QLatin1String other) { return append(other); } ProString &operator+=(const char *other) { return append(other); } ProString &operator+=(QChar other) { return append(other); } @@ -122,9 +109,13 @@ public: bool startsWith(const QString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().startsWith(sub, cs); } bool startsWith(const char *sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().startsWith(QLatin1String(sub), cs); } bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().startsWith(c, cs); } + template<typename A, typename B> + bool startsWith(const QStringBuilder<A, B> &str) { return startsWith(QString(str)); } bool endsWith(const ProString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().endsWith(sub.toQStringView(), cs); } bool endsWith(const QString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().endsWith(sub, cs); } bool endsWith(const char *sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().endsWith(QLatin1String(sub), cs); } + template<typename A, typename B> + bool endsWith(const QStringBuilder<A, B> &str) { return endsWith(QString(str)); } bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().endsWith(c, cs); } int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().indexOf(s, from, cs); } int indexOf(const char *s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringView().indexOf(QLatin1String(s), from, cs); } @@ -135,7 +126,7 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringView().toLongLong(ok, base); } + qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringView().toLongLong(ok, base); } int toInt(bool *ok = nullptr, int base = 10) const { return toQStringView().toInt(ok, base); } short toShort(bool *ok = nullptr, int base = 10) const { return toQStringView().toShort(ok, base); } @@ -168,8 +159,7 @@ private: QString m_string; int m_offset, m_length; int m_file; - mutable uint m_hash; - QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget); + mutable size_t m_hash; size_t updatedHash() const; friend size_t qHash(const ProString &str); friend QString operator+(const ProString &one, const ProString &two); @@ -177,10 +167,15 @@ private: }; Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE); + class ProKey : public ProString { public: ALWAYS_INLINE ProKey() : ProString() {} explicit ProKey(const QString &str); + template<typename A, typename B> + ProKey(const QStringBuilder<A, B> &str) + : ProString(str) + {} PROITEM_EXPLICIT ProKey(const char *str); ProKey(const QString &str, int off, int len); ProKey(const QString &str, int off, int len, uint hash); @@ -204,31 +199,47 @@ private: }; Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE); +template <> struct QConcatenable<ProString> +{ + typedef ProString type; + typedef QString ConvertTo; + enum { ExactSize = true }; + static int size(const ProString &a) { return a.length(); } + static inline void appendTo(const ProString &a, QChar *&out) + { + const auto n = a.size(); + if (!n) + return; + memcpy(out, a.toQStringView().data(), sizeof(QChar) * n); + out += n; + } +}; + +template <> struct QConcatenable<ProKey> +{ + typedef ProKey type; + typedef QString ConvertTo; + enum { ExactSize = true }; + static int size(const ProKey &a) { return a.length(); } + static inline void appendTo(const ProKey &a, QChar *&out) + { + const auto n = a.size(); + if (!n) + return; + memcpy(out, a.toQStringView().data(), sizeof(QChar) * n); + out += n; + } +}; + + size_t qHash(const ProString &str); -QString operator+(const ProString &one, const ProString &two); -inline QString operator+(const ProString &one, const QString &two) - { return one.toQStringView() + two; } -inline QString operator+(const QString &one, const ProString &two) - { return one + two.toQStringView(); } - -inline QString operator+(const ProString &one, const char *two) - { return one.toQStringView() + QLatin1String(two); } -inline QString operator+(const char *one, const ProString &two) - { return QLatin1String(one) + two.toQStringView(); } -inline QString operator+(const ProString &one, QChar two) - { return one.toQStringView() + two; } -inline QString operator+(QChar one, const ProString &two) - { return one + two.toQStringView(); } inline QString &operator+=(QString &that, const ProString &other) { return that += other.toQStringView(); } -inline bool operator==(const QString &that, const ProString &other) - { return other == that; } -inline bool operator!=(const QString &that, const ProString &other) - { return !(other == that); } - QTextStream &operator<<(QTextStream &t, const ProString &str); +template<typename A, typename B> +QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); } // This class manages read-only access to a ProString via a raw data QString // temporary, ensuring that the latter is accessed exclusively. @@ -246,7 +257,7 @@ public: } // No destructor, as a RAII pattern cannot be used: references to the // temporary string can legitimately outlive instances of this class - // (if they are held by Qt, e.g. in QRegularExpression). + // (if they are held by Qt, e.g. in QRegExp). QString &set(const ProString &ps) { return ps.toQString(*m_rs); } QString &str() { return *m_rs; } @@ -293,6 +304,8 @@ public: QString join(const ProString &sep) const; QString join(const QString &sep) const; QString join(QChar sep) const; + template<typename A, typename B> + QString join(const QStringBuilder<A, B> &str) { return join(QString(str)); } void insertUnique(const ProStringList &value); @@ -429,7 +442,7 @@ class ProFunctionDef { public: ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } - ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef(ProFunctionDef &&other) noexcept : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } ~ProFunctionDef() { if (m_pro) m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) @@ -443,13 +456,13 @@ public: } return *this; } - ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef &operator=(ProFunctionDef &&other) noexcept { ProFunctionDef moved(std::move(other)); swap(moved); return *this; } - void swap(ProFunctionDef &other) Q_DECL_NOTHROW + void swap(ProFunctionDef &other) noexcept { qSwap(m_pro, other.m_pro); qSwap(m_offset, other.m_offset); @@ -469,6 +482,8 @@ struct ProFunctionDefs { QHash<ProKey, ProFunctionDef> replaceFunctions; }; +QDebug operator<<(QDebug debug, const ProString &str); + QT_END_NAMESPACE #endif // PROITEMS_H diff --git a/src/linguist/shared/projectdescriptionreader.cpp b/src/linguist/shared/projectdescriptionreader.cpp index 9ba1d23f9..eded3a650 100644 --- a/src/linguist/shared/projectdescriptionreader.cpp +++ b/src/linguist/shared/projectdescriptionreader.cpp @@ -1,32 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "projectdescriptionreader.h" +#include "fmt.h" #include <QtCore/qcoreapplication.h> #include <QtCore/qfile.h> @@ -40,10 +16,6 @@ using std::placeholders::_1; -class FMT { - Q_DECLARE_TR_FUNCTIONS(Linguist) -}; - class Validator { public: diff --git a/src/linguist/shared/projectdescriptionreader.h b/src/linguist/shared/projectdescriptionreader.h index 8aad4acbe..0222bdb42 100644 --- a/src/linguist/shared/projectdescriptionreader.h +++ b/src/linguist/shared/projectdescriptionreader.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PROJECTDESCRIPTIONREADER_H #define PROJECTDESCRIPTIONREADER_H diff --git a/src/linguist/shared/proparser.qrc b/src/linguist/shared/proparser.qrc deleted file mode 100644 index 77ffd258a..000000000 --- a/src/linguist/shared/proparser.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/qmake/override_features" > - <file>exclusive_builds.prf</file> - </qresource> -</RCC> diff --git a/src/linguist/shared/qm.cpp b/src/linguist/shared/qm.cpp index f51735148..82605f492 100644 --- a/src/linguist/shared/qm.cpp +++ b/src/linguist/shared/qm.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -38,6 +13,7 @@ #include <QtCore/QFileInfo> #include <QtCore/QMap> #include <QtCore/QString> +#include <QtCore/QStringDecoder> QT_BEGIN_NAMESPACE @@ -220,7 +196,7 @@ Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTransla void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream, TranslatorSaveMode mode, Prefix prefix) const { - for (int i = 0; i < msg.translations().count(); ++i) + for (int i = 0; i < msg.translations().size(); ++i) stream << quint8(Tag_Translation) << msg.translations().at(i); if (mode == SaveEverything) @@ -287,7 +263,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) { m_dependencyArray.clear(); QDataStream depstream(&m_dependencyArray, QIODevice::WriteOnly); - for (const QString &dep : qAsConst(m_dependencies)) + for (const QString &dep : std::as_const(m_dependencies)) depstream << dep; if (m_messages.isEmpty() && mode == SaveEverything) @@ -381,7 +357,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) do { const char *con = entry.value().constData(); - uint len = uint(entry.value().length()); + uint len = uint(entry.value().size()); len = qMin(len, 255u); t << quint8(len); t.writeRawData(con, len); @@ -522,12 +498,12 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) QString strProN = QLatin1String("%n"); QLocale::Language l; - QLocale::Country c; - Translator::languageAndCountry(translator.languageCode(), &l, &c); + QLocale::Territory c; + Translator::languageAndTerritory(translator.languageCode(), &l, &c); QStringList numerusForms; bool guessPlurals = true; if (getNumerusInfo(l, c, 0, &numerusForms, 0)) - guessPlurals = (numerusForms.count() == 1); + guessPlurals = (numerusForms.size() == 1); QString context, sourcetext, comment; QStringList translations; @@ -558,7 +534,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) if (len != -1) str = QString((const QChar *)m, len / 2); if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { - for (int i = 0; i < str.length(); ++i) + for (int i = 0; i < str.size(); ++i) str[i] = QChar((str.at(i).unicode() >> 8) + ((str.at(i).unicode() << 8) & 0xff00)); } @@ -605,7 +581,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) end:; TranslatorMessage msg; msg.setType(TranslatorMessage::Finished); - if (translations.count() > 1) { + if (translations.size() > 1) { // If guessPlurals is not false here, plural form discard messages // will be spewn out later. msg.setPlural(true); @@ -644,8 +620,8 @@ bool saveQM(const Translator &translator, QIODevice &dev, ConversionData &cd) { Releaser releaser(translator.languageCode()); QLocale::Language l; - QLocale::Country c; - Translator::languageAndCountry(translator.languageCode(), &l, &c); + QLocale::Territory c; + Translator::languageAndTerritory(translator.languageCode(), &l, &c); QByteArray rules; if (getNumerusInfo(l, c, &rules, 0, 0)) releaser.setNumerusRules(rules); diff --git a/src/linguist/shared/qmake_global.h b/src/linguist/shared/qmake_global.h index 36d768f0f..612de43e9 100644 --- a/src/linguist/shared/qmake_global.h +++ b/src/linguist/shared/qmake_global.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKE_GLOBAL_H #define QMAKE_GLOBAL_H diff --git a/src/linguist/shared/qmakebuiltins.cpp b/src/linguist/shared/qmakebuiltins.cpp index c0d1346a7..358176658 100644 --- a/src/linguist/shared/qmakebuiltins.cpp +++ b/src/linguist/shared/qmakebuiltins.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmakeevaluator.h" @@ -38,20 +13,22 @@ #include <qdir.h> #include <qfile.h> #include <qfileinfo.h> +#include <qjsonarray.h> +#include <qjsondocument.h> +#include <qjsonobject.h> #include <qlist.h> #include <qregularexpression.h> #include <qset.h> #include <qstringlist.h> #include <qtextstream.h> -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -# include <qjsondocument.h> -# include <qjsonobject.h> -# include <qjsonarray.h> -#endif + #ifdef PROEVALUATOR_THREAD_SAFE # include <qthreadpool.h> #endif #include <qversionnumber.h> +#ifdef Q_OS_WIN +# include <registry_p.h> +#endif #include <algorithm> @@ -64,7 +41,7 @@ #include <sys/stat.h> #include <sys/utsname.h> #else -#include <windows.h> +#include <qt_windows.h> #endif #include <stdio.h> #include <stdlib.h> @@ -93,7 +70,7 @@ enum ExpandFunc { E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH, - E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV + E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV, E_READ_REGISTRY }; enum TestFunc { @@ -190,6 +167,7 @@ void QMakeEvaluator::initFunctionStatics() { "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" }, { "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" }, { "getenv", E_GETENV, 1, 1, "arg" }, + { "read_registry", E_READ_REGISTRY, 2, 3, "tree, key, [wow64]" }, }; statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0]))); for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i) @@ -218,9 +196,7 @@ void QMakeEvaluator::initFunctionStatics() { "infile", T_INFILE, 2, 3, "file, var, [values]" }, { "count", T_COUNT, 2, 3, "var, count, [op=operator]" }, { "isEmpty", T_ISEMPTY, 1, 1, "var" }, -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) { "parseJson", T_PARSE_JSON, 2, 2, "var, into" }, -#endif { "load", T_LOAD, 1, 2, "feature, [ignore_errors=false]" }, { "include", T_INCLUDE, 1, 3, "file, [into, [silent]]" }, { "debug", T_DEBUG, 2, 2, "level, message" }, @@ -249,12 +225,12 @@ QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringLis int *start, int *end) { *start = 0, *end = 0; - if (args.count() >= 2) { + if (args.size() >= 2) { bool ok = true; const ProString &start_str = args.at(1); *start = start_str.toInt(&ok); if (!ok) { - if (args.count() == 2) { + if (args.size() == 2) { int dotdot = start_str.indexOf(statics.strDotDot); if (dotdot != -1) { *start = start_str.left(dotdot).toInt(&ok); @@ -270,7 +246,7 @@ QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringLis } } else { *end = *start; - if (args.count() == 3) + if (args.size() == 3) *end = args.at(2).toInt(&ok); if (!ok) { ProStringRoUser u1(func, m_tmp1); @@ -358,7 +334,6 @@ QMakeEvaluator::quoteValue(const ProString &val) return ret; } -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map); static void insertJsonKeyValue(const QString &key, const QStringList &values, ProValueMap *map) @@ -470,7 +445,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::parseJsonInto(const QByteArray &json return QMakeEvaluator::ReturnTrue; } -#endif QMakeEvaluator::VisitReturn QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, @@ -572,7 +546,7 @@ void QMakeEvaluator::populateDeps( if (depends.isEmpty()) { rootSet.insert(first(ProKey(prefix + item + priosfx)).toInt(), item); } else { - for (const ProString &dep : qAsConst(depends)) { + for (const ProString &dep : std::as_const(depends)) { dset.insert(dep.toKey()); dependees[dep.toKey()] << item; } @@ -621,7 +595,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( var = args[0]; sep = args.at(1).toQString(); beg = args.at(2).toInt(); - if (args.count() == 4) + if (args.size() == 4) end = args.at(3).toInt(); } else { var = args[0]; @@ -656,7 +630,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( case E_SPRINTF: { ProStringRwUser u1(args.at(0), m_tmp1); QString tmp = u1.str(); - for (int i = 1; i < args.count(); ++i) + for (int i = 1; i < args.size(); ++i) tmp = tmp.arg(args.at(i).toQStringView()); ret << u1.extract(tmp); break; @@ -668,7 +642,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( bool zeropad = false; bool leftalign = false; enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign; - if (args.count() >= 2) { + if (args.size() >= 2) { const auto opts = split_value_list(args.at(1).toQStringView()); for (const ProString &opt : opts) { if (opt.startsWith(QLatin1String("ibase="))) { @@ -713,7 +687,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( outstr = QLatin1Char(' '); } QString numstr = QString::number(num, obase); - int space = width - outstr.length() - numstr.length(); + int space = width - outstr.size() - numstr.size(); if (space <= 0) { outstr += numstr; } else if (leftalign) { @@ -729,7 +703,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( } case E_NUM_ADD: { qlonglong sum = 0; - for (const ProString &arg : qAsConst(args)) { + for (const ProString &arg : std::as_const(args)) { if (arg.contains(QLatin1Char('.'))) { evalError(fL1S("num_add(): floats are currently not supported.")); goto allfail; @@ -748,11 +722,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( } case E_JOIN: { ProString glue, before, after; - if (args.count() >= 2) + if (args.size() >= 2) glue = args.at(1); - if (args.count() >= 3) + if (args.size() >= 3) before = args[2]; - if (args.count() == 4) + if (args.size() == 4) after = args[3]; const ProStringList &var = values(map(args.at(0))); if (!var.isEmpty()) { @@ -768,7 +742,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( } case E_SPLIT: { ProStringRoUser u1(m_tmp1); - const QString &sep = (args.count() == 2) ? u1.set(args.at(1)) : statics.field_sep; + const QString &sep = (args.size() == 2) ? u1.set(args.at(1)) : statics.field_sep; const auto vars = values(map(args.at(0))); for (const ProString &var : vars) { // FIXME: this is inconsistent with the "there are no empty strings" dogma. @@ -842,7 +816,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( bool blob = false; bool lines = false; bool singleLine = true; - if (args.count() > 1) { + if (args.size() > 1) { if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive)) singleLine = false; else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive)) @@ -882,7 +856,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( ret += values(map(args.at(0))); break; case E_LIST: { - QString tmp = QString::asprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++); + QString tmp(QString::asprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++)); ret = ProStringList(ProString(tmp)); ProStringList lst; for (const ProString &arg : args) @@ -909,7 +883,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( bool blob = false; bool lines = false; bool singleLine = true; - if (args.count() > 1) { + if (args.size() > 1) { if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive)) singleLine = false; else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive)) @@ -919,7 +893,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( } int exitCode; QByteArray bytes = getCommandOutput(args.at(0).toQString(), &exitCode); - if (args.count() > 2 && !args.at(2).isEmpty()) { + if (args.size() > 2 && !args.at(2).isEmpty()) { m_valuemapStack.top()[args.at(2).toKey()] = ProStringList(ProString(QString::number(exitCode))); } @@ -962,7 +936,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( for (int i = 0; i < args.size(); ++i) { QString str = args.at(i).toQString(); QChar *i_data = str.data(); - int i_len = str.length(); + int i_len = str.size(); for (int x = 0; x < i_len; ++x) { if (*(i_data+x) == QLatin1Char('\\') && x < i_len-1) { if (*(i_data+x+1) == QLatin1Char('\\')) { @@ -1007,14 +981,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( case E_UPPER: case E_LOWER: case E_TITLE: - for (int i = 0; i < args.count(); ++i) { + for (int i = 0; i < args.size(); ++i) { ProStringRwUser u1(args.at(i), m_tmp1); QString rstr = u1.str(); if (func_t == E_UPPER) { rstr = rstr.toUpper(); } else { rstr = rstr.toLower(); - if (func_t == E_TITLE && rstr.length() > 0) + if (func_t == E_TITLE && rstr.size() > 0) rstr[0] = rstr.at(0).toTitleCase(); } ret << u1.extract(rstr); @@ -1022,7 +996,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( break; case E_FILES: { bool recursive = false; - if (args.count() == 2) + if (args.size() == 2) recursive = isTrue(args.at(1)); QStringList dirs; ProStringRoUser u1(args.at(0), m_tmp1); @@ -1048,10 +1022,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( evalError(fL1S("section(): Encountered invalid wildcard expression '%1'.").arg(pattern)); goto allfail; } - for (int d = 0; d < dirs.count(); d++) { + for (int d = 0; d < dirs.size(); d++) { QString dir = dirs[d]; QDir qdir(pfx + dir); - for (int i = 0; i < (int)qdir.count(); ++i) { + for (int i = 0, count = int(qdir.count()); i < count; ++i) { if (qdir[i] == statics.strDot || qdir[i] == statics.strDotDot) continue; QString fname = dir + qdir[i]; @@ -1117,10 +1091,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( ProValueMap dependees; QMultiMap<int, ProString> rootSet; ProStringList orgList = values(args.at(0).toKey()); - ProString prefix = args.count() < 2 ? ProString() : args.at(1); - ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3); + ProString prefix = args.size() < 2 ? ProString() : args.at(1); + ProString priosfx = args.size() < 4 ? ProString(".priority") : args.at(3); populateDeps(orgList, prefix, - args.count() < 3 ? ProStringList(ProString(".depends")) + args.size() < 3 ? ProStringList(ProString(".depends")) : split_value_list(args.at(2).toQStringView()), priosfx, dependencies, dependees, rootSet); while (!rootSet.isEmpty()) { @@ -1129,7 +1103,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( rootSet.erase(it); if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item)) ret.prepend(item); - for (const ProString &dep : qAsConst(dependees[item.toKey()])) { + for (const ProString &dep : std::as_const(dependees[item.toKey()])) { QSet<ProKey> &dset = dependencies[dep.toKey()]; dset.remove(item.toKey()); if (dset.isEmpty()) @@ -1140,11 +1114,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( } case E_ENUMERATE_VARS: { QSet<ProString> keys; - for (const ProValueMap &vmap : qAsConst(m_valuemapStack)) + for (const ProValueMap &vmap : std::as_const(m_valuemapStack)) for (ProValueMap::ConstIterator it = vmap.constBegin(); it != vmap.constEnd(); ++it) keys.insert(it.key()); ret.reserve(keys.size()); - for (const ProString &key : qAsConst(keys)) + for (const ProString &key : std::as_const(keys)) ret << key; break; } case E_SHADOWED: { @@ -1157,7 +1131,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( case E_ABSOLUTE_PATH: { ProStringRwUser u1(args.at(0), m_tmp1); ProStringRwUser u2(m_tmp2); - QString baseDir = args.count() > 1 + QString baseDir = args.size() > 1 ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1))) : currentDirectory(); QString rstr = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str()); @@ -1167,7 +1141,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( case E_RELATIVE_PATH: { ProStringRwUser u1(args.at(0), m_tmp1); ProStringRoUser u2(m_tmp2); - QString baseDir = args.count() > 1 + QString baseDir = args.size() > 1 ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1))) : currentDirectory(); QString absArg = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str()); @@ -1229,6 +1203,40 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( ret << ProString(m_option->getEnv(u1.str())); break; } +#ifdef Q_OS_WIN + case E_READ_REGISTRY: { + HKEY tree; + const auto par = args.at(0); + if (!par.compare(QLatin1String("HKCU"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_CURRENT_USER"), Qt::CaseInsensitive)) { + tree = HKEY_CURRENT_USER; + } else if (!par.compare(QLatin1String("HKLM"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_LOCAL_MACHINE"), Qt::CaseInsensitive)) { + tree = HKEY_LOCAL_MACHINE; + } else { + evalError(fL1S("read_registry(): invalid or unsupported registry tree %1.") + .arg(par.toQStringView())); + goto allfail; + } + int flags = 0; + if (args.count() > 2) { + const auto opt = args.at(2); + if (opt == "32" + || !opt.compare(QLatin1String("wow64_32key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_32KEY; + } else if (opt == "64" + || !opt.compare(QLatin1String("wow64_64key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_64KEY; + } else { + evalError(fL1S("read_registry(): invalid option %1.") + .arg(opt.toQStringView())); + goto allfail; + } + } + ret << ProString(qt_readRegistryKey(tree, args.at(1).toQString(m_tmp1), flags)); + break; + } +#endif default: evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView())); break; @@ -1244,7 +1252,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList & enum { TargetStash, TargetCache, TargetSuper } target = TargetCache; enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet; ProKey srcvar; - if (args.count() >= 2) { + if (args.size() >= 2) { const auto opts = split_value_list(args.at(1).toQStringView()); for (const ProString &opt : opts) { if (opt == QLatin1String("transient")) { @@ -1264,7 +1272,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList & return ReturnFalse; } } - if (args.count() >= 3) { + if (args.size() >= 3) { srcvar = args.at(2).toKey(); } else if (mode != CacheSet) { evalError(fL1S("cache(): modes other than 'set' require a source variable.")); @@ -1359,7 +1367,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList & varstr += QLatin1String(" -="); else varstr += QLatin1String(" ="); - if (diffval.count() == 1) { + if (diffval.size() == 1) { varstr += QLatin1Char(' '); varstr += quoteValue(diffval.at(0)); } else if (!diffval.isEmpty()) { @@ -1417,7 +1425,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( switch (func_t) { case T_DEFINED: { const ProKey &var = args.at(0).toKey(); - if (args.count() > 1) { + if (args.size() > 1) { if (args[1] == QLatin1String("test")) { return returnBool(m_functionDefs.testFunctions.contains(var)); } else if (args[1] == QLatin1String("replace")) { @@ -1470,7 +1478,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( auto isFrom = [pro](const ProString &s) { return s.sourceFile() == pro; }; - vit->erase(std::remove_if(vit->begin(), vit->end(), isFrom), vit->end()); + vit->removeIf(isFrom); if (vit->isEmpty()) { // When an initially non-empty variable becomes entirely empty, // undefine it altogether. @@ -1504,7 +1512,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( VisitReturn ok = evaluateFileInto(fn, &vars, LoadProOnly); if (ok != ReturnTrue) return ok; - if (args.count() == 2) + if (args.size() == 2) return returnBool(vars.contains(map(args.at(1)))); QRegularExpression regx; regx.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); @@ -1554,14 +1562,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( m_current.pro->fileName(), m_current.line); } case T_CONFIG: { - if (args.count() == 1) + if (args.size() == 1) return returnBool(isActiveConfig(args.at(0).toQStringView())); - const auto &mutuals = args.at(1).toQStringView().split(QLatin1Char('|'), - Qt::SkipEmptyParts); + const auto mutuals = args.at(1).toQStringView().split(QLatin1Char('|'), + Qt::SkipEmptyParts); const ProStringList &configs = values(statics.strCONFIG); for (int i = configs.size() - 1; i >= 0; i--) { - for (int mut = 0; mut < mutuals.count(); mut++) { + for (int mut = 0; mut < mutuals.size(); mut++) { if (configs[i].toQStringView() == mutuals[mut].trimmed()) return returnBool(configs[i] == args[0]); } @@ -1581,7 +1589,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } } const ProStringList &l = values(map(args.at(0))); - if (args.count() == 2) { + if (args.size() == 2) { for (int i = 0; i < l.size(); ++i) { const ProString &val = l[i]; if (val == qry) @@ -1597,7 +1605,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( Qt::SkipEmptyParts); for (int i = l.size() - 1; i >= 0; i--) { const ProString &val = l[i]; - for (int mut = 0; mut < mutuals.count(); mut++) { + for (int mut = 0; mut < mutuals.size(); mut++) { if (val.toQStringView() == mutuals[mut].trimmed()) { if (val == qry) return ReturnTrue; @@ -1614,9 +1622,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } case T_COUNT: { - int cnt = values(map(args.at(0))).count(); + int cnt = values(map(args.at(0))).size(); int val = args.at(1).toInt(); - if (args.count() == 3) { + if (args.size() == 3) { const ProString &comp = args.at(2); if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) { return returnBool(cnt > val); @@ -1691,23 +1699,21 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( m_valuemapStack.top()[var] = statics.fakeValue; return ReturnTrue; } -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) case T_PARSE_JSON: { QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8(); ProStringRoUser u1(args.at(1), m_tmp2); QString parseInto = u1.str(); return parseJsonInto(json, parseInto, &m_valuemapStack.top()); } -#endif case T_INCLUDE: { QString parseInto; LoadFlags flags; if (m_cumulative) flags = LoadSilent; - if (args.count() >= 2) { + if (args.size() >= 2) { if (!args.at(1).isEmpty()) parseInto = args.at(1) + QLatin1Char('.'); - if (args.count() >= 3 && isTrue(args.at(2))) + if (args.size() >= 3 && isTrue(args.at(2))) flags = LoadSilent; } QString fn = filePathEnvArg0(args); @@ -1739,7 +1745,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ok; } case T_LOAD: { - bool ignore_error = (args.count() == 2 && isTrue(args.at(1))); + bool ignore_error = (args.size() == 2 && isTrue(args.at(1))); VisitReturn ok = evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()), ignore_error); if (ok == ReturnFalse && ignore_error) @@ -1838,11 +1844,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( QIODevice::OpenMode mode = QIODevice::Truncate; QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact); QString contents; - if (args.count() >= 2) { + if (args.size() >= 2) { const ProStringList &vals = values(args.at(1).toKey()); if (!vals.isEmpty()) contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n'); - if (args.count() >= 3) { + if (args.size() >= 3) { const auto opts = split_value_list(args.at(2).toQStringView()); for (const ProString &opt : opts) { if (opt == QLatin1String("append")) { @@ -1874,10 +1880,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnTrue; } case T_CACHE: - if (args.count() > 3) { - evalError(fL1S("cache(var, [set|add|sub] [transient] [super|stash], [srcvar]) requires one to three arguments.")); - return ReturnFalse; - } return testFunc_cache(args); case T_RELOAD_PROPERTIES: #ifdef QT_BUILD_QMAKE diff --git a/src/linguist/shared/qmakeevaluator.cpp b/src/linguist/shared/qmakeevaluator.cpp index 37601b388..d4cb8aad7 100644 --- a/src/linguist/shared/qmakeevaluator.cpp +++ b/src/linguist/shared/qmakeevaluator.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmakeevaluator.h" #include "qmakeevaluator_p.h" @@ -57,7 +32,7 @@ # include <sys/sysctl.h> # endif #else -#include <windows.h> +#include <qt_windows.h> #endif #include <stdio.h> #include <stdlib.h> @@ -281,11 +256,11 @@ ProStringList QMakeEvaluator::split_value_list(QStringView vals, int source) source = currentFileId(); const QChar *vals_data = vals.data(); - const int vals_len = vals.length(); - ushort quote = 0; + const int vals_len = vals.size(); + char16_t quote = 0; bool hadWord = false; for (int x = 0; x < vals_len; x++) { - ushort unicode = vals_data[x].unicode(); + char16_t unicode = vals_data[x].unicode(); if (unicode == quote) { quote = 0; hadWord = true; @@ -313,7 +288,7 @@ ProStringList QMakeEvaluator::split_value_list(QStringView vals, int source) break; case '\\': if (x + 1 != vals_len) { - ushort next = vals_data[++x].unicode(); + char16_t next = vals_data[++x].unicode(); if (next == '\'' || next == '"' || next == '\\') { build += QChar(unicode); unicode = next; @@ -826,7 +801,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( } else { ProString val; do { - if (index >= list.count()) + if (index >= list.size()) goto do_break; val = list.at(index++); } while (val.isEmpty()); // stupid, but qmake is like that @@ -878,19 +853,19 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( if (expandVariableReferences(tokPtr, sizeHint, &varVal, true) == ReturnError) return ReturnError; QStringView val = varVal.at(0).toQStringView(); - if (val.length() < 4 || val.at(0) != QLatin1Char('s')) { + if (val.size() < 4 || val.at(0) != QLatin1Char('s')) { evalError(fL1S("The ~= operator can handle only the s/// function.")); return ReturnTrue; } QChar sep = val.at(1); auto func = val.split(sep, Qt::KeepEmptyParts); - if (func.count() < 3 || func.count() > 4) { + if (func.size() < 3 || func.size() > 4) { evalError(fL1S("The s/// function expects 3 or 4 arguments.")); return ReturnTrue; } bool global = false, quote = false, case_sense = false; - if (func.count() == 4) { + if (func.size() == 4) { global = func[3].indexOf(QLatin1Char('g')) != -1; case_sense = func[3].indexOf(QLatin1Char('i')) == -1; quote = func[3].indexOf(QLatin1Char('q')) != -1; @@ -900,9 +875,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( if (quote) pattern = QRegularExpression::escape(pattern); - QRegularExpression regexp(pattern, case_sense ? - QRegularExpression::NoPatternOption : - QRegularExpression::CaseInsensitiveOption); + QRegularExpression regexp(pattern, case_sense ? QRegularExpression::NoPatternOption : + QRegularExpression::CaseInsensitiveOption); // We could make a union of modified and unmodified values, // but this will break just as much as it fixes, so leave it as is. @@ -1259,7 +1233,7 @@ bool QMakeEvaluator::loadSpec() qmakespec = m_hostBuild ? QLatin1String("default-host") : QLatin1String("default"); #endif if (IoUtils::isRelativePath(qmakespec)) { - for (const QString &root : qAsConst(m_mkspecPaths)) { + for (const QString &root : std::as_const(m_mkspecPaths)) { QString mkspec = root + QLatin1Char('/') + qmakespec; if (IoUtils::exists(mkspec)) { qmakespec = mkspec; @@ -1501,7 +1475,7 @@ void QMakeEvaluator::updateMkspecPaths() for (const QString &it : paths) ret << it + concat; - for (const QString &it : qAsConst(m_qmakepath)) + for (const QString &it : std::as_const(m_qmakepath)) ret << it + concat; if (!m_buildRoot.isEmpty()) @@ -1542,7 +1516,7 @@ void QMakeEvaluator::updateFeaturePaths() for (const QString &item : items) feature_bases << (item + mkspecs_concat); - for (const QString &item : qAsConst(m_qmakepath)) + for (const QString &item : std::as_const(m_qmakepath)) feature_bases << (item + mkspecs_concat); if (!m_qmakespec.isEmpty()) { @@ -1564,21 +1538,21 @@ void QMakeEvaluator::updateFeaturePaths() feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + mkspecs_concat); feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + mkspecs_concat); - for (const QString &fb : qAsConst(feature_bases)) { + for (const QString &fb : std::as_const(feature_bases)) { const auto sfxs = values(ProKey("QMAKE_PLATFORM")); for (const ProString &sfx : sfxs) feature_roots << (fb + features_concat + sfx + QLatin1Char('/')); feature_roots << (fb + features_concat); } - for (int i = 0; i < feature_roots.count(); ++i) - if (!feature_roots.at(i).endsWith((ushort)'/')) - feature_roots[i].append((ushort)'/'); + for (int i = 0; i < feature_roots.size(); ++i) + if (!feature_roots.at(i).endsWith(QLatin1Char('/'))) + feature_roots[i].append(QLatin1Char('/')); feature_roots.removeDuplicates(); QStringList ret; - for (const QString &root : qAsConst(feature_roots)) + for (const QString &root : std::as_const(feature_roots)) if (IoUtils::exists(root)) ret << root; m_featureRoots = new QMakeFeatureRoots(ret); @@ -1596,7 +1570,7 @@ ProString QMakeEvaluator::propertyValue(const ProKey &name) const ProFile *QMakeEvaluator::currentProFile() const { - if (m_profileStack.count() > 0) + if (m_profileStack.size() > 0) return m_profileStack.top(); return nullptr; } @@ -1637,7 +1611,7 @@ bool QMakeEvaluator::isActiveConfig(QStringView config, bool regex) return m_hostBuild; if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) { - QRegularExpression re(QRegularExpression::wildcardToRegularExpression(config.toString())); + auto re = QRegularExpression::fromWildcard(config.toString()); // mkspecs if (re.match(m_qmakespecName).hasMatch()) @@ -1713,18 +1687,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction( if (m_valuemapStack.size() >= 100) { evalError(fL1S("Ran into infinite recursion (depth > 100).")); - vr = ReturnFalse; + vr = ReturnError; } else { m_valuemapStack.push(ProValueMap()); m_locationStack.push(m_current); ProStringList args; - for (int i = 0; i < argumentsList.count(); ++i) { + for (int i = 0; i < argumentsList.size(); ++i) { args += argumentsList[i]; m_valuemapStack.top()[ProKey(QString::number(i+1))] = argumentsList[i]; } m_valuemapStack.top()[statics.strARGS] = args; - m_valuemapStack.top()[statics.strARGC] = ProStringList(ProString(QString::number(argumentsList.count()))); + m_valuemapStack.top()[statics.strARGC] = ProStringList(ProString(QString::number(argumentsList.size()))); vr = visitProBlock(func.pro(), func.tokPtr()); if (vr == ReturnReturn) vr = ReturnTrue; diff --git a/src/linguist/shared/qmakeevaluator.h b/src/linguist/shared/qmakeevaluator.h index 5079173a9..2889ac0be 100644 --- a/src/linguist/shared/qmakeevaluator.h +++ b/src/linguist/shared/qmakeevaluator.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKEEVALUATOR_H #define QMAKEEVALUATOR_H diff --git a/src/linguist/shared/qmakeevaluator_p.h b/src/linguist/shared/qmakeevaluator_p.h index a7d911289..ea18c3b45 100644 --- a/src/linguist/shared/qmakeevaluator_p.h +++ b/src/linguist/shared/qmakeevaluator_p.h @@ -1,38 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKEEVALUATOR_P_H #define QMAKEEVALUATOR_P_H #include "proitems.h" -#include <qregularexpression.h> - #define debugMsg if (!m_debugLevel) {} else debugMsgInternal #define traceMsg if (!m_debugLevel) {} else traceMsgInternal #ifdef PROEVALUATOR_DEBUG diff --git a/src/linguist/shared/qmakeglobals.cpp b/src/linguist/shared/qmakeglobals.cpp index f6aad6f2c..e05d33c7c 100644 --- a/src/linguist/shared/qmakeglobals.cpp +++ b/src/linguist/shared/qmakeglobals.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmakeglobals.h" @@ -51,7 +26,7 @@ #include <unistd.h> #include <sys/utsname.h> #else -#include <windows.h> +#include <qt_windows.h> #endif #include <stdio.h> #include <stdlib.h> @@ -103,11 +78,18 @@ QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &s return ret; } +/* + * Return value meanings: + * ArgumentUnknown The argument at *pos was not handled by this function. + * Leave it to the caller to handle this argument. + * ArgumentMalformed There was an error detected. + * ArgumentsOk All arguments were known. There are no arguments left to handle. + */ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( QMakeCmdLineParserState &state, QStringList &args, int *pos) { enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache, ArgQtConf } argState = ArgNone; - for (; *pos < args.count(); (*pos)++) { + for (; *pos < args.size(); (*pos)++) { QString arg = args.at(*pos); switch (argState) { case ArgConfig: @@ -186,7 +168,7 @@ void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state) { if (!state.extraargs.isEmpty()) { QString extra = fL1S("QMAKE_EXTRA_ARGS ="); - for (const QString &ea : qAsConst(state.extraargs)) + for (const QString &ea : std::as_const(state.extraargs)) extra += QLatin1Char(' ') + QMakeEvaluator::quoteValue(ProString(ea)); state.cmds[QMakeEvalBefore] << extra; } @@ -231,8 +213,8 @@ void QMakeGlobals::setDirectories(const QString &input_dir, const QString &outpu QString dstpath = output_dir; if (!dstpath.endsWith(QLatin1Char('/'))) dstpath += QLatin1Char('/'); - int srcLen = srcpath.length(); - int dstLen = dstpath.length(); + int srcLen = srcpath.size(); + int dstLen = dstpath.size(); int lastSl = -1; while (++lastSl, --srcLen, --dstLen, srcLen && dstLen && srcpath.at(srcLen) == dstpath.at(dstLen)) @@ -248,9 +230,9 @@ QString QMakeGlobals::shadowedPath(const QString &fileName) const if (source_root.isEmpty()) return fileName; if (fileName.startsWith(source_root) - && (fileName.length() == source_root.length() - || fileName.at(source_root.length()) == QLatin1Char('/'))) { - return build_root + fileName.mid(source_root.length()); + && (fileName.size() == source_root.size() + || fileName.at(source_root.size()) == QLatin1Char('/'))) { + return build_root + fileName.mid(source_root.size()); } return QString(); } @@ -261,7 +243,7 @@ QStringList QMakeGlobals::splitPathList(const QString &val) const if (!val.isEmpty()) { QString cwd(QDir::currentPath()); const QStringList vals = val.split(dirlist_sep, Qt::SkipEmptyParts); - ret.reserve(vals.length()); + ret.reserve(vals.size()); for (const QString &it : vals) ret << IoUtils::resolvePath(cwd, it); } @@ -290,7 +272,7 @@ QString QMakeGlobals::expandEnvVars(const QString &str) const startIndex = string.indexOf(QLatin1Char('$'), startIndex); if (startIndex < 0) break; - if (string.length() < startIndex + 3) + if (string.size() < startIndex + 3) break; if (string.at(startIndex + 1) != QLatin1Char('(')) { startIndex++; @@ -301,7 +283,7 @@ QString QMakeGlobals::expandEnvVars(const QString &str) const break; QString value = getEnv(string.mid(startIndex + 2, endIndex - startIndex - 2)); string.replace(startIndex, endIndex - startIndex + 1, value); - startIndex += value.length(); + startIndex += value.size(); } return string; } diff --git a/src/linguist/shared/qmakeglobals.h b/src/linguist/shared/qmakeglobals.h index 3b6299a1b..437f13178 100644 --- a/src/linguist/shared/qmakeglobals.h +++ b/src/linguist/shared/qmakeglobals.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKEGLOBALS_H #define QMAKEGLOBALS_H diff --git a/src/linguist/shared/qmakeparser.cpp b/src/linguist/shared/qmakeparser.cpp index 20ced5840..5b799b5eb 100644 --- a/src/linguist/shared/qmakeparser.cpp +++ b/src/linguist/shared/qmakeparser.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmakeparser.h" @@ -52,7 +27,7 @@ ProFileCache::ProFileCache() ProFileCache::~ProFileCache() { - for (const Entry &ent : qAsConst(parsed_files)) + for (const Entry &ent : std::as_const(parsed_files)) if (ent.pro) ent.pro->deref(); QMakeVfs::deref(); @@ -359,7 +334,7 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma xprStack.reserve(10); const ushort *cur = (const ushort *)in.data(); - const ushort *inend = cur + in.length(); + const ushort *inend = cur + in.size(); m_canElse = false; freshLine: m_state = StNew; @@ -372,9 +347,9 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma int wordCount = 0; // Number of words in currently accumulated expression int lastIndent = 0; // Previous line's indentation, to detect accidental continuation abuse bool lineMarked = true; // For in-expression markers - ushort needSep = TokNewStr; // Met unquoted whitespace - ushort quote = 0; - ushort term = 0; + char16_t needSep = TokNewStr; // Met unquoted whitespace + char16_t quote = 0; + char16_t term = 0; Context context; ushort *ptr; @@ -450,7 +425,7 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma } forever { - ushort c; + char16_t c; // First, skip leading whitespace for (indent = 0; ; ++cur, ++indent) { @@ -621,7 +596,7 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma if (c != term) { parseError(fL1S("Missing %1 terminator [found %2]") .arg(QChar(term)) - .arg(c ? QString(c) : QString::fromLatin1("end-of-line"))); + .arg(c ? QString(QChar(c)) : QString::fromLatin1("end-of-line"))); m_inError = true; // Just parse on, as if there was a terminator ... } else { @@ -636,7 +611,7 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma } } else if (c == '\\') { static const char symbols[] = "[]{}()$\\'\""; - ushort c2; + char16_t c2; if (cur != end && !((c2 = *cur) & 0xff00) && strchr(symbols, c2)) { c = c2; cur++; @@ -757,7 +732,7 @@ void QMakeParser::read(ProFile *pro, QStringView in, int line, SubGrammar gramma if (!m_blockstack.top().braceLevel) { parseError(fL1S("Excess closing brace.")); } else if (!--m_blockstack.top().braceLevel - && m_blockstack.count() != 1) { + && m_blockstack.size() != 1) { leaveScope(tokPtr); m_state = StNew; m_canElse = false; @@ -1271,7 +1246,7 @@ bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort // The string is typically longer than the variable reference, so we need // to ensure that there is enough space in the output buffer - as unlikely // as an overflow is to actually happen in practice. - int need = (in.length() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.length(); + int need = (in.size() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.size(); int tused = *tokPtr - (ushort *)tokBuff->constData(); int xused; int total; @@ -1302,9 +1277,9 @@ bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort } xprPtr -= 2; // Was set up for variable reference xprPtr[-2] = TokLiteral | needSep; - xprPtr[-1] = out.length(); - memcpy(xprPtr, out.constData(), out.length() * 2); - *ptr = xprPtr + out.length(); + xprPtr[-1] = out.size(); + memcpy(xprPtr, out.constData(), out.size() * 2); + *ptr = xprPtr + out.size(); return true; } @@ -1549,7 +1524,8 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS ok = getSubBlock(tokens, limit, offset, outStr, indent, "block"); break; default: - Q_ASSERT(!"unhandled token"); + // unhandled token + Q_UNREACHABLE(); } } if (!ok) diff --git a/src/linguist/shared/qmakeparser.h b/src/linguist/shared/qmakeparser.h index c30115750..a5a1192ec 100644 --- a/src/linguist/shared/qmakeparser.h +++ b/src/linguist/shared/qmakeparser.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKEPARSER_H #define QMAKEPARSER_H diff --git a/src/linguist/shared/qmakevfs.cpp b/src/linguist/shared/qmakevfs.cpp index 241cd4ee6..a8517de0f 100644 --- a/src/linguist/shared/qmakevfs.cpp +++ b/src/linguist/shared/qmakevfs.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmakevfs.h" @@ -102,10 +77,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags) return id; } #endif - if (!(flags & VfsAccessedOnly)) { #ifdef PROPARSER_THREAD_SAFE - QMutexLocker locker(&s_mutex); + QMutexLocker locker(&s_mutex); #endif + if (!(flags & VfsAccessedOnly)) { int &id = s_fileIdMap[fn]; if (!id) { id = ++s_fileIdCounter; diff --git a/src/linguist/shared/qmakevfs.h b/src/linguist/shared/qmakevfs.h index 0fbe8461d..56bda3d0a 100644 --- a/src/linguist/shared/qmakevfs.h +++ b/src/linguist/shared/qmakevfs.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef QMAKEVFS_H #define QMAKEVFS_H diff --git a/src/linguist/shared/qph.cpp b/src/linguist/shared/qph.cpp index 9f1b0f2b4..6ecc518bc 100644 --- a/src/linguist/shared/qph.cpp +++ b/src/linguist/shared/qph.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -111,10 +86,10 @@ static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &) return reader.read(translator); } -static QString protect(const QString &str) +static QString qphProtect(const QString &str) { QString result; - result.reserve(str.length() * 12 / 10); + result.reserve(str.size() * 12 / 10); for (int i = 0; i != str.size(); ++i) { uint c = str.at(i).unicode(); switch (c) { @@ -156,14 +131,14 @@ static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData t << ">\n"; for (const TranslatorMessage &msg : translator.messages()) { t << "<phrase>\n"; - t << " <source>" << protect(msg.sourceText()) << "</source>\n"; + t << " <source>" << qphProtect(msg.sourceText()) << "</source>\n"; QString str = msg.translations().join(QLatin1Char('@')); str.replace(QChar(Translator::BinaryVariantSeparator), QChar(Translator::TextVariantSeparator)); - t << " <target>" << protect(str) + t << " <target>" << qphProtect(str) << "</target>\n"; if (!msg.comment().isEmpty()) - t << " <definition>" << protect(msg.comment()) << "</definition>\n"; + t << " <definition>" << qphProtect(msg.comment()) << "</definition>\n"; t << "</phrase>\n"; } t << "</QPH>\n"; diff --git a/src/linguist/shared/qrcreader.cpp b/src/linguist/shared/qrcreader.cpp index ce729a7ff..2f450106f 100644 --- a/src/linguist/shared/qrcreader.cpp +++ b/src/linguist/shared/qrcreader.cpp @@ -1,42 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qrcreader.h" +#include "fmt.h" #include <QtCore/qcoreapplication.h> #include <QtCore/qfileinfo.h> #include <QtCore/qxmlstream.h> -class FMT { - Q_DECLARE_TR_FUNCTIONS(Linguist) -}; - -static bool isSupportedExtension(const QString &ext) +bool isSupportedExtension(const QString &ext) { return ext == QLatin1String("qml") || ext == QLatin1String("js") || ext == QLatin1String("qs") @@ -56,13 +28,13 @@ ReadQrcResult readQrcFile(const QString &resourceFile, const QString &content) QXmlStreamReader::TokenType t = reader.readNext(); switch (t) { case QXmlStreamReader::StartElement: - if (curDepth >= tagStack.count() || reader.name() != tagStack.at(curDepth)) { + if (curDepth >= tagStack.size() || reader.name() != tagStack.at(curDepth)) { result.errorString = FMT::tr("unexpected <%1> tag\n") .arg(reader.name().toString()); result.line = reader.lineNumber(); return result; } - if (++curDepth == tagStack.count()) + if (++curDepth == tagStack.size()) isFileTag = true; break; diff --git a/src/linguist/shared/qrcreader.h b/src/linguist/shared/qrcreader.h index 8508b377e..6a0886c9c 100644 --- a/src/linguist/shared/qrcreader.h +++ b/src/linguist/shared/qrcreader.h @@ -1,30 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef QRCREADER_H +#define QRCREADER_H #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> @@ -40,3 +18,7 @@ public: }; ReadQrcResult readQrcFile(const QString &resourceFile, const QString &content); + +bool isSupportedExtension(const QString &ext); + +#endif // QRCREADER_H diff --git a/src/linguist/shared/registry.cpp b/src/linguist/shared/registry.cpp new file mode 100644 index 000000000..7ab0c71fe --- /dev/null +++ b/src/linguist/shared/registry.cpp @@ -0,0 +1,133 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtCore/qstringlist.h> +#include "registry_p.h" + +QT_BEGIN_NAMESPACE + +#ifdef Q_OS_WIN32 +/* + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/* + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == QLatin1String("Default") || res == QLatin1String(".")) + res = QString(); + return res; +} +#endif + +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned long options) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = nullptr; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, + KEY_READ | options, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, &dataType, nullptr, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, nullptr, + reinterpret_cast<unsigned char*>(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(QLatin1String(", ")); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType)); + break; + } + + RegCloseKey(handle); +#else + Q_UNUSED(parentHandle); + Q_UNUSED(rSubkey); + Q_UNUSED(options); +#endif + + return result; +} + +QT_END_NAMESPACE + diff --git a/src/linguist/shared/registry_p.h b/src/linguist/shared/registry_p.h new file mode 100644 index 000000000..00f2431f6 --- /dev/null +++ b/src/linguist/shared/registry_p.h @@ -0,0 +1,48 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef QT_WINDOWS_REGISTRY_H +#define QT_WINDOWS_REGISTRY_H + +// +// 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. +// + +#include <QtCore/qglobal.h> + +#ifdef Q_OS_WIN32 + #include <QtCore/qt_windows.h> +#else + typedef void* HKEY; +#endif + +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + * + * 32-bit code reads from the registry's 32 bit view (Wow6432Node), + * 64 bit code reads from the 64 bit view. + * Pass KEY_WOW64_32KEY to access the 32 bit view regardless of the + * application's architecture, KEY_WOW64_64KEY respectively. + */ +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, + unsigned long options = 0); + +QT_END_NAMESPACE + +#endif // QT_WINDOWS_REGISTRY_H + diff --git a/src/linguist/shared/runqttool.cpp b/src/linguist/shared/runqttool.cpp index caf1e4135..f0be67c8d 100644 --- a/src/linguist/shared/runqttool.cpp +++ b/src/linguist/shared/runqttool.cpp @@ -1,32 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "runqttool.h" +#include "fmt.h" #include "profileutils.h" @@ -41,10 +17,6 @@ #include <sys/wait.h> #endif -class FMT { - Q_DECLARE_TR_FUNCTIONS(Linguist) -}; - static QString qtToolFilePath(const QString &toolName, QLibraryInfo::LibraryPath location) { QString filePath = QLibraryInfo::path(location) + QLatin1Char('/') + toolName; @@ -54,7 +26,7 @@ static QString qtToolFilePath(const QString &toolName, QLibraryInfo::LibraryPath return QDir::cleanPath(filePath); } -static void printErr(const QString &out) +static void rtPrintErr(const QString &out) { std::cerr << qUtf8Printable(out); } @@ -88,8 +60,8 @@ static QString commandLineForSystem(const QString &program, + shellQuoted(arguments).join(QLatin1Char(' ')); } -void runQtTool(const QString &toolName, const QStringList &arguments, - QLibraryInfo::LibraryPath location) +static int runQtToolHelper(const QString &toolName, const QStringList &arguments, + QLibraryInfo::LibraryPath location) { int exitCode = 0; const QString commandLine = commandLineForSystem(qtToolFilePath(toolName, location), arguments); @@ -101,24 +73,42 @@ void runQtTool(const QString &toolName, const QStringList &arguments, #else exitCode = std::system(qPrintable(commandLine)); #endif + return exitCode; +} + +void runQtTool(const QString &toolName, const QStringList &arguments, + QLibraryInfo::LibraryPath location) +{ + const int exitCode = runQtToolHelper(toolName, arguments, location); if (exitCode != 0) exit(exitCode); } +static int runInternalQtToolHelper(const QString &toolName, const QStringList &arguments) +{ + return runQtToolHelper(toolName, arguments, QLibraryInfo::LibraryExecutablesPath); +} + void runInternalQtTool(const QString &toolName, const QStringList &arguments) { - runQtTool(toolName, arguments, QLibraryInfo::LibraryExecutablesPath); + const int exitCode = runInternalQtToolHelper(toolName, arguments); + if (exitCode != 0) + exit(exitCode); } std::unique_ptr<QTemporaryFile> createProjectDescription(QStringList args) { std::unique_ptr<QTemporaryFile> file(new QTemporaryFile(QStringLiteral("XXXXXX.json"))); if (!file->open()) { - printErr(FMT::tr("Cannot create temporary file: %1\n").arg(file->errorString())); + rtPrintErr(FMT::tr("Cannot create temporary file: %1\n").arg(file->errorString())); exit(1); } file->close(); args << QStringLiteral("-out") << file->fileName(); - runInternalQtTool(QStringLiteral("lprodump"), args); + const int exitCode = runInternalQtToolHelper(QStringLiteral("lprodump"), args); + if (exitCode != 0) { + file.reset(); + exit(exitCode); + } return file; } diff --git a/src/linguist/shared/runqttool.h b/src/linguist/shared/runqttool.h index 4d92066ce..b8553c334 100644 --- a/src/linguist/shared/runqttool.h +++ b/src/linguist/shared/runqttool.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef RUNQTTOOL_H #define RUNQTTOOL_H diff --git a/src/linguist/shared/simtexth.cpp b/src/linguist/shared/simtexth.cpp index feb570178..7d978f475 100644 --- a/src/linguist/shared/simtexth.cpp +++ b/src/linguist/shared/simtexth.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "simtexth.h" #include "translator.h" @@ -171,7 +146,7 @@ static inline CoMatrix intersection(const CoMatrix &m, const CoMatrix &n) StringSimilarityMatcher::StringSimilarityMatcher(const QString &stringToMatch) : m_cm(stringToMatch) { - m_length = stringToMatch.length(); + m_length = stringToMatch.size(); } int StringSimilarityMatcher::getSimilarityScore(const QString &strCandidate) diff --git a/src/linguist/shared/simtexth.h b/src/linguist/shared/simtexth.h index 70c889662..1d0ebcb07 100644 --- a/src/linguist/shared/simtexth.h +++ b/src/linguist/shared/simtexth.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef SIMTEXTH_H #define SIMTEXTH_H diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp index d1d137aba..deaa62120 100644 --- a/src/linguist/shared/translator.cpp +++ b/src/linguist/shared/translator.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -105,7 +80,7 @@ void Translator::ensureIndexed() const m_ctxCmtIdx.clear(); m_idMsgIdx.clear(); m_msgIdx.clear(); - for (int i = 0; i < m_messages.count(); i++) + for (int i = 0; i < m_messages.size(); i++) addIndex(i, m_messages.at(i)); } } @@ -124,7 +99,7 @@ void Translator::replaceSorted(const TranslatorMessage &msg) static QString elidedId(const QString &id, int len) { - return id.length() <= len ? id : id.left(len - 5) + QLatin1String("[...]"); + return id.size() <= len ? id : id.left(len - 5) + QLatin1String("[...]"); } static QString makeMsgId(const TranslatorMessage &msg) @@ -180,7 +155,7 @@ void Translator::extend(const TranslatorMessage &msg, ConversionData &cd) void Translator::insert(int idx, const TranslatorMessage &msg) { if (m_indexOk) { - if (idx == m_messages.count()) + if (idx == m_messages.size()) addIndex(idx, msg); else m_indexOk = false; @@ -190,7 +165,7 @@ void Translator::insert(int idx, const TranslatorMessage &msg) void Translator::append(const TranslatorMessage &msg) { - insert(m_messages.count(), msg); + insert(m_messages.size(), msg); } void Translator::appendSorted(const TranslatorMessage &msg) @@ -212,7 +187,7 @@ void Translator::appendSorted(const TranslatorMessage &msg) // Working vars int prevLine = 0; int curIdx = 0; - for (const TranslatorMessage &mit : qAsConst(m_messages)) { + for (const TranslatorMessage &mit : std::as_const(m_messages)) { bool sameFile = mit.fileName() == msg.fileName() && mit.context() == msg.context(); int curLine; if (sameFile && (curLine = mit.lineNumber()) >= prevLine) { @@ -257,7 +232,7 @@ static QString guessFormat(const QString &filename, const QString &format) if (format != QLatin1String("auto")) return format; - for (const Translator::FileFormat &fmt : qAsConst(Translator::registeredFileFormats())) { + for (const Translator::FileFormat &fmt : std::as_const(Translator::registeredFileFormats())) { if (filename.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) return fmt.extension; } @@ -294,7 +269,7 @@ bool Translator::load(const QString &filename, ConversionData &cd, const QString QString fmt = guessFormat(filename, format); - for (const FileFormat &format : qAsConst(registeredFileFormats())) { + for (const FileFormat &format : std::as_const(registeredFileFormats())) { if (fmt == format.extension) { if (format.loader) return (*format.loader)(*this, file, cd); @@ -335,7 +310,7 @@ bool Translator::save(const QString &filename, ConversionData &cd, const QString QString fmt = guessFormat(filename, format); cd.m_targetDir = QFileInfo(filename).absoluteDir(); - for (const FileFormat &format : qAsConst(registeredFileFormats())) { + for (const FileFormat &format : std::as_const(registeredFileFormats())) { if (fmt == format.extension) { if (format.saver) return (*format.saver)(*this, file, cd); @@ -349,34 +324,38 @@ bool Translator::save(const QString &filename, ConversionData &cd, const QString return false; } -QString Translator::makeLanguageCode(QLocale::Language language, QLocale::Country country) +QString Translator::makeLanguageCode(QLocale::Language language, QLocale::Territory territory) { QString result = QLocale::languageToCode(language); - if (language != QLocale::C && country != QLocale::AnyCountry) { + if (language != QLocale::C && territory != QLocale::AnyTerritory) { result.append(QLatin1Char('_')); - result.append(QLocale::countryToCode(country)); + result.append(QLocale::territoryToCode(territory)); } return result; } -void Translator::languageAndCountry(QStringView languageCode, QLocale::Language *langPtr, - QLocale::Country *countryPtr) +void Translator::languageAndTerritory(QStringView languageCode, QLocale::Language *langPtr, + QLocale::Territory *territoryPtr) { QLocale::Language language = QLocale::AnyLanguage; - QLocale::Country country = QLocale::AnyCountry; - const auto underScore = languageCode.indexOf(u'_'); // "de_DE" - if (underScore != -1) { - language = QLocale::codeToLanguage(languageCode.left(underScore)); - country = QLocale::codeToCountry(languageCode.mid(underScore + 1)); + QLocale::Territory territory = QLocale::AnyTerritory; + auto separator = languageCode.indexOf(u'_'); // "de_DE" + if (separator == -1) { + // compatibility with older .ts files + separator = languageCode.indexOf(u'-'); // "de-DE" + } + if (separator != -1) { + language = QLocale::codeToLanguage(languageCode.left(separator)); + territory = QLocale::codeToTerritory(languageCode.mid(separator + 1)); } else { language = QLocale::codeToLanguage(languageCode); - country = QLocale(language).country(); + territory = QLocale(language).territory(); } if (langPtr) *langPtr = language; - if (countryPtr) - *countryPtr = country; + if (territoryPtr) + *territoryPtr = territory; } int Translator::find(const TranslatorMessage &msg) const @@ -479,7 +458,7 @@ void Translator::stripIdenticalSourceTranslations() { for (auto it = m_messages.begin(); it != m_messages.end(); ) { // we need to have just one translation, and it be equal to the source - if (it->translations().count() == 1 && it->translation() == it->sourceText()) + if (it->translations().size() == 1 && it->translation() == it->sourceText()) it = m_messages.erase(it); else ++it; @@ -516,18 +495,27 @@ void Translator::dropUiLines() } } -struct TranslatorMessageIdPtr { - explicit TranslatorMessageIdPtr(const TranslatorMessage &tm) +class TranslatorMessagePtrBase +{ +public: + explicit TranslatorMessagePtrBase(const Translator *tor, int messageIndex) + : tor(tor), messageIndex(messageIndex) { - ptr = &tm; } inline const TranslatorMessage *operator->() const { - return ptr; + return &tor->message(messageIndex); } - const TranslatorMessage *ptr; + const Translator *tor; + const int messageIndex; +}; + +class TranslatorMessageIdPtr : public TranslatorMessagePtrBase +{ +public: + using TranslatorMessagePtrBase::TranslatorMessagePtrBase; }; Q_DECLARE_TYPEINFO(TranslatorMessageIdPtr, Q_RELOCATABLE_TYPE); @@ -542,18 +530,10 @@ inline bool operator==(TranslatorMessageIdPtr tmp1, TranslatorMessageIdPtr tmp2) return tmp1->id() == tmp2->id(); } -struct TranslatorMessageContentPtr { - explicit TranslatorMessageContentPtr(const TranslatorMessage &tm) - { - ptr = &tm; - } - - inline const TranslatorMessage *operator->() const - { - return ptr; - } - - const TranslatorMessage *ptr; +class TranslatorMessageContentPtr : public TranslatorMessagePtrBase +{ +public: + using TranslatorMessagePtrBase::TranslatorMessagePtrBase; }; Q_DECLARE_TYPEINFO(TranslatorMessageContentPtr, Q_RELOCATABLE_TYPE); @@ -579,33 +559,32 @@ inline bool operator==(TranslatorMessageContentPtr tmp1, TranslatorMessageConten Translator::Duplicates Translator::resolveDuplicates() { - QList<int> duplicateIndices; Duplicates dups; - QHash<TranslatorMessageIdPtr, int> idRefs; - QHash<TranslatorMessageContentPtr, int> contentRefs; - for (int i = 0; i < m_messages.count(); ++i) { + QSet<TranslatorMessageIdPtr> idRefs; + QSet<TranslatorMessageContentPtr> contentRefs; + for (int i = 0; i < m_messages.size();) { const TranslatorMessage &msg = m_messages.at(i); TranslatorMessage *omsg; int oi; - QSet<int> *pDup; + DuplicateEntries *pDup; if (!msg.id().isEmpty()) { - const auto it = idRefs.constFind(TranslatorMessageIdPtr(msg)); + const auto it = idRefs.constFind(TranslatorMessageIdPtr(this, i)); if (it != idRefs.constEnd()) { - oi = *it; + oi = it->messageIndex; omsg = &m_messages[oi]; pDup = &dups.byId; goto gotDupe; } } { - const auto it = contentRefs.constFind(TranslatorMessageContentPtr(msg)); + const auto it = contentRefs.constFind(TranslatorMessageContentPtr(this, i)); if (it != contentRefs.constEnd()) { - oi = *it; + oi = it->messageIndex; omsg = &m_messages[oi]; if (msg.id().isEmpty() || omsg->id().isEmpty()) { if (!msg.id().isEmpty() && omsg->id().isEmpty()) { omsg->setId(msg.id()); - idRefs[TranslatorMessageIdPtr(*omsg)] = oi; + idRefs.insert(TranslatorMessageIdPtr(this, oi)); } pDup = &dups.byContents; goto gotDupe; @@ -614,21 +593,17 @@ Translator::Duplicates Translator::resolveDuplicates() } } if (!msg.id().isEmpty()) - idRefs[TranslatorMessageIdPtr(msg)] = i; - contentRefs[TranslatorMessageContentPtr(msg)] = i; + idRefs.insert(TranslatorMessageIdPtr(this, i)); + contentRefs.insert(TranslatorMessageContentPtr(this, i)); + ++i; continue; gotDupe: - pDup->insert(oi); + (*pDup)[oi].append(msg.tsLineNumber()); if (!omsg->isTranslated() && msg.isTranslated()) omsg->setTranslations(msg.translations()); m_indexOk = false; - // don't remove the duplicate entries yet to not mess up the pointers that - // are in the hashes - duplicateIndices.append(i); + m_messages.removeAt(i); } - // now remove the duplicates from the messages - for (int i = duplicateIndices.size() - 1; i >= 0; --i) - m_messages.removeAt(duplicateIndices.at(i)); return dups; } @@ -641,20 +616,36 @@ void Translator::reportDuplicates(const Duplicates &dupes, std::cerr << "'\n(try -verbose for more info).\n"; } else { std::cerr << "':\n"; - for (int i : dupes.byId) - std::cerr << "\n* ID: " << qPrintable(message(i).id()) << std::endl; - for (int j : dupes.byContents) { - const TranslatorMessage &msg = message(j); + for (auto it = dupes.byId.begin(); it != dupes.byId.end(); ++it) { + const TranslatorMessage &msg = message(it.key()); + std::cerr << "\n* ID: " << qPrintable(msg.id()) << std::endl; + reportDuplicatesLines(msg, it.value()); + } + for (auto it = dupes.byContents.begin(); it != dupes.byContents.end(); ++it) { + const TranslatorMessage &msg = message(it.key()); std::cerr << "\n* Context: " << qPrintable(msg.context()) << "\n* Source: " << qPrintable(msg.sourceText()) << std::endl; if (!msg.comment().isEmpty()) std::cerr << "* Comment: " << qPrintable(msg.comment()) << std::endl; + reportDuplicatesLines(msg, it.value()); } std::cerr << std::endl; } } } +void Translator::reportDuplicatesLines(const TranslatorMessage &msg, + const DuplicateEntries::value_type &dups) const +{ + if (msg.tsLineNumber() >= 0) { + std::cerr << "* Line in .ts file: " << msg.tsLineNumber() << std::endl; + for (int tsLineNumber : dups) { + if (tsLineNumber >= 0) + std::cerr << "* Duplicate at line: " << tsLineNumber << std::endl; + } + } +} + // Used by lupdate to be able to search using absolute paths during merging void Translator::makeFileNamesAbsolute(const QDir &originalPath) { @@ -683,11 +674,11 @@ QStringList Translator::normalizedTranslations(const TranslatorMessage &msg, int // make sure that the stringlist always have the size of the // language's current numerus, or 1 if its not plural - if (translations.count() > numTranslations) { - for (int i = translations.count(); i > numTranslations; --i) + if (translations.size() > numTranslations) { + for (int i = translations.size(); i > numTranslations; --i) translations.removeLast(); - } else if (translations.count() < numTranslations) { - for (int i = translations.count(); i < numTranslations; ++i) + } else if (translations.size() < numTranslations) { + for (int i = translations.size(); i < numTranslations; ++i) translations.append(QString()); } return translations; @@ -697,22 +688,22 @@ void Translator::normalizeTranslations(ConversionData &cd) { bool truncated = false; QLocale::Language l; - QLocale::Country c; - languageAndCountry(languageCode(), &l, &c); + QLocale::Territory c; + languageAndTerritory(languageCode(), &l, &c); int numPlurals = 1; if (l != QLocale::C) { QStringList forms; if (getNumerusInfo(l, c, 0, &forms, 0)) - numPlurals = forms.count(); // includes singular + numPlurals = forms.size(); // includes singular } - for (int i = 0; i < m_messages.count(); ++i) { + for (int i = 0; i < m_messages.size(); ++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) + if (tlns.size() != ccnt) { + while (tlns.size() < ccnt) tlns.append(QString()); - while (tlns.count() > ccnt) { + while (tlns.size() > ccnt) { tlns.removeLast(); truncated = true; } @@ -729,7 +720,7 @@ void Translator::normalizeTranslations(ConversionData &cd) QString Translator::guessLanguageCodeFromFileName(const QString &filename) { QString str = filename; - for (const FileFormat &format : qAsConst(registeredFileFormats())) { + for (const FileFormat &format : std::as_const(registeredFileFormats())) { if (str.endsWith(format.extension)) { str = str.left(str.size() - format.extension.size() - 1); break; diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h index b8d187029..8a0957fd2 100644 --- a/src/linguist/shared/translator.h +++ b/src/linguist/shared/translator.h @@ -1,35 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef METATRANSLATOR_H #define METATRANSLATOR_H #include "translatormessage.h" +#include "fmt.h" #include <QCoreApplication> #include <QDir> @@ -42,10 +18,6 @@ QT_BEGIN_NAMESPACE -class FMT { - Q_DECLARE_TR_FUNCTIONS(Linguist) -}; - class QIODevice; // A struct of "interesting" data passed to and from the load and save routines @@ -95,6 +67,7 @@ public: bool m_noUiLines; bool m_idBased; TranslatorSaveMode m_saveMode; + QStringList m_rootDirs; }; class TMMKey { @@ -141,9 +114,15 @@ public: void makeFileNamesAbsolute(const QDir &originalPath); bool translationsExist() const; - struct Duplicates { QSet<int> byId, byContents; }; + using DuplicateEntries = QHash<int, QVector<int>>; + struct Duplicates + { + DuplicateEntries byId, byContents; + }; Duplicates resolveDuplicates(); void reportDuplicates(const Duplicates &dupes, const QString &fileName, bool verbose); + void reportDuplicatesLines(const TranslatorMessage &msg, + const DuplicateEntries::value_type &dups) const; QString languageCode() const { return m_language; } QString sourceLanguageCode() const { return m_sourceLanguage; } @@ -152,9 +131,9 @@ public: void setLocationsType(LocationsType lt) { m_locationsType = lt; } LocationsType locationsType() const { return m_locationsType; } - static QString makeLanguageCode(QLocale::Language language, QLocale::Country country); - static void languageAndCountry(QStringView languageCode, - QLocale::Language *langPtr, QLocale::Country *countryPtr); + static QString makeLanguageCode(QLocale::Language language, QLocale::Territory territory); + static void languageAndTerritory(QStringView languageCode, QLocale::Language *langPtr, + QLocale::Territory *territoryPtr); void setLanguageCode(const QString &languageCode) { m_language = languageCode; } void setSourceLanguageCode(const QString &languageCode) { m_sourceLanguage = languageCode; } static QString guessLanguageCodeFromFileName(const QString &fileName); @@ -216,9 +195,9 @@ private: LocationsType m_locationsType; // A string beginning with a 2 or 3 letter language code (ISO 639-1 - // or ISO-639-2), followed by the optional country variant to distinguish - // between country-specific variations of the language. The language code - // and country code are always separated by '_' + // or ISO-639-2), followed by the optional territory variant to distinguish + // between territory-specific variations of the language. The language code + // and territory code are always separated by '_' // Note that the language part can also be a 3-letter ISO 639-2 code. // Legal examples: // 'pt' portuguese, assumes portuguese from portugal @@ -235,8 +214,8 @@ private: mutable QHash<TMMKey, int> m_msgIdx; }; -bool getNumerusInfo(QLocale::Language language, QLocale::Country country, - QByteArray *rules, QStringList *forms, const char **gettextRules); +bool getNumerusInfo(QLocale::Language language, QLocale::Territory territory, QByteArray *rules, + QStringList *forms, const char **gettextRules); QString getNumerusInfoString(); diff --git a/src/linguist/shared/translatormessage.cpp b/src/linguist/shared/translatormessage.cpp index fbdb88b31..95fbb0aac 100644 --- a/src/linguist/shared/translatormessage.cpp +++ b/src/linguist/shared/translatormessage.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translatormessage.h" @@ -74,7 +49,7 @@ void TranslatorMessage::addReferenceUniq(const QString &fileName, int lineNumber if (fileName == m_fileName && lineNumber == m_lineNumber) return; if (!m_extraRefs.isEmpty()) { // Rather common case, so special-case it - for (const Reference &ref : qAsConst(m_extraRefs)) { + for (const Reference &ref : std::as_const(m_extraRefs)) { if (fileName == ref.fileName() && lineNumber == ref.lineNumber()) return; } diff --git a/src/linguist/shared/translatormessage.h b/src/linguist/shared/translatormessage.h index aa7431b78..53c739e29 100644 --- a/src/linguist/shared/translatormessage.h +++ b/src/linguist/shared/translatormessage.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef TRANSLATORMESSAGE_H #define TRANSLATORMESSAGE_H @@ -98,6 +73,8 @@ public: void setFileName(const QString &fileName) { m_fileName = fileName; } int lineNumber() const { return m_lineNumber; } void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; } + int tsLineNumber() const { return m_tsLineNumber; } + void setTsLineNumber(int lineNumber) { m_tsLineNumber = lineNumber; } void clearReferences(); void setReferences(const References &refs); void addReference(const QString &fileName, int lineNumber); @@ -151,6 +128,7 @@ private: QStringList m_translations; QString m_fileName; int m_lineNumber; + int m_tsLineNumber = -1; References m_extraRefs; bool m_warningOnly = false; diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp index 3cf5f1d31..36ef0f7d8 100644 --- a/src/linguist/shared/ts.cpp +++ b/src/linguist/shared/ts.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" @@ -37,9 +12,7 @@ #include <algorithm> -#define STRINGIFY_INTERNAL(x) #x -#define STRINGIFY(x) STRINGIFY_INTERNAL(x) -#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s))) +using namespace Qt::StringLiterals; QT_BEGIN_NAMESPACE @@ -102,7 +75,7 @@ void TSReader::handleError() case Characters: { QString tok = text().toString(); - if (tok.length() > 30) + if (tok.size() > 30) tok = tok.left(30) + QLatin1String("[...]"); raiseError(QString::fromLatin1("Unexpected characters '%1' %2").arg(tok, loc)); } @@ -129,8 +102,8 @@ static QString byteValue(QString value) QString TSReader::readContents() { - STRING(byte); - STRING(value); + static const QString strbyte = u"byte"_s; + static const QString strvalue = u"value"_s; QString result; while (!atEnd()) { @@ -158,9 +131,9 @@ QString TSReader::readContents() QString TSReader::readTransContents() { - STRING(lengthvariant); - STRING(variants); - STRING(yes); + static const QString strlengthvariant = u"lengthvariant"_s; + static const QString strvariants = u"variants"_s; + static const QString stryes = u"yes"_s; if (attributes().value(strvariants) == stryes) { QString result; @@ -187,35 +160,35 @@ QString TSReader::readTransContents() bool TSReader::read(Translator &translator) { - STRING(catalog); - STRING(comment); - STRING(context); - STRING(dependencies); - STRING(dependency); - STRING(extracomment); - STRING(filename); - STRING(id); - STRING(language); - STRING(line); - STRING(location); - STRING(message); - STRING(name); - STRING(numerus); - STRING(numerusform); - STRING(obsolete); - STRING(oldcomment); - STRING(oldsource); - STRING(source); - STRING(sourcelanguage); - STRING(translation); - STRING(translatorcomment); - STRING(TS); - STRING(type); - STRING(unfinished); - STRING(userdata); - STRING(vanished); - //STRING(version); - STRING(yes); + static const QString strcatalog = u"catalog"_s; + static const QString strcomment = u"comment"_s; + static const QString strcontext = u"context"_s; + static const QString strdependencies = u"dependencies"_s; + static const QString strdependency = u"dependency"_s; + static const QString strextracomment = u"extracomment"_s; + static const QString strfilename = u"filename"_s; + static const QString strid = u"id"_s; + static const QString strlanguage = u"language"_s; + static const QString strline = u"line"_s; + static const QString strlocation = u"location"_s; + static const QString strmessage = u"message"_s; + static const QString strname = u"name"_s; + static const QString strnumerus = u"numerus"_s; + static const QString strnumerusform = u"numerusform"_s; + static const QString strobsolete = u"obsolete"_s; + static const QString stroldcomment = u"oldcomment"_s; + static const QString stroldsource = u"oldsource"_s; + static const QString strsource = u"source"_s; + static const QString strsourcelanguage = u"sourcelanguage"_s; + static const QString strtranslation = u"translation"_s; + static const QString strtranslatorcomment = u"translatorcomment"_s; + static const QString strTS = u"TS"_s; + static const QString strtype = u"type"_s; + static const QString strunfinished = u"unfinished"_s; + static const QString struserdata = u"userdata"_s; + static const QString strvanished = u"vanished"_s; + //static const QString strversion = u"version"_s; + static const QString stryes = u"yes"_s; static const QString strextrans(QLatin1String("extra-")); @@ -305,6 +278,7 @@ bool TSReader::read(Translator &translator) msg.setContext(context); msg.setType(TranslatorMessage::Finished); msg.setPlural(attributes().value(strnumerus) == stryes); + msg.setTsLineNumber(lineNumber()); while (!atEnd()) { readNext(); if (isEndElement()) { @@ -430,16 +404,16 @@ bool TSReader::read(Translator &translator) return true; } -static QString numericEntity(int ch) +static QString tsNumericEntity(int ch) { return QString(ch <= 0x20 ? QLatin1String("<byte value=\"x%1\"/>") : QLatin1String("&#x%1;")) .arg(ch, 0, 16); } -static QString protect(const QString &str) +static QString tsProtect(const QString &str) { QString result; - result.reserve(str.length() * 12 / 10); + result.reserve(str.size() * 12 / 10); for (int i = 0; i != str.size(); ++i) { const QChar ch = str[i]; uint c = ch.unicode(); @@ -461,7 +435,7 @@ static QString protect(const QString &str) break; default: if ((c < 0x20 || (ch > QChar(0x7f) && ch.isSpace())) && c != '\n' && c != '\t') - result += numericEntity(c); + result += tsNumericEntity(c); else // this also covers surrogates result += QChar(c); } @@ -476,12 +450,12 @@ static void writeExtras(QTextStream &t, const char *indent, for (auto it = extras.cbegin(), end = extras.cend(); it != end; ++it) { if (!drops.match(it.key()).hasMatch()) { outs << (QStringLiteral("<extra-") + it.key() + QLatin1Char('>') - + protect(it.value()) + + tsProtect(it.value()) + QStringLiteral("</extra-") + it.key() + QLatin1Char('>')); } } outs.sort(); - for (const QString &out : qAsConst(outs)) + for (const QString &out : std::as_const(outs)) t << indent << out << Qt::endl; } @@ -493,18 +467,18 @@ static void writeVariants(QTextStream &t, const char *indent, const QString &inp int start = 0; forever { t << "\n " << indent << "<lengthvariant>" - << protect(input.mid(start, offset - start)) + << tsProtect(input.mid(start, offset - start)) << "</lengthvariant>"; - if (offset == input.length()) + if (offset == input.size()) break; start = offset + 1; offset = input.indexOf(QChar(Translator::BinaryVariantSeparator), start); if (offset < 0) - offset = input.length(); + offset = input.size(); } t << "\n" << indent; } else { - t << ">" << protect(input); + t << ">" << tsProtect(input); } } @@ -557,17 +531,17 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd) QHash<QString, int> currentLine; QString currentFile; - for (const QString &context : qAsConst(contextOrder)) { + for (const QString &context : std::as_const(contextOrder)) { t << "<context>\n" " <name>" - << protect(context) + << tsProtect(context) << "</name>\n"; - for (const TranslatorMessage &msg : qAsConst(messageOrder[context])) { + for (const TranslatorMessage &msg : std::as_const(messageOrder[context])) { //msg.dump(); t << " <message"; if (!msg.id().isEmpty()) - t << " id=\"" << msg.id() << "\""; + t << " id=\"" << tsProtect(msg.id()) << "\""; if (msg.isPlural()) t << " numerus=\"yes\""; t << ">\n"; @@ -610,27 +584,27 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd) } t << " <source>" - << protect(msg.sourceText()) + << tsProtect(msg.sourceText()) << "</source>\n"; if (!msg.oldSourceText().isEmpty()) - t << " <oldsource>" << protect(msg.oldSourceText()) << "</oldsource>\n"; + t << " <oldsource>" << tsProtect(msg.oldSourceText()) << "</oldsource>\n"; if (!msg.comment().isEmpty()) { t << " <comment>" - << protect(msg.comment()) + << tsProtect(msg.comment()) << "</comment>\n"; } if (!msg.oldComment().isEmpty()) - t << " <oldcomment>" << protect(msg.oldComment()) << "</oldcomment>\n"; + t << " <oldcomment>" << tsProtect(msg.oldComment()) << "</oldcomment>\n"; if (!msg.extraComment().isEmpty()) - t << " <extracomment>" << protect(msg.extraComment()) + t << " <extracomment>" << tsProtect(msg.extraComment()) << "</extracomment>\n"; if (!msg.translatorComment().isEmpty()) - t << " <translatorcomment>" << protect(msg.translatorComment()) + t << " <translatorcomment>" << tsProtect(msg.translatorComment()) << "</translatorcomment>\n"; t << " <translation"; @@ -643,7 +617,7 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd) if (msg.isPlural()) { t << ">"; const QStringList &translns = msg.translations(); - for (int j = 0; j < translns.count(); ++j) { + for (int j = 0; j < translns.size(); ++j) { t << "\n <numerusform"; writeVariants(t, " ", translns[j]); t << "</numerusform>"; diff --git a/src/linguist/shared/ts.dtd b/src/linguist/shared/ts.dtd deleted file mode 100644 index f1c6d3d33..000000000 --- a/src/linguist/shared/ts.dtd +++ /dev/null @@ -1,104 +0,0 @@ -<!-- - ! - ! Some notes to the DTD: - ! - ! The location element is set as optional since it was introduced first in Qt 4.2. - ! The userdata element is set as optional since it was introduced first in Qt 4.4. - ! The vanished message type was introduced first in Qt 5.2. - ! - --> -<!-- - ! Macro used in order to escape byte entities not allowed in an xml document - ! for instance, only #x9, #xA and #xD are allowed characters below #x20. - --> -<!ENTITY % evilstring '(#PCDATA | byte)*' > -<!ELEMENT byte EMPTY> -<!-- value contains decimal (e.g. 1000) or hex (e.g. x3e8) unicode encoding of one char --> -<!ATTLIST byte - value CDATA #REQUIRED> -<!-- - ! This element wildcard is no valid DTD. No better solution available. - ! extra elements may appear in TS and message elements. Each element may appear - ! only once within each scope. The contents are preserved verbatim; any - ! attributes are dropped. Currently recognized extra tags include: - ! extra-po-msgid_plural, extra-po-old_msgid_plural - ! extra-po-flags (comma-space separated list) - ! extra-loc-layout_id - ! extra-loc-feature - ! extra-loc-blank - --> -<!ELEMENT extra-* %evilstring; > -<!ELEMENT TS (defaultcodec?, extra-**, dependencies?, (context|message)+) > -<!ATTLIST TS - version CDATA #IMPLIED - sourcelanguage CDATA #IMPLIED - language CDATA #IMPLIED> -<!-- The encoding to use in the QM file by default. Default is ISO-8859-1. --> -<!ELEMENT defaultcodec (#PCDATA) > -<!ELEMENT context (name, comment?, (context|message)+) > -<!ATTLIST context - encoding CDATA #IMPLIED> -<!ELEMENT dependencies (dependency+) > -<!ATTLIST dependency - catalog CDATA #IMPLIED> -<!ELEMENT name %evilstring; > -<!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak --> -<!ELEMENT comment %evilstring; > -<!-- Previous content of comment (result of merge) --> -<!ELEMENT oldcomment %evilstring; > -<!-- The real comment (added by developer/designer) --> -<!ELEMENT extracomment %evilstring; > -<!-- Comment added by translator --> -<!ELEMENT translatorcomment %evilstring; > -<!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) > -<!-- - ! If utf8 is "true", the defaultcodec is overridden and the message is encoded - ! in UTF-8 in the QM file. If it is "both", both source encodings are stored - ! in the QM file. - --> -<!ATTLIST message - id CDATA #IMPLIED - utf8 (true|false|both) "false" - numerus (yes|no) "no"> -<!ELEMENT location EMPTY> -<!-- - ! If the line is omitted, the location specifies only a file. - ! - ! location supports relative specifications as well. Line numbers are - ! relative (explicitly positive or negative) to the last reference to a - ! given filename; each file starts with current line 0. If the filename - ! is omitted, the "current" one is used. For the 1st location in a message, - ! "current" is the filename used for the 1st location of the previous message. - ! For subsequent locations, it is the filename used for the previous location. - ! A single TS file has either all absolute or all relative locations. - --> -<!ATTLIST location - filename CDATA #IMPLIED - line CDATA #IMPLIED> -<!ELEMENT source %evilstring;> -<!-- Previous content of source (result of merge) --> -<!ELEMENT oldsource %evilstring;> -<!-- - ! The following should really say one evilstring macro or several - ! numerusform or lengthvariant elements, but the DTD can't express this. - --> -<!ELEMENT translation (#PCDATA|byte|numerusform|lengthvariant)* > -<!-- - ! If no type is set, the message is "finished". - ! Length variants must be ordered by falling display length. - ! variants may not be yes if the message has numerus yes. - --> -<!ATTLIST translation - type (unfinished|vanished|obsolete) #IMPLIED - variants (yes|no) "no"> -<!-- Deprecated. Use extra-* --> -<!ELEMENT userdata (#PCDATA)* > -<!-- - ! The following should really say one evilstring macro or several - ! lengthvariant elements, but the DTD can't express this. - ! Length variants must be ordered by falling display length. - --> -<!ELEMENT numerusform (#PCDATA|byte|lengthvariant)* > -<!ATTLIST numerusform - variants (yes|no) "no"> -<!ELEMENT lengthvariant %evilstring; > diff --git a/src/linguist/shared/ts.xsd b/src/linguist/shared/ts.xsd new file mode 100644 index 000000000..a7c29b3f5 --- /dev/null +++ b/src/linguist/shared/ts.xsd @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ! + ! Some notes to the XSD: + ! + ! The location element is set as optional since it was introduced first in Qt 4.2. + ! The userdata element is set as optional since it was introduced first in Qt 4.4. + ! The vanished message type was introduced first in Qt 5.2. + ! + --> +<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <!-- value contains decimal (e.g. 1000) or hex (e.g. x3e8) unicode encoding of one char --> + <xs:element name="byte"> + <xs:complexType> + <xs:attribute name="value" type="xs:string" use="required" /> + </xs:complexType> + </xs:element> + <!-- + ! Type used in order to escape byte entities not allowed in an xml document + ! for instance, only #x9, #xA and #xD are allowed characters below #x20. + --> + <xs:complexType name="byte-type" mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="byte" /> + </xs:choice> + </xs:complexType> + <!-- + ! extra-something should be described as extra-* but wildcard is not valid in XSD. No better solution found. + ! extra elements may appear in TS and message elements. Each element may appear + ! only once within each scope. The contents are preserved verbatim; any + ! attributes are dropped. Currently recognized extra tags include: + ! extra-po-msgid_plural, extra-po-old_msgid_plural + ! extra-po-flags (comma-space separated list) + ! extra-loc-layout_id + ! extra-loc-feature + ! extra-loc-blank + --> + <xs:element name="extra-something" type= "byte-type"/> + <xs:element name="TS"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="extra-something" /> + <xs:element minOccurs="0" maxOccurs="1" ref="dependencies" /> + <xs:choice minOccurs="1" maxOccurs="unbounded"> + <xs:element ref="context" /> + <xs:element ref="message" /> + </xs:choice> + </xs:sequence> + <xs:attribute name="version" type="xs:string" /> + <xs:attribute name="sourcelanguage" type="xs:string" /> + <xs:attribute name="language" type="xs:string" /> + </xs:complexType> + </xs:element> + <xs:element name="context"> + <xs:complexType> + <xs:sequence> + <xs:element ref="name" /> + <xs:element minOccurs="0" maxOccurs="1" ref="comment" /> + <xs:element minOccurs="1" maxOccurs="unbounded" ref="message"/> + </xs:sequence> + <xs:attribute name="encoding" type="xs:string" /> + </xs:complexType> + </xs:element> + <xs:element name="dependencies"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="1" maxOccurs="unbounded" ref="dependency" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="dependency"> + <xs:complexType> + <xs:attribute name="catalog" type="xs:string" /> + </xs:complexType> + </xs:element> + <xs:element name="name" type= "byte-type"/> + <!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak --> + <xs:element name="comment" type= "byte-type"/> + <!-- Previous content of comment (result of merge) --> + <xs:element name="oldcomment" type= "byte-type"/> + <!-- The real comment (added by developer/designer) --> + <xs:element name="extracomment" type= "byte-type"/> + <!-- Comment added by translator --> + <xs:element name="translatorcomment" type= "byte-type"/> + <xs:element name="message"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="location" /> + <xs:element minOccurs="0" maxOccurs="1" ref="source" /> + <xs:element minOccurs="0" maxOccurs="1" ref="oldsource" /> + <xs:element minOccurs="0" maxOccurs="1" ref="comment" /> + <xs:element minOccurs="0" maxOccurs="1" ref="oldcomment" /> + <xs:element minOccurs="0" maxOccurs="1" ref="extracomment" /> + <xs:element minOccurs="0" maxOccurs="1" ref="translatorcomment" /> + <xs:element minOccurs="0" maxOccurs="1" ref="translation" /> + <xs:element minOccurs="0" maxOccurs="1" ref="userdata" /> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="extra-something" /> + </xs:sequence> + <xs:attribute name="id" type="xs:string" /> + <xs:attribute default="no" name="numerus"> + <xs:simpleType> + <xs:restriction base="xs:NMTOKEN"> + <xs:enumeration value="yes" /> + <xs:enumeration value="no" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + </xs:element> + <!-- + ! If the line is omitted, the location specifies only a file. + ! + ! location supports relative specifications as well. Line numbers are + ! relative (explicitly positive or negative) to the last reference to a + ! given filename; each file starts with current line 0. If the filename + ! is omitted, the "current" one is used. For the 1st location in a message, + ! "current" is the filename used for the 1st location of the previous message. + ! For subsequent locations, it is the filename used for the previous location. + ! A single TS file has either all absolute or all relative locations. + --> + <xs:element name="location"> + <xs:complexType> + <xs:attribute name="filename" type="xs:string" /> + <xs:attribute name="line" type="xs:string" /> + </xs:complexType> + </xs:element> + <xs:element name="source" type= "byte-type"/> + <!-- Previous content of source (result of merge) --> + <xs:element name="oldsource" type= "byte-type"/> + <!-- + ! The following should really say one byte-type or several + ! numerusform or lengthvariant elements. + --> + <xs:element name="translation"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="byte" /> + <xs:element ref="numerusform" /> + <xs:element ref="lengthvariant" /> + </xs:choice> + <!-- + ! If no type is set, the message is "finished". + ! Length variants must be ordered by falling display length. + ! variants may not be yes if the message has numerus yes. + --> + <xs:attribute name="type"> + <xs:simpleType> + <xs:restriction base="xs:NMTOKEN"> + <xs:enumeration value="unfinished" /> + <xs:enumeration value="vanished" /> + <xs:enumeration value="obsolete" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute default="no" name="variants"> + <xs:simpleType> + <xs:restriction base="xs:NMTOKEN"> + <xs:enumeration value="yes" /> + <xs:enumeration value="no" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + </xs:element> + <!-- Deprecated. Use extra-something --> + <xs:element name="userdata" type="xs:string" /> + <!-- + ! The following should really say one byte-type or several + ! lengthvariant elements. + ! Length variants must be ordered by falling display length. + --> + <xs:element name="numerusform"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="byte" /> + <xs:element ref="lengthvariant" /> + </xs:choice> + <xs:attribute default="no" name="variants"> + <xs:simpleType> + <xs:restriction base="xs:NMTOKEN"> + <xs:enumeration value="yes" /> + <xs:enumeration value="no" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name="lengthvariant" type= "byte-type"/> +</xs:schema> diff --git a/src/linguist/shared/xliff.cpp b/src/linguist/shared/xliff.cpp index ef380939e..ceda53994 100644 --- a/src/linguist/shared/xliff.cpp +++ b/src/linguist/shared/xliff.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "translator.h" #include "xmlparser.h" @@ -65,7 +40,7 @@ static QString dataType(const TranslatorMessage &m) { QByteArray fileName = m.fileName().toLatin1(); unsigned int extHash = 0; - int pos = fileName.count() - 1; + int pos = fileName.size() - 1; for (int pass = 0; pass < 4 && pos >=0; ++pass, --pos) { if (fileName.at(pos) == '.') break; @@ -126,7 +101,7 @@ static char charFromEscape(char escape) return escape; } -static QString numericEntity(int ch, bool makePhs) +static QString xlNumericEntity(int ch, bool makePhs) { // ### This needs to be reviewed, to reflect the updated XLIFF-PO spec. if (!makePhs || ch < 7 || ch > 0x0d) @@ -141,7 +116,7 @@ static QString numericEntity(int ch, bool makePhs) .arg(++id) .arg(name) .arg(escapechar); } -static QString protect(const QString &str, bool makePhs = true) +static QString xlProtect(const QString &str, bool makePhs = true) { QString result; int len = str.size(); @@ -165,7 +140,7 @@ static QString protect(const QString &str, bool makePhs = true) break; default: if (c < 0x20 && c != '\r' && c != '\n' && c != '\t') - result += numericEntity(c, makePhs); + result += xlNumericEntity(c, makePhs); else // this also covers surrogates result += QChar(c); } @@ -181,7 +156,7 @@ static void writeExtras(QTextStream &ts, int indent, if (!drops.match(it.key()).hasMatch()) { writeIndent(ts, indent); ts << "<trolltech:" << it.key() << '>' - << protect(it.value()) + << xlProtect(it.value()) << "</trolltech:" << it.key() << ">\n"; } } @@ -210,25 +185,25 @@ static void writeComment(QTextStream &ts, const TranslatorMessage &msg, const QR if (!msg.comment().isEmpty()) { writeIndent(ts, indent); ts << "<context-group><context context-type=\"" << contextMsgctxt << "\">" - << protect(msg.comment(), false) + << xlProtect(msg.comment(), false) << "</context></context-group>\n"; } if (!msg.oldComment().isEmpty()) { writeIndent(ts, indent); ts << "<context-group><context context-type=\"" << contextOldMsgctxt << "\">" - << protect(msg.oldComment(), false) + << xlProtect(msg.oldComment(), false) << "</context></context-group>\n"; } writeExtras(ts, indent, msg.extras(), drops); if (!msg.extraComment().isEmpty()) { writeIndent(ts, indent); ts << "<note annotates=\"source\" from=\"developer\">" - << protect(msg.extraComment()) << "</note>\n"; + << xlProtect(msg.extraComment()) << "</note>\n"; } if (!msg.translatorComment().isEmpty()) { writeIndent(ts, indent); ts << "<note from=\"translator\">" - << protect(msg.translatorComment()) << "</note>\n"; + << xlProtect(msg.translatorComment()) << "</note>\n"; } } @@ -249,7 +224,7 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const oldsources.append(msg.oldSourceText()); if (const auto it = extras.constFind(QString::fromLatin1("po-old_msgid_plural")); it != extrasEnd) { if (oldsources.isEmpty()) { - if (sources.count() == 2) + if (sources.size() == 2) oldsources.append(QString()); else pluralStr = QLatin1Char(' ') + QLatin1String(attribPlural) + QLatin1String("=\"yes\""); @@ -289,7 +264,7 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const source = *srcit; ++srcit; } // else just repeat last element - ts << "<source xml:space=\"preserve\">" << protect(source) << "</source>\n"; + ts << "<source xml:space=\"preserve\">" << xlProtect(source) << "</source>\n"; bool puttrans = false; QString translation; @@ -306,7 +281,7 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const ts << "<alt-trans>\n"; ++indent; writeIndent(ts, indent); - ts << "<source xml:space=\"preserve\"" << pluralStr << '>' << protect(*oldsrcit) << "</source>\n"; + ts << "<source xml:space=\"preserve\"" << pluralStr << '>' << xlProtect(*oldsrcit) << "</source>\n"; if (!puttrans) { writeIndent(ts, indent); ts << "<target restype=\"" << restypeDummy << "\"/>\n"; @@ -315,7 +290,7 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const if (puttrans) { writeIndent(ts, indent); - ts << "<target xml:space=\"preserve\"" << state << ">" << protect(translation) << "</target>\n"; + ts << "<target xml:space=\"preserve\"" << state << ">" << xlProtect(translation) << "</target>\n"; } if (oldsrcit != oldsrcend) { @@ -397,6 +372,7 @@ private: XC_translator_comment, XC_restype_context, XC_restype_translation, + XC_mtype_seg_translation, XC_restype_plurals, XC_alt_trans }; @@ -476,7 +452,7 @@ XLIFFHandler::XliffContext XLIFFHandler::currentContext() const // traverses to the top to check all of the parent contexes. bool XLIFFHandler::hasContext(XliffContext ctx) const { - for (int i = m_contextStack.count() - 1; i >= 0; --i) { + for (int i = m_contextStack.size() - 1; i >= 0; --i) { if (m_contextStack.at(i) == ctx) return true; } @@ -538,6 +514,11 @@ bool XLIFFHandler::startElement(QStringView namespaceURI, QStringView localName, } else if (localName == QLatin1String("target")) { if (atts.value(QLatin1String("restype")) != QLatin1String(restypeDummy)) pushContext(XC_restype_translation); + } else if (localName == QLatin1String("mrk")) { + if (atts.value(QLatin1String("mtype")) == QLatin1String("seg")) { + if (currentContext() == XC_restype_translation) + pushContext(XC_mtype_seg_translation); + } } else if (localName == QLatin1String("context-group")) { if (atts.value(QLatin1String("purpose")) == QLatin1String("location")) pushContext(XC_context_group); @@ -568,7 +549,7 @@ bool XLIFFHandler::startElement(QStringView namespaceURI, QStringView localName, pushContext(XC_ph); } bail: - if (currentContext() != XC_ph) + if (currentContext() != XC_ph && currentContext() != XC_mtype_seg_translation) accum.clear(); return true; } @@ -606,6 +587,8 @@ bool XLIFFHandler::endElement(QStringView namespaceURI, QStringView localName, QChar(Translator::BinaryVariantSeparator)); m_translations.append(accum); } + } else if (localName == QLatin1String("mrk")) { + popContext(XC_mtype_seg_translation); } else if (localName == QLatin1String("context-group")) { if (popContext(XC_context_group)) { m_refs.append(TranslatorMessage::Reference( @@ -709,12 +692,12 @@ bool XLIFFHandler::finalizeMessage(bool isPlural) msg.setOldComment(m_oldComment); msg.setExtraComment(m_extraComment); msg.setTranslatorComment(m_translatorComment); - if (m_sources.count() > 1 && m_sources[1] != m_sources[0]) + if (m_sources.size() > 1 && m_sources[1] != m_sources[0]) m_extra.insert(QLatin1String("po-msgid_plural"), m_sources[1]); if (!m_oldSources.isEmpty()) { if (!m_oldSources[0].isEmpty()) msg.setOldSourceText(m_oldSources[0]); - if (m_oldSources.count() > 1 && m_oldSources[1] != m_oldSources[0]) + if (m_oldSources.size() > 1 && m_oldSources[1] != m_oldSources[0]) m_extra.insert(QLatin1String("po-old_msgid_plural"), m_oldSources[1]); } msg.setExtras(m_extra); @@ -792,7 +775,7 @@ bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd) sourceLanguageCode.replace(QLatin1Char('_'), QLatin1Char('-')); QString languageCode = translator.languageCode(); languageCode.replace(QLatin1Char('_'), QLatin1Char('-')); - for (const QString &fn : qAsConst(fileOrder)) { + for (const QString &fn : std::as_const(fileOrder)) { writeIndent(ts, indent); ts << "<file original=\"" << fn << "\"" << " datatype=\"" << dataType(messageOrder[fn].cbegin()->first()) << "\"" @@ -801,15 +784,15 @@ bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd) << "><body>\n"; ++indent; - for (const QString &ctx : qAsConst(contextOrder[fn])) { + for (const QString &ctx : std::as_const(contextOrder[fn])) { if (!ctx.isEmpty()) { writeIndent(ts, indent); ts << "<group restype=\"" << restypeContext << "\"" - << " resname=\"" << protect(ctx) << "\">\n"; + << " resname=\"" << xlProtect(ctx) << "\">\n"; ++indent; } - for (const TranslatorMessage &msg : qAsConst(messageOrder[fn][ctx])) + for (const TranslatorMessage &msg : std::as_const(messageOrder[fn][ctx])) writeMessage(ts, msg, drops, indent); if (!ctx.isEmpty()) { diff --git a/src/linguist/shared/xmlparser.cpp b/src/linguist/shared/xmlparser.cpp index 35216386c..654d4e0dc 100644 --- a/src/linguist/shared/xmlparser.cpp +++ b/src/linguist/shared/xmlparser.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "xmlparser.h" diff --git a/src/linguist/shared/xmlparser.h b/src/linguist/shared/xmlparser.h index 960b42230..891e46527 100644 --- a/src/linguist/shared/xmlparser.h +++ b/src/linguist/shared/xmlparser.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Linguist of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef XMLPARSER_H #define XMLPARSER_H |