summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2023-03-30 11:17:52 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-04-01 08:01:59 +0000
commit54a77b524ab59fa9ee8f2f37b9963fbb363ea4ae (patch)
tree7b04fd6de162a4b76577da775fc9ec085f1dccec
parent5b954c016d5b5334ae2b470016a51466a7f5fef0 (diff)
lupdate: Handle C++ string literals
The fix for QTBUG-73273 already added code to allow prefixed raw string literals. Now, lupdate supports regular prefixed string literals as well. If the parser encounters a prefixed string literal, ignore the prefix and handle the rest as ordinary string literal. Note that expressions like tr(U"foo") won't compile out of the box. We support them nevertheless. The user might provide their own tr macro that handles such string literals. [ChangeLog][lupdate] lupdate now supports prefixed string literals like u"foo". Fixes: QTBUG-59802 Change-Id: Ibe8b4b83ee1197a73678b1e8f37dd6ac7db57714 Reviewed-by: Kai Köhne <kai.koehne@qt.io> (cherry picked from commit d5007c7a556a94df6ea76a368804dac729aab83a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/linguist/lupdate/cpp.cpp13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp19
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result43
3 files changed, 75 insertions, 0 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index d86481fdc..b9b9f4dfd 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -335,6 +335,14 @@ CppParser::TokenType CppParser::lookAheadToSemicolonOrLeftBrace()
}
}
+static bool isStringLiteralPrefix(const QStringView s)
+{
+ return s == u"L"_s
+ || s == u"U"_s
+ || s == u"u"_s
+ || s == u"u8"_s;
+}
+
static const QString strQ_OBJECT = u"Q_OBJECT"_s;
static const QString strclass = u"class"_s;
static const QString strfinal = u"final"_s;
@@ -563,6 +571,11 @@ CppParser::TokenType CppParser::getToken()
//qDebug() << "IDENT: " << yyWord;
+ if (yyCh == '"' && isStringLiteralPrefix(yyWord)) {
+ // Handle prefixed string literals as ordinary string literals.
+ continue;
+ }
+
switch (yyWord.unicode()[0].unicode()) {
case 'N':
if (yyWord == strNULL)
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
index a4188c4d3..7abc1ac0a 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
@@ -147,3 +147,22 @@ struct IntLiteralsWithSeparators {
int x = 0x1'AF'FE;
int X = 0X2'E5E7;
};
+
+
+// QTBUG-59802: prefixed string literals
+class PrefixedStringLiterals : public QObject {
+ Q_OBJECT
+ void foo()
+ {
+ #if 0
+ tr(u8"UTF-8 string literal");
+ tr(u8R"(UTF-8 raw string literal)");
+ tr(u"UTF-16 string literal");
+ tr(uR"(UTF-16 raw string literal)");
+ tr(U"UTF-32 string literal");
+ tr(UR"(UTF-32 raw string literal)");
+ tr(L"wide string literal");
+ tr(LR"(wide raw string literal)");
+ #endif
+ }
+};
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
index 0710915de..63885debf 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
@@ -18,6 +18,49 @@
</message>
</context>
<context>
+ <name>PrefixedStringLiterals</name>
+ <message>
+ <location filename="main.cpp" line="158"/>
+ <source>UTF-8 string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="159"/>
+ <source>UTF-8 raw string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="160"/>
+ <source>UTF-16 string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="161"/>
+ <source>UTF-16 raw string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="162"/>
+ <source>UTF-32 string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="163"/>
+ <source>UTF-32 raw string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="164"/>
+ <source>wide string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="165"/>
+ <source>wide raw string literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>QObject</name>
<message>
<location filename="main.cpp" line="107"/>