LCOV - code coverage report
Current view: directory - layout/generic - nsFrameUtil.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 354 0 0.0 %
Date: 2012-06-02 Functions: 34 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /* utilities for regression tests based on frame tree comparison */
      39                 :  
      40                 : #include "nsIFrameUtil.h"
      41                 : #include "nsFrame.h"
      42                 : #include "nsString.h"
      43                 : #include "nsRect.h"
      44                 : #include <stdlib.h>
      45                 : #include "plstr.h"
      46                 : 
      47                 : 
      48                 : #ifdef NS_DEBUG
      49                 : class nsFrameUtil : public nsIFrameUtil {
      50                 : public:
      51                 :   nsFrameUtil();
      52                 :   virtual ~nsFrameUtil();
      53                 : 
      54                 :   NS_DECL_ISUPPORTS
      55                 : 
      56                 :   NS_IMETHOD CompareRegressionData(FILE* aFile1, FILE* aFile2,PRInt32 aRegressionOutput=0);
      57                 :   NS_IMETHOD DumpRegressionData(FILE* aInputFile, FILE* aOutputFile);
      58                 : 
      59                 :   struct Node;
      60                 :   struct Tag;
      61                 : 
      62                 :   struct NodeList {
      63                 :     NodeList();
      64                 :     ~NodeList();
      65                 : 
      66                 :     static void Destroy(NodeList* aLists);
      67                 : 
      68                 :     NodeList* next;            // for lists of lists
      69                 :     Node* node;
      70                 :     char* name;
      71                 :   };
      72                 : 
      73                 :   struct Node {
      74                 :     Node();
      75                 :     ~Node();
      76                 : 
      77                 :     static void Destroy(Node* aNode);
      78                 : 
      79                 :     static Node* Read(FILE* aFile, Tag* aTag);
      80                 : 
      81                 :     static Node* ReadTree(FILE* aFile);
      82                 : 
      83                 :     Node* next;
      84                 :     char* type;
      85                 :     PRUint32 state;
      86                 :     nsRect bbox;
      87                 :     nsCString styleData;
      88                 :     NodeList* lists;
      89                 :   };
      90                 : 
      91                 :   struct Tag {
      92                 :     Tag();
      93                 :     ~Tag();
      94                 : 
      95                 :     static Tag* Parse(FILE* aFile);
      96                 : 
      97                 :     void AddAttr(char* aAttr, char* aValue);
      98                 : 
      99                 :     const char* GetAttr(const char* aAttr);
     100                 : 
     101                 :     void ReadAttrs(FILE* aFile);
     102                 : 
     103                 :     void ToString(nsString& aResult);
     104                 : 
     105                 :     enum Type {
     106                 :       open,
     107                 :       close,
     108                 :       openClose
     109                 :     };
     110                 : 
     111                 :     char* name;
     112                 :     Type type;
     113                 :     char** attributes;
     114                 :     PRInt32 num;
     115                 :     PRInt32 size;
     116                 :     char** values;
     117                 :   };
     118                 : 
     119                 :   static char* Copy(const char* aString);
     120                 : 
     121                 :   static void DumpNode(Node* aNode, FILE* aOutputFile, PRInt32 aIndent);
     122                 :   static void DumpTree(Node* aNode, FILE* aOutputFile, PRInt32 aIndent);
     123                 :   static bool CompareTrees(Node* aNode1, Node* aNode2);
     124                 : };
     125                 : 
     126                 : char*
     127               0 : nsFrameUtil::Copy(const char* aString)
     128                 : {
     129               0 :   if (aString) {
     130               0 :     int l = ::strlen(aString);
     131               0 :     char* c = new char[l+1];
     132               0 :     if (!c)
     133               0 :       return nsnull;
     134               0 :     memcpy(c, aString, l+1);
     135               0 :     return c;
     136                 :   }
     137               0 :   return nsnull;
     138                 : }
     139                 : 
     140                 : //----------------------------------------------------------------------
     141                 : 
     142               0 : nsFrameUtil::NodeList::NodeList()
     143               0 :   : next(nsnull), node(nsnull), name(nsnull)
     144                 : {
     145               0 : }
     146                 : 
     147               0 : nsFrameUtil::NodeList::~NodeList()
     148                 : {
     149               0 :   if (nsnull != name) {
     150               0 :     delete name;
     151                 :   }
     152               0 :   if (nsnull != node) {
     153               0 :     Node::Destroy(node);
     154                 :   }
     155               0 : }
     156                 : 
     157                 : void
     158               0 : nsFrameUtil::NodeList::Destroy(NodeList* aLists)
     159                 : {
     160               0 :   while (nsnull != aLists) {
     161               0 :     NodeList* next = aLists->next;
     162               0 :     delete aLists;
     163               0 :     aLists = next;
     164                 :   }
     165               0 : }
     166                 : 
     167                 : //----------------------------------------------------------------------
     168                 : 
     169               0 : nsFrameUtil::Node::Node()
     170               0 :   : next(nsnull), type(nsnull), state(0), lists(nsnull)
     171                 : {
     172               0 : }
     173                 : 
     174               0 : nsFrameUtil::Node::~Node()
     175                 : {
     176               0 :   if (nsnull != type) {
     177               0 :     delete type;
     178                 :   }
     179               0 :   if (nsnull != lists) {
     180               0 :     NodeList::Destroy(lists);
     181                 :   }
     182               0 : }
     183                 : 
     184                 : void
     185               0 : nsFrameUtil::Node::Destroy(Node* aList)
     186                 : {
     187               0 :   while (nsnull != aList) {
     188               0 :     Node* next = aList->next;
     189               0 :     delete aList;
     190               0 :     aList = next;
     191                 :   }
     192               0 : }
     193                 : 
     194               0 : static PRInt32 GetInt(nsFrameUtil::Tag* aTag, const char* aAttr)
     195                 : {
     196               0 :   const char* value = aTag->GetAttr(aAttr);
     197               0 :   if (nsnull != value) {
     198               0 :     return PRInt32( atoi(value) );
     199                 :   }
     200               0 :   return 0;
     201                 : }
     202                 : 
     203                 : nsFrameUtil::Node*
     204               0 : nsFrameUtil::Node::ReadTree(FILE* aFile)
     205                 : {
     206               0 :   Tag* tag = Tag::Parse(aFile);
     207               0 :   if (nsnull == tag) {
     208               0 :     return nsnull;
     209                 :   }
     210               0 :   if (PL_strcmp(tag->name, "frame") != 0) {
     211               0 :     delete tag;
     212               0 :     return nsnull;
     213                 :   }
     214               0 :   Node* result = Read(aFile, tag);
     215               0 :   fclose(aFile);
     216               0 :   return result;
     217                 : }
     218                 : 
     219                 : nsFrameUtil::Node*
     220               0 : nsFrameUtil::Node::Read(FILE* aFile, Tag* tag)
     221                 : {
     222               0 :   Node* node = new Node;
     223               0 :   node->type = Copy(tag->GetAttr("type"));
     224               0 :   if (!node->type) {
     225                 :     /* crash() */
     226                 :   }
     227               0 :   node->state = GetInt(tag, "state");
     228               0 :   delete tag;
     229                 : 
     230               0 :   for (;;) {
     231               0 :     tag = Tag::Parse(aFile);
     232               0 :     if (nsnull == tag) break;
     233               0 :     if (PL_strcmp(tag->name, "frame") == 0) {
     234               0 :       delete tag;
     235               0 :       break;
     236                 :     }
     237               0 :     if (PL_strcmp(tag->name, "bbox") == 0) {
     238               0 :       nscoord x = nscoord( GetInt(tag, "x") );
     239               0 :       nscoord y = nscoord( GetInt(tag, "y") );
     240               0 :       nscoord w = nscoord( GetInt(tag, "w") );
     241               0 :       nscoord h = nscoord( GetInt(tag, "h") );
     242               0 :       node->bbox.SetRect(x, y, w, h);
     243                 :     }
     244               0 :     else if (PL_strcmp(tag->name, "child-list") == 0) {
     245               0 :       NodeList* list = new NodeList();
     246               0 :       list->name = Copy(tag->GetAttr("name"));
     247               0 :       if (!list->name) {
     248                 :         /* crash() */
     249                 :       }
     250               0 :       list->next = node->lists;
     251               0 :       node->lists = list;
     252               0 :       delete tag;
     253                 : 
     254               0 :       Node** tailp = &list->node;
     255               0 :       for (;;) {
     256               0 :         tag = Tag::Parse(aFile);
     257               0 :         if (nsnull == tag) {
     258               0 :           break;
     259                 :         }
     260               0 :         if (PL_strcmp(tag->name, "child-list") == 0) {
     261               0 :           break;
     262                 :         }
     263               0 :         if (PL_strcmp(tag->name, "frame") != 0) {
     264               0 :           break;
     265                 :         }
     266               0 :         Node* child = Node::Read(aFile, tag);
     267               0 :         if (nsnull == child) {
     268               0 :           break;
     269                 :         }
     270               0 :         *tailp = child;
     271               0 :         tailp = &child->next;
     272                 :       }
     273                 :     }
     274               0 :     else if((PL_strcmp(tag->name, "font") == 0) ||
     275               0 :             (PL_strcmp(tag->name, "color") == 0) ||
     276               0 :             (PL_strcmp(tag->name, "spacing") == 0) ||
     277               0 :             (PL_strcmp(tag->name, "list") == 0) ||
     278               0 :             (PL_strcmp(tag->name, "position") == 0) ||
     279               0 :             (PL_strcmp(tag->name, "text") == 0) ||
     280               0 :             (PL_strcmp(tag->name, "display") == 0) ||
     281               0 :             (PL_strcmp(tag->name, "table") == 0) ||
     282               0 :             (PL_strcmp(tag->name, "content") == 0) ||
     283               0 :             (PL_strcmp(tag->name, "UI") == 0) ||
     284               0 :             (PL_strcmp(tag->name, "print") == 0)) {
     285               0 :       const char* attr = tag->GetAttr("data");
     286               0 :       node->styleData.Append('|');
     287               0 :       node->styleData.Append(attr ? attr : "null attr");
     288                 :     }
     289                 : 
     290               0 :     delete tag;
     291                 :   }
     292               0 :   return node;
     293                 : }
     294                 : 
     295                 : //----------------------------------------------------------------------
     296                 : 
     297               0 : nsFrameUtil::Tag::Tag()
     298                 :   : name(nsnull), type(open), attributes(nsnull), num(0), size(0),
     299               0 :     values(nsnull)
     300                 : {
     301               0 : }
     302                 : 
     303               0 : nsFrameUtil::Tag::~Tag()
     304                 : {
     305               0 :   PRInt32 i, n = num;
     306               0 :   if (0 != n) {
     307               0 :     for (i = 0; i < n; i++) {
     308               0 :       delete attributes[i];
     309               0 :       delete values[i];
     310                 :     }
     311               0 :     delete attributes;
     312               0 :     delete values;
     313                 :   }
     314               0 : }
     315                 : 
     316                 : void
     317               0 : nsFrameUtil::Tag::AddAttr(char* aAttr, char* aValue)
     318                 : {
     319               0 :   if (num == size) {
     320               0 :     PRInt32 newSize = size * 2 + 4;
     321               0 :     char** a = new char*[newSize];
     322               0 :     char** v = new char*[newSize];
     323               0 :     if (0 != num) {
     324               0 :       memcpy(a, attributes, num * sizeof(char*));
     325               0 :       memcpy(v, values, num * sizeof(char*));
     326               0 :       delete attributes;
     327               0 :       delete values;
     328                 :     }
     329               0 :     attributes = a;
     330               0 :     values = v;
     331               0 :     size = newSize;
     332                 :   }
     333               0 :   attributes[num] = aAttr;
     334               0 :   values[num] = aValue;
     335               0 :   num = num + 1;
     336               0 : }
     337                 : 
     338                 : const char*
     339               0 : nsFrameUtil::Tag::GetAttr(const char* aAttr)
     340                 : {
     341               0 :   PRInt32 i, n = num;
     342               0 :   for (i = 0; i < n; i++) {
     343               0 :     if (PL_strcmp(attributes[i], aAttr) == 0) {
     344               0 :       return values[i];
     345                 :     }
     346                 :   }
     347               0 :   return nsnull;
     348                 : }
     349                 : 
     350               0 : static inline int IsWhiteSpace(int c) {
     351               0 :   return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
     352                 : }
     353                 : 
     354               0 : static bool EatWS(FILE* aFile)
     355                 : {
     356               0 :   for (;;) {
     357               0 :     int c = getc(aFile);
     358               0 :     if (c < 0) {
     359               0 :       return false;
     360                 :     }
     361               0 :     if (!IsWhiteSpace(c)) {
     362               0 :       ungetc(c, aFile);
     363                 :       break;
     364                 :     }
     365                 :   }
     366               0 :   return true;
     367                 : }
     368                 : 
     369               0 : static bool Expect(FILE* aFile, char aChar)
     370                 : {
     371               0 :   int c = getc(aFile);
     372               0 :   if (c < 0) return false;
     373               0 :   if (c != aChar) {
     374               0 :     ungetc(c, aFile);
     375               0 :     return false;
     376                 :   }
     377               0 :   return true;
     378                 : }
     379                 : 
     380               0 : static char* ReadIdent(FILE* aFile)
     381                 : {
     382                 :   char id[1000];
     383               0 :   char* ip = id;
     384               0 :   char* end = ip + sizeof(id) - 1;
     385               0 :   while (ip < end) {
     386               0 :     int c = fgetc(aFile);
     387               0 :     if (c < 0) return nsnull;
     388               0 :     if ((c == '=') || (c == '>') || (c == '/') || IsWhiteSpace(c)) {
     389               0 :       ungetc(c, aFile);
     390               0 :       break;
     391                 :     }
     392               0 :     *ip++ = char(c);
     393                 :   }
     394               0 :   *ip = '\0';
     395               0 :   return nsFrameUtil::Copy(id);
     396                 :   /* may return a null pointer */
     397                 : }
     398                 : 
     399               0 : static char* ReadString(FILE* aFile)
     400                 : {
     401               0 :   if (!Expect(aFile, '\"')) {
     402               0 :     return nsnull;
     403                 :   }
     404                 :   char id[1000];
     405               0 :   char* ip = id;
     406               0 :   char* end = ip + sizeof(id) - 1;
     407               0 :   while (ip < end) {
     408               0 :     int c = fgetc(aFile);
     409               0 :     if (c < 0) return nsnull;
     410               0 :     if (c == '\"') {
     411               0 :       break;
     412                 :     }
     413               0 :     *ip++ = char(c);
     414                 :   }
     415               0 :   *ip = '\0';
     416               0 :   return nsFrameUtil::Copy(id);
     417                 :   /* may return a null pointer */
     418                 : }
     419                 : 
     420                 : void
     421               0 : nsFrameUtil::Tag::ReadAttrs(FILE* aFile)
     422                 : {
     423               0 :   for (;;) {
     424               0 :     if (!EatWS(aFile)) {
     425               0 :       break;
     426                 :     }
     427               0 :     int c = getc(aFile);
     428               0 :     if (c < 0) break;
     429               0 :     if (c == '/') {
     430               0 :       if (!EatWS(aFile)) {
     431               0 :         return;
     432                 :       }
     433               0 :       if (Expect(aFile, '>')) {
     434               0 :         type = openClose;
     435               0 :         break;
     436                 :       }
     437                 :     }
     438               0 :     else if (c == '>') {
     439               0 :       break;
     440                 :     }
     441               0 :     ungetc(c, aFile);
     442               0 :     char* attr = ReadIdent(aFile);
     443               0 :     if ((nsnull == attr) || !EatWS(aFile)) {
     444               0 :       break;
     445                 :     }
     446               0 :     char* value = nsnull;
     447               0 :     if (Expect(aFile, '=')) {
     448               0 :       value = ReadString(aFile);
     449               0 :       if (nsnull == value) {
     450               0 :         delete [] attr;
     451               0 :         break;
     452                 :       }
     453                 :     }
     454               0 :     AddAttr(attr, value);
     455                 :   }
     456                 : }
     457                 : 
     458                 : nsFrameUtil::Tag*
     459               0 : nsFrameUtil::Tag::Parse(FILE* aFile)
     460                 : {
     461               0 :   if (!EatWS(aFile)) {
     462               0 :     return nsnull;
     463                 :   }
     464               0 :   if (Expect(aFile, '<')) {
     465               0 :     Tag* tag = new Tag;
     466               0 :     if (Expect(aFile, '/')) {
     467               0 :       tag->type = close;
     468                 :     }
     469                 :     else {
     470               0 :       tag->type = open;
     471                 :     }
     472               0 :     tag->name = ReadIdent(aFile);
     473               0 :     tag->ReadAttrs(aFile);
     474               0 :     return tag;
     475                 :   }
     476               0 :   return nsnull;
     477                 : }
     478                 : 
     479                 : void
     480               0 : nsFrameUtil::Tag::ToString(nsString& aResult)
     481                 : {
     482               0 :   aResult.Truncate();
     483               0 :   aResult.Append(PRUnichar('<'));
     484               0 :   if (type == close) {
     485               0 :     aResult.Append(PRUnichar('/'));
     486                 :   }
     487               0 :   aResult.AppendASCII(name);
     488               0 :   if (0 != num) {
     489               0 :     PRInt32 i, n = num;
     490               0 :     for (i = 0; i < n; i++) {
     491               0 :       aResult.Append(PRUnichar(' '));
     492               0 :       aResult.AppendASCII(attributes[i]);
     493               0 :       if (values[i]) {
     494               0 :         aResult.AppendLiteral("=\"");
     495               0 :         aResult.AppendASCII(values[i]);
     496               0 :         aResult.Append(PRUnichar('\"'));
     497                 :       }
     498                 :     }
     499                 :   }
     500               0 :   if (type == openClose) {
     501               0 :     aResult.Append(PRUnichar('/'));
     502                 :   }
     503               0 :   aResult.Append(PRUnichar('>'));
     504               0 : }
     505                 : 
     506                 : //----------------------------------------------------------------------
     507                 : 
     508                 : nsresult
     509               0 : NS_NewFrameUtil(nsIFrameUtil** aResult)
     510                 : {
     511               0 :   NS_PRECONDITION(nsnull != aResult, "null pointer");
     512               0 :   if (nsnull == aResult) {
     513               0 :     return NS_ERROR_NULL_POINTER;
     514                 :   }
     515                 : 
     516               0 :   nsFrameUtil* it = new nsFrameUtil();
     517                 : 
     518               0 :   NS_ADDREF(*aResult = it);
     519               0 :   return NS_OK;
     520                 : }
     521                 : 
     522               0 : nsFrameUtil::nsFrameUtil()
     523                 : {
     524               0 : }
     525                 : 
     526               0 : nsFrameUtil::~nsFrameUtil()
     527                 : {
     528               0 : }
     529                 : 
     530               0 : NS_IMPL_ISUPPORTS1(nsFrameUtil, nsIFrameUtil)
     531                 : 
     532                 : void
     533               0 : nsFrameUtil::DumpNode(Node* aNode, FILE* aOutputFile, PRInt32 aIndent)
     534                 : {
     535               0 :   nsFrame::IndentBy(aOutputFile, aIndent);
     536                 :   fprintf(aOutputFile, "%s 0x%x %d,%d,%d,%d, %s\n", aNode->type, aNode->state,
     537                 :           aNode->bbox.x, aNode->bbox.y,
     538                 :           aNode->bbox.width, aNode->bbox.height,
     539               0 :           aNode->styleData.get());
     540               0 : }
     541                 : 
     542                 : void
     543               0 : nsFrameUtil::DumpTree(Node* aNode, FILE* aOutputFile, PRInt32 aIndent)
     544                 : {
     545               0 :   while (nsnull != aNode) {
     546               0 :     DumpNode(aNode, aOutputFile, aIndent);
     547               0 :     nsFrameUtil::NodeList* lists = aNode->lists;
     548               0 :     if (nsnull != lists) {
     549               0 :       while (nsnull != lists) {
     550               0 :         nsFrame::IndentBy(aOutputFile, aIndent);
     551                 :         fprintf(aOutputFile, " list: %s\n",
     552               0 :                 lists->name ? lists->name : "primary");
     553               0 :         DumpTree(lists->node, aOutputFile, aIndent + 1);
     554               0 :         lists = lists->next;
     555                 :       }
     556                 :     }
     557               0 :     aNode = aNode->next;
     558                 :   }
     559               0 : }
     560                 : 
     561                 : bool
     562               0 : nsFrameUtil::CompareTrees(Node* tree1, Node* tree2)
     563                 : {
     564               0 :   bool result = true;
     565               0 :   for (;; tree1 = tree1->next, tree2 = tree2->next) {
     566                 :     // Make sure both nodes are non-null, or at least agree with each other
     567               0 :     if (nsnull == tree1) {
     568               0 :       if (nsnull == tree2) {
     569                 :         break;
     570                 :       }
     571               0 :       printf("first tree prematurely ends\n");
     572               0 :       return false;
     573                 :     }
     574               0 :     else if (nsnull == tree2) {
     575               0 :       printf("second tree prematurely ends\n");
     576               0 :       return false;
     577                 :     }
     578                 : 
     579                 :     // Check the attributes that we care about
     580               0 :     if (0 != PL_strcmp(tree1->type, tree2->type)) {
     581               0 :       printf("frame type mismatch: %s vs. %s\n", tree1->type, tree2->type);
     582               0 :       printf("Node 1:\n");
     583               0 :       DumpNode(tree1, stdout, 1);
     584               0 :       printf("Node 2:\n");
     585               0 :       DumpNode(tree2, stdout, 1);
     586               0 :       return false;
     587                 :     }
     588                 : 
     589                 :     // Ignore the XUL scrollbar frames
     590                 :     static const char kScrollbarFrame[] = "ScrollbarFrame";
     591               0 :     if (0 == PL_strncmp(tree1->type, kScrollbarFrame, sizeof(kScrollbarFrame) - 1))
     592               0 :       continue;
     593                 : 
     594               0 :     if (tree1->state != tree2->state) {
     595                 :       printf("frame state mismatch: 0x%x vs. 0x%x\n",
     596               0 :              tree1->state, tree2->state);
     597               0 :       printf("Node 1:\n");
     598               0 :       DumpNode(tree1, stdout, 1);
     599               0 :       printf("Node 2:\n");
     600               0 :       DumpNode(tree2, stdout, 1);
     601               0 :       result = false; // we have a non-critical failure, so remember that but continue
     602                 :     }
     603               0 :     if (tree1->bbox.IsEqualInterior(tree2->bbox)) {
     604                 :       printf("frame bbox mismatch: %d,%d,%d,%d vs. %d,%d,%d,%d\n",
     605                 :              tree1->bbox.x, tree1->bbox.y,
     606                 :              tree1->bbox.width, tree1->bbox.height,
     607                 :              tree2->bbox.x, tree2->bbox.y,
     608               0 :              tree2->bbox.width, tree2->bbox.height);
     609               0 :       printf("Node 1:\n");
     610               0 :       DumpNode(tree1, stdout, 1);
     611               0 :       printf("Node 2:\n");
     612               0 :       DumpNode(tree2, stdout, 1);
     613               0 :       result = false; // we have a non-critical failure, so remember that but continue
     614                 :     }
     615               0 :     if (tree1->styleData != tree2->styleData) {
     616                 :       printf("frame style data mismatch: %s vs. %s\n",
     617                 :         tree1->styleData.get(),
     618               0 :         tree2->styleData.get());
     619                 :     }
     620                 : 
     621                 :     // Check child lists too
     622               0 :     NodeList* list1 = tree1->lists;
     623               0 :     NodeList* list2 = tree2->lists;
     624               0 :     for (;;) {
     625               0 :       if (nsnull == list1) {
     626               0 :         if (nsnull != list2) {
     627               0 :           printf("first tree prematurely ends (no child lists)\n");
     628               0 :           printf("Node 1:\n");
     629               0 :           DumpNode(tree1, stdout, 1);
     630               0 :           printf("Node 2:\n");
     631               0 :           DumpNode(tree2, stdout, 1);
     632               0 :           return false;
     633                 :         }
     634                 :         else {
     635               0 :           break;
     636                 :         }
     637                 :       }
     638               0 :       if (nsnull == list2) {
     639               0 :         printf("second tree prematurely ends (no child lists)\n");
     640               0 :         printf("Node 1:\n");
     641               0 :         DumpNode(tree1, stdout, 1);
     642               0 :         printf("Node 2:\n");
     643               0 :         DumpNode(tree2, stdout, 1);
     644               0 :         return false;
     645                 :       }
     646               0 :       if (0 != PL_strcmp(list1->name, list2->name)) {
     647                 :         printf("child-list name mismatch: %s vs. %s\n",
     648                 :                list1->name ? list1->name : "(null)",
     649               0 :                list2->name ? list2->name : "(null)");
     650               0 :         result = false; // we have a non-critical failure, so remember that but continue
     651                 :       }
     652                 :       else {
     653               0 :         bool equiv = CompareTrees(list1->node, list2->node);
     654               0 :         if (!equiv) {
     655               0 :           return equiv;
     656                 :         }
     657                 :       }
     658               0 :       list1 = list1->next;
     659               0 :       list2 = list2->next;
     660                 :     }
     661                 :   }
     662               0 :   return result;
     663                 : }
     664                 : 
     665                 : NS_IMETHODIMP
     666               0 : nsFrameUtil::CompareRegressionData(FILE* aFile1, FILE* aFile2,PRInt32 aRegressionOutput)
     667                 : {
     668               0 :   Node* tree1 = Node::ReadTree(aFile1);
     669               0 :   Node* tree2 = Node::ReadTree(aFile2);
     670                 : 
     671               0 :   nsresult rv = NS_OK;
     672               0 :   if (!CompareTrees(tree1, tree2)) {
     673                 :     // only output this if aRegressionOutput is 0
     674               0 :     if( 0 == aRegressionOutput ){
     675               0 :       printf("Regression data 1:\n");
     676               0 :       DumpTree(tree1, stdout, 0);
     677               0 :       printf("Regression data 2:\n");
     678               0 :       DumpTree(tree2, stdout, 0);
     679                 :     }
     680               0 :     rv = NS_ERROR_FAILURE;
     681                 :   }
     682                 : 
     683               0 :   Node::Destroy(tree1);
     684               0 :   Node::Destroy(tree2);
     685                 : 
     686               0 :   return rv;
     687                 : }
     688                 : 
     689                 : NS_IMETHODIMP
     690               0 : nsFrameUtil::DumpRegressionData(FILE* aInputFile, FILE* aOutputFile)
     691                 : {
     692               0 :   Node* tree1 = Node::ReadTree(aInputFile);
     693               0 :   if (nsnull != tree1) {
     694               0 :     DumpTree(tree1, aOutputFile, 0);
     695               0 :     Node::Destroy(tree1);
     696               0 :     return NS_OK;
     697                 :   }
     698               0 :   return NS_ERROR_FAILURE;
     699                 : }
     700                 : #endif

Generated by: LCOV version 1.7