~ubuntu-branches/ubuntu/oneiric/valkyrie/oneiric

« back to all changes in this revision

Viewing changes to valkyrie/tool_utils/vglogreader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Hai Zaar
  • Date: 2009-05-06 14:48:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090506144800-vw617m4d4qa2pam3
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ---------------------------------------------------------------------
 
2
 * vglogreader: reads xml log into a VgLog                 vglogreader.h
 
3
 * ---------------------------------------------------------------------
 
4
 * This file is part of Valkyrie, a front-end for Valgrind
 
5
 * Copyright (C) 2000-2008, OpenWorks LLP <info@open-works.co.uk>
 
6
 * This program is released under the terms of the GNU GPL v.2
 
7
 * See the file COPYING for the full license details.
 
8
 */
 
9
 
 
10
#include "vglogreader.h"
 
11
#include "vglog.h"
 
12
 
 
13
#include <assert.h>
 
14
 
 
15
/**********************************************************************/
 
16
/* VgLogReader */
 
17
VgLogReader::VgLogReader( VgLog* vglog )
 
18
   : vghandler(0), source(0)
 
19
{
 
20
   vghandler = new VgLogHandler( vglog );
 
21
   setContentHandler( vghandler );
 
22
   setErrorHandler( vghandler );
 
23
   //  setLexicalHandler( vghandler );
 
24
   //  setDeclHandler( vghandler );
 
25
   //  setDTDHandler( vghandler );
 
26
}
 
27
 
 
28
VgLogReader::~VgLogReader()
 
29
{
 
30
   if ( vghandler != 0 ) {
 
31
      delete vghandler;
 
32
      vghandler = 0;
 
33
   }
 
34
   if (source) {
 
35
      delete source;
 
36
      source = 0;
 
37
   }
 
38
   if (file.isOpen())
 
39
      file.close();
 
40
}
 
41
 
 
42
bool VgLogReader::parse( QString filepath, bool incremental/*=false*/ )
 
43
{
 
44
   if (source)
 
45
      delete source;
 
46
   if (file.isOpen())
 
47
      file.close();
 
48
   file.setName( filepath );
 
49
   source = new QXmlInputSource( file );
 
50
   return QXmlSimpleReader::parse( source, incremental );
 
51
}
 
52
 
 
53
bool VgLogReader::parseContinue()
 
54
{
 
55
   if (source)
 
56
      source->fetchData();
 
57
   return QXmlSimpleReader::parseContinue();
 
58
}
 
59
 
 
60
 
 
61
/**********************************************************************/
 
62
/* VgLogHandler */
 
63
VgLogHandler::VgLogHandler( VgLog* alog )
 
64
{
 
65
   vglog = alog;
 
66
   node = doc;
 
67
   m_finished = false;
 
68
}
 
69
 
 
70
VgLogHandler::~VgLogHandler()
 
71
{ }
 
72
 
 
73
/* gets <?xml...> element */
 
74
bool VgLogHandler::processingInstruction( const QString& target, const QString& data )
 
75
{
 
76
   //  vkPrintErr("VgLogHandler::processingInstruction: %s, %s", target.latin1(), data.latin1());
 
77
   doc.appendChild( doc.createProcessingInstruction( target, data ) );
 
78
   node = doc;
 
79
   return true;
 
80
}
 
81
 
 
82
bool VgLogHandler::startElement( const QString&, const QString&,
 
83
                                 const QString& tag,
 
84
                                 const QXmlAttributes& )
 
85
{
 
86
   //  vkPrintErr("VgLogHandler::startElement: '%s'", tag.latin1());
 
87
   QDomNode n = doc.createElement( tag );
 
88
   node.appendChild( n );
 
89
   node = n;
 
90
 
 
91
   if (node == doc.documentElement()) {
 
92
      QDomProcessingInstruction xml_insn =
 
93
         doc.firstChild().toProcessingInstruction();
 
94
      if ( ! vglog->init( xml_insn, tag ) ) {
 
95
         //VK_DEBUG("Error: Failed log initialisation");
 
96
         return false;
 
97
      }
 
98
   }
 
99
 
 
100
   return true;
 
101
}
 
102
 
 
103
bool VgLogHandler::endElement( const QString&, const QString&,
 
104
                               const QString& /*tag*/ )
 
105
{
 
106
   //  vkPrintErr("VgLogHandler::endElement: %s", tag.latin1());
 
107
   // Should never have end element at doc level
 
108
   if ( node == doc ) {
 
109
      //VK_DEBUG("VgLogHandler::endElement(): Error: node == doc");
 
110
      return false;
 
111
   }
 
112
 
 
113
   QDomNode prnt = node.parentNode();
 
114
 
 
115
   /* if closing a top-level tag, append to vglog */
 
116
   if (prnt == doc.documentElement()) {
 
117
      if ( ! vglog->appendNode( node ) ) {
 
118
         //VK_DEBUG("Failed to append node");
 
119
         return false;
 
120
      }
 
121
   }
 
122
   node = prnt;
 
123
 
 
124
   if (node == doc) {
 
125
      /* In case we get bad xml after the closing tag, mark as 'finished'
 
126
         This may happed, for example, as a result of doing fork() but
 
127
         not exec() under valgrind.  When the process forks, you wind up
 
128
         with 2 V's attached to the same logfile, which doesn't get
 
129
         sorted out until the child does exec().
 
130
      */
 
131
      m_finished = true;
 
132
   }
 
133
 
 
134
   return true;
 
135
}
 
136
 
 
137
bool VgLogHandler::characters( const QString&  ch )
 
138
{
 
139
   //  vkPrintErr("characters: '%s'", ch.latin1());
 
140
   // No text as child of some document
 
141
   if ( node == doc )
 
142
      return false;
 
143
 
 
144
   /* ignore text as child of doc_elem
 
145
      => valgrind non-xml output (shouldn't happen), or client output */
 
146
   if ( node == doc.documentElement() )
 
147
      return true;
 
148
 
 
149
   QString chars = ch.simplifyWhiteSpace();
 
150
   if ( !chars.isEmpty() ) {
 
151
      node.appendChild( doc.createTextNode( chars ) );
 
152
      //    vkPrintErr("chars: '%s'", chars.latin1());
 
153
   }
 
154
 
 
155
   return true;
 
156
}
 
157
 
 
158
/* Called by xml reader at start of parsing */
 
159
bool VgLogHandler::startDocument()
 
160
{
 
161
   //   vkPrintErr("VgLogHandler::startDocument()\n");
 
162
   assert(vglog != 0);
 
163
 
 
164
   doc = QDomDocument();
 
165
   node = doc;
 
166
   m_fatalMsg = QString();
 
167
   m_finished = false;
 
168
   return true;
 
169
}
 
170
 
 
171
/* Called by xml reader after it has finished parsing
 
172
   Checks we have a complete document,
 
173
   i.e. endElement() has returned node ptr to root
 
174
*/
 
175
bool VgLogHandler::endDocument()
 
176
{
 
177
   //   vkPrintErr("VgLogHandler::endDocument()\n");
 
178
   m_finished = true;
 
179
   if (node != doc)
 
180
      return false;
 
181
   return true;
 
182
}
 
183
 
 
184
/* non-fatal error: just report it */
 
185
bool VgLogHandler::error( const QXmlParseException& exception )
 
186
{
 
187
//   vkPrintErr("VgLogHandler::error");
 
188
   QString err = exception.message() +
 
189
      " (line: " + QString::number(exception.lineNumber()) +
 
190
      ", col: " + QString::number(exception.columnNumber()) + ")";
 
191
 
 
192
   // printf("VgLogHandler::non-fatal error: %s", err.latin1());
 
193
 
 
194
   return true; /* try to continue. */
 
195
}
 
196
 
 
197
bool VgLogHandler::fatalError( const QXmlParseException& exception )
 
198
{
 
199
   //  vkPrintErr("fatalError");
 
200
   m_fatalMsg = exception.message() +
 
201
      " (line: " + QString::number(exception.lineNumber()) +
 
202
      ", col: " + QString::number(exception.columnNumber()) + ")";
 
203
 
 
204
   if (m_finished) {
 
205
      /* If we finished before we got the error, this is probably the
 
206
         result of Valgrind's fork-no-exec problem. */
 
207
      m_fatalMsg 
 
208
         += "\nError after document closing tag.\nThis may be "
 
209
            "caused by the Valgrinded application doing fork() but "
 
210
            "not exec().  If so, ensure each fork() has a matching "
 
211
            "exec() call.";
 
212
   }
 
213
 
 
214
   return false; /* don't continue parsing */
 
215
}