Qt 4.8
qsignaldumper.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtTest module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "QtTest/private/qsignaldumper_p.h"
43 
44 #include <QtCore/qlist.h>
45 #include <QtCore/qmetaobject.h>
46 #include <QtCore/qmetatype.h>
47 #include <QtCore/qobject.h>
48 #include <QtCore/qvariant.h>
49 
50 #include "QtTest/private/qtestlog_p.h"
51 
53 
54 namespace QTest
55 {
56 
57 inline static void qPrintMessage(const QByteArray &ba)
58 {
59  QTestLog::info(ba.constData(), 0, 0);
60 }
61 
62 Q_GLOBAL_STATIC(QList<QByteArray>, ignoreClasses)
63 static int iLevel = 0;
64 static int ignoreLevel = 0;
65 enum { IndentSpacesCount = 4 };
66 
67 static QByteArray memberName(const QMetaMethod &member)
68 {
69  QByteArray ba = member.signature();
70  return ba.left(ba.indexOf('('));
71 }
72 
73 static void qSignalDumperCallback(QObject *caller, int method_index, void **argv)
74 {
75  Q_ASSERT(caller); Q_ASSERT(argv); Q_UNUSED(argv);
76  const QMetaObject *mo = caller->metaObject();
77  Q_ASSERT(mo);
78  QMetaMethod member = mo->method(method_index);
79  Q_ASSERT(member.signature());
80 
81  if (QTest::ignoreClasses() && QTest::ignoreClasses()->contains(mo->className())) {
83  return;
84  }
85 
86  QByteArray str;
88  str += "Signal: ";
89  str += mo->className();
90  str += '(';
91 
92  QString objname = caller->objectName();
93  str += objname.toLocal8Bit();
94  if (!objname.isEmpty())
95  str += ' ';
96  str += QByteArray::number(quintptr(caller), 16);
97 
98  str += ") ";
99  str += QTest::memberName(member);
100  str += " (";
101 
102  QList<QByteArray> args = member.parameterTypes();
103  for (int i = 0; i < args.count(); ++i) {
104  const QByteArray &arg = args.at(i);
105  int typeId = QMetaType::type(args.at(i).constData());
106  if (arg.endsWith('*') || arg.endsWith('&')) {
107  str += '(';
108  str += arg;
109  str += ')';
110  if (arg.endsWith('&'))
111  str += '@';
112 
113  quintptr addr = quintptr(*reinterpret_cast<void **>(argv[i + 1]));
114  str.append(QByteArray::number(addr, 16));
115  } else if (typeId != QMetaType::Void) {
116  str.append(arg)
117  .append('(')
118  .append(QVariant(typeId, argv[i + 1]).toString().toLocal8Bit())
119  .append(')');
120  }
121  str.append(", ");
122  }
123  if (str.endsWith(", "))
124  str.chop(2);
125  str.append(')');
126  qPrintMessage(str);
127 }
128 
129 static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **argv)
130 {
131  Q_ASSERT(caller); Q_ASSERT(argv); Q_UNUSED(argv);
132  const QMetaObject *mo = caller->metaObject();
133  Q_ASSERT(mo);
134  QMetaMethod member = mo->method(method_index);
135  if (!member.signature())
136  return;
137 
138  if (QTest::ignoreLevel ||
139  (QTest::ignoreClasses() && QTest::ignoreClasses()->contains(mo->className())))
140  return;
141 
142  QByteArray str;
144  str += "Slot: ";
145  str += mo->className();
146  str += '(';
147 
148  QString objname = caller->objectName();
149  str += objname.toLocal8Bit();
150  if (!objname.isEmpty())
151  str += ' ';
152  str += QByteArray::number(quintptr(caller), 16);
153 
154  str += ") ";
155  str += member.signature();
156  qPrintMessage(str);
157 }
158 
159 static void qSignalDumperCallbackEndSignal(QObject *caller, int /*method_index*/)
160 {
161  Q_ASSERT(caller); Q_ASSERT(caller->metaObject());
162  if (QTest::ignoreClasses()
163  && QTest::ignoreClasses()->contains(caller->metaObject()->className())) {
166  return;
167  }
168  --QTest::iLevel;
169  Q_ASSERT(QTest::iLevel >= 0);
170 }
171 
172 }
173 
174 // this struct is copied from qobject_p.h to prevent us
175 // from including private Qt headers.
177 {
178  typedef void (*BeginCallback)(QObject *caller, int method_index, void **argv);
179  typedef void (*EndCallback)(QObject *caller, int method_index);
180  BeginCallback signal_begin_callback,
181  slot_begin_callback;
182  EndCallback signal_end_callback,
183  slot_end_callback;
184 };
186 
188 {
192 }
193 
195 {
196  static QSignalSpyCallbackSet nset = { 0, 0, 0 ,0 };
198 }
199 
201 {
202  if (QTest::ignoreClasses())
203  QTest::ignoreClasses()->append(klass);
204 }
205 
207 {
208  if (QTest::ignoreClasses())
209  QTest::ignoreClasses()->clear();
210 }
211 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &)
void chop(int n)
Removes n bytes from the end of the byte array.
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
QByteArray & fill(char c, int size=-1)
Sets every byte in the byte array to character ch.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static void clearIgnoredClasses()
QByteArray & append(char c)
Appends the character ch to this byte array.
QString objectName
the name of this object
Definition: qobject.h:114
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static void startDump()
static void qSignalDumperCallbackEndSignal(QObject *caller, int)
static void qPrintMessage(const QByteArray &ba)
static int iLevel
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
char * toString(const QLatin1String &str)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qtest.h:73
static int ignoreLevel
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
static int type(const char *typeName)
Returns a handle to the type called typeName, or 0 if there is no such type.
Definition: qmetatype.cpp:607
static void ignoreClass(const QByteArray &klass)
static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **argv)
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QList< QByteArray > parameterTypes() const
Returns a list of parameter types.
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
static void qSignalDumperCallback(QObject *caller, int method_index, void **argv)
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
static QByteArray memberName(const QMetaMethod &member)
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
const char * signature() const
Returns the signature of this method (e.g., setValue(double)).
static void info(const char *msg, const char *file, int line)
Definition: qtestlog.cpp:340
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
static QByteArray number(int, int base=10)
Returns a byte array containing the string equivalent of the number n to base base (10 by default)...
The QTest namespace contains all the functions and declarations that are related to the QTestLib tool...
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
static void endDump()
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...