05fc3aef53
Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
431 lines
16 KiB
C++
431 lines
16 KiB
C++
// 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 "textdump.h"
|
|
|
|
#include <QTextStream>
|
|
#include <QString>
|
|
|
|
namespace QtDiag {
|
|
|
|
struct EnumLookup {
|
|
int value;
|
|
const char *description;
|
|
};
|
|
|
|
static const EnumLookup specialCharactersEnumLookup[] =
|
|
{
|
|
{QChar::Null, "Null"},
|
|
{QChar::Tabulation, "Tabulation"},
|
|
{QChar::LineFeed, "LineFeed"},
|
|
{QChar::FormFeed, "FormFeed"},
|
|
{QChar::CarriageReturn, "CarriageReturn"},
|
|
{QChar::Space, "Space"},
|
|
{QChar::Nbsp, "Nbsp"},
|
|
{QChar::SoftHyphen, "SoftHyphen"},
|
|
{QChar::ReplacementCharacter, "ReplacementCharacter"},
|
|
{QChar::ObjectReplacementCharacter, "ObjectReplacementCharacter"},
|
|
{QChar::ByteOrderMark, "ByteOrderMark"},
|
|
{QChar::ByteOrderSwapped, "ByteOrderSwapped"},
|
|
{QChar::ParagraphSeparator, "ParagraphSeparator"},
|
|
{QChar::LineSeparator, "LineSeparator"},
|
|
{QChar::LastValidCodePoint, "LastValidCodePoint"}
|
|
};
|
|
|
|
static const EnumLookup categoryEnumLookup[] =
|
|
{
|
|
{QChar::Mark_NonSpacing, "Mark_NonSpacing"},
|
|
{QChar::Mark_SpacingCombining, "Mark_SpacingCombining"},
|
|
{QChar::Mark_Enclosing, "Mark_Enclosing"},
|
|
|
|
{QChar::Number_DecimalDigit, "Number_DecimalDigit"},
|
|
{QChar::Number_Letter, "Number_Letter"},
|
|
{QChar::Number_Other, "Number_Other"},
|
|
|
|
{QChar::Separator_Space, "Separator_Space"},
|
|
{QChar::Separator_Line, "Separator_Line"},
|
|
{QChar::Separator_Paragraph, "Separator_Paragraph"},
|
|
|
|
{QChar::Other_Control, "Other_Control"},
|
|
{QChar::Other_Format, "Other_Format"},
|
|
{QChar::Other_Surrogate, "Other_Surrogate"},
|
|
{QChar::Other_PrivateUse, "Other_PrivateUse"},
|
|
{QChar::Other_NotAssigned, "Other_NotAssigned"},
|
|
|
|
{QChar::Letter_Uppercase, "Letter_Uppercase"},
|
|
{QChar::Letter_Lowercase, "Letter_Lowercase"},
|
|
{QChar::Letter_Titlecase, "Letter_Titlecase"},
|
|
{QChar::Letter_Modifier, "Letter_Modifier"},
|
|
{QChar::Letter_Other, "Letter_Other"},
|
|
|
|
{QChar::Punctuation_Connector, "Punctuation_Connector"},
|
|
{QChar::Punctuation_Dash, "Punctuation_Dash"},
|
|
{QChar::Punctuation_Open, "Punctuation_Open"},
|
|
{QChar::Punctuation_Close, "Punctuation_Close"},
|
|
{QChar::Punctuation_InitialQuote, "Punctuation_InitialQuote"},
|
|
{QChar::Punctuation_FinalQuote, "Punctuation_FinalQuote"},
|
|
{QChar::Punctuation_Other, "Punctuation_Other"},
|
|
|
|
{QChar::Symbol_Math, "Symbol_Math"},
|
|
{QChar::Symbol_Currency, "Symbol_Currency"},
|
|
{QChar::Symbol_Modifier, "Symbol_Modifier"},
|
|
{QChar::Symbol_Other, "Symbol_Other"},
|
|
};
|
|
|
|
static const EnumLookup scriptEnumLookup[] =
|
|
{
|
|
{QChar::Script_Unknown, "Script_Unknown"},
|
|
{QChar::Script_Inherited, "Script_Inherited"},
|
|
{QChar::Script_Common, "Script_Common"},
|
|
|
|
{QChar::Script_Latin, "Script_Latin"},
|
|
{QChar::Script_Greek, "Script_Greek"},
|
|
{QChar::Script_Cyrillic, "Script_Cyrillic"},
|
|
{QChar::Script_Armenian, "Script_Armenian"},
|
|
{QChar::Script_Hebrew, "Script_Hebrew"},
|
|
{QChar::Script_Arabic, "Script_Arabic"},
|
|
{QChar::Script_Syriac, "Script_Syriac"},
|
|
{QChar::Script_Thaana, "Script_Thaana"},
|
|
{QChar::Script_Devanagari, "Script_Devanagari"},
|
|
{QChar::Script_Bengali, "Script_Bengali"},
|
|
{QChar::Script_Gurmukhi, "Script_Gurmukhi"},
|
|
{QChar::Script_Gujarati, "Script_Gujarati"},
|
|
{QChar::Script_Oriya, "Script_Oriya"},
|
|
{QChar::Script_Tamil, "Script_Tamil"},
|
|
{QChar::Script_Telugu, "Script_Telugu"},
|
|
{QChar::Script_Kannada, "Script_Kannada"},
|
|
{QChar::Script_Malayalam, "Script_Malayalam"},
|
|
{QChar::Script_Sinhala, "Script_Sinhala"},
|
|
{QChar::Script_Thai, "Script_Thai"},
|
|
{QChar::Script_Lao, "Script_Lao"},
|
|
{QChar::Script_Tibetan, "Script_Tibetan"},
|
|
{QChar::Script_Myanmar, "Script_Myanmar"},
|
|
{QChar::Script_Georgian, "Script_Georgian"},
|
|
{QChar::Script_Hangul, "Script_Hangul"},
|
|
{QChar::Script_Ethiopic, "Script_Ethiopic"},
|
|
{QChar::Script_Cherokee, "Script_Cherokee"},
|
|
{QChar::Script_CanadianAboriginal, "Script_CanadianAboriginal"},
|
|
{QChar::Script_Ogham, "Script_Ogham"},
|
|
{QChar::Script_Runic, "Script_Runic"},
|
|
{QChar::Script_Khmer, "Script_Khmer"},
|
|
{QChar::Script_Mongolian, "Script_Mongolian"},
|
|
{QChar::Script_Hiragana, "Script_Hiragana"},
|
|
{QChar::Script_Katakana, "Script_Katakana"},
|
|
{QChar::Script_Bopomofo, "Script_Bopomofo"},
|
|
{QChar::Script_Han, "Script_Han"},
|
|
{QChar::Script_Yi, "Script_Yi"},
|
|
{QChar::Script_OldItalic, "Script_OldItalic"},
|
|
{QChar::Script_Gothic, "Script_Gothic"},
|
|
{QChar::Script_Deseret, "Script_Deseret"},
|
|
{QChar::Script_Tagalog, "Script_Tagalog"},
|
|
{QChar::Script_Hanunoo, "Script_Hanunoo"},
|
|
{QChar::Script_Buhid, "Script_Buhid"},
|
|
{QChar::Script_Tagbanwa, "Script_Tagbanwa"},
|
|
{QChar::Script_Coptic, "Script_Coptic"},
|
|
|
|
{QChar::Script_Limbu, "Script_Limbu"},
|
|
{QChar::Script_TaiLe, "Script_TaiLe"},
|
|
{QChar::Script_LinearB, "Script_LinearB"},
|
|
{QChar::Script_Ugaritic, "Script_Ugaritic"},
|
|
{QChar::Script_Shavian, "Script_Shavian"},
|
|
{QChar::Script_Osmanya, "Script_Osmanya"},
|
|
{QChar::Script_Cypriot, "Script_Cypriot"},
|
|
{QChar::Script_Braille, "Script_Braille"},
|
|
|
|
{QChar::Script_Buginese, "Script_Buginese"},
|
|
{QChar::Script_NewTaiLue, "Script_NewTaiLue"},
|
|
{QChar::Script_Glagolitic, "Script_Glagolitic"},
|
|
{QChar::Script_Tifinagh, "Script_Tifinagh"},
|
|
{QChar::Script_SylotiNagri, "Script_SylotiNagri"},
|
|
{QChar::Script_OldPersian, "Script_OldPersian"},
|
|
{QChar::Script_Kharoshthi, "Script_Kharoshthi"},
|
|
|
|
{QChar::Script_Balinese, "Script_Balinese"},
|
|
{QChar::Script_Cuneiform, "Script_Cuneiform"},
|
|
{QChar::Script_Phoenician, "Script_Phoenician"},
|
|
{QChar::Script_PhagsPa, "Script_PhagsPa"},
|
|
{QChar::Script_Nko, "Script_Nko"},
|
|
|
|
{QChar::Script_Sundanese, "Script_Sundanese"},
|
|
{QChar::Script_Lepcha, "Script_Lepcha"},
|
|
{QChar::Script_OlChiki, "Script_OlChiki"},
|
|
{QChar::Script_Vai, "Script_Vai"},
|
|
{QChar::Script_Saurashtra, "Script_Saurashtra"},
|
|
{QChar::Script_KayahLi, "Script_KayahLi"},
|
|
{QChar::Script_Rejang, "Script_Rejang"},
|
|
{QChar::Script_Lycian, "Script_Lycian"},
|
|
{QChar::Script_Carian, "Script_Carian"},
|
|
{QChar::Script_Lydian, "Script_Lydian"},
|
|
{QChar::Script_Cham, "Script_Cham"},
|
|
|
|
{QChar::Script_TaiTham, "Script_TaiTham"},
|
|
{QChar::Script_TaiViet, "Script_TaiViet"},
|
|
{QChar::Script_Avestan, "Script_Avestan"},
|
|
{QChar::Script_EgyptianHieroglyphs, "Script_EgyptianHieroglyphs"},
|
|
{QChar::Script_Samaritan, "Script_Samaritan"},
|
|
{QChar::Script_Lisu, "Script_Lisu"},
|
|
{QChar::Script_Bamum, "Script_Bamum"},
|
|
{QChar::Script_Javanese, "Script_Javanese"},
|
|
{QChar::Script_MeeteiMayek, "Script_MeeteiMayek"},
|
|
{QChar::Script_ImperialAramaic, "Script_ImperialAramaic"},
|
|
{QChar::Script_OldSouthArabian, "Script_OldSouthArabian"},
|
|
{QChar::Script_InscriptionalParthian, "Script_InscriptionalParthian"},
|
|
{QChar::Script_InscriptionalPahlavi, "Script_InscriptionalPahlavi"},
|
|
{QChar::Script_OldTurkic, "Script_OldTurkic"},
|
|
{QChar::Script_Kaithi, "Script_Kaithi"},
|
|
|
|
{QChar::Script_Batak, "Script_Batak"},
|
|
{QChar::Script_Brahmi, "Script_Brahmi"},
|
|
{QChar::Script_Mandaic, "Script_Mandaic"},
|
|
|
|
{QChar::Script_Chakma, "Script_Chakma"},
|
|
{QChar::Script_MeroiticCursive, "Script_MeroiticCursive"},
|
|
{QChar::Script_MeroiticHieroglyphs, "Script_MeroiticHieroglyphs"},
|
|
{QChar::Script_Miao, "Script_Miao"},
|
|
{QChar::Script_Sharada, "Script_Sharada"},
|
|
{QChar::Script_SoraSompeng, "Script_SoraSompeng"},
|
|
{QChar::Script_Takri, "Script_Takri"},
|
|
|
|
{QChar::Script_CaucasianAlbanian, "Script_CaucasianAlbanian"},
|
|
{QChar::Script_BassaVah, "Script_BassaVah"},
|
|
{QChar::Script_Duployan, "Script_Duployan"},
|
|
{QChar::Script_Elbasan, "Script_Elbasan"},
|
|
{QChar::Script_Grantha, "Script_Grantha"},
|
|
{QChar::Script_PahawhHmong, "Script_PahawhHmong"},
|
|
{QChar::Script_Khojki, "Script_Khojki"},
|
|
{QChar::Script_LinearA, "Script_LinearA"},
|
|
{QChar::Script_Mahajani, "Script_Mahajani"},
|
|
{QChar::Script_Manichaean, "Script_Manichaean"},
|
|
{QChar::Script_MendeKikakui, "Script_MendeKikakui"},
|
|
{QChar::Script_Modi, "Script_Modi"},
|
|
{QChar::Script_Mro, "Script_Mro"},
|
|
{QChar::Script_OldNorthArabian, "Script_OldNorthArabian"},
|
|
{QChar::Script_Nabataean, "Script_Nabataean"},
|
|
{QChar::Script_Palmyrene, "Script_Palmyrene"},
|
|
{QChar::Script_PauCinHau, "Script_PauCinHau"},
|
|
{QChar::Script_OldPermic, "Script_OldPermic"},
|
|
{QChar::Script_PsalterPahlavi, "Script_PsalterPahlavi"},
|
|
{QChar::Script_Siddham, "Script_Siddham"},
|
|
{QChar::Script_Khudawadi, "Script_Khudawadi"},
|
|
{QChar::Script_Tirhuta, "Script_Tirhuta"},
|
|
{QChar::Script_WarangCiti, "Script_WarangCiti"},
|
|
|
|
{QChar::Script_Ahom, "Script_Ahom"},
|
|
{QChar::Script_AnatolianHieroglyphs, "Script_AnatolianHieroglyphs"},
|
|
{QChar::Script_Hatran, "Script_Hatran"},
|
|
{QChar::Script_Multani, "Script_Multani"},
|
|
{QChar::Script_OldHungarian, "Script_OldHungarian"},
|
|
{QChar::Script_SignWriting, "Script_SignWriting"},
|
|
};
|
|
|
|
static const EnumLookup directionEnumLookup[] =
|
|
{
|
|
{QChar::DirL, "DirL"},
|
|
{QChar::DirR, "DirR"},
|
|
{QChar::DirEN, "DirEN"},
|
|
{QChar::DirES, "DirES"},
|
|
{QChar::DirET, "DirET"},
|
|
{QChar::DirAN, "DirAN"},
|
|
{QChar::DirCS, "DirCS"},
|
|
{QChar::DirB, "DirB"},
|
|
{QChar::DirS, "DirS"},
|
|
{QChar::DirWS, "DirWS"},
|
|
{QChar::DirON, "DirON"},
|
|
{QChar::DirLRE, "DirLRE"},
|
|
{QChar::DirLRO, "DirLRO"},
|
|
{QChar::DirAL, "DirAL"},
|
|
{QChar::DirRLE, "DirRLE"},
|
|
{QChar::DirRLO, "DirRLO"},
|
|
{QChar::DirPDF, "DirPDF"},
|
|
{QChar::DirNSM, "DirNSM"},
|
|
{QChar::DirBN, "DirBN"},
|
|
{QChar::DirLRI, "DirLRI"},
|
|
{QChar::DirRLI, "DirRLI"},
|
|
{QChar::DirFSI, "DirFSI"},
|
|
{QChar::DirPDI, "DirPDI"},
|
|
};
|
|
|
|
static const EnumLookup decompositionEnumLookup[] =
|
|
{
|
|
{QChar::NoDecomposition, "NoDecomposition"},
|
|
{QChar::Canonical, "Canonical"},
|
|
{QChar::Font, "Font"},
|
|
{QChar::NoBreak, "NoBreak"},
|
|
{QChar::Initial, "Initial"},
|
|
{QChar::Medial, "Medial"},
|
|
{QChar::Final, "Final"},
|
|
{QChar::Isolated, "Isolated"},
|
|
{QChar::Circle, "Circle"},
|
|
{QChar::Super, "Super"},
|
|
{QChar::Sub, "Sub"},
|
|
{QChar::Vertical, "Vertical"},
|
|
{QChar::Wide, "Wide"},
|
|
{QChar::Narrow, "Narrow"},
|
|
{QChar::Small, "Small"},
|
|
{QChar::Square, "Square"},
|
|
{QChar::Compat, "Compat"},
|
|
{QChar::Fraction, "Fraction"},
|
|
};
|
|
|
|
static const EnumLookup joiningTypeEnumLookup[] =
|
|
{
|
|
{QChar::Joining_None, "Joining_None"},
|
|
{QChar::Joining_Causing, "Joining_Causing"},
|
|
{QChar::Joining_Dual, "Joining_Dual"},
|
|
{QChar::Joining_Right, "Joining_Right"},
|
|
{QChar::Joining_Left, "Joining_Left"},
|
|
{QChar::Joining_Transparent, "Joining_Transparent"}
|
|
};
|
|
|
|
static const EnumLookup combiningClassEnumLookup[] =
|
|
{
|
|
{QChar::Combining_BelowLeftAttached, "Combining_BelowLeftAttached"},
|
|
{QChar::Combining_BelowAttached, "Combining_BelowAttached"},
|
|
{QChar::Combining_BelowRightAttached, "Combining_BelowRightAttached"},
|
|
{QChar::Combining_LeftAttached, "Combining_LeftAttached"},
|
|
{QChar::Combining_RightAttached, "Combining_RightAttached"},
|
|
{QChar::Combining_AboveLeftAttached, "Combining_AboveLeftAttached"},
|
|
{QChar::Combining_AboveAttached, "Combining_AboveAttached"},
|
|
{QChar::Combining_AboveRightAttached, "Combining_AboveRightAttached"},
|
|
|
|
{QChar::Combining_BelowLeft, "Combining_BelowLeft"},
|
|
{QChar::Combining_Below, "Combining_Below"},
|
|
{QChar::Combining_BelowRight, "Combining_BelowRight"},
|
|
{QChar::Combining_Left, "Combining_Left"},
|
|
{QChar::Combining_Right, "Combining_Right"},
|
|
{QChar::Combining_AboveLeft, "Combining_AboveLeft"},
|
|
{QChar::Combining_Above, "Combining_Above"},
|
|
{QChar::Combining_AboveRight, "Combining_AboveRight"},
|
|
|
|
{QChar::Combining_DoubleBelow, "Combining_DoubleBelow"},
|
|
{QChar::Combining_DoubleAbove, "Combining_DoubleAbove"},
|
|
{QChar::Combining_IotaSubscript, "Combining_IotaSubscript"},
|
|
};
|
|
|
|
static const EnumLookup unicodeVersionEnumLookup[] =
|
|
{
|
|
{QChar::Unicode_Unassigned, "Unicode_Unassigned"},
|
|
{QChar::Unicode_1_1, "Unicode_1_1"},
|
|
{QChar::Unicode_2_0, "Unicode_2_0"},
|
|
{QChar::Unicode_2_1_2, "Unicode_2_1_2"},
|
|
{QChar::Unicode_3_0, "Unicode_3_0"},
|
|
{QChar::Unicode_3_1, "Unicode_3_1"},
|
|
{QChar::Unicode_3_2, "Unicode_3_2"},
|
|
{QChar::Unicode_4_0, "Unicode_4_0"},
|
|
{QChar::Unicode_4_1, "Unicode_4_1"},
|
|
{QChar::Unicode_5_0, "Unicode_5_0"},
|
|
{QChar::Unicode_5_1, "Unicode_5_1"},
|
|
{QChar::Unicode_5_2, "Unicode_5_2"},
|
|
{QChar::Unicode_6_0, "Unicode_6_0"},
|
|
{QChar::Unicode_6_1, "Unicode_6_1"},
|
|
{QChar::Unicode_6_2, "Unicode_6_2"},
|
|
{QChar::Unicode_6_3, "Unicode_6_3"},
|
|
{QChar::Unicode_7_0, "Unicode_7_0"},
|
|
{QChar::Unicode_8_0, "Unicode_8_0"},
|
|
};
|
|
|
|
static const EnumLookup *enumLookup(int v, const EnumLookup *array, size_t size)
|
|
{
|
|
const EnumLookup *end = array + size;
|
|
for (const EnumLookup *p = array; p < end; ++p) {
|
|
if (p->value == v)
|
|
return p;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
static const char *enumName(int v, const EnumLookup *array, size_t size)
|
|
{
|
|
const EnumLookup *e = enumLookup(v, array, size);
|
|
return e ? e->description : "<unknown>";
|
|
}
|
|
|
|
// Context struct storing the parameters of the last character, only the parameters
|
|
// that change will be output.
|
|
struct FormattingContext
|
|
{
|
|
int category = -1;
|
|
int direction = -1;
|
|
int joiningType = -1;
|
|
int decompositionTag = -1;
|
|
int script = -1;
|
|
int unicodeVersion = -1;
|
|
};
|
|
|
|
static void formatCharacter(QTextStream &str, const QChar &qc, FormattingContext &context)
|
|
{
|
|
const ushort unicode = qc.unicode();
|
|
str << "U+" << qSetFieldWidth(4) << qSetPadChar('0') << Qt::uppercasedigits << Qt::hex
|
|
<< unicode << Qt::dec << qSetFieldWidth(0) << ' ';
|
|
|
|
const EnumLookup *specialChar = enumLookup(unicode, specialCharactersEnumLookup, sizeof(specialCharactersEnumLookup) / sizeof(EnumLookup));
|
|
if (specialChar)
|
|
str << specialChar->description;
|
|
else
|
|
str << "'" << qc << '\'';
|
|
|
|
const int category = qc.category();
|
|
if (category != context.category) {
|
|
str << " category="
|
|
<< enumName(category, categoryEnumLookup, sizeof(categoryEnumLookup) / sizeof(EnumLookup));
|
|
context.category = category;
|
|
}
|
|
const int script = qc.script();
|
|
if (script != context.script) {
|
|
str << " script="
|
|
<< enumName(script, scriptEnumLookup, sizeof(scriptEnumLookup) / sizeof(EnumLookup))
|
|
<< '(' << script << ')';
|
|
context.script = script;
|
|
}
|
|
const int direction = qc.direction();
|
|
if (direction != context.direction) {
|
|
str << " direction="
|
|
<< enumName(direction, directionEnumLookup, sizeof(directionEnumLookup) / sizeof(EnumLookup));
|
|
context.direction = direction;
|
|
}
|
|
const int joiningType = qc.joiningType();
|
|
if (joiningType != context.joiningType) {
|
|
str << " joiningType="
|
|
<< enumName(joiningType, joiningTypeEnumLookup, sizeof(joiningTypeEnumLookup) / sizeof(EnumLookup));
|
|
context.joiningType = joiningType;
|
|
}
|
|
const int decompositionTag = qc.decompositionTag();
|
|
if (decompositionTag != context.decompositionTag) {
|
|
str << " decomposition="
|
|
<< enumName(decompositionTag, decompositionEnumLookup, sizeof(decompositionEnumLookup) / sizeof(EnumLookup));
|
|
context.decompositionTag = decompositionTag;
|
|
}
|
|
const int unicodeVersion = qc.unicodeVersion();
|
|
if (unicodeVersion != context.unicodeVersion) {
|
|
str << " version="
|
|
<< enumName(unicodeVersion, unicodeVersionEnumLookup, sizeof(unicodeVersionEnumLookup) / sizeof(EnumLookup));
|
|
context.unicodeVersion = unicodeVersion;
|
|
}
|
|
}
|
|
|
|
QString dumpText(const QString &text)
|
|
{
|
|
QString result;
|
|
QTextStream str(&result);
|
|
FormattingContext context;
|
|
for (int i = 0; i < text.size(); ++i) {
|
|
str << '#' << (i + 1) << ' ';
|
|
formatCharacter(str, text.at(i), context);
|
|
str << '\n';
|
|
}
|
|
return result;
|
|
}
|
|
|
|
QString dumpTextAsCode(const QString &text)
|
|
{
|
|
QString result;
|
|
QTextStream str(&result);
|
|
str << " QString result;\n" << Qt::hex << Qt::showbase;
|
|
for (QChar c : text)
|
|
str << " result += QChar(" << c.unicode() << ");\n";
|
|
str << '\n';
|
|
return result;
|
|
}
|
|
|
|
} // namespace QtDiag
|