Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
metastrings.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "metastrings.h"
5
6namespace {
7using namespace Qt::Literals::StringLiterals;
8
9static constexpr QLatin1String CppMagicComment = "TRANSLATOR"_L1;
10} // namespace
11
12QT_BEGIN_NAMESPACE
13
14bool MetaStrings::parse(QString &string)
15{
16 const QChar *ptr = string.unicode();
17 if (*ptr == u':' && ptr[1].isSpace()) {
18 string.remove(0, 2);
19 m_extracomment += string;
20 if (!m_extracomment.endsWith(u'\n'))
21 m_extracomment.push_back(u'\n');
22 m_extracomment.detach();
23 } else if (*ptr == u'=' && ptr[1].isSpace()) {
24 string.remove(0, 2);
25 m_msgid = string.simplified();
26 m_msgid.detach();
27 m_error =
28 "Setting translation IDs using //= or #= is deprecated and will be removed in the upcoming versions.\n"_L1;
29 } else if (*ptr == u'~' && ptr[1].isSpace()) {
30 string.remove(0, 2);
31 const QString trimmed = string.trimmed();
32 int k = trimmed.indexOf(u' ');
33 if (k > -1) {
34 QString commentvalue = trimmed.mid(k + 1).trimmed();
35 if (commentvalue.startsWith(u'"') && commentvalue.endsWith(u'"')
36 && commentvalue.size() != 1) {
37 commentvalue = commentvalue.sliced(1, commentvalue.size() - 2);
38 }
39 m_extra.insert(trimmed.left(k), commentvalue);
40 }
41 } else if (*ptr == u'%' && ptr[1].isSpace()) {
42 m_sourcetext.reserve(m_sourcetext.size() + string.size() - 2);
43 ushort *ptr = (ushort *)m_sourcetext.data() + m_sourcetext.size();
44 int p = 2, c;
45 forever {
46 if (p >= string.size())
47 break;
48 c = string.unicode()[p++].unicode();
49 if (isspace(c))
50 continue;
51 if (c != '"') {
52 m_error = "Unexpected character in meta string\n"_L1;
53 break;
54 }
55 forever {
56 if (p >= string.size()) {
57 whoops:
58 m_error = "Unterminated meta string\n"_L1;
59 break;
60 }
61 c = string.unicode()[p++].unicode();
62 if (c == '"')
63 break;
64 if (c == '\\') {
65 if (p >= string.size())
66 goto whoops;
67 c = string.unicode()[p++].unicode();
68 if (c == '\n')
69 goto whoops;
70 *ptr++ = '\\';
71 }
72 *ptr++ = c;
73 }
74 }
75 m_sourcetext.resize(ptr - (ushort *)m_sourcetext.data());
76 } else if (*ptr == u'@' && ptr[1].isSpace()) {
77 string.remove(0, 2);
78 m_label = string.trimmed().simplified();
79 m_label.detach();
80 } else if (const QString trimmed = string.trimmed(); trimmed.startsWith(CppMagicComment)) {
81 qsizetype idx = CppMagicComment.size();
82 QString comment =
83 QString::fromRawData(trimmed.unicode() + idx, trimmed.size() - idx).simplified();
84 if (int k = comment.indexOf(u' '); k != -1) {
85 QString context = comment.left(k);
86 comment.remove(0, k + 1);
87 m_magicComment.emplace(MagicComment{ std::move(context), std::move(comment) });
88 }
89 }
90
91 return m_error.isEmpty();
92}
93
94void MetaStrings::clear()
95{
96 m_magicComment.reset();
97 m_extracomment.clear();
98 m_msgid.clear();
99 m_label.clear();
100 m_sourcetext.clear();
101 m_extra.clear();
102}
103
104bool MetaStrings::hasData() const
105{
106 return !m_msgid.isEmpty() || m_magicComment || !m_sourcetext.isEmpty()
107 || !m_extracomment.isEmpty() || !m_extra.isEmpty() || !m_label.isEmpty();
108}
109
110QT_END_NAMESPACE