1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qdebug.h"
6#include "private/qdebug_p.h"
7#include "qmetaobject.h"
8#include <private/qlogging_p.h>
9#include <private/qtextstream_p.h>
10#include <private/qtools_p.h>
11
12#include <array>
13#include <q20chrono.h>
14#include <cstdio>
15
16QT_BEGIN_NAMESPACE
17
18using namespace QtMiscUtils;
19
20/*
21 Returns a human readable representation of the first \a maxSize
22 characters in \a data. The size, \a len, is a 64-bit quantity to
23 avoid truncation due to implicit conversions in callers.
24*/
25QByteArray QtDebugUtils::toPrintable(const char *data, qint64 len, qsizetype maxSize)
26{
27 if (!data)
28 return "(null)";
29
30 QByteArray out;
31 for (qsizetype i = 0; i < qMin(a: len, b: maxSize); ++i) {
32 char c = data[i];
33 if (isAsciiPrintable(ch: c)) {
34 out += c;
35 } else {
36 switch (c) {
37 case '\n':
38 out += "\\n";
39 break;
40 case '\r':
41 out += "\\r";
42 break;
43 case '\t':
44 out += "\\t";
45 break;
46 default: {
47 const char buf[] = {
48 '\\',
49 'x',
50 toHexLower(value: uchar(c) / 16),
51 toHexLower(value: uchar(c) % 16),
52 0
53 };
54 out += buf;
55 }
56 }
57 }
58 }
59
60 if (maxSize < len)
61 out += "...";
62
63 return out;
64}
65
66// This file is needed to force compilation of QDebug into the kernel library.
67
68/*!
69 \class QDebug
70 \inmodule QtCore
71 \ingroup shared
72
73 \brief The QDebug class provides an output stream for debugging information.
74
75 QDebug is used whenever the developer needs to write out debugging or tracing
76 information to a device, file, string or console.
77
78 \section1 Basic Use
79
80 In the common case, it is useful to call the qDebug() function to obtain a
81 default QDebug object to use for writing debugging information.
82
83 \snippet qdebug/qdebugsnippet.cpp 1
84
85 This constructs a QDebug object using the constructor that accepts a QtMsgType
86 value of QtDebugMsg. Similarly, the qWarning(), qCritical() and qFatal()
87 functions also return QDebug objects for the corresponding message types.
88
89 The class also provides several constructors for other situations, including
90 a constructor that accepts a QFile or any other QIODevice subclass that is
91 used to write debugging information to files and other devices. The constructor
92 that accepts a QString is used to write to a string for display or serialization.
93
94 \section1 Formatting Options
95
96 QDebug formats output so that it's easily readable. It automatically adds spaces
97 between arguments, and adds quotes around QString, QByteArray, QChar arguments.
98
99 You can tweak these options through the space(), nospace() and quote(), noquote()
100 methods. Furthermore, \l{QTextStream manipulators} can be piped into a QDebug
101 stream.
102
103 QDebugStateSaver limits changes to the formatting to the current scope.
104 resetFormat() resets the options to the default ones.
105
106 \section1 Writing Custom Types to a Stream
107
108 Many standard types can be written to QDebug objects, and Qt provides support for
109 most Qt value types. To add support for custom types, you need to implement a
110 streaming operator, as in the following example:
111
112 \snippet qdebug/qdebugsnippet.cpp 0
113
114 This is described in the \l{Debugging Techniques} and
115 \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
116 documents.
117*/
118
119/*!
120 \fn QDebug::QDebug(QIODevice *device)
121
122 Constructs a debug stream that writes to the given \a device.
123*/
124
125/*!
126 \fn QDebug::QDebug(QString *string)
127
128 Constructs a debug stream that writes to the given \a string.
129*/
130
131/*!
132 \fn QDebug::QDebug(QtMsgType t)
133
134 Constructs a debug stream that writes to the handler for the message type \a t.
135*/
136
137/*!
138 \fn QDebug::QDebug(const QDebug &o)
139
140 Constructs a copy of the other debug stream \a o.
141*/
142
143/*!
144 \fn QDebug &QDebug::operator=(const QDebug &other)
145
146 Assigns the \a other debug stream to this stream and returns a reference to
147 this stream.
148*/
149
150/*!
151 \fn QDebug::~QDebug()
152
153 Flushes any pending data to be written and destroys the debug stream.
154*/
155QDebug::~QDebug()
156{
157 if (stream && !--stream->ref) {
158 if (stream->space && stream->buffer.endsWith(c: u' '))
159 stream->buffer.chop(n: 1);
160 if (stream->message_output) {
161 QInternalMessageLogContext ctxt(stream->context);
162 qt_message_output(stream->type,
163 context: ctxt,
164 message: stream->buffer);
165 }
166 delete stream;
167 }
168}
169
170/*!
171 \internal
172*/
173void QDebug::putUcs4(uint ucs4)
174{
175 maybeQuote(c: '\'');
176 if (ucs4 < 0x20) {
177 stream->ts << "\\x" << Qt::hex << ucs4 << Qt::reset;
178 } else if (ucs4 < 0x80) {
179 stream->ts << char(ucs4);
180 } else {
181 if (ucs4 < 0x10000)
182 stream->ts << "\\u" << qSetFieldWidth(width: 4);
183 else
184 stream->ts << "\\U" << qSetFieldWidth(width: 8);
185 stream->ts << Qt::hex << qSetPadChar(ch: u'0') << ucs4 << Qt::reset;
186 }
187 maybeQuote(c: '\'');
188}
189
190// These two functions return true if the character should be printed by QDebug.
191// For QByteArray, this is technically identical to US-ASCII isprint();
192// for QString, we use QChar::isPrint, which requires a full UCS-4 decode.
193static inline bool isPrintable(char32_t ucs4) { return QChar::isPrint(ucs4); }
194static inline bool isPrintable(char16_t uc) { return QChar::isPrint(ucs4: uc); }
195static inline bool isPrintable(uchar c)
196{ return isAsciiPrintable(ch: c); }
197
198template <typename Char>
199static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true)
200{
201 QChar quote(u'"');
202 d->write(data: &quote, len: 1);
203
204 bool lastWasHexEscape = false;
205 const Char *end = begin + length;
206 for (const Char *p = begin; p != end; ++p) {
207 // check if we need to insert "" to break an hex escape sequence
208 if (Q_UNLIKELY(lastWasHexEscape)) {
209 if (fromHex(*p) != -1) {
210 // yes, insert it
211 QChar quotes[] = { quote, quote };
212 d->write(data: quotes, len: 2);
213 }
214 lastWasHexEscape = false;
215 }
216
217 if (sizeof(Char) == sizeof(QChar)) {
218 // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them
219 qsizetype runLength = 0;
220 while (p + runLength != end &&
221 isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"')
222 ++runLength;
223 if (runLength) {
224 d->write(data: reinterpret_cast<const QChar *>(p), len: runLength);
225 p += runLength - 1;
226 continue;
227 }
228 } else if (isPrintable(*p) && *p != '\\' && *p != '"') {
229 QChar c = QLatin1Char(*p);
230 d->write(data: &c, len: 1);
231 continue;
232 }
233
234 // print as an escape sequence (maybe, see below for surrogate pairs)
235 qsizetype buflen = 2;
236 char16_t buf[std::char_traits<char>::length(s: "\\U12345678")];
237 buf[0] = '\\';
238
239 switch (*p) {
240 case '"':
241 case '\\':
242 buf[1] = *p;
243 break;
244 case '\b':
245 buf[1] = 'b';
246 break;
247 case '\f':
248 buf[1] = 'f';
249 break;
250 case '\n':
251 buf[1] = 'n';
252 break;
253 case '\r':
254 buf[1] = 'r';
255 break;
256 case '\t':
257 buf[1] = 't';
258 break;
259 default:
260 if (!isUnicode) {
261 // print as hex escape
262 buf[1] = 'x';
263 buf[2] = toHexUpper(value: uchar(*p) >> 4);
264 buf[3] = toHexUpper(value: uchar(*p));
265 buflen = 4;
266 lastWasHexEscape = true;
267 break;
268 }
269 if (QChar::isHighSurrogate(*p)) {
270 if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
271 // properly-paired surrogates
272 char32_t ucs4 = QChar::surrogateToUcs4(*p, p[1]);
273 if (isPrintable(ucs4)) {
274 buf[0] = *p;
275 buf[1] = p[1];
276 buflen = 2;
277 } else {
278 buf[1] = 'U';
279 buf[2] = '0'; // toHexUpper(ucs4 >> 32);
280 buf[3] = '0'; // toHexUpper(ucs4 >> 28);
281 buf[4] = toHexUpper(value: ucs4 >> 20);
282 buf[5] = toHexUpper(value: ucs4 >> 16);
283 buf[6] = toHexUpper(value: ucs4 >> 12);
284 buf[7] = toHexUpper(value: ucs4 >> 8);
285 buf[8] = toHexUpper(value: ucs4 >> 4);
286 buf[9] = toHexUpper(value: ucs4);
287 buflen = 10;
288 }
289 ++p;
290 break;
291 }
292 // improperly-paired surrogates, fall through
293 }
294 buf[1] = 'u';
295 buf[2] = toHexUpper(value: char16_t(*p) >> 12);
296 buf[3] = toHexUpper(value: char16_t(*p) >> 8);
297 buf[4] = toHexUpper(*p >> 4);
298 buf[5] = toHexUpper(*p);
299 buflen = 6;
300 }
301 d->write(data: reinterpret_cast<QChar *>(buf), len: buflen);
302 }
303
304 d->write(data: &quote, len: 1);
305}
306
307/*!
308 \internal
309 Duplicated from QtTest::toPrettyUnicode().
310*/
311void QDebug::putString(const QChar *begin, size_t length)
312{
313 if (stream->noQuotes) {
314 // no quotes, write the string directly too (no pretty-printing)
315 // this respects the QTextStream state, though
316 stream->ts.d_ptr->putString(data: begin, len: qsizetype(length));
317 } else {
318 // we'll reset the QTextStream formatting mechanisms, so save the state
319 QDebugStateSaver saver(*this);
320 stream->ts.d_ptr->params.reset();
321 putEscapedString(d: stream->ts.d_ptr.get(), begin: reinterpret_cast<const char16_t *>(begin), length);
322 }
323}
324
325/*!
326 \internal
327 Duplicated from QtTest::toPrettyCString().
328*/
329void QDebug::putByteArray(const char *begin, size_t length, Latin1Content content)
330{
331 if (stream->noQuotes) {
332 // no quotes, write the string directly too (no pretty-printing)
333 // this respects the QTextStream state, though
334 QString string = content == ContainsLatin1 ? QString::fromLatin1(str: begin, size: qsizetype(length))
335 : QString::fromUtf8(utf8: begin, size: qsizetype(length));
336 stream->ts.d_ptr->putString(string);
337 } else {
338 // we'll reset the QTextStream formatting mechanisms, so save the state
339 QDebugStateSaver saver(*this);
340 stream->ts.d_ptr->params.reset();
341 putEscapedString(d: stream->ts.d_ptr.get(), begin: reinterpret_cast<const uchar *>(begin),
342 length, isUnicode: content == ContainsLatin1);
343 }
344}
345
346static QByteArray timeUnit(qint64 num, qint64 den)
347{
348 using namespace std::chrono;
349 using namespace q20::chrono;
350
351 if (num == 1 && den > 1) {
352 // sub-multiple of seconds
353 char prefix = '\0';
354 auto tryprefix = [&](auto d, char c) {
355 static_assert(decltype(d)::num == 1, "not an SI prefix");
356 if (den == decltype(d)::den)
357 prefix = c;
358 };
359
360 // "u" should be "µ", but debugging output is not always UTF-8-safe
361 tryprefix(std::milli{}, 'm');
362 tryprefix(std::micro{}, 'u');
363 tryprefix(std::nano{}, 'n');
364 tryprefix(std::pico{}, 'p');
365 tryprefix(std::femto{}, 'f');
366 tryprefix(std::atto{}, 'a');
367 // uncommon ones later
368 tryprefix(std::centi{}, 'c');
369 tryprefix(std::deci{}, 'd');
370 if (prefix) {
371 char unit[3] = { prefix, 's' };
372 return QByteArray(unit, sizeof(unit) - 1);
373 }
374 }
375
376 const char *unit = nullptr;
377 if (num > 1 && den == 1) {
378 // multiple of seconds - but we don't use SI prefixes
379 auto tryunit = [&](auto d, const char *name) {
380 static_assert(decltype(d)::period::den == 1, "not a multiple of a second");
381 if (unit || num % decltype(d)::period::num)
382 return;
383 unit = name;
384 num /= decltype(d)::period::num;
385 };
386 tryunit(years{}, "yr");
387 tryunit(weeks{}, "wk");
388 tryunit(days{}, "d");
389 tryunit(hours{}, "h");
390 tryunit(minutes{}, "min");
391 }
392 if (!unit)
393 unit = "s";
394
395 if (num == 1 && den == 1)
396 return unit;
397 if (Q_UNLIKELY(num < 1 || den < 1))
398 return QString::asprintf(format: "<invalid time unit %lld/%lld>", num, den).toLatin1();
399
400 // uncommon units: will return something like "[2/3]s"
401 // strlen("[/]min") = 6
402 char buf[2 * (std::numeric_limits<qint64>::digits10 + 2) + 10];
403 size_t len = 0;
404 auto appendChar = [&](char c) {
405 Q_ASSERT(len < sizeof(buf));
406 buf[len++] = c;
407 };
408 auto appendNumber = [&](qint64 value) {
409 if (value >= 10'000 && (value % 1000) == 0)
410 len += std::snprintf(s: buf + len, maxlen: sizeof(buf) - len, format: "%.6g", double(value)); // "1e+06"
411 else
412 len += std::snprintf(s: buf + len, maxlen: sizeof(buf) - len, format: "%lld", value);
413 };
414 appendChar('[');
415 appendNumber(num);
416 if (den != 1) {
417 appendChar('/');
418 appendNumber(den);
419 }
420 appendChar(']');
421 memcpy(dest: buf + len, src: unit, n: strlen(s: unit));
422 return QByteArray(buf, len + strlen(s: unit));
423}
424
425/*!
426 \since 6.6
427 \internal
428 Helper to the std::chrono::duration debug streaming output.
429 */
430void QDebug::putTimeUnit(qint64 num, qint64 den)
431{
432 stream->ts << timeUnit(num, den); // ### optimize
433}
434
435namespace {
436
437#ifdef QT_SUPPORTS_INT128
438
439constexpr char Q_INT128_MIN_STR[] = "-170141183460469231731687303715884105728";
440
441constexpr int Int128BufferSize = sizeof(Q_INT128_MIN_STR);
442using Int128Buffer = std::array<char, Int128BufferSize>;
443 // numeric_limits<qint128>::digits10 may not exist
444
445static char *i128ToStringHelper(Int128Buffer &buffer, quint128 n)
446{
447 auto dst = buffer.data() + buffer.size();
448 *--dst = '\0'; // NUL-terminate
449 if (n == 0) {
450 *--dst = '0'; // and done
451 } else {
452 while (n != 0) {
453 *--dst = "0123456789"[n % 10];
454 n /= 10;
455 }
456 }
457 return dst;
458}
459#endif // QT_SUPPORTS_INT128
460
461[[maybe_unused]]
462static const char *int128Warning()
463{
464 const char *msg = "Qt was not compiled with int128 support.";
465 qWarning(msg: "%s", msg);
466 return msg;
467}
468
469} // unnamed namespace
470
471/*!
472 \since 6.7
473 \internal
474 Helper to the qint128 debug streaming output.
475 */
476void QDebug::putInt128([[maybe_unused]] const void *p)
477{
478#ifdef QT_SUPPORTS_INT128
479 Q_ASSERT(p);
480 qint128 i;
481 memcpy(dest: &i, src: p, n: sizeof(i)); // alignment paranoia
482 if (i == Q_INT128_MIN) {
483 // -i is not representable, hardcode the result:
484 stream->ts << Q_INT128_MIN_STR;
485 } else {
486 Int128Buffer buffer;
487 auto dst = i128ToStringHelper(buffer, n: i < 0 ? -i : i);
488 if (i < 0)
489 *--dst = '-';
490 stream->ts << dst;
491 }
492 return;
493#endif // QT_SUPPORTS_INT128
494 stream->ts << int128Warning();
495}
496
497/*!
498 \since 6.7
499 \internal
500 Helper to the quint128 debug streaming output.
501 */
502void QDebug::putUInt128([[maybe_unused]] const void *p)
503{
504#ifdef QT_SUPPORTS_INT128
505 Q_ASSERT(p);
506 quint128 i;
507 memcpy(dest: &i, src: p, n: sizeof(i)); // alignment paranoia
508 Int128Buffer buffer;
509 stream->ts << i128ToStringHelper(buffer, n: i);
510 return;
511#endif // QT_SUPPORTS_INT128
512 stream->ts << int128Warning();
513}
514
515
516/*!
517 \fn QDebug::swap(QDebug &other)
518 \since 5.0
519 \memberswap{debug stream instance}
520*/
521
522/*!
523 Resets the stream formatting options, bringing it back to its original constructed state.
524
525 \sa space(), quote()
526 \since 5.4
527*/
528QDebug &QDebug::resetFormat()
529{
530 stream->ts.reset();
531 stream->space = true;
532 stream->noQuotes = false;
533 stream->verbosity = DefaultVerbosity;
534 return *this;
535}
536
537/*!
538 \fn QDebug &QDebug::space()
539
540 Writes a space character to the debug stream and returns a reference to
541 the stream.
542
543 The stream remembers that automatic insertion of spaces is
544 enabled for future writes.
545
546 \sa nospace(), maybeSpace()
547*/
548
549/*!
550 \fn QDebug &QDebug::nospace()
551
552 Disables automatic insertion of spaces and returns a reference to the stream.
553
554 \sa space(), maybeSpace()
555*/
556
557/*!
558 \fn QDebug &QDebug::maybeSpace()
559
560 Writes a space character to the debug stream, depending on the current
561 setting for automatic insertion of spaces, and returns a reference to the stream.
562
563 \sa space(), nospace()
564*/
565
566/*!
567 \fn bool QDebug::autoInsertSpaces() const
568
569 Returns \c true if this QDebug instance will automatically insert spaces
570 between writes.
571
572 \since 5.0
573
574 \sa QDebugStateSaver
575*/
576
577/*!
578 \fn void QDebug::setAutoInsertSpaces(bool b)
579
580 Enables automatic insertion of spaces between writes if \a b is true; otherwise
581 automatic insertion of spaces is disabled.
582
583 \since 5.0
584
585 \sa QDebugStateSaver
586*/
587
588
589/*!
590 \fn bool QDebug::quoteStrings() const
591 \since 6.7
592
593 Returns \c true if this QDebug instance will quote strings streamed into
594 it (which is the default).
595
596 \sa QDebugStateSaver, quote(), noquote(), setQuoteStrings()
597*/
598
599/*!
600 \fn void QDebug::setQuoteStrings(bool b)
601 \since 6.7
602
603 Enables quoting of strings streamed into this QDebug instance if \a b is
604 \c true; otherwise quoting is disabled.
605
606 The default is to quote strings.
607
608 \sa QDebugStateSaver, quote(), noquote(), quoteStrings()
609*/
610
611
612/*!
613 \fn QDebug &QDebug::quote()
614 \since 5.4
615
616 Enables automatic insertion of quotation characters around QChar, QString and QByteArray
617 contents and returns a reference to the stream.
618
619 Quoting is enabled by default.
620
621 \sa noquote(), maybeQuote()
622*/
623
624/*!
625 \fn QDebug &QDebug::noquote()
626 \since 5.4
627
628 Disables automatic insertion of quotation characters around QChar, QString and QByteArray
629 contents and returns a reference to the stream.
630
631 When quoting is disabled, these types are printed without quotation
632 characters and without escaping of non-printable characters.
633
634 \sa quote(), maybeQuote()
635*/
636
637/*!
638 \fn QDebug &QDebug::maybeQuote(char c)
639 \since 5.4
640
641 Writes a character \a c to the debug stream, depending on the
642 current setting for automatic insertion of quotes, and returns a reference to the stream.
643
644 The default character is a double quote \c{"}.
645
646 \sa quote(), noquote()
647*/
648
649/*!
650 \fn int QDebug::verbosity() const
651 \since 5.6
652
653 Returns the verbosity of the debug stream.
654
655 Streaming operators can check the value to decide whether
656 verbose output is desired and print more information depending on the
657 level. Higher values indicate that more information is desired.
658
659 The allowed range is from 0 to 7. The default value is 2.
660
661 \sa setVerbosity(), VerbosityLevel
662*/
663
664/*!
665 \fn void QDebug::setVerbosity(int verbosityLevel)
666 \since 5.6
667
668 Sets the verbosity of the stream to \a verbosityLevel.
669
670 The allowed range is from 0 to 7. The default value is 2.
671
672 \sa verbosity(), VerbosityLevel
673*/
674
675/*!
676 \fn QDebug &QDebug::verbosity(int verbosityLevel)
677 \since 5.13
678
679 Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream.
680
681 The allowed range is from 0 to 7. The default value is 2.
682
683 \sa verbosity(), setVerbosity(), VerbosityLevel
684*/
685
686/*!
687 \enum QDebug::VerbosityLevel
688 \since 5.13
689
690 This enum describes the range of verbosity levels.
691
692 \value MinimumVerbosity
693 \value DefaultVerbosity
694 \value MaximumVerbosity
695
696 \sa verbosity(), setVerbosity()
697*/
698
699/*!
700 \fn QDebug &QDebug::operator<<(QChar t)
701
702 Writes the character, \a t, to the stream and returns a reference to the
703 stream. Normally, QDebug prints control characters and non-US-ASCII
704 characters as their C escape sequences or their Unicode value (\\u1234). To
705 print non-printable characters without transformation, enable the noquote()
706 functionality, but note that some QDebug backends may not be 8-bit clean
707 and may not be able to represent \c t.
708*/
709
710/*!
711 \fn QDebug &QDebug::operator<<(bool t)
712
713 Writes the boolean value, \a t, to the stream and returns a reference to the
714 stream.
715*/
716
717/*!
718 \fn QDebug &QDebug::operator<<(char t)
719
720 Writes the character, \a t, to the stream and returns a reference to the
721 stream.
722*/
723
724/*!
725 \fn QDebug &QDebug::operator<<(signed short t)
726
727 Writes the signed short integer, \a t, to the stream and returns a reference
728 to the stream.
729*/
730
731/*!
732 \fn QDebug &QDebug::operator<<(unsigned short t)
733
734 Writes then unsigned short integer, \a t, to the stream and returns a
735 reference to the stream.
736*/
737
738/*!
739 \fn QDebug &QDebug::operator<<(signed int t)
740
741 Writes the signed integer, \a t, to the stream and returns a reference
742 to the stream.
743*/
744
745/*!
746 \fn QDebug &QDebug::operator<<(unsigned int t)
747
748 Writes then unsigned integer, \a t, to the stream and returns a reference to
749 the stream.
750*/
751
752/*!
753 \fn QDebug &QDebug::operator<<(signed long t)
754
755 Writes the signed long integer, \a t, to the stream and returns a reference
756 to the stream.
757*/
758
759/*!
760 \fn QDebug &QDebug::operator<<(unsigned long t)
761
762 Writes then unsigned long integer, \a t, to the stream and returns a reference
763 to the stream.
764*/
765
766/*!
767 \fn QDebug &QDebug::operator<<(qint64 t)
768
769 Writes the signed 64-bit integer, \a t, to the stream and returns a reference
770 to the stream.
771*/
772
773/*!
774 \fn QDebug &QDebug::operator<<(quint64 t)
775
776 Writes then unsigned 64-bit integer, \a t, to the stream and returns a
777 reference to the stream.
778*/
779
780/*!
781 \fn QDebug &QDebug::operator<<(float t)
782
783 Writes the 32-bit floating point number, \a t, to the stream and returns a
784 reference to the stream.
785*/
786
787/*!
788 \fn QDebug &QDebug::operator<<(double t)
789
790 Writes the 64-bit floating point number, \a t, to the stream and returns a
791 reference to the stream.
792*/
793
794/*!
795 \fn QDebug &QDebug::operator<<(const char *t)
796
797 Writes the '\\0'-terminated UTF-8 string, \a t, to the stream and returns a
798 reference to the stream. The string is never quoted or escaped for the
799 output. Note that QDebug buffers internally as UTF-16 and may need to
800 transform to 8-bit using the locale's codec in order to use some backends,
801 which may cause garbled output (mojibake). Restricting to US-ASCII strings
802 is recommended.
803*/
804
805/*!
806 \fn QDebug &QDebug::operator<<(const char16_t *t)
807 \since 6.0
808
809 Writes the u'\\0'-terminated UTF-16 string, \a t, to the stream and returns
810 a reference to the stream. The string is never quoted or escaped for the
811 output. Note that QDebug buffers internally as UTF-16 and may need to
812 transform to 8-bit using the locale's codec in order to use some backends,
813 which may cause garbled output (mojibake). Restricting to US-ASCII strings
814 is recommended.
815*/
816
817/*!
818 \fn QDebug &QDebug::operator<<(char16_t t)
819 \since 5.5
820
821 Writes the UTF-16 character, \a t, to the stream and returns a reference
822 to the stream.
823*/
824
825/*!
826 \fn QDebug &QDebug::operator<<(char32_t t)
827 \since 5.5
828
829 Writes the UTF-32 character, \a t, to the stream and returns a reference
830 to the stream.
831*/
832
833/*!
834 \fn QDebug &QDebug::operator<<(const QString &t)
835
836 Writes the string, \a t, to the stream and returns a reference to the
837 stream. Normally, QDebug prints the string inside quotes and transforms
838 non-printable characters to their Unicode values (\\u1234).
839
840 To print non-printable characters without transformation, enable the
841 noquote() functionality. Note that some QDebug backends might not be 8-bit
842 clean.
843
844 Output examples:
845 \snippet code/src_corelib_io_qdebug.cpp 0
846*/
847
848/*!
849 \since 5.10
850 \fn QDebug &QDebug::operator<<(QStringView s)
851
852 Writes the string view, \a s, to the stream and returns a reference to the
853 stream. Normally, QDebug prints the string inside quotes and transforms
854 non-printable characters to their Unicode values (\\u1234).
855
856 To print non-printable characters without transformation, enable the
857 noquote() functionality. Note that some QDebug backends might not be 8-bit
858 clean.
859
860 See the QString overload for examples.
861*/
862
863/*!
864 \since 6.0
865 \fn QDebug &QDebug::operator<<(QUtf8StringView s)
866
867 Writes the string view, \a s, to the stream and returns a reference to the
868 stream.
869
870 Normally, QDebug prints the data inside quotes and transforms control or
871 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
872 output is always 7-bit clean and the string can be copied from the output
873 and pasted back into C++ sources, if necessary.
874
875 To print non-printable characters without transformation, enable the
876 noquote() functionality. Note that some QDebug backends might not be 8-bit
877 clean.
878*/
879
880/*!
881 \fn QDebug &QDebug::operator<<(QLatin1StringView t)
882
883 Writes the string, \a t, to the stream and returns a reference to the
884 stream. Normally, QDebug prints the string inside quotes and transforms
885 non-printable characters to their Unicode values (\\u1234).
886
887 To print non-printable characters without transformation, enable the
888 noquote() functionality. Note that some QDebug backends might not be 8-bit
889 clean.
890
891 See the QString overload for examples.
892*/
893
894/*!
895 \fn QDebug &QDebug::operator<<(const QByteArray &t)
896
897 Writes the byte array, \a t, to the stream and returns a reference to the
898 stream. Normally, QDebug prints the array inside quotes and transforms
899 control or non-US-ASCII characters to their C escape sequences (\\xAB). This
900 way, the output is always 7-bit clean and the string can be copied from the
901 output and pasted back into C++ sources, if necessary.
902
903 To print non-printable characters without transformation, enable the
904 noquote() functionality. Note that some QDebug backends might not be 8-bit
905 clean.
906
907 Output examples:
908 \snippet code/src_corelib_io_qdebug.cpp 1
909
910 Note how QDebug needed to close and reopen the string in the way C and C++
911 languages concatenate string literals so that the letter 'b' is not
912 interpreted as part of the previous hexadecimal escape sequence.
913*/
914
915/*!
916 \since 6.0
917 \fn QDebug &QDebug::operator<<(QByteArrayView t)
918
919 Writes the data of the observed byte array, \a t, to the stream and returns
920 a reference to the stream.
921
922 Normally, QDebug prints the data inside quotes and transforms control or
923 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
924 output is always 7-bit clean and the string can be copied from the output
925 and pasted back into C++ sources, if necessary.
926
927 To print non-printable characters without transformation, enable the
928 noquote() functionality. Note that some QDebug backends might not be 8-bit
929 clean.
930
931 See the QByteArray overload for examples.
932*/
933
934/*!
935 \fn QDebug &QDebug::operator<<(const void *t)
936
937 Writes a pointer, \a t, to the stream and returns a reference to the stream.
938*/
939
940/*!
941 \fn QDebug &QDebug::operator<<(QTextStreamFunction f)
942 \internal
943*/
944
945/*!
946 \fn QDebug &QDebug::operator<<(QTextStreamManipulator m)
947 \internal
948*/
949
950/*!
951 \since 6.5
952 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(const std::basic_string<Char, Args...> &s)
953 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(std::basic_string_view<Char, Args...> s)
954
955 Writes the string or string-view \a s to the stream and returns a reference
956 to the stream.
957
958 These operators only participate in overload resolution if \c Char is one of
959 \list
960 \li char
961 \li char8_t (C++20 only)
962 \li char16_t
963 \li char32_t
964 \li wchar_t
965 \endlist
966*/
967
968/*!
969 \since 6.6
970 \fn template <typename Rep, typename Period> QDebug &QDebug::operator<<(std::chrono::duration<Rep, Period> duration)
971
972 Prints the time duration \a duration to the stream and returns a reference
973 to the stream. The printed string is the numeric representation of the
974 period followed by the time unit, similar to what the C++ Standard Library
975 would produce with \c{std::ostream}.
976
977 The unit is not localized.
978*/
979
980/*!
981 \fn template <typename T, QDebug::if_qint128<T>> QDebug::operator<<(T i)
982 \fn template <typename T, QDebug::if_quint128<T>> QDebug::operator<<(T i)
983 \since 6.7
984
985 Prints the textual representation of the 128-bit integer \a i.
986
987 \note This operator is only available if Qt supports 128-bit integer types.
988 If 128-bit integer types are available in your build, but the Qt libraries
989 were compiled without, the operator will print a warning instead.
990
991 \note Because the operator is a function template, no implicit conversions
992 are performed on its argument. It must be exactly qint128/quint128.
993
994 \sa QT_SUPPORTS_INT128
995*/
996
997/*!
998 \fn template <class T> QString QDebug::toString(const T &object)
999 \since 6.0
1000
1001 \include qdebug-toString.qdocinc
1002*/
1003
1004/*! \internal */
1005QString QDebug::toStringImpl(StreamTypeErased s, const void *obj)
1006{
1007 QString result;
1008 {
1009 QDebug d(&result);
1010 s(d.nospace(), obj);
1011 }
1012 return result;
1013}
1014
1015/*!
1016 \fn template <class T> QDebug operator<<(QDebug debug, const QList<T> &list)
1017 \relates QDebug
1018
1019 Writes the contents of \a list to \a debug. \c T needs to
1020 support streaming into QDebug.
1021*/
1022
1023/*!
1024 \fn template <class T, qsizetype P> QDebug operator<<(QDebug debug, const QVarLengthArray<T,P> &array)
1025 \relates QDebug
1026 \since 6.3
1027
1028 Writes the contents of \a array to \a debug. \c T needs to
1029 support streaming into QDebug.
1030*/
1031
1032/*!
1033 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec)
1034 \relates QDebug
1035 \since 5.7
1036
1037 Writes the contents of list \a vec to \a debug. \c T needs to
1038 support streaming into QDebug.
1039*/
1040
1041/*!
1042 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
1043 \relates QDebug
1044 \since 5.7
1045
1046 Writes the contents of vector \a vec to \a debug. \c T needs to
1047 support streaming into QDebug.
1048*/
1049
1050/*!
1051 \fn template <typename T> QDebug operator<<(QDebug debug, const QSet<T> &set)
1052 \relates QDebug
1053
1054 Writes the contents of \a set to \a debug. \c T needs to
1055 support streaming into QDebug.
1056*/
1057
1058/*!
1059 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMap<Key, T> &map)
1060 \relates QDebug
1061
1062 Writes the contents of \a map to \a debug. Both \c Key and
1063 \c T need to support streaming into QDebug.
1064*/
1065
1066/*!
1067 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiMap<Key, T> &map)
1068 \relates QDebug
1069
1070 Writes the contents of \a map to \a debug. Both \c Key and
1071 \c T need to support streaming into QDebug.
1072*/
1073
1074/*!
1075 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
1076 \relates QDebug
1077 \since 5.7
1078
1079 Writes the contents of \a map to \a debug. Both \c Key and
1080 \c T need to support streaming into QDebug.
1081*/
1082
1083/*!
1084 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
1085 \relates QDebug
1086 \since 5.7
1087
1088 Writes the contents of \a map to \a debug. Both \c Key and
1089 \c T need to support streaming into QDebug.
1090*/
1091
1092/*!
1093 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
1094 \relates QDebug
1095
1096 Writes the contents of \a hash to \a debug. Both \c Key and
1097 \c T need to support streaming into QDebug.
1098*/
1099
1100/*!
1101 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
1102 \relates QDebug
1103
1104 Writes the contents of \a hash to \a debug. Both \c Key and
1105 \c T need to support streaming into QDebug.
1106*/
1107
1108/*!
1109 \fn template <class T1, class T2> QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair)
1110 \relates QDebug
1111
1112 Writes the contents of \a pair to \a debug. Both \c T1 and
1113 \c T2 need to support streaming into QDebug.
1114*/
1115
1116/*!
1117 \since 6.7
1118 \fn template <class T> QDebug operator<<(QDebug debug, const std::optional<T> &opt)
1119 \relates QDebug
1120
1121 Writes the contents of \a opt (or \c nullopt if not set) to \a debug.
1122 \c T needs to support streaming into QDebug.
1123*/
1124
1125/*!
1126 \fn template <typename T> QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
1127 \relates QDebug
1128
1129 Writes the contents of \a cache to \a debug. \c T needs to
1130 support streaming into QDebug.
1131*/
1132
1133/*!
1134 \fn template<typename T> QDebug operator<<(QDebug debug, const QFlags<T> &flags)
1135 \relates QDebug
1136 \since 4.7
1137
1138 Writes \a flags to \a debug.
1139*/
1140
1141/*!
1142 \fn template<typename T> QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
1143 \relates QSharedPointer
1144 \since 5.7
1145
1146 Writes the pointer tracked by \a ptr into the debug object \a debug for
1147 debugging purposes.
1148
1149 \sa {Debugging Techniques}
1150*/
1151
1152/*!
1153 \fn QDebug &QDebug::operator<<(std::nullptr_t)
1154 \internal
1155 */
1156
1157/*!
1158 \since 6.7
1159 \fn QDebug &QDebug::operator<<(std::nullopt_t)
1160
1161 Writes nullopt to the stream.
1162*/
1163
1164/*!
1165 \class QDebugStateSaver
1166 \inmodule QtCore
1167 \brief Convenience class for custom QDebug operators.
1168
1169 Saves the settings used by QDebug, and restores them upon destruction,
1170 then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if
1171 \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver.
1172
1173 The automatic insertion of spaces between writes is one of the settings
1174 that QDebugStateSaver stores for the duration of the current block.
1175
1176 The settings of the internal QTextStream are also saved and restored,
1177 so that using << Qt::hex in a QDebug operator doesn't affect other QDebug
1178 operators.
1179
1180 QDebugStateSaver is typically used in the implementation of an operator<<() for debugging:
1181
1182 \snippet customtype/customtypeexample.cpp custom type streaming operator
1183
1184 \since 5.1
1185*/
1186
1187class QDebugStateSaverPrivate
1188{
1189public:
1190 QDebugStateSaverPrivate(QDebug::Stream *stream)
1191 : m_stream(stream),
1192 m_spaces(stream->space),
1193 m_noQuotes(stream->noQuotes),
1194 m_verbosity(stream->verbosity),
1195 m_streamParams(stream->ts.d_ptr->params)
1196 {
1197 }
1198 void restoreState()
1199 {
1200 const bool currentSpaces = m_stream->space;
1201 if (currentSpaces && !m_spaces)
1202 if (m_stream->buffer.endsWith(c: u' '))
1203 m_stream->buffer.chop(n: 1);
1204
1205 m_stream->space = m_spaces;
1206 m_stream->noQuotes = m_noQuotes;
1207 m_stream->ts.d_ptr->params = m_streamParams;
1208 m_stream->verbosity = m_verbosity;
1209
1210 if (!currentSpaces && m_spaces)
1211 m_stream->ts << ' ';
1212 }
1213
1214 QDebug::Stream *m_stream;
1215
1216 // QDebug state
1217 const bool m_spaces;
1218 const bool m_noQuotes;
1219 const int m_verbosity;
1220
1221 // QTextStream state
1222 const QTextStreamPrivate::Params m_streamParams;
1223};
1224
1225
1226/*!
1227 Creates a QDebugStateSaver instance, which saves the settings
1228 currently used by \a dbg.
1229
1230 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1231*/
1232QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
1233 : d(new QDebugStateSaverPrivate(dbg.stream))
1234{
1235}
1236
1237/*!
1238 Destroys a QDebugStateSaver instance, which restores the settings
1239 used when the QDebugStateSaver instance was created.
1240
1241 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1242*/
1243QDebugStateSaver::~QDebugStateSaver()
1244{
1245 d->restoreState();
1246}
1247
1248/*!
1249 \internal
1250
1251 Specialization of the primary template in qdebug.h to out-of-line
1252 the common case of QFlags<T>::Int being 32-bit.
1253
1254 Just call the generic version so the two don't get out of sync.
1255*/
1256void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
1257{
1258 qt_QMetaEnum_flagDebugOperator<uint>(debug, sizeofT, value);
1259}
1260
1261#ifndef QT_NO_QOBJECT
1262/*!
1263 \internal
1264
1265 Formats the given enum \a value for debug output.
1266
1267 The supported verbosity are:
1268
1269 0: Just the key, or value with enum name if no key is found:
1270
1271 MyEnum2
1272 MyEnum(123)
1273 MyScopedEnum::Enum3
1274 MyScopedEnum(456)
1275
1276 1: Same as 0, but treating all enums as scoped:
1277
1278 MyEnum::MyEnum2
1279 MyEnum(123)
1280 MyScopedEnum::Enum3
1281 MyScopedEnum(456)
1282
1283 2: The QDebug default. Same as 0, and includes class/namespace scope:
1284
1285 MyNamespace::MyClass::MyEnum2
1286 MyNamespace::MyClass::MyEnum(123)
1287 MyNamespace::MyClass::MyScopedEnum::Enum3
1288 MyNamespace::MyClass::MyScopedEnum(456)
1289
1290 3: Same as 2, but treating all enums as scoped:
1291
1292 MyNamespace::MyClass::MyEnum::MyEnum2
1293 MyNamespace::MyClass::MyEnum(123)
1294 MyNamespace::MyClass::MyScopedEnum::Enum3
1295 MyNamespace::MyClass::MyScopedEnum(456)
1296 */
1297QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, qint64 value, const QMetaObject *meta, const char *name)
1298{
1299 QDebugStateSaver saver(dbg);
1300 dbg.nospace();
1301 QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
1302
1303 const int verbosity = dbg.verbosity();
1304 if (verbosity >= QDebug::DefaultVerbosity) {
1305 if (const char *scope = me.scope())
1306 dbg << scope << u"::";
1307 }
1308
1309 const char *key = me.valueToKey(value: static_cast<int>(value));
1310 const bool scoped = me.isScoped() || verbosity & 1;
1311 if (scoped || !key)
1312 dbg << me.enumName() << (!key ? u"(" : u"::");
1313
1314 if (key)
1315 dbg << key;
1316 else
1317 dbg << value << ')';
1318
1319 return dbg;
1320}
1321
1322/*!
1323 \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name)
1324 \internal
1325
1326 Formats the given flag \a value for debug output.
1327
1328 The supported verbosity are:
1329
1330 0: Just the key(s):
1331
1332 MyFlag1
1333 MyFlag2|MyFlag3
1334 MyScopedFlag(MyFlag2)
1335 MyScopedFlag(MyFlag2|MyFlag3)
1336
1337 1: Same as 0, but treating all flags as scoped:
1338
1339 MyFlag(MyFlag1)
1340 MyFlag(MyFlag2|MyFlag3)
1341 MyScopedFlag(MyFlag2)
1342 MyScopedFlag(MyFlag2|MyFlag3)
1343
1344 2: The QDebug default. Same as 1, and includes class/namespace scope:
1345
1346 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1)
1347 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)
1348 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)
1349 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)
1350 */
1351QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name)
1352{
1353 const int verbosity = debug.verbosity();
1354
1355 QDebugStateSaver saver(debug);
1356 debug.resetFormat();
1357 debug.noquote();
1358 debug.nospace();
1359
1360 const QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
1361
1362 const bool classScope = verbosity >= QDebug::DefaultVerbosity;
1363 if (classScope) {
1364 debug << u"QFlags<";
1365
1366 if (const char *scope = me.scope())
1367 debug << scope << u"::";
1368 }
1369
1370 const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
1371 if (enumScope) {
1372 debug << me.enumName();
1373 if (classScope)
1374 debug << '>';
1375 debug << '(';
1376 }
1377
1378 debug << me.valueToKeys(value: static_cast<int>(value));
1379
1380 if (enumScope)
1381 debug << ')';
1382
1383 return debug;
1384}
1385#endif // !QT_NO_QOBJECT
1386
1387QT_END_NAMESPACE
1388

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/io/qdebug.cpp