[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