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// Qt-Security score:critical reason:data-parsing
5
6#include "qdebug.h"
7#include "private/qdebug_p.h"
8#include "qmetaobject.h"
9#include <private/qlogging_p.h>
10#include <private/qtextstream_p.h>
11#include <private/qtools_p.h>
12
13#include <array>
14#include <q20chrono.h>
15#include <cstdio>
16
17QT_BEGIN_NAMESPACE
18
19using namespace QtMiscUtils;
20
21/*
22 Returns a human readable representation of the first \a maxSize
23 characters in \a data. The size, \a len, is a 64-bit quantity to
24 avoid truncation due to implicit conversions in callers.
25*/
26QByteArray QtDebugUtils::toPrintable(const char *data, qint64 len, qsizetype maxSize)
27{
28 if (!data)
29 return "(null)";
30
31 QByteArray out;
32 for (qsizetype i = 0; i < qMin(a: len, b: maxSize); ++i) {
33 char c = data[i];
34 if (isAsciiPrintable(ch: c)) {
35 out += c;
36 } else {
37 switch (c) {
38 case '\n':
39 out += "\\n";
40 break;
41 case '\r':
42 out += "\\r";
43 break;
44 case '\t':
45 out += "\\t";
46 break;
47 default: {
48 const char buf[] = {
49 '\\',
50 'x',
51 toHexLower(value: uchar(c) / 16),
52 toHexLower(value: uchar(c) % 16),
53 0
54 };
55 out += buf;
56 }
57 }
58 }
59 }
60
61 if (maxSize < len)
62 out += "...";
63
64 return out;
65}
66
67// This file is needed to force compilation of QDebug into the kernel library.
68
69/*!
70 \class QDebug
71 \inmodule QtCore
72 \ingroup shared
73
74 \brief The QDebug class provides an output stream for debugging information.
75
76 QDebug is used whenever the developer needs to write out debugging or tracing
77 information to a device, file, string or console.
78
79 \section1 Basic Use
80
81 In the common case, it is useful to call the qDebug() function to obtain a
82 default QDebug object to use for writing debugging information.
83
84 \snippet qdebug/qdebugsnippet.cpp 1
85
86 This constructs a QDebug object using the constructor that accepts a QtMsgType
87 value of QtDebugMsg. Similarly, the qInfo(), qWarning(), qCritical() and qFatal()
88 functions also return QDebug objects for the corresponding message types.
89
90 The class also provides several constructors for other situations, including
91 a constructor that accepts a QFile or any other QIODevice subclass that is
92 used to write debugging information to files and other devices. The constructor
93 that accepts a QString is used to write to a string for display or serialization.
94
95 \section1 Formatting Options
96
97 QDebug formats output so that it's easily readable. It automatically adds spaces
98 between arguments, and adds quotes around QString, QByteArray, QChar arguments.
99
100 You can tweak these options through the space(), nospace() and quote(), noquote()
101 methods. Furthermore, \l{QTextStream manipulators} can be piped into a QDebug
102 stream.
103
104 QDebugStateSaver limits changes to the formatting to the current scope.
105 resetFormat() resets the options to the default ones.
106
107 \section1 Writing Custom Types to a Stream
108
109 Many standard types can be written to QDebug objects, and Qt provides support for
110 most Qt value types. To add support for custom types, you need to implement a
111 streaming operator, as in the following example:
112
113 \snippet qdebug/qdebugsnippet.cpp 0
114
115 This is described in the \l{Debugging Techniques} and
116 \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
117 documents.
118*/
119
120/*!
121 \fn QDebug::QDebug(QIODevice *device)
122
123 Constructs a debug stream that writes to the given \a device.
124*/
125
126/*!
127 \fn QDebug::QDebug(QString *string)
128
129 Constructs a debug stream that writes to the given \a string.
130*/
131
132/*!
133 \fn QDebug::QDebug(QtMsgType t)
134
135 Constructs a debug stream that writes to the handler for the message type \a t.
136*/
137
138/*!
139 \fn QDebug::QDebug(const QDebug &o)
140
141 Constructs a copy of the other debug stream \a o.
142*/
143
144/*!
145 \fn QDebug &QDebug::operator=(const QDebug &other)
146
147 Assigns the \a other debug stream to this stream and returns a reference to
148 this stream.
149*/
150
151/*!
152 \fn QDebug::~QDebug()
153
154 Flushes any pending data to be written and destroys the debug stream.
155*/
156QDebug::~QDebug()
157{
158 if (stream && !--stream->ref) {
159 if (stream->space && stream->buffer.endsWith(c: u' '))
160 stream->buffer.chop(n: 1);
161 if (stream->message_output) {
162 QInternalMessageLogContext ctxt(stream->context);
163 qt_message_output(stream->type,
164 context: ctxt,
165 message: stream->buffer);
166 }
167 delete stream;
168 }
169}
170
171/*!
172 \internal
173*/
174void QDebug::putUcs4(uint ucs4)
175{
176 maybeQuote(c: '\'');
177 if (ucs4 < 0x20) {
178 stream->ts << "\\x" << Qt::hex << ucs4 << Qt::reset;
179 } else if (ucs4 < 0x80) {
180 stream->ts << char(ucs4);
181 } else {
182 if (ucs4 < 0x10000)
183 stream->ts << "\\u" << qSetFieldWidth(width: 4);
184 else
185 stream->ts << "\\U" << qSetFieldWidth(width: 8);
186 stream->ts << Qt::hex << qSetPadChar(ch: u'0') << ucs4 << Qt::reset;
187 }
188 maybeQuote(c: '\'');
189}
190
191// These two functions return true if the character should be printed by QDebug.
192// For QByteArray, this is technically identical to US-ASCII isprint();
193// for QString, we use QChar::isPrint, which requires a full UCS-4 decode.
194static inline bool isPrintable(char32_t ucs4) { return QChar::isPrint(ucs4); }
195static inline bool isPrintable(char16_t uc) { return QChar::isPrint(ucs4: uc); }
196static inline bool isPrintable(uchar c)
197{ return isAsciiPrintable(ch: c); }
198
199template <typename Char>
200static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true)
201{
202 constexpr char16_t quotes[] = uR"("")";
203 constexpr char16_t quote = quotes[0];
204 d->write(ch: quote);
205
206 bool lastWasHexEscape = false;
207 const Char *end = begin + length;
208 for (const Char *p = begin; p != end; ++p) {
209 // check if we need to insert "" to break an hex escape sequence
210 if (Q_UNLIKELY(lastWasHexEscape)) {
211 if (fromHex(*p) != -1) {
212 // yes, insert it
213 d->write(data: quotes);
214 }
215 lastWasHexEscape = false;
216 }
217
218 if constexpr (sizeof(Char) == sizeof(QChar)) {
219 // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them
220 qsizetype runLength = 0;
221 while (p + runLength != end &&
222 isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"')
223 ++runLength;
224 if (runLength) {
225 d->write(data: QStringView{p, runLength});
226 p += runLength - 1;
227 continue;
228 }
229 } else if (isPrintable(*p) && *p != '\\' && *p != '"') {
230 d->write(ch: char16_t{uchar(*p)});
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 >> 28);
280 buf[3] = '0'; // toHexUpper(ucs4 >> 24);
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: QStringView{buf, buflen});
302 }
303
304 d->write(ch: quote);
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(string: QStringView{begin, 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 switch (content) {
335 case Latin1Content::ContainsLatin1:
336 stream->ts.d_ptr->putString(data: QLatin1StringView{begin, qsizetype(length)});
337 break;
338 case Latin1Content::ContainsBinary:
339 stream->ts.d_ptr->putString(data: QUtf8StringView{begin, qsizetype(length)});
340 break;
341 }
342 } else {
343 // we'll reset the QTextStream formatting mechanisms, so save the state
344 QDebugStateSaver saver(*this);
345 stream->ts.d_ptr->params.reset();
346 putEscapedString(d: stream->ts.d_ptr.get(), begin: reinterpret_cast<const uchar *>(begin),
347 length, isUnicode: content == ContainsLatin1);
348 }
349}
350
351static QByteArray timeUnit(qint64 num, qint64 den)
352{
353 using namespace std::chrono;
354 using namespace q20::chrono;
355
356 if (num == 1 && den > 1) {
357 // sub-multiple of seconds
358 char prefix = '\0';
359 auto tryprefix = [&](auto d, char c) {
360 static_assert(decltype(d)::num == 1, "not an SI prefix");
361 if (den == decltype(d)::den)
362 prefix = c;
363 };
364
365 // "u" should be "µ", but debugging output is not always UTF-8-safe
366 tryprefix(std::milli{}, 'm');
367 tryprefix(std::micro{}, 'u');
368 tryprefix(std::nano{}, 'n');
369 tryprefix(std::pico{}, 'p');
370 tryprefix(std::femto{}, 'f');
371 tryprefix(std::atto{}, 'a');
372 // uncommon ones later
373 tryprefix(std::centi{}, 'c');
374 tryprefix(std::deci{}, 'd');
375 if (prefix) {
376 char unit[3] = { prefix, 's' };
377 return QByteArray(unit, sizeof(unit) - 1);
378 }
379 }
380
381 const char *unit = nullptr;
382 if (num > 1 && den == 1) {
383 // multiple of seconds - but we don't use SI prefixes
384 auto tryunit = [&](auto d, const char *name) {
385 static_assert(decltype(d)::period::den == 1, "not a multiple of a second");
386 if (unit || num % decltype(d)::period::num)
387 return;
388 unit = name;
389 num /= decltype(d)::period::num;
390 };
391 tryunit(years{}, "yr");
392 tryunit(weeks{}, "wk");
393 tryunit(days{}, "d");
394 tryunit(hours{}, "h");
395 tryunit(minutes{}, "min");
396 }
397 if (!unit)
398 unit = "s";
399
400 if (num == 1 && den == 1)
401 return unit;
402 if (Q_UNLIKELY(num < 1 || den < 1))
403 return QString::asprintf(format: "<invalid time unit %lld/%lld>", num, den).toLatin1();
404
405 // uncommon units: will return something like "[2/3]s"
406 // strlen("[/]min") = 6
407 char buf[2 * (std::numeric_limits<qint64>::digits10 + 2) + 10];
408 size_t len = 0;
409 auto appendChar = [&](char c) {
410 Q_ASSERT(len < sizeof(buf));
411 buf[len++] = c;
412 };
413 auto appendNumber = [&](qint64 value) {
414 if (value >= 10'000 && (value % 1000) == 0)
415 len += std::snprintf(s: buf + len, maxlen: sizeof(buf) - len, format: "%.6g", double(value)); // "1e+06"
416 else
417 len += std::snprintf(s: buf + len, maxlen: sizeof(buf) - len, format: "%lld", value);
418 };
419 appendChar('[');
420 appendNumber(num);
421 if (den != 1) {
422 appendChar('/');
423 appendNumber(den);
424 }
425 appendChar(']');
426 memcpy(dest: buf + len, src: unit, n: strlen(s: unit));
427 return QByteArray(buf, len + strlen(s: unit));
428}
429
430/*!
431 \since 6.6
432 \internal
433 Helper to the std::chrono::duration debug streaming output.
434 */
435void QDebug::putTimeUnit(qint64 num, qint64 den)
436{
437 stream->ts << timeUnit(num, den); // ### optimize
438}
439
440namespace {
441
442#ifdef QT_SUPPORTS_INT128
443
444constexpr char Q_INT128_MIN_STR[] = "-170141183460469231731687303715884105728";
445
446constexpr int Int128BufferSize = sizeof(Q_INT128_MIN_STR);
447using Int128Buffer = std::array<char, Int128BufferSize>;
448 // numeric_limits<qint128>::digits10 may not exist
449
450static char *i128ToStringHelper(Int128Buffer &buffer, quint128 n)
451{
452 auto dst = buffer.data() + buffer.size();
453 *--dst = '\0'; // NUL-terminate
454 if (n == 0) {
455 *--dst = '0'; // and done
456 } else {
457 while (n != 0) {
458 *--dst = "0123456789"[n % 10];
459 n /= 10;
460 }
461 }
462 return dst;
463}
464#endif // QT_SUPPORTS_INT128
465
466[[maybe_unused]]
467static const char *int128Warning()
468{
469 const char *msg = "Qt was not compiled with int128 support.";
470 qWarning(msg: "%s", msg);
471 return msg;
472}
473
474} // unnamed namespace
475
476/*!
477 \since 6.7
478 \internal
479 Helper to the qint128 debug streaming output.
480 */
481void QDebug::putInt128([[maybe_unused]] const void *p)
482{
483#ifdef QT_SUPPORTS_INT128
484 Q_ASSERT(p);
485 qint128 i;
486 memcpy(dest: &i, src: p, n: sizeof(i)); // alignment paranoia
487 if (i == Q_INT128_MIN) {
488 // -i is not representable, hardcode the result:
489 stream->ts << Q_INT128_MIN_STR;
490 } else {
491 Int128Buffer buffer;
492 auto dst = i128ToStringHelper(buffer, n: i < 0 ? -i : i);
493 if (i < 0)
494 *--dst = '-';
495 stream->ts << dst;
496 }
497 return;
498#endif // QT_SUPPORTS_INT128
499 stream->ts << int128Warning();
500}
501
502/*!
503 \since 6.7
504 \internal
505 Helper to the quint128 debug streaming output.
506 */
507void QDebug::putUInt128([[maybe_unused]] const void *p)
508{
509#ifdef QT_SUPPORTS_INT128
510 Q_ASSERT(p);
511 quint128 i;
512 memcpy(dest: &i, src: p, n: sizeof(i)); // alignment paranoia
513 Int128Buffer buffer;
514 stream->ts << i128ToStringHelper(buffer, n: i);
515 return;
516#endif // QT_SUPPORTS_INT128
517 stream->ts << int128Warning();
518}
519
520/*!
521 \since 6.9
522 \internal
523 Helper to the <Std/Qt>::<>_ordering debug output.
524 It generates the string in following format:
525 <Qt/Std>::<weak/partial/strong>_ordering::<less/equal/greater/unordered>
526 */
527void QDebug::putQtOrdering(QtOrderingPrivate::QtOrderingTypeFlag flags, Qt::partial_ordering order)
528{
529 using QtOrderingPrivate::QtOrderingType;
530 std::string result;
531 if ((flags & QtOrderingType::StdOrder) == QtOrderingType::StdOrder)
532 result += "std";
533 else if ((flags & QtOrderingType::QtOrder) == QtOrderingType::QtOrder)
534 result += "Qt";
535
536 result += "::";
537 const bool isStrong = ((flags & QtOrderingType::Strong) == QtOrderingType::Strong);
538 if (isStrong)
539 result += "strong";
540 else if ((flags & QtOrderingType::Weak) == QtOrderingType::Weak)
541 result += "weak";
542 else if ((flags & QtOrderingType::Partial) == QtOrderingType::Partial)
543 result += "partial";
544 result += "_ordering::";
545
546 if (order == Qt::partial_ordering::equivalent) {
547 if (isStrong)
548 result += "equal";
549 else
550 result += "equivalent";
551 } else if (order == Qt::partial_ordering::greater) {
552 result += "greater";
553 } else if (order == Qt::partial_ordering::less) {
554 result += "less";
555 } else {
556 result += "unordered";
557 }
558 stream->ts << result.data();
559}
560
561/*!
562 \fn QDebug::swap(QDebug &other)
563 \since 5.0
564 \memberswap{debug stream instance}
565*/
566
567/*!
568 Resets the stream formatting options, bringing it back to its original constructed state.
569
570 \sa space(), quote()
571 \since 5.4
572*/
573QDebug &QDebug::resetFormat()
574{
575 stream->ts.reset();
576 stream->space = true;
577 stream->noQuotes = false;
578 stream->verbosity = DefaultVerbosity;
579 return *this;
580}
581
582/*!
583 \fn QDebug &QDebug::space()
584
585 Writes a space character to the debug stream and returns a reference to
586 the stream.
587
588 The stream remembers that automatic insertion of spaces is
589 enabled for future writes.
590
591 \sa nospace(), maybeSpace()
592*/
593
594/*!
595 \fn QDebug &QDebug::nospace()
596
597 Disables automatic insertion of spaces and returns a reference to the stream.
598
599 \sa space(), maybeSpace()
600*/
601
602/*!
603 \fn QDebug &QDebug::maybeSpace()
604
605 Writes a space character to the debug stream, depending on the current
606 setting for automatic insertion of spaces, and returns a reference to the stream.
607
608 \sa space(), nospace()
609*/
610
611/*!
612 \fn bool QDebug::autoInsertSpaces() const
613
614 Returns \c true if this QDebug instance will automatically insert spaces
615 between writes.
616
617 \since 5.0
618
619 \sa QDebugStateSaver
620*/
621
622/*!
623 \fn void QDebug::setAutoInsertSpaces(bool b)
624
625 Enables automatic insertion of spaces between writes if \a b is true; otherwise
626 automatic insertion of spaces is disabled.
627
628 \since 5.0
629
630 \sa QDebugStateSaver
631*/
632
633
634/*!
635 \fn bool QDebug::quoteStrings() const
636 \since 6.7
637
638 Returns \c true if this QDebug instance will quote strings streamed into
639 it (which is the default).
640
641 \sa QDebugStateSaver, quote(), noquote(), setQuoteStrings()
642*/
643
644/*!
645 \fn void QDebug::setQuoteStrings(bool b)
646 \since 6.7
647
648 Enables quoting of strings streamed into this QDebug instance if \a b is
649 \c true; otherwise quoting is disabled.
650
651 The default is to quote strings.
652
653 \sa QDebugStateSaver, quote(), noquote(), quoteStrings()
654*/
655
656
657/*!
658 \fn QDebug &QDebug::quote()
659 \since 5.4
660
661 Enables automatic insertion of quotation characters around QChar, QString and QByteArray
662 contents and returns a reference to the stream.
663
664 Quoting is enabled by default.
665
666 \sa noquote(), maybeQuote()
667*/
668
669/*!
670 \fn QDebug &QDebug::noquote()
671 \since 5.4
672
673 Disables automatic insertion of quotation characters around QChar, QString and QByteArray
674 contents and returns a reference to the stream.
675
676 When quoting is disabled, these types are printed without quotation
677 characters and without escaping of non-printable characters.
678
679 \sa quote(), maybeQuote()
680*/
681
682/*!
683 \fn QDebug &QDebug::maybeQuote(char c)
684 \since 5.4
685
686 Writes a character \a c to the debug stream, depending on the
687 current setting for automatic insertion of quotes, and returns a reference to the stream.
688
689 The default character is a double quote \c{"}.
690
691 \sa quote(), noquote()
692*/
693
694/*!
695 \fn int QDebug::verbosity() const
696 \since 5.6
697
698 Returns the verbosity of the debug stream.
699
700 Streaming operators can check the value to decide whether
701 verbose output is desired and print more information depending on the
702 level. Higher values indicate that more information is desired.
703
704 The allowed range is from 0 to 7. The default value is 2.
705
706 \sa setVerbosity(), VerbosityLevel
707*/
708
709/*!
710 \fn void QDebug::setVerbosity(int verbosityLevel)
711 \since 5.6
712
713 Sets the verbosity of the stream to \a verbosityLevel.
714
715 The allowed range is from 0 to 7. The default value is 2.
716
717 \sa verbosity(), VerbosityLevel
718*/
719
720/*!
721 \fn QDebug &QDebug::verbosity(int verbosityLevel)
722 \since 5.13
723
724 Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream.
725
726 The allowed range is from 0 to 7. The default value is 2.
727
728 \sa verbosity(), setVerbosity(), VerbosityLevel
729*/
730
731/*!
732 \enum QDebug::VerbosityLevel
733 \since 5.13
734
735 This enum describes the range of verbosity levels.
736
737 \value MinimumVerbosity
738 \value DefaultVerbosity
739 \value MaximumVerbosity
740
741 \sa verbosity(), setVerbosity()
742*/
743
744/*!
745 \fn QDebug &QDebug::operator<<(QChar t)
746
747 Writes the character, \a t, to the stream and returns a reference to the
748 stream. Normally, QDebug prints control characters and non-US-ASCII
749 characters as their C escape sequences or their Unicode value (\\u1234). To
750 print non-printable characters without transformation, enable the noquote()
751 functionality, but note that some QDebug backends may not be 8-bit clean
752 and may not be able to represent \c t.
753*/
754
755/*!
756 \fn QDebug &QDebug::operator<<(bool t)
757
758 Writes the boolean value, \a t, to the stream and returns a reference to the
759 stream.
760*/
761
762/*!
763 \fn QDebug &QDebug::operator<<(char t)
764
765 Writes the character, \a t, to the stream and returns a reference to the
766 stream.
767*/
768
769/*!
770 \fn QDebug &QDebug::operator<<(signed short t)
771
772 Writes the signed short integer, \a t, to the stream and returns a reference
773 to the stream.
774*/
775
776/*!
777 \fn QDebug &QDebug::operator<<(unsigned short t)
778
779 Writes then unsigned short integer, \a t, to the stream and returns a
780 reference to the stream.
781*/
782
783/*!
784 \fn QDebug &QDebug::operator<<(signed int t)
785
786 Writes the signed integer, \a t, to the stream and returns a reference
787 to the stream.
788*/
789
790/*!
791 \fn QDebug &QDebug::operator<<(unsigned int t)
792
793 Writes then unsigned integer, \a t, to the stream and returns a reference to
794 the stream.
795*/
796
797/*!
798 \fn QDebug &QDebug::operator<<(signed long t)
799
800 Writes the signed long integer, \a t, to the stream and returns a reference
801 to the stream.
802*/
803
804/*!
805 \fn QDebug &QDebug::operator<<(unsigned long t)
806
807 Writes then unsigned long integer, \a t, to the stream and returns a reference
808 to the stream.
809*/
810
811/*!
812 \fn QDebug &QDebug::operator<<(qint64 t)
813
814 Writes the signed 64-bit integer, \a t, to the stream and returns a reference
815 to the stream.
816*/
817
818/*!
819 \fn QDebug &QDebug::operator<<(quint64 t)
820
821 Writes then unsigned 64-bit integer, \a t, to the stream and returns a
822 reference to the stream.
823*/
824
825/*!
826 \fn QDebug &QDebug::operator<<(float t)
827
828 Writes the 32-bit floating point number, \a t, to the stream and returns a
829 reference to the stream.
830*/
831
832/*!
833 \fn QDebug &QDebug::operator<<(double t)
834
835 Writes the 64-bit floating point number, \a t, to the stream and returns a
836 reference to the stream.
837*/
838
839/*!
840 \fn QDebug &QDebug::operator<<(const char *t)
841
842 Writes the '\\0'-terminated UTF-8 string, \a t, to the stream and returns a
843 reference to the stream. The string is never quoted or escaped for the
844 output. Note that QDebug buffers internally as UTF-16 and may need to
845 transform to 8-bit using the locale's codec in order to use some backends,
846 which may cause garbled output (mojibake). Restricting to US-ASCII strings
847 is recommended.
848*/
849
850/*!
851 \fn QDebug &QDebug::operator<<(const char16_t *t)
852 \since 6.0
853
854 Writes the u'\\0'-terminated UTF-16 string, \a t, to the stream and returns
855 a reference to the stream. The string is never quoted or escaped for the
856 output. Note that QDebug buffers internally as UTF-16 and may need to
857 transform to 8-bit using the locale's codec in order to use some backends,
858 which may cause garbled output (mojibake). Restricting to US-ASCII strings
859 is recommended.
860*/
861
862/*!
863 \fn QDebug &QDebug::operator<<(char16_t t)
864 \since 5.5
865
866 Writes the UTF-16 character, \a t, to the stream and returns a reference
867 to the stream.
868*/
869
870/*!
871 \fn QDebug &QDebug::operator<<(char32_t t)
872 \since 5.5
873
874 Writes the UTF-32 character, \a t, to the stream and returns a reference
875 to the stream.
876*/
877
878/*!
879 \fn QDebug &QDebug::operator<<(const QString &t)
880
881 Writes the string, \a t, to the stream and returns a reference to the
882 stream. Normally, QDebug prints the string inside quotes and transforms
883 non-printable characters to their Unicode values (\\u1234).
884
885 To print non-printable characters without transformation, enable the
886 noquote() functionality. Note that some QDebug backends might not be 8-bit
887 clean.
888
889 Output examples:
890 \snippet code/src_corelib_io_qdebug.cpp 0
891*/
892
893/*!
894 \since 5.10
895 \fn QDebug &QDebug::operator<<(QStringView s)
896
897 Writes the string view, \a s, to the stream and returns a reference to the
898 stream. Normally, QDebug prints the string inside quotes and transforms
899 non-printable characters to their Unicode values (\\u1234).
900
901 To print non-printable characters without transformation, enable the
902 noquote() functionality. Note that some QDebug backends might not be 8-bit
903 clean.
904
905 See the QString overload for examples.
906*/
907
908/*!
909 \since 6.0
910 \fn QDebug &QDebug::operator<<(QUtf8StringView s)
911
912 Writes the string view, \a s, to the stream and returns a reference to the
913 stream.
914
915 Normally, QDebug prints the data inside quotes and transforms control or
916 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
917 output is always 7-bit clean and the string can be copied from the output
918 and pasted back into C++ sources, if necessary.
919
920 To print non-printable characters without transformation, enable the
921 noquote() functionality. Note that some QDebug backends might not be 8-bit
922 clean.
923*/
924
925/*!
926 \fn QDebug &QDebug::operator<<(QLatin1StringView t)
927
928 Writes the string, \a t, to the stream and returns a reference to the
929 stream. Normally, QDebug prints the string inside quotes and transforms
930 non-printable characters to their Unicode values (\\u1234).
931
932 To print non-printable characters without transformation, enable the
933 noquote() functionality. Note that some QDebug backends might not be 8-bit
934 clean.
935
936 See the QString overload for examples.
937*/
938
939/*!
940 \fn QDebug &QDebug::operator<<(const QByteArray &t)
941
942 Writes the byte array, \a t, to the stream and returns a reference to the
943 stream. Normally, QDebug prints the array inside quotes and transforms
944 control or non-US-ASCII characters to their C escape sequences (\\xAB). This
945 way, the output is always 7-bit clean and the string can be copied from the
946 output and pasted back into C++ sources, if necessary.
947
948 To print non-printable characters without transformation, enable the
949 noquote() functionality. Note that some QDebug backends might not be 8-bit
950 clean.
951
952 Output examples:
953 \snippet code/src_corelib_io_qdebug.cpp 1
954
955 Note how QDebug needed to close and reopen the string in the way C and C++
956 languages concatenate string literals so that the letter 'b' is not
957 interpreted as part of the previous hexadecimal escape sequence.
958*/
959
960/*!
961 \since 6.0
962 \fn QDebug &QDebug::operator<<(QByteArrayView t)
963
964 Writes the data of the observed byte array, \a t, to the stream and returns
965 a reference to the stream.
966
967 Normally, QDebug prints the data inside quotes and transforms control or
968 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
969 output is always 7-bit clean and the string can be copied from the output
970 and pasted back into C++ sources, if necessary.
971
972 To print non-printable characters without transformation, enable the
973 noquote() functionality. Note that some QDebug backends might not be 8-bit
974 clean.
975
976 See the QByteArray overload for examples.
977*/
978
979/*!
980 \fn QDebug &QDebug::operator<<(const void *t)
981
982 Writes a pointer, \a t, to the stream and returns a reference to the stream.
983*/
984
985/*!
986 \fn QDebug &QDebug::operator<<(QTextStreamFunction f)
987 \internal
988*/
989
990/*!
991 \fn QDebug &QDebug::operator<<(QTextStreamManipulator m)
992 \internal
993*/
994
995/*!
996 \fn template <typename T, QDebug::if_ordering_type<T>> QDebug::operator<<(QDebug debug, T t)
997 \since 6.9
998 Prints the Qt or std ordering value \a t to the \a debug object.
999
1000 \constraints \c T is one of <Qt/Std>::<weak/partial/strong>_ordering.
1001*/
1002
1003/*!
1004 \since 6.5
1005 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(const std::basic_string<Char, Args...> &s)
1006 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(std::basic_string_view<Char, Args...> s)
1007
1008 Writes the string or string-view \a s to the stream and returns a reference
1009 to the stream.
1010
1011 These operators only participate in overload resolution if \c Char is one of
1012 \list
1013 \li char
1014 \li char8_t (C++20 only)
1015 \li char16_t
1016 \li char32_t
1017 \li wchar_t
1018 \endlist
1019*/
1020
1021/*!
1022 \since 6.6
1023 \fn template <typename Rep, typename Period> QDebug &QDebug::operator<<(std::chrono::duration<Rep, Period> duration)
1024
1025 Prints the time duration \a duration to the stream and returns a reference
1026 to the stream. The printed string is the numeric representation of the
1027 period followed by the time unit, similar to what the C++ Standard Library
1028 would produce with \c{std::ostream}.
1029
1030 The unit is not localized.
1031*/
1032
1033/*!
1034 \fn template <typename T, QDebug::if_qint128<T>> QDebug::operator<<(T i)
1035 \fn template <typename T, QDebug::if_quint128<T>> QDebug::operator<<(T i)
1036 \since 6.7
1037
1038 Prints the textual representation of the 128-bit integer \a i.
1039
1040 \note This operator is only available if Qt supports 128-bit integer types.
1041 If 128-bit integer types are available in your build, but the Qt libraries
1042 were compiled without, the operator will print a warning instead.
1043
1044 \note Because the operator is a function template, no implicit conversions
1045 are performed on its argument. It must be exactly qint128/quint128.
1046
1047 \sa QT_SUPPORTS_INT128
1048*/
1049
1050/*!
1051 \fn template <class T> QString QDebug::toString(const T &object)
1052 \since 6.0
1053
1054 \include qdebug-toString.qdocinc
1055
1056 \sa toBytes()
1057*/
1058
1059/*! \internal */
1060QString QDebug::toStringImpl(StreamTypeErased s, const void *obj)
1061{
1062 QString result;
1063 {
1064 QDebug d(&result);
1065 s(d.nospace(), obj);
1066 }
1067 return result;
1068}
1069
1070/*!
1071 \fn template <class T> QByteArray QDebug::toBytes(const T &object)
1072 \since 6.9
1073
1074 This is equivalent to passing \a object to
1075 \c{QDebug::toString(object).toUtf8()}, but more efficient.
1076
1077 \sa toString()
1078*/
1079
1080/*! \internal */
1081QByteArray QDebug::toBytesImpl(StreamTypeErased s, const void *obj)
1082{
1083 QByteArray result;
1084 {
1085 QDebug d(&result);
1086 s(d.nospace(), obj);
1087 }
1088 return result;
1089}
1090
1091/*!
1092 \internal
1093 \since 6.9
1094
1095 Outputs a heterogeneous product type (pair, tuple, or anything that
1096 implements the Tuple Protocol). The class name is described by "\a ns
1097 \c{::} \a what", while the addresses of the \a n elements are stored in the
1098 array \a data. The formatters are stored in the array \a ops.
1099
1100 If \a ns is empty, only \a what is used.
1101*/
1102QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
1103 size_t n, StreamTypeErased *ops, const void **data)
1104{
1105 const QDebugStateSaver saver(*this);
1106 nospace();
1107 if (ns && *ns)
1108 *this << ns << "::";
1109 *this << what << '(';
1110 while (n--) {
1111 (*ops++)(*this, *data++);
1112 if (n)
1113 *this << ", ";
1114 }
1115 return *this << ')';
1116}
1117
1118/*!
1119 \fn template <class T> QDebug operator<<(QDebug debug, const QList<T> &list)
1120 \relates QDebug
1121
1122 Writes the contents of \a list to \a debug. \c T needs to
1123 support streaming into QDebug.
1124*/
1125
1126/*!
1127 \fn template <class T, qsizetype P> QDebug operator<<(QDebug debug, const QVarLengthArray<T,P> &array)
1128 \relates QDebug
1129 \since 6.3
1130
1131 Writes the contents of \a array to \a debug. \c T needs to
1132 support streaming into QDebug.
1133*/
1134
1135/*!
1136 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec)
1137 \relates QDebug
1138 \since 5.7
1139
1140 Writes the contents of list \a vec to \a debug. \c T needs to
1141 support streaming into QDebug.
1142*/
1143
1144/*!
1145 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
1146 \relates QDebug
1147 \since 5.7
1148
1149 Writes the contents of vector \a vec to \a debug. \c T needs to
1150 support streaming into QDebug.
1151*/
1152
1153/*!
1154 \fn template <typename T, std::size_t N> QDebug operator<<(QDebug debug, const std::array<T, N> &array)
1155 \relates QDebug
1156 \since 6.9
1157
1158 Writes the contents of \a array to \a debug. \c T needs to
1159 support streaming into QDebug.
1160*/
1161
1162/*!
1163 \fn template <typename T> QDebug operator<<(QDebug debug, const QSet<T> &set)
1164 \relates QDebug
1165
1166 Writes the contents of \a set to \a debug. \c T needs to
1167 support streaming into QDebug.
1168*/
1169
1170/*!
1171 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMap<Key, T> &map)
1172 \relates QDebug
1173
1174 Writes the contents of \a map to \a debug. Both \c Key and
1175 \c T need to support streaming into QDebug.
1176*/
1177
1178/*!
1179 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiMap<Key, T> &map)
1180 \relates QDebug
1181
1182 Writes the contents of \a map to \a debug. Both \c Key and
1183 \c T need to support streaming into QDebug.
1184*/
1185
1186/*!
1187 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
1188 \relates QDebug
1189 \since 5.7
1190
1191 Writes the contents of \a map to \a debug. Both \c Key and
1192 \c T need to support streaming into QDebug.
1193*/
1194
1195/*!
1196 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
1197 \relates QDebug
1198 \since 5.7
1199
1200 Writes the contents of \a map to \a debug. Both \c Key and
1201 \c T need to support streaming into QDebug.
1202*/
1203
1204/*!
1205 \fn template <typename Key, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multiset<Key, Compare, Alloc> &multiset)
1206 \relates QDebug
1207 \since 6.9
1208
1209 Writes the contents of \a multiset to \a debug. The \c Key type
1210 needs to support streaming into QDebug.
1211*/
1212
1213/*!
1214 \fn template <typename Key, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::set<Key, Compare, Alloc> &set)
1215 \relates QDebug
1216 \since 6.9
1217
1218 Writes the contents of \a set to \a debug. The \c Key type
1219 needs to support streaming into QDebug.
1220*/
1221
1222/*!
1223 \fn template <typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_map<Key, T, Hash, KeyEqual, Alloc> &map)
1224 \relates QDebug
1225 \since 6.9
1226
1227 Writes the contents of \a map to \a debug. Both \c Key and
1228 \c T need to support streaming into QDebug.
1229*/
1230
1231/*!
1232 \fn template <typename Key, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_set<Key, Hash, KeyEqual, Alloc> &unordered_set)
1233 \relates QDebug
1234 \since 6.9
1235
1236 Writes the contents of \a unordered_set to \a debug. The \c Key type
1237 needs to support streaming into QDebug.
1238*/
1239
1240/*!
1241 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
1242 \relates QDebug
1243
1244 Writes the contents of \a hash to \a debug. Both \c Key and
1245 \c T need to support streaming into QDebug.
1246*/
1247
1248/*!
1249 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
1250 \relates QDebug
1251
1252 Writes the contents of \a hash to \a debug. Both \c Key and
1253 \c T need to support streaming into QDebug.
1254*/
1255
1256/*!
1257 \fn template <class...Ts, QDebug::if_streamable<Ts...>> QDebug &QDebug::operator<<(const std::tuple<Ts...> &tuple)
1258 \since 6.9
1259
1260 Writes the contents of \a tuple to the stream. All \c Ts... need to support
1261 streaming into QDebug.
1262*/
1263
1264/*!
1265 \fn template <class T1, class T2> QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair)
1266 \relates QDebug
1267
1268 Writes the contents of \a pair to \a debug. Both \c T1 and
1269 \c T2 need to support streaming into QDebug.
1270*/
1271
1272/*!
1273 \since 6.7
1274 \fn template <class T, QDebug::if_streamable<T>> QDebug::operator<<(const std::optional<T> &opt)
1275
1276 Writes the contents of \a opt (or \c nullopt if not set) to this stream.
1277 \c T needs to support streaming into QDebug.
1278*/
1279
1280/*!
1281 \fn template <typename T> QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
1282 \relates QDebug
1283
1284 Writes the contents of \a cache to \a debug. \c T needs to
1285 support streaming into QDebug.
1286*/
1287
1288/*!
1289 \fn template<typename T> QDebug operator<<(QDebug debug, const QFlags<T> &flags)
1290 \relates QDebug
1291 \since 4.7
1292
1293 Writes \a flags to \a debug.
1294*/
1295
1296/*!
1297 \fn template<typename T> QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
1298 \relates QSharedPointer
1299 \since 5.7
1300
1301 Writes the pointer tracked by \a ptr into the debug object \a debug for
1302 debugging purposes.
1303
1304 \sa {Debugging Techniques}
1305*/
1306
1307/*!
1308 \fn QDebug &QDebug::operator<<(std::nullptr_t)
1309 \internal
1310 */
1311
1312/*!
1313 \since 6.7
1314 \fn QDebug &QDebug::operator<<(std::nullopt_t)
1315
1316 Writes nullopt to the stream.
1317*/
1318
1319/*!
1320 \class QDebugStateSaver
1321 \inmodule QtCore
1322 \brief Convenience class for custom QDebug operators.
1323
1324 Saves the settings used by QDebug, and restores them upon destruction,
1325 then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if
1326 \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver.
1327
1328 The automatic insertion of spaces between writes is one of the settings
1329 that QDebugStateSaver stores for the duration of the current block.
1330
1331 The settings of the internal QTextStream are also saved and restored,
1332 so that using << Qt::hex in a QDebug operator doesn't affect other QDebug
1333 operators.
1334
1335 QDebugStateSaver is typically used in the implementation of an operator<<() for debugging:
1336
1337 \snippet customtype/customtypeexample.cpp custom type streaming operator
1338
1339 \since 5.1
1340*/
1341
1342class QDebugStateSaverPrivate
1343{
1344public:
1345 QDebugStateSaverPrivate(QDebug::Stream *stream)
1346 : m_stream(stream),
1347 m_spaces(stream->space),
1348 m_noQuotes(stream->noQuotes),
1349 m_verbosity(stream->verbosity),
1350 m_streamParams(stream->ts.d_ptr->params)
1351 {
1352 }
1353 void restoreState()
1354 {
1355 const bool currentSpaces = m_stream->space;
1356 if (currentSpaces && !m_spaces)
1357 if (m_stream->buffer.endsWith(c: u' '))
1358 m_stream->buffer.chop(n: 1);
1359
1360 m_stream->space = m_spaces;
1361 m_stream->noQuotes = m_noQuotes;
1362 m_stream->ts.d_ptr->params = m_streamParams;
1363 m_stream->verbosity = m_verbosity;
1364
1365 if (!currentSpaces && m_spaces)
1366 m_stream->ts << ' ';
1367 }
1368
1369 QDebug::Stream *m_stream;
1370
1371 // QDebug state
1372 const bool m_spaces;
1373 const bool m_noQuotes;
1374 const int m_verbosity;
1375
1376 // QTextStream state
1377 const QTextStreamPrivate::Params m_streamParams;
1378};
1379
1380
1381/*!
1382 Creates a QDebugStateSaver instance, which saves the settings
1383 currently used by \a dbg.
1384
1385 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1386*/
1387QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
1388 : d(new QDebugStateSaverPrivate(dbg.stream))
1389{
1390}
1391
1392/*!
1393 Destroys a QDebugStateSaver instance, which restores the settings
1394 used when the QDebugStateSaver instance was created.
1395
1396 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1397*/
1398QDebugStateSaver::~QDebugStateSaver()
1399{
1400 d->restoreState();
1401}
1402
1403/*!
1404 \internal
1405
1406 Specialization of the primary template in qdebug.h to out-of-line
1407 the common case of QFlags<T>::Int being 32-bit.
1408
1409 Just call the generic version so the two don't get out of sync.
1410*/
1411void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
1412{
1413 qt_QMetaEnum_flagDebugOperator(debug, sizeofT, value: quint64(value));
1414}
1415
1416/*!
1417 \internal
1418 Ditto, for 64-bit.
1419*/
1420void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, quint64 value)
1421{
1422 qt_QMetaEnum_flagDebugOperator<quint64>(debug, sizeofT, value);
1423}
1424
1425
1426#ifndef QT_NO_QOBJECT
1427/*!
1428 \internal
1429
1430 Formats the given enum \a value for debug output.
1431
1432 The supported verbosity are:
1433
1434 0: Just the key, or value with enum name if no key is found:
1435
1436 MyEnum2
1437 MyEnum(123)
1438 MyScopedEnum::Enum3
1439 MyScopedEnum(456)
1440
1441 1: Same as 0, but treating all enums as scoped:
1442
1443 MyEnum::MyEnum2
1444 MyEnum(123)
1445 MyScopedEnum::Enum3
1446 MyScopedEnum(456)
1447
1448 2: The QDebug default. Same as 0, and includes class/namespace scope:
1449
1450 MyNamespace::MyClass::MyEnum2
1451 MyNamespace::MyClass::MyEnum(123)
1452 MyNamespace::MyClass::MyScopedEnum::Enum3
1453 MyNamespace::MyClass::MyScopedEnum(456)
1454
1455 3: Same as 2, but treating all enums as scoped:
1456
1457 MyNamespace::MyClass::MyEnum::MyEnum2
1458 MyNamespace::MyClass::MyEnum(123)
1459 MyNamespace::MyClass::MyScopedEnum::Enum3
1460 MyNamespace::MyClass::MyScopedEnum(456)
1461 */
1462QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, qint64 value, const QMetaObject *meta, const char *name)
1463{
1464 QDebugStateSaver saver(dbg);
1465 dbg.nospace();
1466 QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
1467
1468 const int verbosity = dbg.verbosity();
1469 if (verbosity >= QDebug::DefaultVerbosity) {
1470 if (const char *scope = me.scope())
1471 dbg << scope << u"::";
1472 }
1473
1474 const char *key = me.valueToKey(value: static_cast<int>(value));
1475 const bool scoped = me.isScoped() || verbosity & 1;
1476 if (scoped || !key)
1477 dbg << me.enumName() << (!key ? u"(" : u"::");
1478
1479 if (key)
1480 dbg << key;
1481 else
1482 dbg << value << ')';
1483
1484 return dbg;
1485}
1486
1487/*!
1488 \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name)
1489 \internal
1490
1491 Formats the given flag \a value for debug output.
1492
1493 The supported verbosity are:
1494
1495 0: Just the key(s):
1496
1497 MyFlag1
1498 MyFlag2|MyFlag3
1499 MyScopedFlag(MyFlag2)
1500 MyScopedFlag(MyFlag2|MyFlag3)
1501
1502 1: Same as 0, but treating all flags as scoped:
1503
1504 MyFlag(MyFlag1)
1505 MyFlag(MyFlag2|MyFlag3)
1506 MyScopedFlag(MyFlag2)
1507 MyScopedFlag(MyFlag2|MyFlag3)
1508
1509 2: The QDebug default. Same as 1, and includes class/namespace scope:
1510
1511 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1)
1512 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)
1513 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)
1514 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)
1515 */
1516QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name)
1517{
1518 const int verbosity = debug.verbosity();
1519
1520 QDebugStateSaver saver(debug);
1521 debug.resetFormat();
1522 debug.noquote();
1523 debug.nospace();
1524
1525 const QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
1526
1527 const bool classScope = verbosity >= QDebug::DefaultVerbosity;
1528 if (classScope) {
1529 debug << u"QFlags<";
1530
1531 if (const char *scope = me.scope())
1532 debug << scope << u"::";
1533 }
1534
1535 const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
1536 if (enumScope) {
1537 debug << me.enumName();
1538 if (classScope)
1539 debug << '>';
1540 debug << '(';
1541 }
1542
1543 debug << me.valueToKeys(value);
1544
1545 if (enumScope)
1546 debug << ')';
1547
1548 return debug;
1549}
1550
1551/*!
1552 \macro QDebug qDebug()
1553 \relates QDebug
1554 \threadsafe
1555
1556 Returns a QDebug object that logs a debug message to the central message handler.
1557
1558 Example:
1559
1560 \snippet code/src_corelib_global_qglobal.cpp 25
1561
1562 Using qDebug() is an alternative to \l{qDebug(const char *, ...)},
1563 which follows the printf paradigm.
1564
1565 Note that QDebug and the type specific stream operators do add various
1566 formatting to make the debug message easier to read. See the
1567 \l{Formatting Options}{formatting options} documentation for more details.
1568
1569 This function does nothing if \c QT_NO_DEBUG_OUTPUT was defined during
1570 compilation.
1571
1572 \sa {qDebug(const char *, ...)}, qCDebug()
1573*/
1574
1575/*!
1576 \macro QDebug qInfo()
1577 \relates QDebug
1578 \threadsafe
1579
1580 Returns a QDebug object that logs an informational message to the central message handler.
1581
1582 Example:
1583
1584 \snippet code/src_corelib_global_qglobal.cpp qInfo_stream
1585
1586 Using qInfo() is an alternative to \l{qInfo(const char *, ...)},
1587 which follows the printf paradigm.
1588
1589 Note that QDebug and the type specific stream operators do add various
1590 formatting to make the debug message easier to read. See the
1591 \l{Formatting Options}{formatting options} documentation for more details.
1592
1593 This function does nothing if \c QT_NO_INFO_OUTPUT was defined during
1594 compilation.
1595
1596 \sa {qInfo(const char *, ...)}, qCInfo()
1597*/
1598
1599/*!
1600 \macro QDebug qWarning()
1601 \relates QDebug
1602 \threadsafe
1603
1604 Returns a QDebug object that logs a warning message to the central message handler.
1605
1606 Example:
1607
1608 \snippet code/src_corelib_global_qglobal.cpp 27
1609
1610 Using qWarning() is an alternative to \l{qWarning(const char *, ...)},
1611 which follows the printf paradigm.
1612
1613 Note that QDebug and the type specific stream operators do add various
1614 formatting to make the debug message easier to read. See the
1615 \l{Formatting Options}{formatting options} documentation for more details.
1616
1617 This function does nothing if \c QT_NO_WARNING_OUTPUT was defined during
1618 compilation.
1619
1620 For debugging purposes, it is sometimes convenient to let the
1621 program abort for warning messages. This allows you then
1622 to inspect the core dump, or attach a debugger - see also \l{qFatal()}.
1623 To enable this, set the environment variable \c{QT_FATAL_WARNINGS}
1624 to a number \c n. The program terminates then for the n-th warning.
1625 That is, if the environment variable is set to 1, it will terminate
1626 on the first call; if it contains the value 10, it will exit on the 10th
1627 call. Any non-numeric value in the environment variable is equivalent to 1.
1628
1629 \sa {qWarning(const char *, ...)}, qCWarning()
1630*/
1631
1632/*!
1633 \macro QDebug qCritical()
1634 \relates QDebug
1635 \threadsafe
1636
1637 Returns a QDebug object that logs a critical message to the central message handler.
1638
1639 Example:
1640
1641 \snippet code/src_corelib_global_qglobal.cpp 29
1642
1643 Using qCritical() is an alternative to \l{qCritical(const char *, ...)},
1644 which follows the printf paradigm.
1645
1646 Note that QDebug and the type specific stream operators do add various
1647 formatting to make the debug message easier to read. See the
1648 \l{Formatting Options}{formatting options} documentation for more details.
1649
1650 For debugging purposes, it is sometimes convenient to let the
1651 program abort for critical messages. This allows you then
1652 to inspect the core dump, or attach a debugger - see also \l{qFatal()}.
1653 To enable this, set the environment variable \c{QT_FATAL_CRITICALS}
1654 to a number \c n. The program terminates then for the n-th critical
1655 message.
1656 That is, if the environment variable is set to 1, it will terminate
1657 on the first call; if it contains the value 10, it will exit on the 10th
1658 call. Any non-numeric value in the environment variable is equivalent to 1.
1659
1660 \sa {qCritical(const char *, ...)}, qCCritical()
1661*/
1662
1663/*!
1664 \macro QDebug qFatal()
1665 \relates QDebug
1666 \threadsafe
1667
1668 Returns a QDebug object that logs a fatal message to the central message handler.
1669
1670 Using qFatal() is an alternative to \l{qFatal(const char *, ...)},
1671 which follows the printf paradigm.
1672
1673 Note that QDebug and the type specific stream operators do add various
1674 formatting to make the debug message easier to read. See the
1675 \l{Formatting Options}{formatting options} documentation for more details.
1676
1677 If you are using the \b{default message handler}, the returned stream will abort
1678 to create a core dump. On Windows, for debug builds,
1679 this function will report a _CRT_ERROR enabling you to connect a debugger
1680 to the application.
1681
1682 \sa {qFatal(const char *, ...)}, qCFatal()
1683*/
1684
1685#endif // !QT_NO_QOBJECT
1686
1687QT_END_NAMESPACE
1688

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