summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>2014-11-10 11:17:28 +0100
committerTor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>2015-01-18 19:59:27 +0100
commitb2883a6acc7a8d8372a815cc91dd1a8449f25723 (patch)
tree79a8284b7d18306f71daf9a27ee4b2d588c787f5 /src/corelib
parentb8e46fce5c70c399c615e1b846076f379db173c5 (diff)
Add QDebug support for NSObject and a few selected CoreFoundation types
Lets us print out the interface name in addition to the address when doing: qDebug() << myNSObject; Unfortunately, CFTypeRef is just a typedef to void*, so we can't add a generic overload for CFTypeRef. For now, we provide operators for commonly used Core Foundation and Core Graphics types. Additional types may be added using Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE. Change-Id: I27b12ef9e62cb1be348b9771cb31657692903f6c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qdebug.h76
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm34
2 files changed, 110 insertions, 0 deletions
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 2f487b8a1f..27abf2a740 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -281,6 +281,82 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
return debug;
}
+#ifdef Q_OS_MAC
+
+// We provide QDebug stream operators for commonly used Core Foundation
+// and Core Graphics types, as well as NSObject. Additional CF/CG types
+// may be added by the user, using Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE.
+
+#define QT_FOR_EACH_CORE_FOUNDATION_TYPE(F) \
+ F(CFArray) \
+ F(CFURL) \
+ F(CFData) \
+ F(CFNumber) \
+ F(CFDictionary) \
+ F(CFLocale) \
+ F(CFDate) \
+ F(CFBoolean) \
+ F(CFTimeZone) \
+
+#define QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(F) \
+ F(CFError) \
+ F(CFBundle) \
+
+#define QT_FOR_EACH_CORE_GRAPHICS_TYPE(F) \
+ F(CGPath) \
+
+#define QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(F) \
+ F(CGColorSpace) \
+ F(CGImage) \
+ F(CGFont) \
+ F(CGColor) \
+
+#define QT_FORWARD_DECLARE_CF_TYPE(type) Q_FORWARD_DECLARE_CF_TYPE(type);
+#define QT_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type);
+#define QT_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type ## Ref;
+#define QT_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type ## Ref;
+
+QT_END_NAMESPACE
+Q_FORWARD_DECLARE_CF_TYPE(CFString);
+Q_FORWARD_DECLARE_OBJC_CLASS(NSObject);
+QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_MUTABLE_CF_TYPE);
+QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_CG_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_MUTABLE_CG_TYPE);
+QT_BEGIN_NAMESPACE
+
+#define QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
+ Q_CORE_EXPORT QDebug operator<<(QDebug, CFType##Ref);
+
+#define Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
+ QDebug operator<<(QDebug debug, CFType##Ref ref) \
+ { \
+ if (!ref) \
+ return debug << QT_STRINGIFY(CFType) "Ref(0x0)"; \
+ if (CFStringRef description = CFCopyDescription(ref)) { \
+ QDebugStateSaver saver(debug); \
+ debug.noquote() << description; \
+ CFRelease(description); \
+ } \
+ return debug; \
+ }
+
+// Defined in qcore_mac_objc.mm
+Q_CORE_EXPORT QDebug operator<<(QDebug, const NSObject *);
+Q_CORE_EXPORT QDebug operator<<(QDebug, CFStringRef);
+
+QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+
+#undef QT_FORWARD_DECLARE_CF_TYPE
+#undef QT_FORWARD_DECLARE_MUTABLE_CF_TYPE
+#undef QT_FORWARD_DECLARE_CG_TYPE
+#undef QT_FORWARD_DECLARE_MUTABLE_CG_TYPE
+
+#endif // Q_OS_MAC
+
QT_END_NAMESPACE
#endif // QDEBUG_H
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 8ac062a154..265126dc58 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -42,6 +42,8 @@
#include <private/qcore_mac_p.h>
+#include <qdebug.h>
+
#ifdef Q_OS_IOS
#import <UIKit/UIKit.h>
#endif
@@ -61,6 +63,38 @@ QString QCFString::toQString(const NSString *nsstr)
return toQString(reinterpret_cast<CFStringRef>(nsstr));
}
+// -------------------------------------------------------------------------
+
+QDebug operator<<(QDebug dbg, const NSObject *nsObject)
+{
+ return dbg << (nsObject ? nsObject.description.UTF8String : "NSObject(0x0)");
+}
+
+QDebug operator<<(QDebug dbg, CFStringRef stringRef)
+{
+ if (!stringRef)
+ return dbg << "CFStringRef(0x0)";
+
+ if (const UniChar *chars = CFStringGetCharactersPtr(stringRef))
+ dbg << QString::fromRawData(reinterpret_cast<const QChar *>(chars), CFStringGetLength(stringRef));
+ else
+ dbg << QString::fromCFString(stringRef);
+
+ return dbg;
+}
+
+// Prevents breaking the ODR in case we introduce support for more types
+// later on, and lets the user override our default QDebug operators.
+#define QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
+ __attribute__((weak)) Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType)
+
+QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TYPE);
+
+// -------------------------------------------------------------------------
+
QAppleOperatingSystemVersion qt_apple_os_version()
{
QAppleOperatingSystemVersion v = {0, 0, 0};