[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: branches/KDE/3.5/kdewebdev/quanta
From: Andras Mantia <amantia () kde ! org>
Date: 2007-03-02 20:19:22
Message-ID: 1172866762.155775.23246.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 638661 by amantia:
Fix crash when the tag editing dialog was quickly invoke after a delete from the tag.
Add guard for a possible crash in the rebuild process.
Add some code to track the node creation/destruction process to help debugging parser \
related crashes.
M +22 -0 parsers/node.cpp
M +69 -55 parsers/parser.cpp
M +17 -0 parsers/parsercommon.cpp
M +1 -0 parsers/parsercommon.h
M +2 -1 parsers/saparser.cpp
M +2 -2 quanta.kdevelop
M +2 -2 src/quanta.cpp
M +8 -2 src/quantaview.cpp
--- branches/KDE/3.5/kdewebdev/quanta/parsers/node.cpp #638660:638661
@@ -27,6 +27,8 @@
#include "structtreetag.h"
#include "kafkacommon.h"
+QValueList<Node*> nodes; //list of all created nodes. Used to do some own memory \
management and avoid double deletes, for whatever reason they happen... +
int NN = 0; //for debugging purposes: count the Node objects
GroupElementMapList globalGroupMap;
@@ -46,11 +48,23 @@
m_leafNode = 0L;
m_groupElements.clear();
NN++;
+ if (nodes.contains(this) == 0)
+ nodes.append(this);
+ else
+ {
+ kdError(24000) << "A node with this address " << this << " already exists!" << \
endl; + }
}
Node::~Node()
{
+ if (nodes.contains(this) == 0)
+ {
+ kdError(24000) << "No node with this address " << this << " was allocated!" << \
endl; + return;
+ }
+
//It has no use, except to know when it crash why it has crashed.
//If it has crashed here, the Node doesn't exist anymore.
// If it has crashed the next line, it is a GroupElements bug.
@@ -60,6 +74,8 @@
tag->setCleanStrBuilt(false);
detachNode();
+ if (nodes.contains(this) > 0)
+ nodes.remove(this);
if (prev && prev->next == this)
prev->next = 0L;
if (parent && parent->child == this)
@@ -487,6 +503,12 @@
void Node::detachNode()
{
+ if (nodes.contains(this) == 0)
+ {
+ kdError(24000) << "No node with this address " << this << " was allocated!" << \
endl; + return;
+ }
+
int count = 0;
//kdDebug(24000) << &m_groupElements << " " << this << endl;
//Remove the references to this node from the list of group elements.
--- branches/KDE/3.5/kdewebdev/quanta/parsers/parser.cpp #638660:638661
@@ -68,6 +68,7 @@
static const QChar space(' ');
extern int NN;
+extern QValueList<Node*> nodes;
Parser::Parser()
{
@@ -520,12 +521,16 @@
// clearGroups();
if (baseNode)
{
- kdDebug(24000) << "NN before delete = " << NN << endl;
+ kdDebug(24000) << "Node objects before delete = " << NN << " ; list count = " \
<< nodes.count() << endl; //kdDebug(24000) << "baseNode before delete = " << \
baseNode << endl; //ParserCommon::coutTree(m_node, 2);
delete baseNode;
baseNode = 0L;
- kdDebug(24000) << "NN after delete = " << NN << endl;
+ kdDebug(24000) << "Node objects after delete = " << NN << " ; list count = " << \
nodes.count() << endl; + QValueList<Node*> nList = nodes;
+/* for (QValueList<Node*>::ConstIterator it = nList.constBegin(); it != \
nList.constEnd(); ++it) + delete (*it);
+ kdDebug(24000) << "Node objects after cleanup = " << NN << " ; list count = " \
<< nodes.count() << endl; */ }
m_node = 0L;
@@ -1013,9 +1018,10 @@
kdDebug(24000) << QString("Invalid area: \
%1,%2,%3,%4").arg(area.bLine).arg(area.bCol).arg(area.eLine).arg(area.eCol) << "\n"; \
+// kdDebug(24000) << "lastNode1: " << lastNode << " " << lastNode->tag << endl;
deleteNodes(firstNode->nextSibling(), lastNode, modifs);
+// kdDebug(24000) << "lastNode2: " << lastNode << " " << lastNode->tag << endl;
-
firstNode->child = 0L;
Node *lastInserted = 0L;
//this makes sure that the first found node it put right after the firstNode
@@ -1053,10 +1059,11 @@
m_saParser->setParsingEnabled(saParserEnabled);
return parse(w);
}
-
+// kdDebug(24000) << "lastNode3: " << lastNode << " " << lastNode->tag << endl;
bool goUp;
if (lastNode && lastInserted)
{
+// kdDebug(24000) << "lastNode4: " << lastNode << " " << lastNode->tag << endl;
//merge the nodes if they are both of type Text or Empty
if ( (lastInserted->tag->type == Tag::Empty || lastInserted->tag->type == \
Tag::Text) &&
(lastNode->tag->type == Tag::Empty || lastNode->tag->type == Tag::Text))
@@ -1115,9 +1122,11 @@
node = lastInserted;
+// kdDebug(24000) << "lastNode5: " << lastNode << " " << lastNode->tag << endl;
QTag *qTag = 0L;
while (node && lastNode)
{
+// kdDebug(24000) << "lastNode6: " << lastNode << " " << lastNode->tag << \
endl; qTag = 0L;
goUp = ( node->parent &&
( (lastNode->tag->type == Tag::XmlTagEnd && \
QuantaCommon::closesTag(node->parent->tag, lastNode->tag) ) || @@ -1142,65 +1151,69 \
@@
(!m_dtd->caseSensitive && node->tag->name.lower() == \
node->parent->tag->name.lower())) )
goUp = false; //it can happen that the tag closes the previous and not the \
parent
- if (goUp) //lastnode closes the node->parent
- {
- //handle cases like <ul><li></ul>
- if (lastNode->tag->type == Tag::XmlTagEnd &&
- !QuantaCommon::closesTag(node->parent->tag, lastNode->tag))
- {
- while ( node->parent->parent &&
- QuantaCommon::closesTag(node->parent->parent->tag, lastNode->tag)
- )
+ if (goUp) //lastnode closes the node->parent
+ {
+ //handle cases like <ul><li></ul>
+ if (lastNode->tag->type == Tag::XmlTagEnd &&
+ !QuantaCommon::closesTag(node->parent->tag, lastNode->tag))
{
- node = node->parent;
- }
- } else
- if (qTag && lastNode->tag->type != Tag::XmlTagEnd)
- {
- //handle the case when a tag is a stopping tag for parent, and grandparent \
and so on. I'm not sure it's needed here, but anyway...
- Node *n = node->parent;
- QString searchFor = (m_dtd->caseSensitive) ? lastNode->tag->name : \
lastNode->tag->name.upper();
- while (qTag && n)
+ while ( node->parent->parent &&
+ QuantaCommon::closesTag(node->parent->parent->tag, \
lastNode->tag) + )
+ {
+ node = node->parent;
+ }
+ } else
+ if (qTag && lastNode->tag->type != Tag::XmlTagEnd)
{
- qTag = QuantaCommon::tagFromDTD(m_dtd, n->tag->name);
- if ( qTag )
+ //handle the case when a tag is a stopping tag for parent, and \
grandparent and so on. I'm not sure it's needed here, but anyway... + Node \
*n = node->parent; + QString searchFor = (m_dtd->caseSensitive) ? \
lastNode->tag->name : lastNode->tag->name.upper(); + while (qTag && n)
{
- if ( qTag->stoppingTags.contains(searchFor) )
+ qTag = QuantaCommon::tagFromDTD(m_dtd, n->tag->name);
+ if ( qTag )
{
- n->tag->closingMissing = true; //parent is single...
- if (n->parent)
- node = n;
- n = n->parent;
- } else
- {
- break;
+ if ( qTag->stoppingTags.contains(searchFor) )
+ {
+ n->tag->closingMissing = true; //parent is single...
+ if (n->parent)
+ node = n;
+ n = n->parent;
+ } else
+ {
+ break;
+ }
}
}
}
- }
- if (lastNode->prev && lastNode->prev->next == lastNode)
- lastNode->prev->next = 0L;
- if (lastNode->parent && lastNode->parent->child == lastNode)
- lastNode->parent->child = 0L;
- node->parent->next = lastNode;
- lastNode->prev = node->parent;
- if (node->parent)
- lastNode->parent = node->parent->parent;
- else
- lastNode->parent = 0L;
- node->next = 0L;
- lastNode->closesPrevious = true;
- } else
- {
- if (lastNode->prev && lastNode->prev->next == lastNode)
+ if (lastNode->prev && lastNode->prev->next == lastNode)
lastNode->prev->next = 0L;
- node->next = lastNode;
- lastNode->prev = node;
- lastNode->parent = node->parent;
+ if (lastNode->parent && lastNode->parent->child == lastNode)
+ lastNode->parent->child = 0L;
+ if (node->parent)
+ node->parent->next = lastNode;
+ lastNode->prev = node->parent;
+ if (node->parent)
+ lastNode->parent = node->parent->parent;
+ else
+ lastNode->parent = 0L;
+ node->next = 0L;
+ lastNode->closesPrevious = true;
+ } else
+ {
+ if (lastNode->prev && lastNode->prev->next == lastNode)
+ lastNode->prev->next = 0L;
+ node->next = lastNode;
+ lastNode->prev = node;
+ lastNode->parent = node->parent;
+// kdDebug(24000) << "lastNode7: " << lastNode << " " << lastNode->tag << \
endl; + }
+ node = lastNode;
+ lastNode = lastNode->nextNotChild();
+ if (lastNode)
+ QString s = lastNode->tag->tagStr();
}
- node = lastNode;
- lastNode = lastNode->nextNotChild();
- }
}
/* kdDebug(24000)<< "END"<< endl;
ParserCommon::coutTree(baseNode, 2);
@@ -1209,7 +1222,8 @@
w->docUndoRedo->addNewModifsSet(modifs, undoRedo::SourceModif);
}
kdDebug(24000) << "Rebuild: " << t.elapsed() << " ms; baseNode=" << baseNode << \
"\n";
-
+
+// ParserCommon::verifyTree(m_node);
/* treeSize = 0;
ParserCommon::coutTree(m_node, 2);
kdDebug(24000) << "Size of tree: " << treeSize << endl;*/
--- branches/KDE/3.5/kdewebdev/quanta/parsers/parsercommon.cpp #638660:638661
@@ -236,4 +236,21 @@
}
}
+void verifyTree(Node *node)
+{
+ QString output;
+ int bLine, bCol, eLine, eCol;
+ while (node)
+ {
+ if (!node->tag)
+ {
+ kdDebug(24000) << "Bad node: " << node << endl;
+ kdDebug(24000) << "Parent: " << node->parent << " " << \
node->parent->tag->tagStr() << endl; + }
+ if (node->child)
+ verifyTree(node->child);
+ node = node->next;
+ }
}
+
+}
--- branches/KDE/3.5/kdewebdev/quanta/parsers/parsercommon.h #638660:638661
@@ -53,6 +53,7 @@
/** Print the doc structure tree to the standard output.
Only for debugging purposes. */
void coutTree(Node *node, int indent);
+ void verifyTree(Node *node);
}
#endif
--- branches/KDE/3.5/kdewebdev/quanta/parsers/saparser.cpp #638660:638661
@@ -900,7 +900,8 @@
AreaStruct area(m_currentNode->tag->area());
s_next = 0L;
m_useNext = false;
- if (m_currentNode->next)
+ //FIXME: Find out why can the tag become 0L
+ if (m_currentNode->next && m_currentNode->next->tag)
{
AreaStruct area2(m_currentNode->next->tag->area());
area.eLine = area2.eLine;
--- branches/KDE/3.5/kdewebdev/quanta/quanta.kdevelop #638660:638661
@@ -259,10 +259,10 @@
</kdevcvs>
<kdevfilecreate>
<filetypes>
- <type icon="" ext="h" name="C++ header" create="template" >
+ <type icon="" ext="h" create="template" name="C++ header" >
<descr>Quanta speicfic header</descr>
</type>
- <type icon="source_cpp" ext="cpp" name="C++ source" create="template" >
+ <type icon="source_cpp" ext="cpp" create="template" name="C++ source" >
<descr>A new empty C++ file.</descr>
</type>
</filetypes>
--- branches/KDE/3.5/kdewebdev/quanta/src/quanta.cpp #638660:638661
@@ -4274,7 +4274,7 @@
QString tagName;
if (node && node->tag)
{
- Tag *tag = node->tag;
+ Tag *tag = new Tag(*node->tag); //create a copy, as a reparse might happen \
meantime and that would make node (and node->tag) invalid tagName = tag->name;
if ( QuantaCommon::isKnownTag(tag->dtd()->name,tagName) )
{
@@ -4287,7 +4287,7 @@
{
w->changeTag(tag, dlg->getAttributes() );
}
-
+ delete tag;
delete dlg;
}
}
--- branches/KDE/3.5/kdewebdev/quanta/src/quantaview.cpp #638660:638661
@@ -74,6 +74,8 @@
#include "tagdialog.h"
extern int NN;
+extern QValueList<Node*> nodes;
+
QuantaView::QuantaView(QWidget *parent, const char *name, const QString &caption )
: KMdiChildView(parent, name)
, m_document(0L)
@@ -143,10 +145,14 @@
if (static_cast<QuantaView *>(quantaApp->activeWindow()) == this)
{
parser->setSAParserEnabled(false);
- kdDebug(24000) << "Node objects before delete :" << NN << " baseNode= " << \
baseNode << endl; + kdDebug(24000) << "Node objects before delete = " << NN << \
" ; list count = " << nodes.count() << endl; delete baseNode;
baseNode = 0L;
- kdDebug(24000) << "Node objects after delete :" << NN << " baseNode= " << \
baseNode << endl; + kdDebug(24000) << "Node objects after delete = " << NN << \
" ; list count = " << nodes.count() << endl; + QValueList<Node*> nList = \
nodes; +/* for (QValueList<Node*>::ConstIterator it = nList.constBegin(); it \
!= nList.constEnd(); ++it) + delete (*it);
+ kdDebug(24000) << "Node objects after cleanup = " << NN << " ; list count = \
" << nodes.count() << endl;*/ }
if (m_document)
{
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic