1
/****************************************************************************
2
** VgLogReader implementation
3
** - reads valgrind xml log into a VgLog
4
** --------------------------------------------------------------------------
6
** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved.
7
** <info@open-works.co.uk>
9
** This file is part of Valkyrie, a front-end for Valgrind.
11
** This file may be used under the terms of the GNU General Public
12
** License version 2.0 as published by the Free Software Foundation
13
** and appearing in the file COPYING included in the packaging of
16
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
17
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
****************************************************************************/
21
#include "utils/vglogreader.h"
22
#include "utils/vk_utils.h"
25
/**********************************************************************/
29
VgLogReader::VgLogReader( VgLogView* lv )
30
: vghandler( 0 ), source( 0 )
32
vghandler = new VgLogHandler( lv );
33
setContentHandler( vghandler );
34
setErrorHandler( vghandler );
35
// setLexicalHandler( vghandler );
36
// setDeclHandler( vghandler );
37
// setDTDHandler( vghandler );
40
VgLogReader::~VgLogReader()
42
if ( vghandler != 0 ) {
52
if ( file.isOpen() ) {
57
bool VgLogReader::parse( QString filepath, bool incremental/*=false*/ )
63
if ( file.isOpen() ) {
67
file.setFileName( filepath );
68
source = new QXmlInputSource( &file );
69
return QXmlSimpleReader::parse( source, incremental );
72
bool VgLogReader::parseContinue()
78
return QXmlSimpleReader::parseContinue();
82
/**********************************************************************/
84
VgLogHandler::VgLogHandler( VgLogView* lv )
92
VgLogHandler::~VgLogHandler()
95
/* gets <?xml...> element */
96
bool VgLogHandler::processingInstruction( const QString& target, const QString& data )
98
// vkPrintErr("VgLogHandler::processingInstruction: %s, %s", target.latin1(), data.latin1());
99
doc.appendChild( doc.createProcessingInstruction( target, data ) );
104
bool VgLogHandler::startElement( const QString&, const QString&,
106
const QXmlAttributes& )
108
// vkPrintErr("VgLogHandler::startElement: '%s'", tag.latin1());
109
QDomNode n = doc.createElement( tag );
110
node.appendChild( n );
113
if ( node == doc.documentElement() ) {
114
QDomProcessingInstruction xml_insn =
115
doc.firstChild().toProcessingInstruction();
116
if ( ! logview->init( xml_insn, tag ) ) {
117
//VK_DEBUG("Error: Failed log initialisation");
125
bool VgLogHandler::endElement( const QString&, const QString&,
126
const QString& /*tag*/ )
128
// vkPrintErr("VgLogHandler::endElement: %s", qPrintable( tag ));
129
// Should never have end element at doc level
131
//VK_DEBUG("VgLogHandler::endElement(): Error: node == doc");
135
QDomNode prnt = node.parentNode();
137
/* if closing a top-level tag, append to vglog */
138
if ( prnt == doc.documentElement() ) {
140
if ( ! logview->appendNode( node, errMsg ) ) {
141
//VK_DEBUG("Failed to append node");
150
/* In case we get bad xml after the closing tag, mark as 'finished'
151
This may happed, for example, as a result of doing fork() but
152
not exec() under valgrind. When the process forks, you wind up
153
with 2 V's attached to the same logfile, which doesn't get
154
sorted out until the child does exec().
162
bool VgLogHandler::characters( const QString& ch )
164
// vkPrintErr("characters: '%s'", ch.latin1());
165
// No text as child of some document
170
/* ignore text as child of doc_elem
171
=> valgrind non-xml output (shouldn't happen), or client output */
172
if ( node == doc.documentElement() ) {
176
QString chars = ch.simplified();
178
if ( !chars.isEmpty() ) {
179
node.appendChild( doc.createTextNode( chars ) );
180
// vkPrintErr("chars: '%s'", chars.latin1());
186
/* Called by xml reader at start of parsing */
187
bool VgLogHandler::startDocument()
189
// vkPrintErr("VgLogHandler::startDocument()\n");
190
vk_assert( logview != 0 );
192
doc = QDomDocument();
194
m_fatalMsg = QString();
200
/* Called by xml reader after it has finished parsing
201
Checks we have a complete document,
202
i.e. endElement() has returned node ptr to root
204
bool VgLogHandler::endDocument()
206
// vkPrintErr("VgLogHandler::endDocument()\n");
216
/* non-fatal error: just report it */
217
bool VgLogHandler::error( const QXmlParseException& exception )
219
// vkPrintErr("VgLogHandler::error");
220
QString err = exception.message() +
221
" (line: " + QString::number( exception.lineNumber() ) +
222
", col: " + QString::number( exception.columnNumber() ) + ")";
224
// printf("VgLogHandler::non-fatal error: %s", err.latin1());
226
return true; /* try to continue. */
229
bool VgLogHandler::fatalError( const QXmlParseException& exception )
231
// vkPrintErr("fatalError");
233
// msg previously set by logview: print everything.
234
m_fatalMsg = exception.message() +
235
" (line: " + QString::number( exception.lineNumber() ) +
236
", col: " + QString::number( exception.columnNumber() ) + ")" +
240
/* If we finished before we got the error, this is probably the
241
result of Valgrind's fork-no-exec problem. */
243
+= "\nError after document closing tag.\nThis may be "
244
"caused by the Valgrinded application doing fork() but "
245
"not exec(). If so, ensure each fork() has a matching "
249
return false; /* don't continue parsing */