1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
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 The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <cstdio> |
30 | |
31 | #include <QBuffer> |
32 | #include <QStringList> |
33 | #include <QtDebug> |
34 | #include <QtTest> |
35 | #include <QtGlobal> |
36 | #include <QXmlQuery> |
37 | #include <QXmlResultItems> |
38 | |
39 | #include "ErrorHandler.h" |
40 | |
41 | using namespace QPatternistSDK; |
42 | |
43 | ErrorHandler *ErrorHandler::handler = 0; |
44 | |
45 | void qMessageHandler(QtMsgType type, const QMessageLogContext &, const QString &description) |
46 | { |
47 | if(type == QtDebugMsg) |
48 | { |
49 | std::fprintf(stderr, format: "%s\n" , qPrintable(description)); |
50 | return; |
51 | } |
52 | |
53 | QtMsgType t; |
54 | |
55 | switch(type) |
56 | { |
57 | case QtWarningMsg: |
58 | { |
59 | t = QtWarningMsg; |
60 | break; |
61 | } |
62 | case QtCriticalMsg: |
63 | { |
64 | t = QtFatalMsg; |
65 | break; |
66 | } |
67 | case QtFatalMsg: |
68 | { |
69 | /* We can't swallow Q_ASSERTs, we need to fail the hard way here. |
70 | * But maybe not: when run from "patternistrunsingle" it could be an idea |
71 | * to actually try to record it(but nevertheless fail somehow) such |
72 | * that it gets reported. */ |
73 | std::fprintf(stderr, format: "Fatal error: %s\n" , qPrintable(description)); |
74 | t = QtFatalMsg; /* Dummy, to silence a bogus compiler warning. */ |
75 | return; |
76 | } |
77 | case QtDebugMsg: /* This enum is handled above in the if-clause. */ |
78 | /* Fallthrough. */ |
79 | default: |
80 | { |
81 | Q_ASSERT(false); |
82 | return; |
83 | } |
84 | } |
85 | |
86 | Q_ASSERT(ErrorHandler::handler); |
87 | /* This message is hacky. Ideally, we should do it the same way |
88 | * ReportContext::error() constructs messages, but this is just testing |
89 | * code. */ |
90 | ErrorHandler::handler->message(type: t, description: QLatin1String("<p>" ) + QPatternist::escape(input: description) + QLatin1String("</p>" )); |
91 | } |
92 | |
93 | void ErrorHandler::installQtMessageHandler(ErrorHandler *const h) |
94 | { |
95 | handler = h; |
96 | |
97 | if(h) |
98 | qInstallMessageHandler(qMessageHandler); |
99 | else |
100 | qInstallMessageHandler(0); |
101 | } |
102 | |
103 | void ErrorHandler::handleMessage(QtMsgType type, |
104 | const QString &description, |
105 | const QUrl &identifier, |
106 | const QSourceLocation &) |
107 | { |
108 | /* Don't use pDebug() in this function, it results in infinite |
109 | * recursion. Talking from experience.. */ |
110 | |
111 | Message msg; |
112 | msg.setType(type); |
113 | msg.setIdentifier(identifier); |
114 | |
115 | /* Let's remove all the XHTML markup. */ |
116 | QBuffer buffer; |
117 | buffer.setData(description.toLatin1()); |
118 | buffer.open(openMode: QIODevice::ReadOnly); |
119 | |
120 | QXmlQuery query; |
121 | query.bindVariable(localName: QLatin1String("desc" ), &buffer); |
122 | query.setQuery(sourceCode: QLatin1String("string(doc($desc))" )); |
123 | |
124 | QStringList result; |
125 | const bool success = query.evaluateTo(target: &result); |
126 | |
127 | if(!description.startsWith(s: QLatin1String("\"Test-suite harness error:" ))) |
128 | { |
129 | const QString msg(QString::fromLatin1(str: "Invalid description: %1" ).arg(a: description)); |
130 | QVERIFY2(success, qPrintable(msg)); |
131 | |
132 | if(!success) |
133 | QTextStream(stderr) << msg; |
134 | } |
135 | |
136 | |
137 | if(!result.isEmpty()) |
138 | msg.setDescription(result.first()); |
139 | |
140 | m_messages.append(t: msg); |
141 | } |
142 | |
143 | ErrorHandler::Message::List ErrorHandler::messages() const |
144 | { |
145 | return m_messages; |
146 | } |
147 | |
148 | void ErrorHandler::reset() |
149 | { |
150 | m_messages.clear(); |
151 | } |
152 | |
153 | // vim: et:ts=4:sw=4:sts=4 |
154 | |