Commits

Anonymous committed ed0b9d6

Files have moved into the src directory.

Comments (0)

Files changed (37)

kdiff3/kdiff3/Makefile.am

-####### kdevelop will overwrite this part!!! (begin)##########
-bin_PROGRAMS = kdiff3
-
-## INCLUDES were found outside kdevelop specific part
-
-kdiff3_SOURCES = optiondialog.cpp merger.cpp pdiff.cpp mergeresultwindow.cpp difftextwindow.cpp diff.cpp kdiff3.cpp main.cpp 
-kdiff3_LDADD   =  $(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET)
-
-
-EXTRA_DIST = main.cpp kdiff3.cpp kdiff3.h kdiff3ui.rc kdiff3.desktop lo32-app-kdiff3.png lo16-app-kdiff3.png diff.h diff.cpp difftextwindow.cpp mergeresultwindow.cpp pdiff.cpp merger.cpp merger.h optiondialog.cpp optiondialog.h hi32-app-kdiff3.png hi16-app-kdiff3.png 
-
-install-data-local:
-	$(mkinstalldirs) $(kde_appsdir)/Applications/
-	$(INSTALL_DATA) $(srcdir)/kdiff3.desktop $(kde_appsdir)/Applications/kdiff3.desktop
-	$(mkinstalldirs) $(kde_icondir)/locolor/32x32/apps/
-	$(INSTALL_DATA) $(srcdir)/lo32-app-kdiff3.png $(kde_icondir)/locolor/32x32/apps/kdiff3.png
-	$(mkinstalldirs) $(kde_icondir)/locolor/16x16/apps/
-	$(INSTALL_DATA) $(srcdir)/lo16-app-kdiff3.png $(kde_icondir)/locolor/16x16/apps/kdiff3.png
-	$(mkinstalldirs) $(kde_icondir)/hicolor/32x32/apps/
-	$(INSTALL_DATA) $(srcdir)/hi32-app-kdiff3.png $(kde_icondir)/hicolor/32x32/apps/kdiff3.png
-	$(mkinstalldirs) $(kde_icondir)/hicolor/16x16/apps/
-	$(INSTALL_DATA) $(srcdir)/hi16-app-kdiff3.png $(kde_icondir)/hicolor/16x16/apps/kdiff3.png
-
-uninstall-local:
-	-rm -f $(kde_appsdir)/Applications/kdiff3.desktop
-	-rm -f $(kde_icondir)/locolor/32x32/apps/kdiff3.png
-	-rm -f $(kde_icondir)/locolor/16x16/apps/kdiff3.png
-	-rm -f $(kde_icondir)/hicolor/32x32/apps/kdiff3.png
-	-rm -f $(kde_icondir)/hicolor/16x16/apps/kdiff3.png
-
-####### kdevelop will overwrite this part!!! (end)############
-# These paths are KDE specific. Use them:
-# kde_appsdir         Where your application's menu entry (.desktop) should go to.
-# kde_icondir         Where your icon should go to - better use KDE_ICON.
-# kde_sounddir        Where your sounds should go to.
-# kde_htmldir         Where your docs should go to. (contains lang subdirs)
-# kde_datadir         Where you install application data. (Use a subdir)
-# kde_locale          Where translation files should go to. (contains lang subdirs)
-# kde_cgidir          Where cgi-bin executables should go to.
-# kde_confdir         Where config files should go to (system-wide ones with default values).
-# kde_mimedir         Where mimetypes .desktop files should go to.
-# kde_servicesdir     Where services .desktop files should go to.
-# kde_servicetypesdir Where servicetypes .desktop files should go to.
-# kde_toolbardir      Where general toolbar icons should go to (deprecated, use KDE_ICON).
-# kde_wallpaperdir    Where general wallpapers should go to.
-# kde_templatesdir    Where templates for the "New" menu (Konqueror/KDesktop) should go to.
-# kde_bindir          Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS.
-# kde_libdir          Where shared libraries should go to. Use lib_LTLIBRARIES.
-# kde_moduledir       Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES.
-# kde_styledir        Where Qt/KDE widget styles should go to (new in KDE 3).
-# kde_designerdir     Where Qt Designer plugins should go to (new in KDE 3).
-
-# set the include path for X, qt and KDE
-INCLUDES= $(all_includes)
-
-METASOURCES = AUTO
-
-# the library search path. 
-kdiff3_LDFLAGS = $(all_libraries) $(KDE_RPATH)
-
-rcdir = $(kde_datadir)/kdiff3
-rc_DATA = kdiff3ui.rc
-
-messages: rc.cpp
-	LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \
-	if test -n "$$LIST"; then \
-	 $(XGETTEXT) $$LIST -o $(podir)/kdiff3.pot; \
-	fi
-

kdiff3/kdiff3/diff.cpp

-/***************************************************************************
-                          diff.cpp  -  description
-                             -------------------
-    begin                : Mon Mar 18 2002
-    copyright            : (C) 2002 by Joachim Eibl
-    email                : joachim.eibl@gmx.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- ***************************************************************************/
-
-/***************************************************************************
- * $Log$
- * Revision 1.1  2002/08/18 16:24:15  joachim99
- * Initial revision
- *                                                                   *
- ***************************************************************************/
-
-#include <stdio.h>
-#include "diff.h"
-
-#include <kmessagebox.h>
-#include <klocale.h>
-using namespace std;
-
-int LineData::width()
-{
-   int w=0;
-   int j=0;
-   for( int i=0; i<size; ++i )
-   {
-      if ( pLine[i]=='\t' )
-      {
-         for(j %= g_tabSize; j<g_tabSize; ++j)
-            ++w;
-         j=0;
-      }
-      else
-      {
-         ++w;
-         ++j;
-      }
-   }
-   return w;
-}
-
-
-// The bStrict flag is true during the test where a nonmatching area ends.
-// Then the equal()-function requires that the match has more than 2 nonwhite characters.
-// This is to avoid matches on trivial lines (e.g. with white space only).
-// This choice is good for C/C++.
-bool equal( const LineData& l1, const LineData& l2, bool bStrict )
-{
-   if ( l1.pLine==0 || l2.pLine==0) return false;
-
-   // Ignore white space diff
-   const char* p1 = l1.pLine;
-   const char* p1End = p1 + l1.size;
-
-   const char* p2 = l2.pLine;
-   const char* p2End = p2 + l2.size;
-
-   if ( g_bIgnoreWhiteSpace )
-   {
-      int nonWhite = 0;
-      for(;;)
-      {
-         while( (*p1==' ' || *p1=='\t') && p1!=p1End ) ++p1;
-         while( (*p2==' ' || *p2=='\t') && p2!=p2End ) ++p2;
-
-         if ( p1 == p1End  &&  p2 == p2End )
-            return bStrict ? (nonWhite>2 || !g_bIgnoreTrivialMatches) : true;
-         else if ( p1 == p1End || p2 == p2End )
-            return false;
-
-         if( *p1 != *p2 )
-            return false;
-         ++p1;
-         ++p2;
-         ++nonWhite;
-      }
-   }
-
-   else
-   {
-      if ( l1.size==l2.size && memcmp(p1, p2, l1.size)==0)
-         return true;
-      else
-         return false;
-   }
-}
-
-
-
-/** Prepare the linedata vector for every input line.*/
-int preprocess( const char* p, int size, vector<LineData>& v )
-{
-   int lines = 1;
-   int i;
-   for( i=0; i<size; ++i )
-   {
-      if (p[i]=='\n')
-      {
-         ++lines;
-      }
-   }
-
-   v.resize( lines+5 );
-   int lineIdx=0;
-   int lineLength=0;
-   for( i=0; i<=size; ++i )
-   {
-
-      // For WIN32
-      if ( i==size || ( p[i]=='\r' && p[i+1]=='\n' ) || p[i]=='\n')        // The last line does not end with a linefeed.
-      {
-         v[lineIdx].pLine = &p[ i-lineLength ];
-         v[lineIdx].size = lineLength;
-         lineLength = 0;
-         ++lineIdx;
-         if ( i<size && p[i]=='\r') ++i;
-      }
-      else
-      {
-         ++lineLength;
-      }
-   }
-   assert( lineIdx == lines );
-
-   return lines;
-}
-
-
-const char* readFile( const char* filename, int& size )
-{
-   size = 0;
-   if (filename==0 || filename[0]=='\0')   return 0;
-   
-   FILE* f = fopen( filename, "rb" );
-   if ( f==0 )
-   {
-      cerr << "File open error for file: '"<< filename <<"': ";
-      perror("");
-      return 0;
-   }
-
-   fseek( f, 0, SEEK_END );
-
-   size =  ftell(f);
-
-   fseek( f, 0, SEEK_SET );
-
-   char* buf = new char[size+100];
-   int bytesRead = fread( buf, 1, size, f );
-   if( bytesRead != size )
-   {
-      cerr << "File read error for file: '"<< filename <<"': ";
-
-
-      perror("");
-      exit(-1);
-   }
-
-   return buf;
-}
-
-
-// First step
-void calcDiff3LineListUsingAB(       
-   const DiffList* pDiffListAB,
-   Diff3LineList& d3ll
-   )
-{
-   // First make d3ll for AB (from pDiffListAB)
-
-   DiffList::const_iterator i=pDiffListAB->begin();
-   int lineA=0;
-   int lineB=0;
-   Diff d(0,0,0);
-
-   for(;;)
-   {
-      if ( d.nofEquals==0 && d.diff1==0 && d.diff2==0 )
-      {
-         if ( i!=pDiffListAB->end() )
-         {
-            d=*i;
-            ++i;
-         }
-         else
-            break;
-      }
-
-      Diff3Line d3l;
-      if( d.nofEquals>0 )
-      {
-         d3l.bAEqB = true;
-         d3l.lineA = lineA;
-         d3l.lineB = lineB;
-         --d.nofEquals;
-         ++lineA;
-         ++lineB;
-      }
-      else if ( d.diff1>0 && d.diff2>0 )
-      {
-         d3l.lineA = lineA;
-         d3l.lineB = lineB;
-         --d.diff1;
-         --d.diff2;
-         ++lineA;
-         ++lineB;
-      }
-      else if ( d.diff1>0 )
-      {
-         d3l.lineA = lineA;
-         --d.diff1;
-         ++lineA;
-      }
-      else if ( d.diff2>0 )
-      {
-         d3l.lineB = lineB;
-         --d.diff2;
-         ++lineB;
-      }
-
-      d3ll.push_back( d3l );      
-   }
-}
-
-
-// Second step
-void calcDiff3LineListUsingAC(       
-   const DiffList* pDiffListAC,
-   Diff3LineList& d3ll
-   )
-{
-   ////////////////
-   // Now insert data from C using pDiffListAC
-
-   DiffList::const_iterator i=pDiffListAC->begin();
-   Diff3LineList::iterator i3 = d3ll.begin();
-   int lineA=0;
-   int lineC=0;
-   Diff d(0,0,0);
-
-   for(;;)
-   {
-      if ( d.nofEquals==0 && d.diff1==0 && d.diff2==0 )
-      {
-         if ( i!=pDiffListAC->end() )
-         {
-            d=*i;
-            ++i;
-         }
-         else
-            break;
-      }
-
-      Diff3Line d3l;
-      if( d.nofEquals>0 )
-      {
-         // Find the corresponding lineA
-         while( (*i3).lineA!=lineA ) 
-            ++i3;
-         (*i3).lineC = lineC;
-
-
-         (*i3).bAEqC = true;
-         (*i3).bBEqC = (*i3).bAEqB;
-                  
-         --d.nofEquals;
-         ++lineA;
-         ++lineC;
-         ++i3;
-      }
-      else if ( d.diff1>0 && d.diff2>0 )
-      {
-         d3l.lineC = lineC;
-         d3ll.insert( i3, d3l );
-         --d.diff1;
-         --d.diff2;
-         ++lineA;
-         ++lineC;
-      }
-      else if ( d.diff1>0 )
-      {
-         --d.diff1;
-         ++lineA;
-      }
-      else if ( d.diff2>0 )
-      {
-         d3l.lineC = lineC;
-         d3ll.insert( i3, d3l );
-         --d.diff2;
-         ++lineC;
-      }
-   }
-}
-
-// Third step
-void calcDiff3LineListUsingBC(       
-   const DiffList* pDiffListBC,
-   Diff3LineList& d3ll
-   )
-{
-   ////////////////
-   // Now improve the position of data from C using pDiffListBC
-   // If a line from C equals a line from A then it is in the
-   // same Diff3Line already.
-   // If a line from C equals a line from B but not A, this
-   // information will be used here.
-
-   DiffList::const_iterator i=pDiffListBC->begin();
-   Diff3LineList::iterator i3b = d3ll.begin();
-   Diff3LineList::iterator i3c = d3ll.begin();
-   int lineB=0;
-   int lineC=0;
-   Diff d(0,0,0);
-
-   for(;;)
-   {
-      if ( d.nofEquals==0 && d.diff1==0 && d.diff2==0 )
-      {
-         if ( i!=pDiffListBC->end() )
-         {
-            d=*i;
-            ++i;
-         }
-         else
-            break;
-      }
-
-      Diff3Line d3l;
-      if( d.nofEquals>0 )
-      {
-         // Find the corresponding lineB and lineC
-         while( i3b!=d3ll.end() && (*i3b).lineB!=lineB ) 
-            ++i3b;
-
-         while( i3c!=d3ll.end() && (*i3c).lineC!=lineC )
-            ++i3c;
-
-         assert(i3b!=d3ll.end());
-         assert(i3c!=d3ll.end());
-
-         if ( i3b==i3c )
-         {
-            assert( (*i3b).lineC == lineC );
-            (*i3b).bBEqC = true;
-         }
-         else //if ( !(*i3b).bAEqB )
-         {
-            // Is it possible to move this line up?
-            // Test if no other B's are used between i3c and i3b
-
-            // First test which is before: i3c or i3b ?
-            Diff3LineList::iterator i3c1 = i3c;
-            Diff3LineList::iterator i3b1 = i3b;
-            while( i3c1!=i3b  &&  i3b1!=i3c )
-            {
-               assert(i3b1!=d3ll.end() || i3c1!=d3ll.end());
-               if( i3c1!=d3ll.end() ) ++i3c1;
-               if( i3b1!=d3ll.end() ) ++i3b1;
-            }
-
-            if( i3c1==i3b  &&  !(*i3b).bAEqB ) // i3c before i3b
-            {
-               Diff3LineList::iterator i3 = i3c;
-               int nofDisturbingLines = 0;
-               while( i3 != i3b && i3!=d3ll.end() )
-               {
-                  if ( (*i3).lineB != -1 ) 
-                     ++nofDisturbingLines;
-                  ++i3;
-               }
-
-               if ( nofDisturbingLines>0 && nofDisturbingLines < d.nofEquals )
-               {
-                  // Move the disturbing lines up, out of sight.
-                  i3 = i3c;
-                  while( i3 != i3b )
-                  {
-                     if ( (*i3).lineB != -1 ) 
-                     {
-                        Diff3Line d3l;
-                        d3l.lineB = (*i3).lineB;
-                        (*i3).lineB = -1;
-
-
-                        (*i3).bAEqB = false;
-                        (*i3).bBEqC = false;
-                        d3ll.insert( i3c, d3l );
-                     }
-                     ++i3;
-                  }
-                  nofDisturbingLines=0;
-               }
-
-               if ( nofDisturbingLines == 0 )
-               {
-                  // Yes, the line from B can be moved.
-                  (*i3b).lineB = -1;   // This might leave an empty line: removed later.
-                  (*i3b).bAEqB = false;
-                  (*i3b).bAEqC = false;
-                  (*i3b).bBEqC = false;
-                  //(*i3b).lineC = -1;
-                  (*i3c).lineB = lineB;
-                  (*i3c).bBEqC = true;
-               }
-            }
-
-            else if( i3b1==i3c  &&  !(*i3b).bAEqC)
-            {
-               Diff3LineList::iterator i3 = i3b;
-               int nofDisturbingLines = 0;
-               while( i3 != i3c && i3!=d3ll.end() )
-               {
-                  if ( (*i3).lineC != -1 ) 
-                     ++nofDisturbingLines;
-                  ++i3;
-               }
-
-               if ( nofDisturbingLines>0 && nofDisturbingLines < d.nofEquals )
-               {
-                  // Move the disturbing lines up, out of sight.
-                  i3 = i3b;
-                  while( i3 != i3c )
-                  {
-                     if ( (*i3).lineC != -1 ) 
-                     {
-                        Diff3Line d3l;
-                        d3l.lineC = (*i3).lineC;
-                        (*i3).lineC = -1;
-                        (*i3).bAEqC = false;
-                        (*i3).bBEqC = false;
-                        d3ll.insert( i3b, d3l );
-                     }
-                     ++i3;
-
-                  }
-                  nofDisturbingLines=0;
-               }
-
-               if ( nofDisturbingLines == 0 )
-               {
-                  // Yes, the line from C can be moved.
-                  (*i3c).lineC = -1;   // This might leave an empty line: removed later.
-                  (*i3c).bAEqC = false;
-                  (*i3c).bBEqC = false;
-                  //(*i3c).lineB = -1;
-                  (*i3b).lineC = lineC;
-                  (*i3b).bBEqC = true;
-               }
-            }
-         }
-                  
-         --d.nofEquals;
-         ++lineB;
-         ++lineC;
-         ++i3b;
-         ++i3c;
-      }
-      else if ( d.diff1>0 )
-      {
-         Diff3LineList::iterator i3 = i3b;
-         while( (*i3).lineB!=lineB ) 
-            ++i3;
-         if( i3 != i3b  &&  (*i3).bAEqB==false )
-         {
-            // Take this line and move it up as far as possible
-            d3l.lineB = lineB;
-            d3ll.insert( i3b, d3l );
-            (*i3).lineB = -1;
-         }
-         else
-         {
-            i3b=i3;
-         }
-         --d.diff1;
-         ++lineB;
-         ++i3b;
-
-         if( d.diff2>0 )
-         {
-            --d.diff2;
-            ++lineC;
-         }
-      }
-      else if ( d.diff2>0 )
-      {
-         --d.diff2;
-         ++lineC;
-      }
-   }
-/*
-   Diff3LineList::iterator it = d3ll.begin();
-   int li=0;
-   for( ; it!=d3ll.end(); ++it, ++li )
-   {
-      printf( "%4d %4d %4d %4d  A%c=B A%c=C B%c=C\n",  
-         li, (*it).lineA, (*it).lineB, (*it).lineC, 
-         (*it).bAEqB ? '=' : '!', (*it).bAEqC ? '=' : '!', (*it).bBEqC ? '=' : '!' );
-   }
-   printf("\n");*/
-}
-
-// Fourth step
-void calcDiff3LineListTrim(       
-   Diff3LineList& d3ll, LineData* pldA, LineData* pldB, LineData* pldC
-   )
-{
-   const Diff3Line d3l_empty;
-   d3ll.remove( d3l_empty );
-
-   Diff3LineList::iterator i3 = d3ll.begin();
-   Diff3LineList::iterator i3A = d3ll.begin();
-   Diff3LineList::iterator i3B = d3ll.begin();
-   Diff3LineList::iterator i3C = d3ll.begin();
-
-
-   int line=0;
-   int lineA=0;
-   int lineB=0;
-   int lineC=0;
-
-   // The iterator i3 and the variable line look ahead.
-   // The iterators i3A, i3B, i3C and corresponding lineA, lineB and lineC stop at empty lines, if found.
-   // If possible, then the texts from the look ahead will be moved back to the empty places.
-
-   for( ; i3!=d3ll.end(); ++i3, ++line )
-   {
-
-      if( line>lineA && (*i3).lineA != -1 && (*i3A).lineB!=-1 && (*i3A).bBEqC  &&
-
-          equal( pldA[(*i3).lineA], pldB[(*i3A).lineB], false ))
-      {
-         // Empty space for A. A matches B and C in the empty line. Move it up.
-         (*i3A).lineA = (*i3).lineA;
-         (*i3A).bAEqB = true;
-         (*i3A).bAEqC = true;
-         (*i3).lineA = -1;
-         (*i3).bAEqB = false;
-         (*i3).bAEqC = false;
-         ++i3A;
-         ++lineA;
-      }
-
-      if( line>lineB && (*i3).lineB != -1 && (*i3B).lineA!=-1 && (*i3B).bAEqC  &&
-          equal( pldB[(*i3).lineB], pldA[(*i3B).lineA], false ))
-      {
-         // Empty space for B. B matches A and C in the empty line. Move it up.
-         (*i3B).lineB = (*i3).lineB;
-         (*i3B).bAEqB = true;
-         (*i3B).bBEqC = true;
-         (*i3).lineB = -1;
-         (*i3).bAEqB = false;
-         (*i3).bBEqC = false;
-         ++i3B;
-         ++lineB;
-      }
-
-      if( line>lineC && (*i3).lineC != -1 && (*i3C).lineA!=-1 && (*i3C).bAEqB  &&
-          equal( pldC[(*i3).lineC], pldA[(*i3C).lineA], false ))
-      {
-         // Empty space for C. C matches A and B in the empty line. Move it up.
-         (*i3C).lineC = (*i3).lineC;
-         (*i3C).bAEqC = true;
-         (*i3C).bBEqC = true;
-         (*i3).lineC = -1;
-         (*i3).bAEqC = false;
-         (*i3).bBEqC = false;
-         ++i3C;
-         ++lineC;
-      }
-
-      if( line>lineA && (*i3).lineA != -1 && !(*i3).bAEqB && !(*i3).bAEqC )
-      {
-         // Empty space for A. A doesn't match B or C. Move it up.
-         (*i3A).lineA = (*i3).lineA;
-         (*i3).lineA = -1;
-         ++i3A;
-         ++lineA;
-      }
-
-      if( line>lineB && (*i3).lineB != -1 && !(*i3).bAEqB && !(*i3).bBEqC )
-      {
-         // Empty space for B. B matches neither A nor C. Move B up.
-         (*i3B).lineB = (*i3).lineB;
-         (*i3).lineB = -1;
-         ++i3B;
-         ++lineB;
-      }
-
-      if( line>lineC && (*i3).lineC != -1 && !(*i3).bAEqC && !(*i3).bBEqC )
-      {
-         // Empty space for C. C matches neither A nor B. Move C up.
-         (*i3C).lineC = (*i3).lineC;
-         (*i3).lineC = -1;
-         ++i3C;
-         ++lineC;
-      }
-
-      if( line>lineA && line>lineB && (*i3).lineA != -1 && (*i3).bAEqB && !(*i3).bAEqC )
-      {
-         // Empty space for A and B. A matches B, but not C. Move A & B up.
-         Diff3LineList::iterator i = lineA > lineB ? i3A   : i3B;
-         int                     l = lineA > lineB ? lineA : lineB;
-         (*i).lineA = (*i3).lineA;
-         (*i).lineB = (*i3).lineB;
-         (*i).bAEqB = true;
-                  
-         (*i3).lineA = -1;
-         (*i3).lineB = -1;
-         (*i3).bAEqB = false;
-         i3A = i;
-         i3B = i;
-         ++i3A;
-         ++i3B;
-         lineA=l+1;
-         lineB=l+1;
-      }
-      else if( line>lineA && line>lineC && (*i3).lineA != -1 && (*i3).bAEqC && !(*i3).bAEqB )
-      {
-         // Empty space for A and C. A matches C, but not B. Move A & C up.
-         Diff3LineList::iterator i = lineA > lineC ? i3A   : i3C;
-         int                     l = lineA > lineC ? lineA : lineC;
-         (*i).lineA = (*i3).lineA;
-         (*i).lineC = (*i3).lineC;
-         (*i).bAEqC = true;
-                  
-         (*i3).lineA = -1;
-         (*i3).lineC = -1;
-         (*i3).bAEqC = false;
-         i3A = i;
-         i3C = i;
-         ++i3A;
-         ++i3C;
-         lineA=l+1;
-         lineC=l+1;
-      }
-      else if( line>lineB && line>lineC && (*i3).lineB != -1 && (*i3).bBEqC && !(*i3).bAEqC )
-      {
-         // Empty space for B and C. B matches C, but not A. Move B & C up.
-         Diff3LineList::iterator i = lineB > lineC ? i3B   : i3C;
-         int                     l = lineB > lineC ? lineB : lineC;
-         (*i).lineB = (*i3).lineB;
-         (*i).lineC = (*i3).lineC;
-         (*i).bBEqC = true;
-                  
-         (*i3).lineB = -1;
-         (*i3).lineC = -1;
-         (*i3).bBEqC = false;
-         i3B = i;
-         i3C = i;
-         ++i3B;
-         ++i3C;
-         lineB=l+1;
-         lineC=l+1;
-      }
-
-      if ( (*i3).lineA != -1 )
-      {
-         lineA = line+1;
-         i3A = i3;
-         ++i3A;
-      }
-      if ( (*i3).lineB != -1 )
-      {
-         lineB = line+1;
-         i3B = i3;
-         ++i3B;
-      }
-      if ( (*i3).lineC != -1 )
-      {
-         lineC = line+1;
-         i3C = i3;
-         ++i3C;
-      }
-   }
-
-   d3ll.remove( d3l_empty );
-
-/*
-
-   Diff3LineList::iterator it = d3ll.begin();
-   int li=0;
-   for( ; it!=d3ll.end(); ++it, ++li )
-   {
-      printf( "%4d %4d %4d %4d  A%c=B A%c=C B%c=C\n",  
-         li, (*it).lineA, (*it).lineB, (*it).lineC, 
-         (*it).bAEqB ? '=' : '!', (*it).bAEqC ? '=' : '!', (*it).bBEqC ? '=' : '!' );
-
-   }
-*/
-}
-
-
-// Just make sure that all input lines are in the output too, exactly once.
-void debugLineCheck( Diff3LineList& d3ll, int size, int idx )
-{
-   Diff3LineList::iterator it = d3ll.begin();
-
-   
-   int i=0;
-
-   for ( it = d3ll.begin(); it!= d3ll.end(); ++it )
-   {
-      int l;
-      if      (idx==1) l=(*it).lineA;
-      else if (idx==2) l=(*it).lineB;
-      else if (idx==3) l=(*it).lineC;
-      else assert(false);
-
-      if ( l!=-1 )
-      {
-         if( l!=i )
-         {
-            KMessageBox::error(0, i18n(
-               "Data loss error:\n"
-               "If it is reproducable please contact the author.\n"
-               ), "Severe internal Error" );
-            assert(false);
-            cerr << "Severe Internal Error.\n";
-            exit(-1);
-         }
-         ++i;
-      }
-   }
-
-   if( size!=i )
-   {
-      KMessageBox::error(0, i18n(
-         "Data loss error:\n"
-         "If it is reproducable please contact the author.\n"
-         ), "Severe internal Error" );
-      assert(false);
-      cerr << "Severe Internal Error.\n";
-      exit(-1);
-   }
-}
-
-
-void fineDiff(
-   Diff3LineList& diff3LineList,
-   int selector,
-   LineData* v1,
-   LineData* v2
-   )
-{
-   // Finetuning: Diff each line with deltas
-   Diff3LineList::iterator i;
-   int k1=0;
-   int k2=0;
-   for( i= diff3LineList.begin(); i!= diff3LineList.end(); ++i)
-   {
-      if      (selector==1){ k1=i->lineA; k2=i->lineB; }
-      else if (selector==2){ k1=i->lineB; k2=i->lineC; }
-      else if (selector==3){ k1=i->lineC; k2=i->lineA; }
-      else assert(false);
-
-      if( k1!=-1 && k2!=-1 )
-      {
-         if ( v1[k1].size != v2[k2].size || memcmp( v1[k1].pLine, v2[k2].pLine, v1[k1].size)!=0 )
-         {
-            DiffList* pDiffList = new DiffList;
-            calcDiff( v1[k1].pLine, v1[k1].size, v2[k2].pLine, v2[k2].size, *pDiffList, 2 );
-
-            // Optimize the diff list.
-            DiffList::iterator dli;
-            for( dli = pDiffList->begin(); dli!=pDiffList->end(); ++dli)
-            {
-               if( dli->nofEquals < 4  &&  (dli->diff1>0 || dli->diff2>0)  )
-               {
-                  dli->diff1 += dli->nofEquals;
-                  dli->diff2 += dli->nofEquals;
-                  dli->nofEquals = 0;
-               }
-            }
-
-            if      (selector==1){ delete (*i).pFineAB; (*i).pFineAB = pDiffList; }
-            else if (selector==2){ delete (*i).pFineBC; (*i).pFineBC = pDiffList; }
-            else if (selector==3){ delete (*i).pFineCA; (*i).pFineCA = pDiffList; }
-            else assert(false);
-         }
-      }
-   }
-}

kdiff3/kdiff3/diff.h

-/***************************************************************************
-                          diff.h  -  description
-                             -------------------
-    begin                : Mon Mar 18 2002
-    copyright            : (C) 2002 by Joachim Eibl
-    email                : joachim.eibl@gmx.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- ***************************************************************************/
-
-/***************************************************************************
- * $Log$
- * Revision 1.1  2002/08/18 16:24:17  joachim99
- * Initial revision
- *                                                                   *
- ***************************************************************************/
-
-#ifndef DIFF_H
-#define DIFF_H
-
-#include <qwidget.h>
-#include <qpixmap.h>
-#include <qtimer.h>
-#include <qframe.h>
-#include <list>
-#include <vector>
-
-typedef unsigned char UINT8;
-typedef unsigned short UINT16;
-typedef unsigned int UINT32;
-
-
-// Each range with matching elements is followed by a range with differences on either side.
-// Then again range of matching elements should follow.
-struct Diff
-{
-   int nofEquals;
-
-   int diff1;
-   int diff2;
-
-   Diff(int eq, int d1, int d2){nofEquals=eq; diff1=d1; diff2=d2; }
-};
-
-typedef std::list<Diff> DiffList;
-
-struct Diff3Line
-{
-   int lineA;
-   int lineB;
-   int lineC;
-
-   bool bAEqC;
-   bool bBEqC;
-   bool bAEqB;
-
-   DiffList* pFineAB;
-   DiffList* pFineBC;
-   DiffList* pFineCA;
-
-   Diff3Line()
-   {
-      lineA=-1; lineB=-1; lineC=-1;
-      bAEqC=false; bAEqB=false; bBEqC=false;
-      pFineAB=0; pFineBC=0; pFineCA=0;
-   }
-
-   ~Diff3Line()
-   {
-      if (pFineAB!=0) delete pFineAB;
-      if (pFineBC!=0) delete pFineBC;
-      if (pFineCA!=0) delete pFineCA;
-      pFineAB=0; pFineBC=0; pFineCA=0;
-   }
-
-   bool operator==( const Diff3Line& d3l )
-   {
-      return lineA == d3l.lineA  &&  lineB == d3l.lineB  &&  lineC == d3l.lineC  
-         && bAEqB == d3l.bAEqB  && bAEqC == d3l.bAEqC  && bBEqC == d3l.bBEqC;
-   }
-};
-
-typedef std::list<Diff3Line> Diff3LineList;
-
-void calcDiff3LineListUsingAB(       
-   const DiffList* pDiffListAB,
-   Diff3LineList& d3ll
-   );
-
-void calcDiff3LineListUsingAC(       
-   const DiffList* pDiffListBC,
-   Diff3LineList& d3ll
-   );
-
-void calcDiff3LineListUsingBC(       
-   const DiffList* pDiffListBC,
-   Diff3LineList& d3ll
-   );
-
-struct LineData
-{
-   const char* pLine;
-   int size;
-
-   LineData(){ pLine=0; size=0; }
-   int width();  // Calcs width considering tabs.
-};
-
-void calcDiff3LineListTrim( Diff3LineList& d3ll, LineData* pldA, LineData* pldB, LineData* pldC );
-
-void debugLineCheck( Diff3LineList& d3ll, int size, int idx );
-
-class QStatusBar;
-
-
-
-
-
-
-class Selection
-{
-public:
-   Selection(){ reset(); oldLastLine=-1; oldFirstLine=-1; }
-   int firstLine;
-   int firstPos;
-   int lastLine;
-   int lastPos;
-   int oldLastLine;
-   int oldFirstLine;
-   bool bSelectionContainsData;
-   void reset(){
-      oldFirstLine=firstLine;
-      oldLastLine =lastLine;
-      firstLine=-1;
-      bSelectionContainsData = false;
-   }
-   void start( int l, int p ) { firstLine = l; firstPos = p; }
-   void end( int l, int p )  {
-      if ( oldLastLine == -1 )
-         oldLastLine = lastLine;
-      lastLine  = l;
-      lastPos  = p;
-   }
-   bool within( int l, int p );
-   bool lineWithin( int l );
-   int firstPosInLine(int l);
-   int lastPosInLine(int l);
-   int beginLine(){ return min(firstLine,lastLine); }
-   int endLine(){ return max(firstLine,lastLine); }
-   int beginPos() { return firstLine==lastLine ? min(firstPos,lastPos) :
-                           firstLine<lastLine ? firstPos : lastPos;      }
-   int endPos()   { return firstLine==lastLine ? max(firstPos,lastPos) :
-                           firstLine<lastLine ? lastPos : firstPos;      }
-};
-
-class OptionDialog;
-
-class DiffTextWindow : public QWidget
-{
-   Q_OBJECT
-public:
-   DiffTextWindow(
-      QWidget* pParent,
-      QStatusBar* pStatusBar,
-      OptionDialog* pOptionDialog
-      );
-   void init(
-      const char* pFilename,
-      LineData* pLineData,
-      int size,
-      const Diff3LineList* pDiff3LineList,
-      int winIdx,
-      bool bTriple
-      );
-   virtual void mousePressEvent ( QMouseEvent * );
-   virtual void mouseReleaseEvent ( QMouseEvent * );
-   virtual void mouseMoveEvent ( QMouseEvent * );
-   virtual void mouseDoubleClickEvent ( QMouseEvent * e );
-   void convertToLinePos( int x, int y, int& line, int& pos );
-
-   virtual void paintEvent( QPaintEvent*  );
-
-   //void setData( const char* pText);
-
-   virtual void resizeEvent( QResizeEvent* );
-
-   QString getSelection();
-   int getFirstLine() { return m_firstLine; }
-
-   int getNofColumns();
-   int getNofLines();
-
-signals:
-   void resizeSignal( int nofVisibleColumns, int nofVisibleLines );
-   void scroll( int deltaX, int deltaY );
-   void newSelection();
-   void selectionEnd();
-   void setFastSelectorLine( int line );
-
-public slots:
-   void setFirstLine( int line );
-   void setFirstColumn( int col );
-   void resetSelection();
-   void setFastSelectorRange( int line1, int nofLines );
-private:
-   LineData* m_pLineData;
-   int m_size;
-   const char* m_pFilename;
-
-   const Diff3LineList* m_pDiff3LineList;
-
-   OptionDialog* m_pOptionDialog;
-   QColor m_cThis;
-   QColor m_cDiff1;
-   QColor m_cDiff2;
-   QColor m_cDiffBoth;
-
-   int m_fastSelectorLine1;
-   int m_fastSelectorNofLines;
-
-   bool m_bTriple;
-   int m_winIdx;
-   int m_firstLine;
-   int m_oldFirstLine;
-   int m_oldFirstColumn;
-   int m_firstColumn;
-
-   int m_visibleColumns;
-   int m_visibleLines;
-
-   void getLineInfo(
-      const Diff3Line& d,
-      int& lineIdx,
-      DiffList*& pFineDiff1, DiffList*& pFineDiff2,   // return values
-      int& changed, int& changed  );
-
-   QCString getString( int line );
-
-   void writeLine(
-      QPainter& p, const LineData* pld,
-      const DiffList* pLineDiff1, const DiffList* pLineDiff2, int line,
-      int whatChanged, int whatChanged2 );
-
-   QStatusBar* m_pStatusBar;
-
-   Selection selection;
-
-   int m_scrollDeltaX;
-   int m_scrollDeltaY;
-   virtual void timerEvent(QTimerEvent*);
-   bool m_bMyUpdate;
-   void myUpdate(int afterMilliSecs );
-
-   QRect m_invalidRect;
-};
-
-
-
-class Overview : public QWidget
-{
-   Q_OBJECT
-public:
-   Overview( QWidget* pParent, Diff3LineList* pDiff3LineList,
-             OptionDialog* pOptions, bool bTripleDiff );
-   void setRange( int firstLine, int pageHeight );
-
-public slots:
-   void setFirstLine(int firstLine);
-signals:
-   void setLine(int);
-private:
-   const Diff3LineList* m_pDiff3LineList;
-   OptionDialog* m_pOptions;
-   bool m_bTripleDiff;
-   int m_firstLine;
-   int m_pageHeight;
-   QPixmap m_pixmap;
-
-   virtual void paintEvent( QPaintEvent* e );
-   virtual void mousePressEvent( QMouseEvent* e );
-   virtual void mouseMoveEvent( QMouseEvent* e );
-};
-
-
-enum e_MergeDetails
-{
-   eDefault,
-   eNoChange,
-   eBChanged,
-   eCChanged,
-   eBCChanged,         // conflict
-   eBCChangedAndEqual, // possible conflict
-   eBDeleted,
-   eCDeleted,
-   eBCDeleted,         // possible conflict
-
-   eBChanged_CDeleted, // conflict
-   eCChanged_BDeleted, // conflict
-   eBAdded,
-   eCAdded,
-   eBCAdded,           // conflict
-   eBCAddedAndEqual    // possible conflict
-};
-
-void mergeOneLine( const Diff3Line& d, e_MergeDetails& mergeDetails, bool& bConflict, bool& bLineRemoved, int& src, bool bTwoInputs );
-
-
-class MergeResultWindow : public QWidget
-{
-   Q_OBJECT
-public:
-
-
-   MergeResultWindow(
-      QWidget* pParent,
-      const LineData* pLineDataA,
-      const LineData* pLineDataB,
-      const LineData* pLineDataC,
-      const Diff3LineList* pDiff3LineList,
-      QString fileName,
-      OptionDialog* pOptionDialog
-      );
-
-   bool saveDocument( const QString& fileName );
-   void choose(int selector);
-
-   int getNofColumns();
-   int getNofLines();
-   int getNofVisibleColumns();
-   int getNofVisibleLines();
-   virtual void resizeEvent( QResizeEvent* e );
-   virtual void keyPressEvent( QKeyEvent* e );
-   QString getSelection();
-   void resetSelection();
-public slots:
-   void setFirstLine(int firstLine);
-   void setFirstColumn(int firstCol);
-
-   void slotGoTop();
-   void slotGoBottom();
-   void slotGoPrevDelta();
-   void slotGoNextDelta();
-   void slotGoPrevConflict();
-
-   void slotGoNextConflict();
-   void slotChooseA();
-   void slotChooseB();
-   void slotChooseC();
-
-   void slotSetFastSelectorLine(int);
-
-
-signals:
-   void scroll( int deltaX, int deltaY );
-   void modified();
-   void savable( bool bSavable );
-   void setFastSelectorRange( int line1, int nofLines );
-
-   void sourceMask( int srcMask, int enabledMask );
-   void resizeSignal();
-   void selectionEnd();
-   void newSelection();
-
-private:
-   void merge();
-
-   OptionDialog* m_pOptionDialog;
-
-   const LineData* m_pldA;
-   const LineData* m_pldB;
-   const LineData* m_pldC;
-
-   const Diff3LineList* m_pDiff3LineList;
-
-private:
-
-   class MergeEditLine
-   {
-   public:
-      MergeEditLine(){ m_src=0; m_bLineRemoved=false; }
-      void setConflict() { m_src=0; m_bLineRemoved=false; m_str=QCString(); }
-      bool isConflict()  { return  m_src==0 && !m_bLineRemoved && m_str.isNull(); }
-      void setRemoved(int src=0)  { m_src=src; m_bLineRemoved=true; m_str=QCString(); }
-      bool isRemoved()   { return m_bLineRemoved; }
-      bool isEditableText() { return !isConflict() && !isRemoved(); }
-      void setString( const QCString& s ){ m_str=s; m_bLineRemoved=false; m_src=0; }
-      const char* getString( const MergeResultWindow*, int& size );
-      bool isModified() { return ! m_str.isNull() ||  (m_bLineRemoved && m_src==0); }
-      void setSource( int src, Diff3LineList::const_iterator i, bool bLineRemoved )
-      {
-         m_src=src; m_id3l=i; m_bLineRemoved =bLineRemoved;
-      }
-      int src() { return m_src; }
-      Diff3LineList::const_iterator id3l(){return m_id3l;}
-      // getString() is implemented as MergeResultWindow::getString()
-   private:
-      Diff3LineList::const_iterator m_id3l;
-      int m_src;         // 1, 2 or 3 for A, B or C respectively, or 0 when line is from neither source.
-      QCString m_str;    // String when modified by user or null-string when orig data is used.
-      bool m_bLineRemoved;
-   };
-   typedef list<MergeEditLine> MergeEditLineList;
-
-   friend class MergeEditLine;
-
-   struct MergeLine
-   {
-      MergeLine()
-      { srcSelect=0; mergeDetails=eDefault; d3lLineIdx = -1; srcRangeLength=0; bConflict=false; bDelta=false;}
-      Diff3LineList::const_iterator id3l;
-      e_MergeDetails mergeDetails;
-      int d3lLineIdx;  // Needed to show the correct window pos.
-      int srcRangeLength; // how many src-lines have this properties
-      bool bConflict;
-      bool bDelta;
-      int srcSelect;
-      MergeEditLineList mergeEditLineList;
-   };
-
-private:
-   static bool sameKindCheck( const MergeLine& ml1, const MergeLine& ml2 );
-
-
-   typedef list<MergeLine> MergeLineList;
-   MergeLineList m_mergeLineList;
-
-
-   MergeLineList::iterator m_currentMergeLineIt;
-   int m_currentPos;
-
-   enum e_Direction { eUp, eDown };
-   enum e_EndPoint  { eDelta, eConflict, eLine, eEnd };
-   void go( e_Direction eDir, e_EndPoint eEndPoint );
-   void calcIteratorFromLineNr(
-      int line,
-      MergeLineList::iterator& mlIt,
-      MergeEditLineList::iterator& melIt
-
-      );
-
-   virtual void paintEvent( QPaintEvent* e );
-
-   void myUpdate(int afterMilliSecs);
-   virtual void timerEvent(QTimerEvent*);
-   void writeLine(
-      QPainter& p, int line, const char* pStr, int size,
-      int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved
-      );
-   void setFastSelector(MergeLineList::iterator i);
-   void convertToLinePos( int x, int y, int& line, int& pos );
-   virtual void mousePressEvent ( QMouseEvent* e );
-   virtual void mouseDoubleClickEvent ( QMouseEvent* e );
-   virtual void mouseReleaseEvent ( QMouseEvent * );
-   virtual void mouseMoveEvent ( QMouseEvent * );
-
-   QPixmap m_pixmap;
-   int m_firstLine;
-   int m_firstColumn;
-   int m_nofColumns;
-   int m_nofLines;
-   bool m_bMyUpdate;
-   bool m_bInsertMode;
-   QString m_fileName;
-   bool m_bModified;
-   void setModified();
-
-   int m_scrollDeltaX;
-   int m_scrollDeltaY;
-   int m_cursorXPos;
-   int m_cursorYPos;
-   int m_cursorOldXPos;
-   bool m_bCursorOn; // blinking on and off each second
-   QTimer m_cursorTimer;
-
-   Selection m_selection;
-
-   bool deleteSelection2( const char*& ps, int& stringLength, int& x, int& y,
-                    MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt );
-public slots:
-   void deleteSelection();
-   void pasteClipboard();
-private slots:
-   void slotCursorUpdate();
-};
-
-void fineDiff(
-   Diff3LineList& diff3LineList,
-   int selector,
-   LineData* v1,
-   LineData* v2
-   );
-
-const char* readFile( const char* filename, int& size );
-
-int preprocess( const char* p, int size, std::vector<LineData>& v );
-
-bool equal( const LineData& l1, const LineData& l2, bool bStrict );
-
-
-
-inline bool equal( char c1, char c2, bool bStrict )
-{
-   // If bStrict then white space doesn't match
-   if ( bStrict &&  ( c1==' ' || c1=='\t' ) )
-      return false;
-
-   return c1==c2;
-}
-
-
-template <class T>
-void calcDiff( const T* p1, int size1, const T* p2, int size2, DiffList& diffList, int match=1 )
-{
-
-   diffList.clear();
-
-   const T* p1start = p1;
-   const T* p2start = p2;
-   const T* p1end=p1+size1;
-   const T* p2end=p2+size2;
-   for(;;)
-   {
-      int nofEquals = 0;
-      while( p1!=p1end &&  p2!=p2end && equal(*p1, *p2, false) )
-      {
-         ++p1;
-         ++p2;
-         ++nofEquals;
-      }
-
-      bool bBestValid=false;
-      int bestI1=0;
-      int bestI2=0;
-      int i1=0;
-      int i2=0;
-      for( i1=0; ; ++i1 )
-      {
-         if ( &p1[i1]==p1end || ( bBestValid && i1>= bestI1+bestI2))
-         {
-            break;
-         }
-         for(i2=0;;++i2)
-         {
-            if( &p2[i2]==p2end ||  ( bBestValid && i1+i2>=bestI1+bestI2) )
-            {
-               break;
-            }
-            else if(  equal( p2[i2], p1[i1], true ) &&
-                      ( match==1 ||  abs(i1-i2)<3  || ( &p2[i2+1]==p2end  &&  &p1[i1+1]==p1end ) ||
-                         ( &p2[i2+1]!=p2end  &&  &p1[i1+1]!=p1end  && equal( p2[i2+1], p1[i1+1], false ))
-                      )
-                   )
-            {
-               if ( i1+i2 < bestI1+bestI2 || bBestValid==false )
-               {
-                  bestI1 = i1;
-                  bestI2 = i2;
-                  bBestValid = true;
-                  break;
-               }
-            }
-         }
-      }
-
-      // The match was found using the strict search. Go back if there are non-strict
-      // matches.
-      while( bestI1>=1 && bestI2>=1 && equal( p1[bestI1-1], p2[bestI2-1], false ) )
-      {
-         --bestI1;
-         --bestI2;
-      }
-
-      bool bEndReached = false;
-      if (bBestValid)
-      {
-         // continue somehow
-         Diff d(nofEquals, bestI1, bestI2);
-         diffList.push_back( d );
-
-         p1 += bestI1;
-         p2 += bestI2;
-      }
-      else
-      {
-         // Nothing else to match.
-         Diff d(nofEquals, p1end-p1, p2end-p2);
-         diffList.push_back( d );
-
-         bEndReached = true; //break;
-      }
-
-      // Sometimes the algorithm that chooses the first match unfortunately chooses
-      // a match where later actually equal parts don't match anymore.
-      // A different match could be achieved, if we start at the end.
-      // Do it, if it would be a better match.
-      int nofUnmatched = 0;
-      const T* pu1 = p1-1;
-      const T* pu2 = p2-1;
-      while ( pu1>=p1start && pu2>=p2start && equal( *pu1, *pu2, false ) )
-      {
-         ++nofUnmatched;
-         --pu1;
-         --pu2;
-      }
-
-
-      Diff d = diffList.back();
-      if ( nofUnmatched > 0 )
-      {
-         // We want to go backwards the nofUnmatched elements and redo
-         // the matching
-         d = diffList.back();
-         Diff origBack = d;
-         diffList.pop_back();
-
-         while (  nofUnmatched > 0 )
-         {
-            if ( d.diff1 > 0  &&  d.diff2 > 0 )
-            {
-               --d.diff1;
-               --d.diff2;
-               --nofUnmatched;
-            }
-            else if ( d.nofEquals > 0 )
-            {
-               --d.nofEquals;
-               --nofUnmatched;
-            }
-
-            if ( d.nofEquals==0 && (d.diff1==0 || d.diff2==0) &&  nofUnmatched>0 )
-            {
-               if ( diffList.empty() )
-                  break;
-               d.nofEquals += diffList.back().nofEquals;
-               d.diff1 += diffList.back().diff1;
-               d.diff2 += diffList.back().diff2;
-               diffList.pop_back();
-               bEndReached = false;
-            }
-         }
-
-         if ( bEndReached )
-            diffList.push_back( origBack );
-         else
-         {
-            p1 = pu1 + 1 + nofUnmatched;
-            p2 = pu2 + 1 + nofUnmatched;
-            diffList.push_back( d );
-         }
-      }
-      if ( bEndReached )
-         break;
-   }
-
-#ifndef NDEBUG 
-   // Verify difflist
-   {
-      int l1=0;
-      int l2=0;
-      DiffList::iterator i;
-      for( i = diffList.begin(); i!=diffList.end(); ++i )
-      {
-         l1+= i->nofEquals + i->diff1;
-         l2+= i->nofEquals + i->diff2;
-      }
-
-      //if( l1!=p1-p1start || l2!=p2-p2start )
-      if( l1!=size1 || l2!=size2 )
-         assert( false );
-   }
-#endif
-}
-
-
-template <class T>
-T min3( T d1, T d2, T d3 )
-{
-   if ( d1 < d2  &&  d1 < d3 ) return d1;
-   if ( d2 < d3 ) return d2;
-   return d3;
-}
-
-template <class T>
-T max3( T d1, T d2, T d3 )
-{
-
-   if ( d1 > d2  &&  d1 > d3 ) return d1;
-
-   if ( d2 > d3 ) return d2;
-   return d3;
-
-}
-
-template <class T>
-T minMaxLimiter( T d, T minimum, T maximum )
-{
-   assert(minimum<=maximum);
-   if ( d < minimum ) return minimum;
-   if ( d > maximum ) return maximum;
-   return d;
-}
-
-/** Returns the number of equivalent spaces at position outPos.
-*/
-inline int tabber( int outPos, int tabSize )
-{
-   return tabSize - ( outPos % tabSize );
-}
-
-/** Returns a line number where the linerange [line, line+nofLines] can
-    be displayed best. If it fits into the currently visible range then
-    the returned value is the current firstLine.
-*/
-int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines );
-
-extern int g_tabSize;
-extern bool g_bIgnoreWhiteSpace;
-extern bool g_bIgnoreTrivialMatches;
-
-// Cursor conversions that consider g_tabSize.
-int convertToPosInText( const char* p, int size, int posOnScreen );
-int convertToPosOnScreen( const char* p, int posInText );
-void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 );
-#endif

kdiff3/kdiff3/difftextwindow.cpp

-/***************************************************************************
-                          difftextwindow.cpp  -  description
-                             -------------------
-    begin                : Mon Apr 8 2002
-    copyright            : (C) 2002 by Joachim Eibl
-    email                : joachim.eibl@gmx.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- ***************************************************************************/
-
-/***************************************************************************
- * $Log$
- * Revision 1.1  2002/08/18 16:24:14  joachim99
- * Initial revision
- *                                                                   *
- ***************************************************************************/
-
-#include <iostream>
-#include "diff.h"
-#include "merger.h"
-#include <qpainter.h>
-#include <assert.h>
-#include <qpixmap.h>
-#include <qstatusbar.h>
-#include <qapplication.h>
-#include <optiondialog.h>
-
-#define leftInfoWidth 4   // Nr of information columns on left side
-
-using namespace std;
-
-DiffTextWindow::DiffTextWindow(
-   QWidget* pParent,
-   QStatusBar* pStatusBar,
-   OptionDialog* pOptionDialog
-   )
-: QWidget(pParent, 0, WRepaintNoErase)
-{
-   setFocusPolicy( QWidget::ClickFocus );
-
-   m_pOptionDialog = pOptionDialog;
-   init( 0, 0, 0, 0, 0, false );
-
-   setBackgroundMode( PaletteBase );
-   setMinimumSize(QSize(20,20));
-
-   m_pStatusBar = pStatusBar;
-
-   m_fastSelectorLine1 = 0;
-   m_fastSelectorNofLines = 0;
-}
-
-
-void DiffTextWindow::init(
-   const char* pFilename,
-   LineData* pLineData,
-   int size,
-   const Diff3LineList* pDiff3LineList,
-   int winIdx,
-   bool bTriple
-   )
-{
-   m_pFilename = pFilename;
-   m_pLineData = pLineData;
-   m_size = size;
-   m_pDiff3LineList = pDiff3LineList;
-   m_winIdx = winIdx;
-
-   m_firstLine = 0;
-   m_oldFirstLine = -1;
-   m_firstColumn = 0;
-   m_oldFirstColumn = -1;
-   m_bTriple = bTriple;
-   m_scrollDeltaX=0;
-   m_scrollDeltaY=0;
-   m_bMyUpdate = false;
-}
-
-void DiffTextWindow::setFirstLine(int firstLine)
-{
-   m_firstLine = max(0,firstLine);
-   myUpdate(0); // Immediately
-}
-
-void DiffTextWindow::setFirstColumn(int firstCol)
-{
-   m_firstColumn = max(0,firstCol);
-   myUpdate(0); // Immediately
-}
-
-int DiffTextWindow::getNofColumns()
-{
-   int nofColumns = 0;
-   for( int i = 0; i< m_size; ++i )
-   {
-      if ( m_pLineData[i].width() > nofColumns )
-         nofColumns = m_pLineData[i].width();
-   }
-   return nofColumns;
-}
-
-int DiffTextWindow::getNofLines()
-{
-   return m_pDiff3LineList->size();
-}
-
-/** Returns a line number where the linerange [line, line+nofLines] can
-    be displayed best. If it fits into the currently visible range then
-    the returned value is the current firstLine.
-*/
-int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines )
-{
-   int newFirstLine = firstLine;
-   if ( line < firstLine  ||  line + nofLines > firstLine + visibleLines )
-   {
-      if ( nofLines > visibleLines || nofLines <= ( 2*visibleLines / 3 - 1)  )
-         newFirstLine = line - visibleLines/3;
-      else
-         newFirstLine = line - (visibleLines - nofLines);
-   }
-
-   return newFirstLine;
-}
-
-
-void DiffTextWindow::setFastSelectorRange( int line1, int nofLines )
-{
-   m_fastSelectorLine1 = line1;
-   m_fastSelectorNofLines = nofLines;
-
-   int newFirstLine = getBestFirstLine( line1, nofLines, m_firstLine, m_visibleLines );
-   if ( newFirstLine != m_firstLine )
-   {
-      scroll( 0, newFirstLine - m_firstLine );
-   }
-
-   update();
-}
-
-static void showStatusLine(int line, int winIdx, const char* pFilename, const Diff3LineList* pd3ll, QStatusBar* sb)
-{
-   int l=0;
-   Diff3LineList::const_iterator i;
-   for ( i=pd3ll->begin();i!=pd3ll->end() && l!=line; ++i,++l )
-   {
-   }
-   if(i!=pd3ll->end())
-   {
-      if      ( winIdx==1 ) l=(*i).lineA;
-      else if ( winIdx==2 ) l=(*i).lineB;
-      else if ( winIdx==3 ) l=(*i).lineC;
-      else assert(false);
-
-      QString s;
-      if ( l!=-1 )
-         s.sprintf("File %s: Line %d", pFilename, l+1 );
-      else
-         s.sprintf("File %s: Line not available", pFilename );
-      sb->message(s);
-   }
-}
-
-
-void DiffTextWindow::mousePressEvent ( QMouseEvent* e )
-{
-   if ( e->button() == LeftButton )
-   {
-      int line;
-      int pos;
-      convertToLinePos( e->x(), e->y(), line, pos );
-      if ( pos < m_firstColumn )
-      {
-         emit setFastSelectorLine( line );
-         selection.firstLine = -1;     // Disable current selection
-      }
-      else
-      {  // Selection
-         resetSelection();
-         selection.start( line, pos );
-         selection.end( line, pos );
-
-         showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar );
-      }
-   }
-}
-
-bool isCTokenChar( char c )
-{
-   return (c=='_')  ||
-          ( c>='A' && c<='Z' ) || ( c>='a' && c<='z' ) ||
-          (c>='0' && c<='9');
-}
-
-/// Calculate where a token starts and ends, given the x-position on screen.
-void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 )
-{
-   // Cursor conversions that consider g_tabSize
-   int pos = convertToPosInText( p, size, max( 0, posOnScreen ) );
-   if ( pos>=size )
-   {
-      pos1=size;
-      pos2=size;
-      return;
-   }
-
-   pos1 = pos;
-   pos2 = pos+1;
-
-   if( isCTokenChar( p[pos1] ) )
-   {
-      while( pos1>=0 && isCTokenChar( p[pos1] ) )
-         --pos1;
-      ++pos1;
-
-      while( pos2<size && isCTokenChar( p[pos2] ) )
-         ++pos2;
-   }
-}
-
-void DiffTextWindow::mouseDoubleClickEvent( QMouseEvent* e )
-{
-   if ( e->button() == LeftButton )
-   {
-      int line;
-      int pos;
-      convertToLinePos( e->x(), e->y(), line, pos );
-
-      // Get the string data of the current line
-      QCString s = getString( line );
-
-      if ( ! s.isEmpty() )
-      {
-         int pos1, pos2;
-         calcTokenPos( s, s.length(), pos, pos1, pos2 );
-
-         resetSelection();
-         selection.start( line, convertToPosOnScreen( s, pos1 ) );
-         selection.end( line, convertToPosOnScreen( s, pos2 ) );
-         update();
-         // emit selectionEnd() happens in the mouseReleaseEvent.
-         showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar );
-      }
-   }
-}
-
-void DiffTextWindow::mouseReleaseEvent ( QMouseEvent * e )
-{
-   if ( e->button() == LeftButton )
-   {
-      killTimers();
-      if (selection.firstLine != -1 )
-      {
-         emit selectionEnd();
-      }
-   }
-}
-
-void DiffTextWindow::mouseMoveEvent ( QMouseEvent * e )
-{
-   int line;
-   int pos;
-   convertToLinePos( e->x(), e->y(), line, pos );
-   if (selection.firstLine != -1 )
-   {
-      selection.end( line, pos );
-      myUpdate(0);
-
-      showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar );
-
-      // Scroll because mouse moved out of the window
-      const QFontMetrics& fm = fontMetrics();
-      int fontHeight = fm.height();
-      int fontWidth = fm.width('W');
-      int topLineYOffset = fontHeight + 3;
-      int deltaX=0;
-      int deltaY=0;
-      if ( e->x() < leftInfoWidth*fontWidth )       deltaX=-1;
-      if ( e->x() > width()     )       deltaX=+1;
-      if ( e->y() < topLineYOffset )    deltaY=-1;
-      if ( e->y() > height() )          deltaY=+1;
-      m_scrollDeltaX = deltaX;
-      m_scrollDeltaY = deltaY;
-      if ( deltaX != 0 || deltaY!= 0)
-      {
-         emit scroll( deltaX, deltaY );
-      }
-   }
-}
-
-
-void DiffTextWindow::myUpdate(int afterMilliSecs)
-{
-   killTimers();
-   m_bMyUpdate = true;
-   startTimer( afterMilliSecs );
-}
-
-void DiffTextWindow::timerEvent(QTimerEvent*)
-{
-   killTimers();
-
-   if ( m_bMyUpdate )
-   {
-      paintEvent( 0 );
-      m_bMyUpdate = false;
-   }
-
-   if ( m_scrollDeltaX != 0 || m_scrollDeltaY != 0 )
-   {
-      selection.end( selection.lastLine + m_scrollDeltaY, selection.lastPos +  m_scrollDeltaX );
-      emit scroll( m_scrollDeltaX, m_scrollDeltaY );
-      killTimers();
-      startTimer(50);
-   }
-}
-
-void DiffTextWindow::resetSelection()
-{
-   selection.reset();
-   update();
-}
-
-void DiffTextWindow::convertToLinePos( int x, int y, int& line, int& pos )
-{
-   const QFontMetrics& fm = fontMetrics();
-   int fontHeight = fm.height();
-   int fontWidth = fm.width('W');
-   int xOffset = (leftInfoWidth-m_firstColumn)*fontWidth;
-   int topLineYOffset = fontHeight + 3;
-
-   int yOffset = topLineYOffset - m_firstLine * fontHeight;
-
-   line = ( y - yOffset ) / fontHeight;
-   pos  = ( x - xOffset ) / fontWidth;
-}
-
-int Selection::firstPosInLine(int l)
-{
-   assert( firstLine != -1 );
-
-   int l1 = firstLine;
-   int l2 = lastLine;
-   int p1 = firstPos;
-   int p2 = lastPos;
-   if ( l1>l2 ){ swap(l1,l2); swap(p1,p2); }
-   if ( l1==l2 && p1>p2 ){ swap(p1,p2); }
-
-   if ( l==l1 )
-      return p1;
-   return 0;
-}
-
-int Selection::lastPosInLine(int l)
-{
-   assert( firstLine != -1 );
-
-   int l1 = firstLine;
-   int l2 = lastLine;
-   int p1 = firstPos;
-   int p2 = lastPos;
-   if ( l1>l2 ){ swap(l1,l2); swap(p1,p2); }
-   if ( l1==l2 && p1>p2 ){ swap(p1,p2); }
-
-   if ( l==l2 )
-      return p2;
-   return INT_MAX;
-}
-
-bool Selection::within( int l, int p )
-{
-   if ( firstLine == -1 ) return false;
-   int l1 = firstLine;
-   int l2 = lastLine;
-   int p1 = firstPos;
-   int p2 = lastPos;
-   if ( l1>l2 ){ swap(l1,l2); swap(p1,p2); }
-   if ( l1==l2 && p1>p2 ){ swap(p1,p2); }
-   if( l1 <= l && l <= l2 )
-   {
-      if ( l1==l2 )
-         return p>=p1 && p<p2;
-      if ( l==l1 )
-         return p>=p1;
-      if ( l==l2 )
-         return p<p2;
-      return true;
-   }
-   return false;
-}
-
-bool Selection::lineWithin( int l )
-{
-   if ( firstLine == -1 ) return false;
-   int l1 = firstLine;
-   int l2 = lastLine;
-
-   if ( l1>l2 ){ swap(l1,l2); }
-
-   return ( l1 <= l && l <= l2 );
-}
-
-void DiffTextWindow::writeLine(
-   QPainter& p,
-   const LineData* pld,
-   const DiffList* pLineDiff1,
-   const DiffList* pLineDiff2,
-   int line,
-   int whatChanged,
-   int whatChanged2
-   )
-{
-   const QFontMetrics& fm = fontMetrics();
-   int fontHeight = fm.height();
-   int fontAscent = fm.ascent();
-   int fontDescent = fm.descent();
-   int fontWidth = fm.width('W');
-   int topLineYOffset = fontHeight + 3;
-
-   int xOffset = (leftInfoWidth - m_firstColumn)*fontWidth;
-   int yOffset = (line-m_firstLine) * fontHeight + topLineYOffset;
-
-   QRect lineRect( 0, yOffset, width(), fontHeight );
-   if ( ! m_invalidRect.intersects( lineRect ) )
-      return;
-
-//   QRect winRect = rect(); //p.window();
-   if ( yOffset+fontHeight<0  ||  height() + fontHeight < yOffset )
-      return;
-
-   int changed = whatChanged;
-   if ( pLineDiff1 != 0 ) changed |= 1;
-   if ( pLineDiff2 != 0 ) changed |= 2;
-
-   QColor c = m_pOptionDialog->m_fgColor;
-   if ( changed == 2 ) {
-      c = m_cDiff2;
-   } else if ( changed == 1 ) {
-      c = m_cDiff1;
-   } else if ( changed == 3 ) {
-      c = m_cDiffBoth;
-   }
-
-
-   if (pld!=0)
-   {
-      // First calculate the "changed" information for each character.
-      int i=0;
-      vector<UINT8> charChanged( pld->size );
-      if ( pLineDiff1!=0 || pLineDiff2 != 0 )
-      {
-         Merger merger( pLineDiff1, pLineDiff2 );
-         while( ! merger.isEndReached() &&  i<pld->size )
-         {
-            if ( i < pld->size )
-            {
-               charChanged[i] = merger.whatChanged();
-               ++i;
-            }
-            merger.next();
-         }
-      }
-
-      QCString s=" ";
-      // Convert tabs
-      int outPos = 0;
-      for( i=0; i<pld->size; ++i )
-      {
-         int spaces = 1;
-
-         if ( pld->pLine[i]=='\t' )
-         {
-            spaces = tabber( outPos, g_tabSize );
-            s[0] = ' ';
-         }
-         else
-         {
-            s[0] = pld->pLine[i];
-         }
-
-         QColor c = m_pOptionDialog->m_fgColor;
-         int cchanged = charChanged[i] | whatChanged;
-
-         if ( cchanged == 2 ) {
-            c = m_cDiff2;
-         } else if ( cchanged == 1 ) {
-            c = m_cDiff1;
-         } else if ( cchanged == 3 ) {
-            c = m_cDiffBoth;
-         }
-
-         QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight );
-         if ( m_invalidRect.intersects( outRect ) )
-         {
-
-            if( !selection.within( line, outPos ) )
-            {
-               if( c!=m_pOptionDialog->m_fgColor )
-               {
-                  QColor lightc = m_pOptionDialog->m_diffBgColor;
-                  p.fillRect( xOffset + fontWidth*outPos, yOffset,
-                           fontWidth*spaces, fontHeight, lightc );
-               }
-
-               p.setPen( c );
-               if ( s[0]==' '  &&  c!=m_pOptionDialog->m_fgColor  &&  charChanged[i]!=0 )
-               {
-                  p.fillRect( xOffset + fontWidth*outPos, yOffset+fontAscent,
-                              fontWidth*(spaces)-1, fontDescent+1, c );
-               }
-               else
-               {
-                  p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s );
-               }
-            }
-            else
-            {
-               p.fillRect( xOffset + fontWidth*outPos, yOffset,
-                           fontWidth*(spaces), fontHeight, colorGroup().highlight() );
-               p.setPen( colorGroup().highlightedText() );
-               p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s );
-
-               selection.bSelectionContainsData = true;
-            }
-         }
-
-         outPos += spaces;
-      }
-
-      if( selection.lineWithin( line ) && selection.lineWithin( line+1 ) )
-      {
-         p.fillRect( xOffset + fontWidth*outPos, yOffset,
-                     width(), fontHeight, colorGroup().highlight() );
-      }
-
-   }
-
-   p.fillRect( 0, yOffset, leftInfoWidth*fontWidth-1, fontHeight, m_pOptionDialog->m_bgColor );
-
-   xOffset = 2*fontWidth;
-   p.setPen( m_pOptionDialog->m_fgColor );
-   if ( pld!=0 )
-      p.drawLine( xOffset +1, yOffset, xOffset +1, yOffset+fontHeight-1 );
-   if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 && whatChanged==0 )
-   {
-      p.fillRect( 0, yOffset, xOffset-1, fontHeight, QBrush(c,Dense5Pattern) );
-   }
-   else
-   {
-      p.fillRect( 0, yOffset, xOffset-1, fontHeight, c==m_pOptionDialog->m_fgColor ? m_pOptionDialog->m_bgColor : c );
-   }
-
-   int fastSelectorLine2 = m_fastSelectorLine1+m_fastSelectorNofLines - 1;
-   if (line>=m_fastSelectorLine1 && line<= fastSelectorLine2 )
-   {
-      p.drawLine( xOffset + fontWidth-1, yOffset, xOffset + fontWidth-1, yOffset+fontHeight-1 );
-      if ( line == m_fastSelectorLine1 )
-      {
-         p.drawLine( xOffset + fontWidth-1, yOffset, xOffset + fontWidth+2, yOffset );
-      }
-      if ( line == fastSelectorLine2 )
-      {
-         p.drawLine( xOffset + fontWidth-1, yOffset+fontHeight-1, xOffset + fontWidth+2, yOffset+fontHeight-1 );
-      }
-   }
-}
-
-void DiffTextWindow::paintEvent( QPaintEvent* e )
-{
-   if (e!=0)
-   {
-      m_invalidRect |= e->rect();
-   }
-
-   if ( m_winIdx==1 )
-   {
-      m_cThis = m_pOptionDialog->m_colorA;
-      m_cDiff1 = m_pOptionDialog->m_colorB;
-      m_cDiff2 = m_pOptionDialog->m_colorC;
-   }
-   if ( m_winIdx==2 )
-   {
-      m_cThis = m_pOptionDialog->m_colorB;
-      m_cDiff1 = m_pOptionDialog->m_colorC;