1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#ifdef QT_NO_DEBUG
42#undef QT_NO_DEBUG
43#endif
44#ifdef qDebug
45#undef qDebug
46#endif
47
48#include "qdebug.h"
49#include "qmetaobject.h"
50#include <private/qtextstream_p.h>
51#include <private/qtools_p.h>
52
53QT_BEGIN_NAMESPACE
54
55using QtMiscUtils::toHexUpper;
56using QtMiscUtils::fromHex;
57
58// This file is needed to force compilation of QDebug into the kernel library.
59
60/*!
61 \class QDebug
62 \inmodule QtCore
63 \ingroup shared
64
65 \brief The QDebug class provides an output stream for debugging information.
66
67 QDebug is used whenever the developer needs to write out debugging or tracing
68 information to a device, file, string or console.
69
70 \section1 Basic Use
71
72 In the common case, it is useful to call the qDebug() function to obtain a
73 default QDebug object to use for writing debugging information.
74
75 \snippet qdebug/qdebugsnippet.cpp 1
76
77 This constructs a QDebug object using the constructor that accepts a QtMsgType
78 value of QtDebugMsg. Similarly, the qWarning(), qCritical() and qFatal()
79 functions also return QDebug objects for the corresponding message types.
80
81 The class also provides several constructors for other situations, including
82 a constructor that accepts a QFile or any other QIODevice subclass that is
83 used to write debugging information to files and other devices. The constructor
84 that accepts a QString is used to write to a string for display or serialization.
85
86 \section1 Formatting Options
87
88 QDebug formats output so that it's easily readable. It automatically adds spaces
89 between arguments, and adds quotes around QString, QByteArray, QChar arguments.
90
91 You can tweak these options through the space(), nospace() and quote(), noquote()
92 methods. Furthermore, \l{QTextStream manipulators} can be piped into a QDebug
93 stream.
94
95 QDebugStateSaver limits changes to the formatting to the current scope.
96 resetFormat() resets the options to the default ones.
97
98 \section1 Writing Custom Types to a Stream
99
100 Many standard types can be written to QDebug objects, and Qt provides support for
101 most Qt value types. To add support for custom types, you need to implement a
102 streaming operator, as in the following example:
103
104 \snippet qdebug/qdebugsnippet.cpp 0
105
106 This is described in the \l{Debugging Techniques} and
107 \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
108 documents.
109*/
110
111/*!
112 \fn QDebug::QDebug(QIODevice *device)
113
114 Constructs a debug stream that writes to the given \a device.
115*/
116
117/*!
118 \fn QDebug::QDebug(QString *string)
119
120 Constructs a debug stream that writes to the given \a string.
121*/
122
123/*!
124 \fn QDebug::QDebug(QtMsgType t)
125
126 Constructs a debug stream that writes to the handler for the message type \a t.
127*/
128
129/*!
130 \fn QDebug::QDebug(const QDebug &o)
131
132 Constructs a copy of the other debug stream \a o.
133*/
134
135/*!
136 \fn QDebug &QDebug::operator=(const QDebug &other)
137
138 Assigns the \a other debug stream to this stream and returns a reference to
139 this stream.
140*/
141
142/*!
143 \fn QDebug::~QDebug()
144
145 Flushes any pending data to be written and destroys the debug stream.
146*/
147// Has been defined in the header / inlined before Qt 5.4
148QDebug::~QDebug()
149{
150 if (stream && !--stream->ref) {
151 if (stream->space && stream->buffer.endsWith(c: QLatin1Char(' ')))
152 stream->buffer.chop(n: 1);
153 if (stream->message_output) {
154 qt_message_output(stream->type,
155 context: stream->context,
156 message: stream->buffer);
157 }
158 delete stream;
159 }
160}
161
162/*!
163 \internal
164*/
165void QDebug::putUcs4(uint ucs4)
166{
167 maybeQuote(c: '\'');
168 if (ucs4 < 0x20) {
169 stream->ts << "\\x" << Qt::hex << ucs4 << Qt::reset;
170 } else if (ucs4 < 0x80) {
171 stream->ts << char(ucs4);
172 } else {
173 if (ucs4 < 0x10000)
174 stream->ts << "\\u" << qSetFieldWidth(width: 4);
175 else
176 stream->ts << "\\U" << qSetFieldWidth(width: 8);
177 stream->ts << Qt::hex << qSetPadChar(ch: QLatin1Char('0')) << ucs4 << Qt::reset;
178 }
179 maybeQuote(c: '\'');
180}
181
182// These two functions return true if the character should be printed by QDebug.
183// For QByteArray, this is technically identical to US-ASCII isprint();
184// for QString, we use QChar::isPrint, which requires a full UCS-4 decode.
185static inline bool isPrintable(uint ucs4)
186{ return QChar::isPrint(ucs4); }
187static inline bool isPrintable(ushort uc)
188{ return QChar::isPrint(ucs4: uc); }
189static inline bool isPrintable(uchar c)
190{ return c >= ' ' && c < 0x7f; }
191
192template <typename Char>
193static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, int length, bool isUnicode = true)
194{
195 QChar quote(QLatin1Char('"'));
196 d->write(data: &quote, len: 1);
197
198 bool lastWasHexEscape = false;
199 const Char *end = begin + length;
200 for (const Char *p = begin; p != end; ++p) {
201 // check if we need to insert "" to break an hex escape sequence
202 if (Q_UNLIKELY(lastWasHexEscape)) {
203 if (fromHex(*p) != -1) {
204 // yes, insert it
205 QChar quotes[] = { QLatin1Char('"'), QLatin1Char('"') };
206 d->write(data: quotes, len: 2);
207 }
208 lastWasHexEscape = false;
209 }
210
211 if (sizeof(Char) == sizeof(QChar)) {
212 // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them
213 int runLength = 0;
214 while (p + runLength != end &&
215 isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"')
216 ++runLength;
217 if (runLength) {
218 d->write(data: reinterpret_cast<const QChar *>(p), len: runLength);
219 p += runLength - 1;
220 continue;
221 }
222 } else if (isPrintable(*p) && *p != '\\' && *p != '"') {
223 QChar c = QLatin1Char(*p);
224 d->write(data: &c, len: 1);
225 continue;
226 }
227
228 // print as an escape sequence (maybe, see below for surrogate pairs)
229 int buflen = 2;
230 ushort buf[sizeof "\\U12345678" - 1];
231 buf[0] = '\\';
232
233 switch (*p) {
234 case '"':
235 case '\\':
236 buf[1] = *p;
237 break;
238 case '\b':
239 buf[1] = 'b';
240 break;
241 case '\f':
242 buf[1] = 'f';
243 break;
244 case '\n':
245 buf[1] = 'n';
246 break;
247 case '\r':
248 buf[1] = 'r';
249 break;
250 case '\t':
251 buf[1] = 't';
252 break;
253 default:
254 if (!isUnicode) {
255 // print as hex escape
256 buf[1] = 'x';
257 buf[2] = toHexUpper(value: uchar(*p) >> 4);
258 buf[3] = toHexUpper(value: uchar(*p));
259 buflen = 4;
260 lastWasHexEscape = true;
261 break;
262 }
263 if (QChar::isHighSurrogate(*p)) {
264 if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
265 // properly-paired surrogates
266 uint ucs4 = QChar::surrogateToUcs4(*p, p[1]);
267 if (isPrintable(ucs4)) {
268 buf[0] = *p;
269 buf[1] = p[1];
270 buflen = 2;
271 } else {
272 buf[1] = 'U';
273 buf[2] = '0'; // toHexUpper(ucs4 >> 32);
274 buf[3] = '0'; // toHexUpper(ucs4 >> 28);
275 buf[4] = toHexUpper(value: ucs4 >> 20);
276 buf[5] = toHexUpper(value: ucs4 >> 16);
277 buf[6] = toHexUpper(value: ucs4 >> 12);
278 buf[7] = toHexUpper(value: ucs4 >> 8);
279 buf[8] = toHexUpper(value: ucs4 >> 4);
280 buf[9] = toHexUpper(value: ucs4);
281 buflen = 10;
282 }
283 ++p;
284 break;
285 }
286 // improperly-paired surrogates, fall through
287 }
288 buf[1] = 'u';
289 buf[2] = toHexUpper(value: ushort(*p) >> 12);
290 buf[3] = toHexUpper(value: ushort(*p) >> 8);
291 buf[4] = toHexUpper(*p >> 4);
292 buf[5] = toHexUpper(*p);
293 buflen = 6;
294 }
295 d->write(data: reinterpret_cast<QChar *>(buf), len: buflen);
296 }
297
298 d->write(data: &quote, len: 1);
299}
300
301/*!
302 \internal
303 Duplicated from QtTest::toPrettyUnicode().
304*/
305void QDebug::putString(const QChar *begin, size_t length)
306{
307 if (stream->testFlag(flag: Stream::NoQuotes)) {
308 // no quotes, write the string directly too (no pretty-printing)
309 // this respects the QTextStream state, though
310 stream->ts.d_ptr->putString(data: begin, len: int(length));
311 } else {
312 // we'll reset the QTextStream formatting mechanisms, so save the state
313 QDebugStateSaver saver(*this);
314 stream->ts.d_ptr->params.reset();
315 putEscapedString(d: stream->ts.d_ptr.data(), begin: reinterpret_cast<const ushort *>(begin), length: int(length));
316 }
317}
318
319/*!
320 \internal
321 Duplicated from QtTest::toPrettyCString().
322*/
323void QDebug::putByteArray(const char *begin, size_t length, Latin1Content content)
324{
325 if (stream->testFlag(flag: Stream::NoQuotes)) {
326 // no quotes, write the string directly too (no pretty-printing)
327 // this respects the QTextStream state, though
328 QString string = content == ContainsLatin1 ? QString::fromLatin1(str: begin, size: int(length)) : QString::fromUtf8(str: begin, size: int(length));
329 stream->ts.d_ptr->putString(ch: string);
330 } else {
331 // we'll reset the QTextStream formatting mechanisms, so save the state
332 QDebugStateSaver saver(*this);
333 stream->ts.d_ptr->params.reset();
334 putEscapedString(d: stream->ts.d_ptr.data(), begin: reinterpret_cast<const uchar *>(begin),
335 length: int(length), isUnicode: content == ContainsLatin1);
336 }
337}
338
339/*!
340 \fn QDebug::swap(QDebug &other)
341 \since 5.0
342
343 Swaps this debug stream instance with \a other. This function is
344 very fast and never fails.
345*/
346
347/*!
348 Resets the stream formatting options, bringing it back to its original constructed state.
349
350 \sa space(), quote()
351 \since 5.4
352*/
353QDebug &QDebug::resetFormat()
354{
355 stream->ts.reset();
356 stream->space = true;
357 if (stream->context.version > 1)
358 stream->flags = 0;
359 stream->setVerbosity(DefaultVerbosity);
360 return *this;
361}
362
363/*!
364 \fn QDebug &QDebug::space()
365
366 Writes a space character to the debug stream and returns a reference to
367 the stream.
368
369 The stream remembers that automatic insertion of spaces is
370 enabled for future writes.
371
372 \sa nospace(), maybeSpace()
373*/
374
375/*!
376 \fn QDebug &QDebug::nospace()
377
378 Disables automatic insertion of spaces and returns a reference to the stream.
379
380 \sa space(), maybeSpace()
381*/
382
383/*!
384 \fn QDebug &QDebug::maybeSpace()
385
386 Writes a space character to the debug stream, depending on the current
387 setting for automatic insertion of spaces, and returns a reference to the stream.
388
389 \sa space(), nospace()
390*/
391
392/*!
393 \fn bool QDebug::autoInsertSpaces() const
394
395 Returns \c true if this QDebug instance will automatically insert spaces
396 between writes.
397
398 \since 5.0
399
400 \sa QDebugStateSaver
401*/
402
403/*!
404 \fn void QDebug::setAutoInsertSpaces(bool b)
405
406 Enables automatic insertion of spaces between writes if \a b is true; otherwise
407 automatic insertion of spaces is disabled.
408
409 \since 5.0
410
411 \sa QDebugStateSaver
412*/
413
414
415/*!
416 \fn QDebug &QDebug::quote()
417 \since 5.4
418
419 Enables automatic insertion of quotation characters around QChar, QString and QByteArray
420 contents and returns a reference to the stream.
421
422 Quoting is enabled by default.
423
424 \sa noquote(), maybeQuote()
425*/
426
427/*!
428 \fn QDebug &QDebug::noquote()
429 \since 5.4
430
431 Disables automatic insertion of quotation characters around QChar, QString and QByteArray
432 contents and returns a reference to the stream.
433
434 When quoting is disabled, these types are printed without quotation
435 characters and without escaping of non-printable characters.
436
437 \sa quote(), maybeQuote()
438*/
439
440/*!
441 \fn QDebug &QDebug::maybeQuote(char c)
442 \since 5.4
443
444 Writes a character \a c to the debug stream, depending on the
445 current setting for automatic insertion of quotes, and returns a reference to the stream.
446
447 The default character is a double quote \c{"}.
448
449 \sa quote(), noquote()
450*/
451
452/*!
453 \fn int QDebug::verbosity() const
454 \since 5.6
455
456 Returns the verbosity of the debug stream.
457
458 Streaming operators can check the value to decide whether
459 verbose output is desired and print more information depending on the
460 level. Higher values indicate that more information is desired.
461
462 The allowed range is from 0 to 7. The default value is 2.
463
464 \sa setVerbosity(), VerbosityLevel
465*/
466
467/*!
468 \fn void QDebug::setVerbosity(int verbosityLevel)
469 \since 5.6
470
471 Sets the verbosity of the stream to \a verbosityLevel.
472
473 The allowed range is from 0 to 7. The default value is 2.
474
475 \sa verbosity(), VerbosityLevel
476*/
477
478/*!
479 \fn QDebug &QDebug::verbosity(int verbosityLevel)
480 \since 5.13
481
482 Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream.
483
484 The allowed range is from 0 to 7. The default value is 2.
485
486 \sa verbosity(), setVerbosity(), VerbosityLevel
487*/
488
489/*!
490 \enum QDebug::VerbosityLevel
491 \since 5.13
492
493 This enum describes the range of verbosity levels.
494
495 \value MinimumVerbosity
496 \value DefaultVerbosity
497 \value MaximumVerbosity
498
499 \sa verbosity(), setVerbosity()
500*/
501
502/*!
503 \fn QDebug &QDebug::operator<<(QChar t)
504
505 Writes the character, \a t, to the stream and returns a reference to the
506 stream. Normally, QDebug prints control characters and non-US-ASCII
507 characters as their C escape sequences or their Unicode value (\\u1234). To
508 print non-printable characters without transformation, enable the noquote()
509 functionality, but note that some QDebug backends may not be 8-bit clean
510 and may not be able to represent \c t.
511*/
512
513/*!
514 \fn QDebug &QDebug::operator<<(bool t)
515
516 Writes the boolean value, \a t, to the stream and returns a reference to the
517 stream.
518*/
519
520/*!
521 \fn QDebug &QDebug::operator<<(char t)
522
523 Writes the character, \a t, to the stream and returns a reference to the
524 stream.
525*/
526
527/*!
528 \fn QDebug &QDebug::operator<<(signed short t)
529
530 Writes the signed short integer, \a t, to the stream and returns a reference
531 to the stream.
532*/
533
534/*!
535 \fn QDebug &QDebug::operator<<(unsigned short t)
536
537 Writes then unsigned short integer, \a t, to the stream and returns a
538 reference to the stream.
539*/
540
541/*!
542 \fn QDebug &QDebug::operator<<(signed int t)
543
544 Writes the signed integer, \a t, to the stream and returns a reference
545 to the stream.
546*/
547
548/*!
549 \fn QDebug &QDebug::operator<<(unsigned int t)
550
551 Writes then unsigned integer, \a t, to the stream and returns a reference to
552 the stream.
553*/
554
555/*!
556 \fn QDebug &QDebug::operator<<(signed long t)
557
558 Writes the signed long integer, \a t, to the stream and returns a reference
559 to the stream.
560*/
561
562/*!
563 \fn QDebug &QDebug::operator<<(unsigned long t)
564
565 Writes then unsigned long integer, \a t, to the stream and returns a reference
566 to the stream.
567*/
568
569/*!
570 \fn QDebug &QDebug::operator<<(qint64 t)
571
572 Writes the signed 64-bit integer, \a t, to the stream and returns a reference
573 to the stream.
574*/
575
576/*!
577 \fn QDebug &QDebug::operator<<(quint64 t)
578
579 Writes then unsigned 64-bit integer, \a t, to the stream and returns a
580 reference to the stream.
581*/
582
583/*!
584 \fn QDebug &QDebug::operator<<(float t)
585
586 Writes the 32-bit floating point number, \a t, to the stream and returns a
587 reference to the stream.
588*/
589
590/*!
591 \fn QDebug &QDebug::operator<<(double t)
592
593 Writes the 64-bit floating point number, \a t, to the stream and returns a
594 reference to the stream.
595*/
596
597/*!
598 \fn QDebug &QDebug::operator<<(const char *t)
599
600 Writes the '\\0'-terminated string, \a t, to the stream and returns a
601 reference to the stream. The string is never quoted nor transformed to the
602 output, but note that some QDebug backends might not be 8-bit clean.
603*/
604
605/*!
606 \fn QDebug &QDebug::operator<<(char16_t t)
607 \since 5.5
608
609 Writes the UTF-16 character, \a t, to the stream and returns a reference
610 to the stream.
611*/
612
613/*!
614 \fn QDebug &QDebug::operator<<(char32_t t)
615 \since 5.5
616
617 Writes the UTF-32 character, \a t, to the stream and returns a reference
618 to the stream.
619*/
620
621/*!
622 \fn QDebug &QDebug::operator<<(const QString &t)
623
624 Writes the string, \a t, to the stream and returns a reference to the
625 stream. Normally, QDebug prints the string inside quotes and transforms
626 non-printable characters to their Unicode values (\\u1234).
627
628 To print non-printable characters without transformation, enable the
629 noquote() functionality. Note that some QDebug backends might not be 8-bit
630 clean.
631
632 Output examples:
633 \snippet code/src_corelib_io_qdebug.cpp 0
634*/
635
636/*!
637 \fn QDebug &QDebug::operator<<(const QStringRef &t)
638
639 Writes the string, \a t, to the stream and returns a reference to the
640 stream. Normally, QDebug prints the string inside quotes and transforms
641 non-printable characters to their Unicode values (\\u1234).
642
643 To print non-printable characters without transformation, enable the
644 noquote() functionality. Note that some QDebug backends might not be 8-bit
645 clean.
646
647 See the QString overload for examples.
648*/
649
650/*!
651 \since 5.10
652 \fn QDebug &QDebug::operator<<(QStringView s)
653
654 Writes the string view, \a s, to the stream and returns a reference to the
655 stream. Normally, QDebug prints the string inside quotes and transforms
656 non-printable characters to their Unicode values (\\u1234).
657
658 To print non-printable characters without transformation, enable the
659 noquote() functionality. Note that some QDebug backends might not be 8-bit
660 clean.
661
662 See the QString overload for examples.
663*/
664
665/*!
666 \fn QDebug &QDebug::operator<<(QLatin1String t)
667
668 Writes the string, \a t, to the stream and returns a reference to the
669 stream. Normally, QDebug prints the string inside quotes and transforms
670 non-printable characters to their Unicode values (\\u1234).
671
672 To print non-printable characters without transformation, enable the
673 noquote() functionality. Note that some QDebug backends might not be 8-bit
674 clean.
675
676 See the QString overload for examples.
677*/
678
679/*!
680 \fn QDebug &QDebug::operator<<(const QByteArray &t)
681
682 Writes the byte array, \a t, to the stream and returns a reference to the
683 stream. Normally, QDebug prints the array inside quotes and transforms
684 control or non-US-ASCII characters to their C escape sequences (\\xAB). This
685 way, the output is always 7-bit clean and the string can be copied from the
686 output and pasted back into C++ sources, if necessary.
687
688 To print non-printable characters without transformation, enable the
689 noquote() functionality. Note that some QDebug backends might not be 8-bit
690 clean.
691
692 Output examples:
693 \snippet code/src_corelib_io_qdebug.cpp 1
694
695 Note how QDebug needed to close and reopen the string in the way C and C++
696 languages concatenate string literals so that the letter 'b' is not
697 interpreted as part of the previous hexadecimal escape sequence.
698*/
699
700/*!
701 \fn QDebug &QDebug::operator<<(const void *t)
702
703 Writes a pointer, \a t, to the stream and returns a reference to the stream.
704*/
705
706/*!
707 \fn QDebug &QDebug::operator<<(QTextStreamFunction f)
708 \internal
709*/
710
711/*!
712 \fn QDebug &QDebug::operator<<(QTextStreamManipulator m)
713 \internal
714*/
715
716/*!
717 \fn template <class T> QDebug operator<<(QDebug debug, const QList<T> &list)
718 \relates QDebug
719
720 Writes the contents of \a list to \a debug. \c T needs to
721 support streaming into QDebug.
722*/
723
724/*!
725 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec)
726 \relates QDebug
727 \since 5.7
728
729 Writes the contents of list \a vec to \a debug. \c T needs to
730 support streaming into QDebug.
731*/
732
733/*!
734 \fn template <typename T> QDebug operator<<(QDebug debug, const QVector<T> &vec)
735 \relates QDebug
736
737 Writes the contents of vector \a vec to \a debug. \c T needs to
738 support streaming into QDebug.
739*/
740
741/*!
742 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
743 \relates QDebug
744 \since 5.7
745
746 Writes the contents of vector \a vec to \a debug. \c T needs to
747 support streaming into QDebug.
748*/
749
750/*!
751 \fn template <typename T> QDebug operator<<(QDebug debug, const QSet<T> &set)
752 \relates QDebug
753
754 Writes the contents of \a set to \a debug. \c T needs to
755 support streaming into QDebug.
756*/
757
758/*!
759 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMap<Key, T> &map)
760 \relates QDebug
761
762 Writes the contents of \a map to \a debug. Both \c Key and
763 \c T need to support streaming into QDebug.
764*/
765
766/*!
767 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
768 \relates QDebug
769 \since 5.7
770
771 Writes the contents of \a map to \a debug. Both \c Key and
772 \c T need to support streaming into QDebug.
773*/
774
775/*!
776 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
777 \relates QDebug
778 \since 5.7
779
780 Writes the contents of \a map to \a debug. Both \c Key and
781 \c T need to support streaming into QDebug.
782*/
783
784/*!
785 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
786 \relates QDebug
787
788 Writes the contents of \a hash to \a debug. Both \c Key and
789 \c T need to support streaming into QDebug.
790*/
791
792/*!
793 \fn template <class T1, class T2> QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair)
794 \relates QDebug
795
796 Writes the contents of \a pair to \a debug. Both \c T1 and
797 \c T2 need to support streaming into QDebug.
798*/
799
800/*!
801 \fn template<typename T> QDebug operator<<(QDebug debug, const QFlags<T> &flags)
802 \relates QDebug
803 \since 4.7
804
805 Writes \a flags to \a debug.
806*/
807
808/*!
809 \fn template<typename T> QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
810 \relates QSharedPointer
811 \since 5.7
812
813 Writes the pointer tracked by \a ptr into the debug object \a debug for
814 debugging purposes.
815
816 \sa {Debugging Techniques}
817*/
818
819/*!
820 \fn QDebug &QDebug::operator<<(std::nullptr_t)
821 \internal
822 */
823
824/*!
825 \class QDebugStateSaver
826 \inmodule QtCore
827 \brief Convenience class for custom QDebug operators.
828
829 Saves the settings used by QDebug, and restores them upon destruction,
830 then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if
831 \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver.
832
833 The automatic insertion of spaces between writes is one of the settings
834 that QDebugStateSaver stores for the duration of the current block.
835
836 The settings of the internal QTextStream are also saved and restored,
837 so that using << Qt::hex in a QDebug operator doesn't affect other QDebug
838 operators.
839
840 \since 5.1
841*/
842
843class QDebugStateSaverPrivate
844{
845public:
846 QDebugStateSaverPrivate(QDebug::Stream *stream)
847 : m_stream(stream),
848 m_spaces(stream->space),
849 m_flags(stream->context.version > 1 ? stream->flags : 0),
850 m_streamParams(stream->ts.d_ptr->params)
851 {
852 }
853 void restoreState()
854 {
855 const bool currentSpaces = m_stream->space;
856 if (currentSpaces && !m_spaces)
857 if (m_stream->buffer.endsWith(c: QLatin1Char(' ')))
858 m_stream->buffer.chop(n: 1);
859
860 m_stream->space = m_spaces;
861 m_stream->ts.d_ptr->params = m_streamParams;
862 if (m_stream->context.version > 1)
863 m_stream->flags = m_flags;
864
865 if (!currentSpaces && m_spaces)
866 m_stream->ts << ' ';
867 }
868
869 QDebug::Stream *m_stream;
870
871 // QDebug state
872 const bool m_spaces;
873 const int m_flags;
874
875 // QTextStream state
876 const QTextStreamPrivate::Params m_streamParams;
877};
878
879
880/*!
881 Creates a QDebugStateSaver instance, which saves the settings
882 currently used by \a dbg.
883
884 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
885*/
886QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
887 : d(new QDebugStateSaverPrivate(dbg.stream))
888{
889}
890
891/*!
892 Destroys a QDebugStateSaver instance, which restores the settings
893 used when the QDebugStateSaver instance was created.
894
895 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
896*/
897QDebugStateSaver::~QDebugStateSaver()
898{
899 d->restoreState();
900}
901
902/*!
903 \internal
904
905 Specialization of the primary template in qdebug.h to out-of-line
906 the common case of QFlags<T>::Int being int.
907
908 Just call the generic version so the two don't get out of sync.
909*/
910void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
911{
912 qt_QMetaEnum_flagDebugOperator<int>(debug, sizeofT, value);
913}
914
915#ifndef QT_NO_QOBJECT
916/*!
917 \fn QDebug qt_QMetaEnum_debugOperator(QDebug &, int value, const QMetaObject *, const char *name)
918 \internal
919
920 Formats the given enum \a value for debug output.
921
922 The supported verbosity are:
923
924 0: Just the key, or value with enum name if no key is found:
925
926 MyEnum2
927 MyEnum(123)
928 MyScopedEnum::Enum3
929 MyScopedEnum(456)
930
931 1: Same as 0, but treating all enums as scoped:
932
933 MyEnum::MyEnum2
934 MyEnum(123)
935 MyScopedEnum::Enum3
936 MyScopedEnum(456)
937
938 2: The QDebug default. Same as 0, and includes class/namespace scope:
939
940 MyNamespace::MyClass::MyEnum2
941 MyNamespace::MyClass::MyEnum(123)
942 MyNamespace::MyClass::MyScopedEnum::Enum3
943 MyNamespace::MyClass::MyScopedEnum(456)
944
945 3: Same as 2, but treating all enums as scoped:
946
947 MyNamespace::MyClass::MyEnum::MyEnum2
948 MyNamespace::MyClass::MyEnum(123)
949 MyNamespace::MyClass::MyScopedEnum::Enum3
950 MyNamespace::MyClass::MyScopedEnum(456)
951 */
952QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name)
953{
954 QDebugStateSaver saver(dbg);
955 dbg.nospace();
956 QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
957
958 const int verbosity = dbg.verbosity();
959 if (verbosity >= QDebug::DefaultVerbosity) {
960 if (const char *scope = me.scope())
961 dbg << scope << "::";
962 }
963
964 const char *key = me.valueToKey(value);
965 const bool scoped = me.isScoped() || verbosity & 1;
966 if (scoped || !key)
967 dbg << me.enumName() << (!key ? "(" : "::");
968
969 if (key)
970 dbg << key;
971 else
972 dbg << value << ")";
973
974 return dbg;
975}
976
977/*!
978 \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name)
979 \internal
980
981 Formats the given flag \a value for debug output.
982
983 The supported verbosity are:
984
985 0: Just the key(s):
986
987 MyFlag1
988 MyFlag2|MyFlag3
989 MyScopedFlag(MyFlag2)
990 MyScopedFlag(MyFlag2|MyFlag3)
991
992 1: Same as 0, but treating all flags as scoped:
993
994 MyFlag(MyFlag1)
995 MyFlag(MyFlag2|MyFlag3)
996 MyScopedFlag(MyFlag2)
997 MyScopedFlag(MyFlag2|MyFlag3)
998
999 2: The QDebug default. Same as 1, and includes class/namespace scope:
1000
1001 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1)
1002 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)
1003 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)
1004 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)
1005 */
1006QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name)
1007{
1008 const int verbosity = debug.verbosity();
1009
1010 QDebugStateSaver saver(debug);
1011 debug.resetFormat();
1012 debug.noquote();
1013 debug.nospace();
1014
1015 const QMetaEnum me = meta->enumerator(index: meta->indexOfEnumerator(name));
1016
1017 const bool classScope = verbosity >= QDebug::DefaultVerbosity;
1018 if (classScope) {
1019 debug << "QFlags<";
1020
1021 if (const char *scope = me.scope())
1022 debug << scope << "::";
1023 }
1024
1025 const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
1026 if (enumScope) {
1027 debug << me.enumName();
1028 if (classScope)
1029 debug << ">";
1030 debug << "(";
1031 }
1032
1033 debug << me.valueToKeys(value);
1034
1035 if (enumScope)
1036 debug << ')';
1037
1038 return debug;
1039}
1040#endif // !QT_NO_QOBJECT
1041
1042QT_END_NAMESPACE
1043

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