summaryrefslogtreecommitdiffstats
path: root/src/tools/uic/shared/language.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-11-01 11:11:12 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-05 08:28:56 +0000
commit89120c4a76fed3c62c019514c12e7fb7c063b4b7 (patch)
treee3b301df1529ac9cd382441a7a27889dcab355c3 /src/tools/uic/shared/language.cpp
parented485243b594a730cebee4d76847e0f556d369f4 (diff)
uic: Refactor string constant formatting
Refactor the fixString() helper, moving the code into a streamable class using a helper which can be used for different encodings. Task-number: PYSIDE-797 Change-Id: I0f82945b6b334da8524882dda2f104327eba79d4 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'src/tools/uic/shared/language.cpp')
-rw-r--r--src/tools/uic/shared/language.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp
index 730e1562bc..d0491b74e3 100644
--- a/src/tools/uic/shared/language.cpp
+++ b/src/tools/uic/shared/language.cpp
@@ -32,6 +32,8 @@
namespace language {
+static Encoding encoding = Encoding::Utf8;
+
QTextStream &operator<<(QTextStream &str, const qtConfig &c)
{
str << "QT_CONFIG(" << c.parameter() << ')';
@@ -141,4 +143,129 @@ const char *paletteColorRole(int v)
return lookupEnum(colorRoles, v);
}
+// Helpers for formatting a character sequences
+
+// Format a special character like '\x0a'
+static int formatEscapedNumber(QTextStream &str, ushort value, int base, int width,
+ char prefix = 0)
+{
+ int length = 1 + width;
+ str << '\\';
+ if (prefix) {
+ str << prefix;
+ ++length;
+ }
+ const auto oldPadChar = str.padChar();
+ const auto oldFieldWidth = str.fieldWidth();
+ const auto oldFieldAlignment = str.fieldAlignment();
+ const auto oldIntegerBase = str.integerBase();
+ str.setPadChar(QLatin1Char('0'));
+ str.setFieldWidth(width);
+ str.setFieldAlignment(QTextStream::AlignRight);
+ str.setIntegerBase(base);
+ str << value;
+ str.setIntegerBase(oldIntegerBase);
+ str.setFieldAlignment(oldFieldAlignment);
+ str.setFieldWidth(oldFieldWidth);
+ str.setPadChar(oldPadChar);
+ return length;
+}
+
+static int formatSpecialCharacter(QTextStream &str, ushort value)
+{
+ int length = 0;
+ switch (value) {
+ case '\\':
+ str << "\\\\";
+ length += 2;
+ break;
+ case '\"':
+ str << "\\\"";
+ length += 2;
+ break;
+ case '\n':
+ str << "\\n\"\n\"";
+ length += 5;
+ break;
+ default:
+ break;
+ }
+ return length;
+}
+
+// Format a sequence of characters for C++ with special characters numerically
+// escaped (non-raw string literals), wrappped at maxSegmentSize. FormattingTraits
+// are used to transform characters into (unsigned) codes, which can be used
+// for either normal escapes or Unicode code points as used in Unicode literals.
+
+enum : int { maxSegmentSize = 1024 };
+
+template <Encoding e>
+struct FormattingTraits
+{
+};
+
+template <>
+struct FormattingTraits<Encoding::Utf8>
+{
+ static ushort code(char c) { return uchar(c); }
+};
+
+template <>
+struct FormattingTraits<Encoding::Unicode>
+{
+ static ushort code(QChar c) { return c.unicode(); }
+};
+
+template <Encoding e, class Iterator>
+static void formatStringSequence(QTextStream &str, Iterator it, Iterator end,
+ const QString &indent,
+ int escapeIntegerBase, int escapeWidth,
+ char escapePrefix = 0)
+{
+ str << '"';
+ int length = 0;
+ while (it != end) {
+ const auto code = FormattingTraits<e>::code(*it);
+ if (code >= 0x80) {
+ length += formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix);
+ } else if (const int l = formatSpecialCharacter(str, code)) {
+ length += l;
+ } else if (code != '\r') {
+ str << *it;
+ ++length;
+ }
+ ++it;
+ if (it != end && length > maxSegmentSize) {
+ str << "\"\n" << indent << indent << '"';
+ length = 0;
+ }
+ }
+ str << '"';
+}
+
+void _formatString(QTextStream &str, const QString &value, const QString &indent,
+ bool qString)
+{
+ switch (encoding) {
+ // Special characters as 3 digit octal escapes (u8"\303\234mlaut")
+ case Encoding::Utf8: {
+ if (qString)
+ str << "QString::fromUtf8(";
+ const QByteArray utf8 = value.toUtf8();
+ formatStringSequence<Encoding::Utf8>(str, utf8.cbegin(), utf8.cend(), indent,
+ 8, 3);
+ if (qString)
+ str << ')';
+ }
+ break;
+ // Special characters as 4 digit hex Unicode points (u8"\u00dcmlaut")
+ case Encoding::Unicode:
+ str << 'u'; // Python Unicode literal (would be UTF-16 in C++)
+ formatStringSequence<Encoding::Unicode>(str, value.cbegin(), value.cend(), indent,
+ 16, 4, 'u');
+ break;
+ }
+}
+
} // namespace language