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>
This commit is contained in:
parent
b8e46fce5c
commit
b2883a6acc
@ -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
|
||||
|
@ -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};
|
||||
|
Loading…
x
Reference in New Issue
Block a user