diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-04-27 03:00:13 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-04-27 03:00:14 +0200 |
commit | 44b86253855dc820ca03e65c1ad529eee602bbbb (patch) | |
tree | 97a69047cfd8593524f1be0ed0dd1ebdf2c6d410 /src/linguist | |
parent | f439af367b28bd1a729434ab46f55bc961015391 (diff) | |
parent | 7203e6a94ced619eadbc14aedf73d40530671662 (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Change-Id: I388e646bec0ef1de734702568f9bd65877bde97a
Diffstat (limited to 'src/linguist')
-rw-r--r-- | src/linguist/Qt5LinguistToolsMacros.cmake | 3 | ||||
-rw-r--r-- | src/linguist/lupdate/cpp.cpp | 91 | ||||
-rw-r--r-- | src/linguist/lupdate/lupdate.h | 5 | ||||
-rw-r--r-- | src/linguist/lupdate/main.cpp | 64 | ||||
-rw-r--r-- | src/linguist/lupdate/qdeclarative.cpp | 14 | ||||
-rw-r--r-- | src/linguist/shared/translator.cpp | 11 | ||||
-rw-r--r-- | src/linguist/shared/translator.h | 1 | ||||
-rw-r--r-- | src/linguist/shared/ts.cpp | 2 |
8 files changed, 121 insertions, 70 deletions
diff --git a/src/linguist/Qt5LinguistToolsMacros.cmake b/src/linguist/Qt5LinguistToolsMacros.cmake index b99597304..5c357a152 100644 --- a/src/linguist/Qt5LinguistToolsMacros.cmake +++ b/src/linguist/Qt5LinguistToolsMacros.cmake @@ -74,7 +74,8 @@ function(QT5_CREATE_TRANSLATION _qm_files) add_custom_command(OUTPUT ${_ts_file} COMMAND ${Qt5_LUPDATE_EXECUTABLE} ARGS ${_lupdate_options} "@${_ts_lst_file}" -ts ${_ts_file} - DEPENDS ${_my_sources} ${_ts_lst_file} VERBATIM) + DEPENDS ${_my_sources} + BYPRODUCTS ${_ts_lst_file} VERBATIM) endforeach() qt5_add_translation(${_qm_files} ${_my_tsfiles}) set(${_qm_files} ${${_qm_files}} PARENT_SCOPE) diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp index aac9a90ff..e96e102af 100644 --- a/src/linguist/lupdate/cpp.cpp +++ b/src/linguist/lupdate/cpp.cpp @@ -239,6 +239,7 @@ private: std::ostream &yyMsg(int line = 0); int getChar(); + TokenType lookAheadToSemicolonOrLeftBrace(); TokenType getToken(); void processComment(); @@ -249,7 +250,6 @@ private: bool matchStringOrNull(QString *s); bool matchExpression(); - QString transcode(const QString &str); void recordMessage( int line, const QString &context, const QString &text, const QString &comment, const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, @@ -450,6 +450,23 @@ int CppParser::getChar() } } +CppParser::TokenType CppParser::lookAheadToSemicolonOrLeftBrace() +{ + if (*yyInPtr == 0) + return Tok_Eof; + const ushort *uc = yyInPtr + 1; + forever { + ushort c = *uc; + if (!c) + return Tok_Eof; + if (c == ';') + return Tok_Semicolon; + if (c == '{') + return Tok_LeftBrace; + ++uc; + } +} + STRING(Q_OBJECT); STRING(class); STRING(final); @@ -1451,7 +1468,7 @@ bool CppParser::matchString(QString *s) return matches; matches = true; if (yyTok == Tok_String) - *s += transcode(yyWord); + *s += ParserTool::transcode(yyWord); else *s += yyWord; s->detach(); @@ -1532,65 +1549,14 @@ bool CppParser::matchExpression() return true; } -QString CppParser::transcode(const QString &str) -{ - static const char tab[] = "abfnrtv"; - static const char backTab[] = "\a\b\f\n\r\t\v"; - // This function has to convert back to bytes, as C's \0* sequences work at that level. - const QByteArray in = str.toUtf8(); - QByteArray out; - - out.reserve(in.length()); - for (int i = 0; i < in.length();) { - uchar c = in[i++]; - if (c == '\\') { - if (i >= in.length()) - break; - c = in[i++]; - - if (c == '\n') - continue; - - if (c == 'x' || c == 'u' || c == 'U') { - const bool unicode = (c != 'x'); - QByteArray hex; - while (i < in.length() && isxdigit((c = in[i]))) { - hex += c; - i++; - } - if (unicode) - out += QString(QChar(hex.toUInt(nullptr, 16))).toUtf8(); - else - out += hex.toUInt(nullptr, 16); - } else if (c >= '0' && c < '8') { - QByteArray oct; - int n = 0; - oct += c; - while (n < 2 && i < in.length() && (c = in[i]) >= '0' && c < '8') { - i++; - n++; - oct += c; - } - out += oct.toUInt(0, 8); - } else { - const char *p = strchr(tab, c); - out += !p ? c : backTab[p - tab]; - } - } else { - out += c; - } - } - return QString::fromUtf8(out.constData(), out.length()); -} - void CppParser::recordMessage(int line, const QString &context, const QString &text, const QString &comment, const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, bool plural) { TranslatorMessage msg( - transcode(context), text, transcode(comment), QString(), + ParserTool::transcode(context), text, ParserTool::transcode(comment), QString(), yyFileName, line, QStringList(), TranslatorMessage::Unfinished, plural); - msg.setExtraComment(transcode(extracomment.simplified())); + msg.setExtraComment(ParserTool::transcode(extracomment.simplified())); msg.setId(msgid); msg.setExtras(extra); tor->append(msg); @@ -1760,7 +1726,7 @@ void CppParser::handleTrId(bool plural) yyTok = getToken(); if (matchString(&msgid) && !msgid.isEmpty()) { plural |= match(Tok_Comma); - recordMessage(line, QString(), transcode(sourcetext), QString(), extracomment, + recordMessage(line, QString(), ParserTool::transcode(sourcetext), QString(), extracomment, msgid, extra, plural); } sourcetext.clear(); @@ -2182,8 +2148,11 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac pendingContext = prospectiveContext; prospectiveContext.clear(); } - if (yyTok == Tok_Colon) - yyTokColonSeen = true; + //ignore colons for bitfields (are usually followed by a semicolon) + if (yyTok == Tok_Colon) { + if (lookAheadToSemicolonOrLeftBrace() != Tok_Semicolon) + yyTokColonSeen = true; + } } metaExpected = true; yyTok = getToken(); @@ -2314,11 +2283,11 @@ void CppParser::processComment() context = comment.left(k); comment.remove(0, k + 1); TranslatorMessage msg( - transcode(context), QString(), - transcode(comment), QString(), + ParserTool::transcode(context), QString(), + ParserTool::transcode(comment), QString(), yyFileName, yyLineNo, QStringList(), TranslatorMessage::Finished, false); - msg.setExtraComment(transcode(extracomment.simplified())); + msg.setExtraComment(ParserTool::transcode(extracomment.simplified())); extracomment.clear(); tor->append(msg); tor->setExtras(extra); diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h index 0d98379d0..bb58cbd1e 100644 --- a/src/linguist/lupdate/lupdate.h +++ b/src/linguist/lupdate/lupdate.h @@ -99,6 +99,11 @@ bool loadQml(Translator &translator, const QString &filename, ConversionData &cd UNARY_MACRO(qsTranslate) \ /*end*/ +class ParserTool +{ +public: + static QString transcode(const QString &str); +}; class TrFunctionAliasManager { public: diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp index eb81ee9e8..d9c6f7966 100644 --- a/src/linguist/lupdate/main.cpp +++ b/src/linguist/lupdate/main.cpp @@ -134,6 +134,57 @@ QStringList TrFunctionAliasManager::availableFunctionsWithAliases() const TrFunctionAliasManager trFunctionAliasManager; +QString ParserTool::transcode(const QString &str) +{ + static const char tab[] = "abfnrtv"; + static const char backTab[] = "\a\b\f\n\r\t\v"; + // This function has to convert back to bytes, as C's \0* sequences work at that level. + const QByteArray in = str.toUtf8(); + QByteArray out; + + out.reserve(in.length()); + for (int i = 0; i < in.length();) { + uchar c = in[i++]; + if (c == '\\') { + if (i >= in.length()) + break; + c = in[i++]; + + if (c == '\n') + continue; + + if (c == 'x' || c == 'u' || c == 'U') { + const bool unicode = (c != 'x'); + QByteArray hex; + while (i < in.length() && isxdigit((c = in[i]))) { + hex += c; + i++; + } + if (unicode) + out += QString(QChar(hex.toUInt(nullptr, 16))).toUtf8(); + else + out += hex.toUInt(nullptr, 16); + } else if (c >= '0' && c < '8') { + QByteArray oct; + int n = 0; + oct += c; + while (n < 2 && i < in.length() && (c = in[i]) >= '0' && c < '8') { + i++; + n++; + oct += c; + } + out += oct.toUInt(0, 8); + } else { + const char *p = strchr(tab, c); + out += !p ? c : backTab[p - tab]; + } + } else { + out += c; + } + } + return QString::fromUtf8(out.constData(), out.length()); +} + static QString m_defaultExtensions; static void printOut(const QString & out) @@ -314,6 +365,19 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil printErr(LU::tr("lupdate warning: Specified source language '%1' disagrees with" " existing file's language '%2'. Ignoring.\n") .arg(sourceLanguage, tor.sourceLanguageCode())); + // If there is translation in the file, the language should be recognized + // (when the language is not recognized, plural translations are lost) + if (tor.translationsExist()) { + QLocale::Language l; + QLocale::Country c; + tor.languageAndCountry(tor.languageCode(), &l, &c); + QStringList forms; + if (!getNumerusInfo(l, c, 0, &forms, 0)) { + printErr(LU::tr("File %1 won't be updated: it contains translation but the" + " target language is not recognized\n").arg(fileName)); + continue; + } + } } else { if (!targetLanguage.isEmpty()) tor.setLanguageCode(targetLanguage); diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp index 0938b86e8..fa8ad260e 100644 --- a/src/linguist/lupdate/qdeclarative.cpp +++ b/src/linguist/lupdate/qdeclarative.cpp @@ -130,11 +130,11 @@ protected: if (!sourcetext.isEmpty()) yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name)); - TranslatorMessage msg(m_component, source, + TranslatorMessage msg(m_component, ParserTool::transcode(source), comment, QString(), m_fileName, node->firstSourceLocation().startLine, QStringList(), TranslatorMessage::Unfinished, plural); - msg.setExtraComment(extracomment.simplified()); + msg.setExtraComment(ParserTool::transcode(extracomment.simplified())); msg.setId(msgid); msg.setExtras(extra); m_translator->extend(msg, m_cd); @@ -171,11 +171,11 @@ protected: plural = true; } - TranslatorMessage msg(context, source, + TranslatorMessage msg(context, ParserTool::transcode(source), comment, QString(), m_fileName, node->firstSourceLocation().startLine, QStringList(), TranslatorMessage::Unfinished, plural); - msg.setExtraComment(extracomment.simplified()); + msg.setExtraComment(ParserTool::transcode(extracomment.simplified())); msg.setId(msgid); msg.setExtras(extra); m_translator->extend(msg, m_cd); @@ -199,11 +199,11 @@ protected: bool plural = node->arguments->next; - TranslatorMessage msg(QString(), sourcetext, + TranslatorMessage msg(QString(), ParserTool::transcode(sourcetext), QString(), QString(), m_fileName, node->firstSourceLocation().startLine, QStringList(), TranslatorMessage::Unfinished, plural); - msg.setExtraComment(extracomment.simplified()); + msg.setExtraComment(ParserTool::transcode(extracomment.simplified())); msg.setId(id); msg.setExtras(extra); m_translator->extend(msg, m_cd); @@ -221,7 +221,7 @@ private: return std::cerr << qPrintable(m_fileName) << ':' << line << ": "; } - void throwRecursionDepthError() + void throwRecursionDepthError() final { std::cerr << qPrintable(m_fileName) << ": " << qPrintable(LU::tr("Maximum statement or expression depth exceeded")); diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp index af669e235..db28ea396 100644 --- a/src/linguist/shared/translator.cpp +++ b/src/linguist/shared/translator.cpp @@ -433,6 +433,17 @@ void Translator::stripUntranslatedMessages() m_indexOk = false; } +bool Translator::translationsExist() +{ + for (TMM::Iterator it = m_messages.begin(); it != m_messages.end(); ) { + if (it->isTranslated()) + return true; + else + ++it; + } + return false; +} + void Translator::stripEmptyContexts() { for (TMM::Iterator it = m_messages.begin(); it != m_messages.end();) diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h index 8919a13df..5b5d12250 100644 --- a/src/linguist/shared/translator.h +++ b/src/linguist/shared/translator.h @@ -135,6 +135,7 @@ public: void dropTranslations(); void dropUiLines(); void makeFileNamesAbsolute(const QDir &originalPath); + bool translationsExist(); struct Duplicates { QSet<int> byId, byContents; }; Duplicates resolveDuplicates(); diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp index 5914319c9..153f9708b 100644 --- a/src/linguist/shared/ts.cpp +++ b/src/linguist/shared/ts.cpp @@ -464,7 +464,7 @@ static QString protect(const QString &str) result += QLatin1String("'"); break; default: - if ((c < 0x20 || (ch > 0x7f && ch.isSpace())) && c != '\r' && c != '\n' && c != '\t') + if ((c < 0x20 || (ch > 0x7f && ch.isSpace())) && c != '\n' && c != '\t') result += numericEntity(c); else // this also covers surrogates result += QChar(c); |