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
qqmldomstringdumper.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
6#include <QtCore/QDebug>
7
9
10namespace QQmlJS {
11namespace Dom {
12
13/*!
14 * \internal
15 * \fn QQmlJS::Dom::Sink
16 * \brief A Sink is a function that accepts a QStringView as input
17 *
18 * A Sink it the core element of a text based stream oriented output.
19 * It is simply a function accepting a QStringView as input.
20 */
21
22/*!
23 * \internal
24 * \fn QQmlJS::Dom::sinkInt
25 * \brief writes an integer to a sink without any axtra heap allocation
26 * \param sink where to write
27 * \param i the integer to write out
28 *
29 * mainly for debugging/fatal errors
30 */
31
32/*!
33 * \internal
34 * \class QQmlJS::Dom::Dumper
35 * \brief Helper class to accept eithe a string or a dumper (a function that writes to a sink)
36 *
37 * Using a Dumper as input parameter one always obtains a dumper (i.e. a
38 * function_ref<void(function_ref<void(QStringView)>)> , but can pass in any
39 * object accepted by QStringView, and it is automatically converted to a dumper.
40 */
41
42/*!
43 * \internal
44 * \brief Converts a dumper to a string
45 * \param writer The dumper convert to a string
46 */
48{
49 QString s;
50 QTextStream d(&s);
51 writer([&d](QStringView s){ d << s; });
52 d.flush();
53 return s;
54}
55
56/*!
57 * \internal
58 * \brief dumps a string as quoted string (escaping things like quotes or newlines)
59 * \param sink The sink to write the quoted string to
60 * \param s The string to sink
61 * \param options If quotes should be outputted around the string (defaults to yes)
62 */
63void sinkEscaped(const Sink &sink, QStringView s, EscapeOptions options) {
64 if (options == EscapeOptions::OuterQuotes)
65 sink(u"\"");
66 int it0=0;
67 for (int it = 0; it < s.size();++it) {
68 QChar c=s[it];
69 bool noslash = c != QLatin1Char('\\');
70 bool noquote = c != QLatin1Char('"');
71 bool nonewline = c != QLatin1Char('\n');
72 bool noreturn = c != QLatin1Char('\r');
73 if (noslash && noquote && nonewline && noreturn)
74 continue;
75 sink(s.mid(it0, it - it0));
76 it0 = it + 1;
77 if (!noslash)
78 sink(u"\\\\");
79 else if (!noquote)
80 sink(u"\\\"");
81 else if (!nonewline)
82 sink(u"\\n");
83 else if (!noreturn)
84 sink(u"\\r");
85 else
86 Q_ASSERT(0);
87 }
88 sink(s.mid(it0, s.size() - it0));
89 if (options == EscapeOptions::OuterQuotes)
90 sink(u"\"");
91}
92
93/*!
94 * \internal
95 * \brief Dumps a string describing the given error level (ErrorLevel::Error -> Error,...)
96 * \param s the sink to write to
97 * \param level the level to describe
98 */
99void dumpErrorLevel(const Sink &s, ErrorLevel level)
100{
101 switch (level) {
103 s(u"Debug");
104 break;
105 case ErrorLevel::Info:
106 s(u"Info");
107 break;
109 s(u"Warning");
110 break;
112 s(u"Error");
113 break;
115 s(u"Fatal");
116 break;
117 }
118
119}
120
121void dumperToQDebug(const Dumper &dumper, QDebug debug)
122{
123 QDebug & d = debug.noquote().nospace();
124 dumper([&d](QStringView s){
125 d << s;
126 });
127}
128
129/*!
130 * \internal
131 * \brief writes the dumper to the QDebug object corrsponding to the given error level
132 * \param level the error level of the message
133 * \param dumper the dumper that writes a message
134 */
135void dumperToQDebug(const Dumper &dumper, ErrorLevel level)
136{
137 QDebug d = qDebug().noquote().nospace();
138 switch (level) {
140 break;
141 case ErrorLevel::Info:
142 d = qInfo().noquote().nospace();
143 break;
145 d = qWarning().noquote().nospace();
146 break;
148 case ErrorLevel::Fatal: // should be handled differently (avoid allocations...), we try to catch them before ending up here
149 d = qCritical().noquote().nospace();
150 break;
151 }
152 dumper([&d](QStringView s){
153 d << s;
154 });
155}
156
157/*!
158 * \internal
159 * \brief sinks the requested amount of spaces
160 */
161void sinkIndent(const Sink &s, int indent)
162{
163 if (indent > 0) {
164 QStringView spaces = u" ";
165 while (indent > spaces.size()) {
166 s(spaces);
167 indent -= spaces.size();
168 }
169 s(spaces.left(indent));
170 }
171}
172
173/*!
174 * \internal
175 * \brief sinks a neline and indents by the given amount
176 */
177void sinkNewline(const Sink &s, int indent)
178{
179 s(u"\n");
180 if (indent > 0)
181 sinkIndent(s, indent);
182}
183
184/*!
185 * \internal
186 * \fn QQmlJS::Dom::devNull
187 * \brief A sink that ignores whatever it receives
188 */
189
190QDebug operator<<(QDebug d, const Dumper &dumper)
191{
192 QDebug dd = d.noquote().nospace();
193 dumper([&dd](QStringView s) { dd << s; });
194 return d;
195}
196
197} // end namespace Dom
198} // end namespace QQmlJS
199
200QT_END_NAMESPACE
Helper class to accept eithe a string or a dumper (a function that writes to a sink)
QMLDOM_EXPORT void dumperToQDebug(const Dumper &dumper, QDebug debug)
QMLDOM_EXPORT void dumpErrorLevel(const Sink &s, ErrorLevel level)
Dumps a string describing the given error level (ErrorLevel::Error -> Error,...)
QMLDOM_EXPORT void dumperToQDebug(const Dumper &dumper, ErrorLevel level=ErrorLevel::Debug)
writes the dumper to the QDebug object corrsponding to the given error level
QMLDOM_EXPORT void sinkNewline(const Sink &s, int indent=0)
sinks a neline and indents by the given amount
QMLDOM_EXPORT QDebug operator<<(QDebug d, const Dumper &dumper)
QMLDOM_EXPORT void sinkIndent(const Sink &s, int indent)
sinks the requested amount of spaces
QMLDOM_EXPORT void sinkEscaped(const Sink &sink, QStringView s, EscapeOptions options=EscapeOptions::OuterQuotes)
dumps a string as quoted string (escaping things like quotes or newlines)
QMLDOM_EXPORT QString dumperToString(const Dumper &writer)
Converts a dumper to a string.