Hex Artifact Content
Not logged in

Artifact 017b4249144920782678e4964f219ea565667ac4:

File src/diff.c part of check-in [36b96b8616] - Rework the merge algorithm. It now only works for text files. But, it no longer gets confused by line endings (\r\n versus \n) and it reports conflicts. by drh on 2007-11-16 20:42:31.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 37 20 44 2e 20 52 69 63 68  (c) 2007 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65 20 75   contains code u
0380: 73 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 20 61  sed to compute a
0390: 20 22 64 69 66 66 22 20 62 65 74 77 65 65 6e 20   "diff" between 
03a0: 74 77 6f 0a 2a 2a 20 74 65 78 74 20 66 69 6c 65  two.** text file
03b0: 73 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22  s..*/.#include "
03c0: 63 6f 6e 66 69 67 2e 68 22 0a 23 69 6e 63 6c 75  config.h".#inclu
03d0: 64 65 20 22 64 69 66 66 32 2e 68 22 0a 23 69 6e  de "diff2.h".#in
03e0: 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e  clude <assert.h>
03f0: 0a 0a 0a 23 69 66 20 30 0a 23 64 65 66 69 6e 65  ...#if 0.#define
0400: 20 44 45 42 55 47 28 58 29 20 58 0a 23 65 6c 73   DEBUG(X) X.#els
0410: 65 0a 23 64 65 66 69 6e 65 20 44 45 42 55 47 28  e.#define DEBUG(
0420: 58 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  X).#endif../*.**
0430: 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   Information abo
0440: 75 74 20 65 61 63 68 20 6c 69 6e 65 20 6f 66 20  ut each line of 
0450: 61 20 66 69 6c 65 20 62 65 69 6e 67 20 64 69 66  a file being dif
0460: 66 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c  fed..**.** The l
0470: 6f 77 65 72 20 32 30 20 62 69 74 73 20 6f 66 20  ower 20 bits of 
0480: 74 68 65 20 68 61 73 68 20 61 72 65 20 74 68 65  the hash are the
0490: 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 0a 2a   length of the.*
04a0: 2a 20 6c 69 6e 65 2e 20 20 49 66 20 61 6e 79 20  * line.  If any 
04b0: 6c 69 6e 65 20 69 73 20 6c 6f 6e 67 65 72 20 74  line is longer t
04c0: 68 61 6e 20 31 30 34 38 35 37 35 20 63 68 61 72  han 1048575 char
04d0: 61 63 74 65 72 73 2c 0a 2a 2a 20 74 68 65 20 66  acters,.** the f
04e0: 69 6c 65 20 69 73 20 63 6f 6e 73 69 64 65 72 65  ile is considere
04f0: 64 20 62 69 6e 61 72 79 2e 0a 2a 2f 0a 74 79 70  d binary..*/.typ
0500: 65 64 65 66 20 73 74 72 75 63 74 20 44 4c 69 6e  edef struct DLin
0510: 65 20 44 4c 69 6e 65 3b 0a 73 74 72 75 63 74 20  e DLine;.struct 
0520: 44 4c 69 6e 65 20 7b 0a 20 20 63 6f 6e 73 74 20  DLine {.  const 
0530: 63 68 61 72 20 2a 7a 3b 20 20 20 20 2f 2a 20 54  char *z;    /* T
0540: 68 65 20 74 65 78 74 20 6f 66 20 74 68 65 20 6c  he text of the l
0550: 69 6e 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ine */.  unsigne
0560: 64 20 69 6e 74 20 68 3b 20 20 20 2f 2a 20 48 61  d int h;   /* Ha
0570: 73 68 20 6f 66 20 74 68 65 20 6c 69 6e 65 20 2a  sh of the line *
0580: 2f 0a 7d 3b 0a 0a 23 64 65 66 69 6e 65 20 4c 45  /.};..#define LE
0590: 4e 47 54 48 5f 4d 41 53 4b 20 20 30 78 30 30 30  NGTH_MASK  0x000
05a0: 66 66 66 66 66 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  fffff../*.** Ret
05b0: 75 72 6e 20 61 6e 20 61 72 72 61 79 20 6f 66 20  urn an array of 
05c0: 44 4c 69 6e 65 20 6f 62 6a 65 63 74 73 20 63 6f  DLine objects co
05d0: 6e 74 61 69 6e 69 6e 67 20 61 20 70 6f 69 6e 74  ntaining a point
05e0: 65 72 20 74 6f 20 74 68 65 0a 2a 2a 20 73 74 61  er to the.** sta
05f0: 72 74 20 6f 66 20 65 61 63 68 20 6c 69 6e 65 20  rt of each line 
0600: 61 6e 64 20 61 20 68 61 73 68 20 6f 66 20 74 68  and a hash of th
0610: 61 74 20 6c 69 6e 65 2e 20 20 54 68 65 20 6c 6f  at line.  The lo
0620: 77 65 72 20 0a 2a 2a 20 62 69 74 73 20 6f 66 20  wer .** bits of 
0630: 74 68 65 20 68 61 73 68 20 73 74 6f 72 65 20 74  the hash store t
0640: 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 65 61 63  he length of eac
0650: 68 20 6c 69 6e 65 2e 0a 2a 2a 0a 2a 2a 20 54 72  h line..**.** Tr
0660: 61 69 6c 69 6e 67 20 77 68 69 74 65 73 70 61 63  ailing whitespac
0670: 65 20 69 73 20 72 65 6d 6f 76 65 64 20 66 72 6f  e is removed fro
0680: 6d 20 65 61 63 68 20 6c 69 6e 65 2e 0a 2a 2a 0a  m each line..**.
0690: 2a 2a 20 52 65 74 75 72 6e 20 30 20 69 66 20 74  ** Return 0 if t
06a0: 68 65 20 66 69 6c 65 20 69 73 20 62 69 6e 61 72  he file is binar
06b0: 79 20 6f 72 20 63 6f 6e 74 61 69 6e 73 20 61 20  y or contains a 
06c0: 6c 69 6e 65 20 74 68 61 74 20 69 73 0a 2a 2a 20  line that is.** 
06d0: 6c 6f 6e 67 65 72 20 74 68 61 6e 20 31 30 34 38  longer than 1048
06e0: 35 37 35 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74  575 bytes..*/.st
06f0: 61 74 69 63 20 44 4c 69 6e 65 20 2a 62 72 65 61  atic DLine *brea
0700: 6b 5f 69 6e 74 6f 5f 6c 69 6e 65 73 28 63 68 61  k_into_lines(cha
0710: 72 20 2a 7a 2c 20 69 6e 74 20 2a 70 6e 4c 69 6e  r *z, int *pnLin
0720: 65 29 7b 0a 20 20 69 6e 74 20 6e 4c 69 6e 65 2c  e){.  int nLine,
0730: 20 69 2c 20 6a 2c 20 6b 2c 20 78 3b 0a 20 20 75   i, j, k, x;.  u
0740: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20  nsigned int h;. 
0750: 20 44 4c 69 6e 65 20 2a 61 3b 0a 0a 20 20 2f 2a   DLine *a;..  /*
0760: 20 43 6f 75 6e 74 20 74 68 65 20 6e 75 6d 62 65   Count the numbe
0770: 72 20 6f 66 20 6c 69 6e 65 73 2e 20 20 41 6c 6c  r of lines.  All
0780: 6f 63 61 74 65 20 73 70 61 63 65 20 74 6f 20 68  ocate space to h
0790: 6f 6c 64 0a 20 20 2a 2a 20 74 68 65 20 72 65 74  old.  ** the ret
07a0: 75 72 6e 65 64 20 61 72 72 61 79 2e 0a 20 20 2a  urned array..  *
07b0: 2f 0a 20 20 66 6f 72 28 69 3d 6a 3d 30 2c 20 6e  /.  for(i=j=0, n
07c0: 4c 69 6e 65 3d 31 3b 20 7a 5b 69 5d 3b 20 69 2b  Line=1; z[i]; i+
07d0: 2b 2c 20 6a 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  +, j++){.    int
07e0: 20 63 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20 69   c = z[i];.    i
07f0: 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20  f( c==0 ){.     
0800: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d   return 0;.    }
0810: 0a 20 20 20 20 69 66 28 20 63 3d 3d 27 5c 6e 27  .    if( c=='\n'
0820: 20 26 26 20 7a 5b 69 2b 31 5d 21 3d 30 20 29 7b   && z[i+1]!=0 ){
0830: 0a 20 20 20 20 20 20 6e 4c 69 6e 65 2b 2b 3b 0a  .      nLine++;.
0840: 20 20 20 20 20 20 69 66 28 20 6a 3e 31 30 34 38        if( j>1048
0850: 35 37 35 20 29 7b 0a 20 20 20 20 20 20 20 20 72  575 ){.        r
0860: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d  eturn 0;.      }
0870: 0a 20 20 20 20 20 20 6a 20 3d 20 30 3b 0a 20 20  .      j = 0;.  
0880: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 6a 3e    }.  }.  if( j>
0890: 31 30 34 38 35 37 35 20 29 7b 0a 20 20 20 20 72  1048575 ){.    r
08a0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 61  eturn 0;.  }.  a
08b0: 20 3d 20 6d 61 6c 6c 6f 63 28 20 6e 4c 69 6e 65   = malloc( nLine
08c0: 2a 73 69 7a 65 6f 66 28 61 5b 30 5d 29 20 29 3b  *sizeof(a[0]) );
08d0: 0a 20 20 69 66 28 20 61 3d 3d 30 20 29 20 66 6f  .  if( a==0 ) fo
08e0: 73 73 69 6c 5f 70 61 6e 69 63 28 22 6f 75 74 20  ssil_panic("out 
08f0: 6f 66 20 6d 65 6d 6f 72 79 22 29 3b 0a 0a 20 20  of memory");..  
0900: 2f 2a 20 46 69 6c 6c 20 69 6e 20 74 68 65 20 61  /* Fill in the a
0910: 72 72 61 79 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  rray */.  for(i=
0920: 30 3b 20 69 3c 6e 4c 69 6e 65 3b 20 69 2b 2b 29  0; i<nLine; i++)
0930: 7b 0a 20 20 20 20 61 5b 69 5d 2e 7a 20 3d 20 7a  {.    a[i].z = z
0940: 3b 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 7a  ;.    for(j=0; z
0950: 5b 6a 5d 20 26 26 20 7a 5b 6a 5d 21 3d 27 5c 6e  [j] && z[j]!='\n
0960: 27 3b 20 6a 2b 2b 29 7b 7d 0a 20 20 20 20 66 6f  '; j++){}.    fo
0970: 72 28 6b 3d 6a 3b 20 6b 3e 30 20 26 26 20 69 73  r(k=j; k>0 && is
0980: 73 70 61 63 65 28 7a 5b 6b 2d 31 5d 29 3b 20 6b  space(z[k-1]); k
0990: 2d 2d 29 7b 7d 0a 20 20 20 20 66 6f 72 28 68 3d  --){}.    for(h=
09a0: 30 2c 20 78 3d 30 3b 20 78 3c 6b 3b 20 78 2b 2b  0, x=0; x<k; x++
09b0: 29 7b 0a 20 20 20 20 20 20 68 20 3d 20 68 20 5e  ){.      h = h ^
09c0: 20 28 68 3c 3c 32 29 20 5e 20 7a 5b 78 5d 3b 0a   (h<<2) ^ z[x];.
09d0: 20 20 20 20 7d 0a 20 20 20 20 61 5b 69 5d 2e 68      }.    a[i].h
09e0: 20 3d 20 28 68 3c 3c 32 30 29 20 7c 20 6b 3b 3b   = (h<<20) | k;;
09f0: 0a 20 20 20 20 7a 20 2b 3d 20 6a 2b 31 3b 0a 20  .    z += j+1;. 
0a00: 20 7d 0a 0a 20 20 2f 2a 20 52 65 74 75 72 6e 20   }..  /* Return 
0a10: 72 65 73 75 6c 74 73 20 2a 2f 0a 20 20 2a 70 6e  results */.  *pn
0a20: 4c 69 6e 65 20 3d 20 6e 4c 69 6e 65 3b 0a 20 20  Line = nLine;.  
0a30: 72 65 74 75 72 6e 20 61 3b 0a 7d 0a 0a 2f 2a 0a  return a;.}../*.
0a40: 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  ** Return true i
0a50: 66 20 74 77 6f 20 44 4c 69 6e 65 20 65 6c 65 6d  f two DLine elem
0a60: 65 6e 74 73 20 61 72 65 20 69 64 65 6e 74 69 63  ents are identic
0a70: 61 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  al..*/.static in
0a80: 74 20 73 61 6d 65 5f 64 6c 69 6e 65 28 44 4c 69  t same_dline(DLi
0a90: 6e 65 20 2a 70 41 2c 20 44 4c 69 6e 65 20 2a 70  ne *pA, DLine *p
0aa0: 42 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 41 2d  B){.  return pA-
0ab0: 3e 68 3d 3d 70 42 2d 3e 68 20 26 26 20 6d 65 6d  >h==pB->h && mem
0ac0: 63 6d 70 28 70 41 2d 3e 7a 2c 70 42 2d 3e 7a 2c  cmp(pA->z,pB->z,
0ad0: 70 41 2d 3e 68 20 26 20 4c 45 4e 47 54 48 5f 4d  pA->h & LENGTH_M
0ae0: 41 53 4b 29 3d 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a  ASK)==0;.}../*.*
0af0: 2a 20 47 65 6e 65 72 61 74 65 20 61 20 72 65 70  * Generate a rep
0b00: 6f 72 74 20 6f 66 20 74 68 65 20 64 69 66 66 65  ort of the diffe
0b10: 72 65 6e 63 65 73 20 62 65 74 77 65 65 6e 20 66  rences between f
0b20: 69 6c 65 73 20 70 41 20 61 6e 64 20 70 42 2e 0a  iles pA and pB..
0b30: 2a 2a 20 49 66 20 70 4f 75 74 20 69 73 20 6e 6f  ** If pOut is no
0b40: 74 20 4e 55 4c 4c 20 74 68 65 6e 20 61 20 75 6e  t NULL then a un
0b50: 69 66 69 65 64 20 64 69 66 66 20 69 73 20 61 70  ified diff is ap
0b60: 70 65 6e 64 65 64 20 74 68 65 72 65 2e 20 20 49  pended there.  I
0b70: 74 0a 2a 2a 20 69 73 20 61 73 73 75 6d 65 64 20  t.** is assumed 
0b80: 74 68 61 74 20 70 4f 75 74 20 68 61 73 20 61 6c  that pOut has al
0b90: 72 65 61 64 79 20 62 65 65 6e 20 69 6e 69 74 69  ready been initi
0ba0: 61 6c 69 7a 65 64 2e 20 20 49 66 20 70 4f 75 74  alized.  If pOut
0bb0: 20 69 73 0a 2a 2a 20 4e 55 4c 4c 2c 20 74 68 65   is.** NULL, the
0bc0: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  n a pointer to a
0bd0: 6e 20 61 72 72 61 79 20 6f 66 20 69 6e 74 65 67  n array of integ
0be0: 65 72 73 20 69 73 20 72 65 74 75 72 6e 65 64 2e  ers is returned.
0bf0: 20 20 0a 2a 2a 20 54 68 65 20 69 6e 74 65 67 65    .** The intege
0c00: 72 73 20 63 6f 6d 65 20 69 6e 20 74 72 69 70 6c  rs come in tripl
0c10: 65 73 2e 20 20 46 6f 72 20 65 61 63 68 20 74 72  es.  For each tr
0c20: 69 70 6c 65 2c 0a 2a 2a 20 74 68 65 20 65 6c 65  iple,.** the ele
0c30: 6d 65 6e 74 73 20 61 72 65 20 74 68 65 20 6e 75  ments are the nu
0c40: 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 63 6f  mber of lines co
0c50: 70 69 65 64 2c 20 74 68 65 20 6e 75 6d 62 65 72  pied, the number
0c60: 20 6f 66 0a 2a 2a 20 6c 69 6e 65 73 20 64 65 6c   of.** lines del
0c70: 65 74 65 64 2c 20 61 6e 64 20 74 68 65 20 6e 75  eted, and the nu
0c80: 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 69 6e  mber of lines in
0c90: 73 65 72 74 65 64 2e 20 20 54 68 65 20 76 65 63  serted.  The vec
0ca0: 74 6f 72 0a 2a 2a 20 69 73 20 74 65 72 6d 69 6e  tor.** is termin
0cb0: 61 74 65 64 20 62 79 20 61 20 74 72 69 70 6c 65  ated by a triple
0cc0: 20 6f 66 20 61 6c 6c 20 7a 65 72 6f 73 2e 0a 2a   of all zeros..*
0cd0: 2a 0a 2a 2a 20 54 68 69 73 20 64 69 66 66 20 75  *.** This diff u
0ce0: 74 69 6c 69 74 79 20 64 6f 65 73 20 6e 6f 74 20  tility does not 
0cf0: 77 6f 72 6b 20 6f 6e 20 62 69 6e 61 72 79 20 66  work on binary f
0d00: 69 6c 65 73 2e 20 20 49 66 20 61 20 62 69 6e 61  iles.  If a bina
0d10: 72 79 0a 2a 2a 20 66 69 6c 65 20 69 73 20 65 6e  ry.** file is en
0d20: 63 6f 75 6e 74 65 72 65 64 2c 20 30 20 69 73 20  countered, 0 is 
0d30: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 70 4f 75  returned and pOu
0d40: 74 20 69 73 20 77 72 69 74 74 65 6e 20 77 69 74  t is written wit
0d50: 68 0a 2a 2a 20 74 65 78 74 20 22 63 61 6e 6e 6f  h.** text "canno
0d60: 74 20 63 6f 6d 70 75 74 65 20 64 69 66 66 65 72  t compute differ
0d70: 65 6e 63 65 20 62 65 74 77 65 65 6e 20 62 69 6e  ence between bin
0d80: 61 72 79 20 66 69 6c 65 73 22 2e 0a 2a 2a 0a 2a  ary files"..**.*
0d90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0da0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0db0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0dd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a  ***********.**.*
0de0: 2a 20 54 68 65 20 63 6f 72 65 20 61 6c 67 6f 72  * The core algor
0df0: 69 74 68 6d 20 69 73 20 61 20 76 61 72 69 61 74  ithm is a variat
0e00: 69 6f 6e 20 6f 6e 20 74 68 65 20 63 6c 61 73 73  ion on the class
0e10: 69 63 20 57 61 67 6e 65 72 0a 2a 2a 20 6d 69 6e  ic Wagner.** min
0e20: 69 6d 75 6d 20 65 64 69 74 20 64 69 73 74 61 6e  imum edit distan
0e30: 63 65 20 77 69 74 68 20 65 6e 68 61 6e 63 65 6d  ce with enhancem
0e40: 65 6e 74 73 20 74 6f 20 72 65 64 75 63 65 20 74  ents to reduce t
0e50: 68 65 20 72 75 6e 74 69 6d 65 0a 2a 2a 20 74 6f  he runtime.** to
0e60: 20 62 65 20 61 6c 6d 6f 73 74 20 6c 69 6e 65 61   be almost linea
0e70: 72 20 69 6e 20 74 68 65 20 63 6f 6d 6d 6f 6e 20  r in the common 
0e80: 63 61 73 65 20 77 68 65 72 65 20 74 68 65 20 74  case where the t
0e90: 77 6f 20 66 69 6c 65 73 0a 2a 2a 20 68 61 76 65  wo files.** have
0ea0: 20 61 20 6c 6f 74 20 69 6e 20 63 6f 6d 6d 6f 6e   a lot in common
0eb0: 2e 20 20 46 6f 72 20 61 64 64 69 74 69 6f 6e 61  .  For additiona
0ec0: 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 73 65  l information se
0ed0: 65 0a 2a 2a 20 45 75 67 65 6e 65 20 57 2e 20 4d  e.** Eugene W. M
0ee0: 79 65 72 73 2c 20 22 41 6e 20 4f 28 4e 44 29 20  yers, "An O(ND) 
0ef0: 44 69 66 66 65 72 65 6e 63 65 20 41 6c 67 6f 72  Difference Algor
0f00: 69 74 68 6d 20 41 6e 64 20 49 74 73 0a 2a 2a 20  ithm And Its.** 
0f10: 56 61 72 69 61 74 69 6f 6e 73 22 0a 2a 2a 0a 2a  Variations".**.*
0f20: 2a 20 43 6f 6e 73 69 64 65 72 20 63 6f 6d 70 61  * Consider compa
0f30: 72 69 6e 67 20 73 74 72 69 6e 67 73 20 41 20 61  ring strings A a
0f40: 6e 64 20 42 2e 20 20 41 3d 61 62 63 61 62 62 61  nd B.  A=abcabba
0f50: 20 61 6e 64 20 42 3d 63 62 61 62 61 63 0a 2a 2a   and B=cbabac.**
0f60: 20 57 65 20 63 6f 6e 73 74 72 75 63 74 20 61 20   We construct a 
0f70: 22 57 61 67 6e 65 72 22 20 6d 61 74 72 69 78 20  "Wagner" matrix 
0f80: 57 20 77 69 74 68 20 41 20 61 6c 6f 6e 67 20 74  W with A along t
0f90: 68 65 20 58 20 61 78 69 73 20 61 6e 64 20 0a 2a  he X axis and .*
0fa0: 2a 20 42 20 61 6c 6f 6e 67 20 74 68 65 20 59 20  * B along the Y 
0fb0: 61 78 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  axis:.**.**     
0fc0: 63 20 36 20 20 20 20 20 20 20 20 20 20 20 20 20  c 6             
0fd0: 20 20 2a 0a 2a 2a 20 20 20 20 20 61 20 35 20 20    *.**     a 5  
0fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 0a 2a               *.*
0ff0: 2a 20 20 20 20 20 62 20 34 20 20 20 20 20 20 20  *     b 4       
1000: 20 20 20 20 2a 20 2a 0a 2a 2a 20 20 20 20 20 61      * *.**     a
1010: 20 33 20 20 20 20 20 20 20 20 20 2a 0a 2a 2a 20   3         *.** 
1020: 20 20 20 20 62 20 32 20 20 20 20 20 20 20 2a 0a      b 2       *.
1030: 2a 2a 20 20 20 42 20 63 20 31 20 20 20 20 20 20  **   B c 1      
1040: 20 2a 0a 2a 2a 20 20 20 20 20 20 20 30 20 2a 20   *.**       0 * 
1050: 2a 20 2a 20 0a 2a 2a 20 20 20 20 20 20 20 20 20  * * .**         
1060: 30 20 31 20 32 20 33 20 34 20 35 20 36 20 37 0a  0 1 2 3 4 5 6 7.
1070: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 61 20 62  **           a b
1080: 20 63 20 61 20 62 20 62 20 61 0a 2a 2a 20 20 20   c a b b a.**   
1090: 20 20 20 20 20 20 20 20 41 0a 2a 2a 0a 2a 2a 20          A.**.** 
10a0: 28 4e 6f 74 65 3a 20 77 65 20 64 72 61 77 20 74  (Note: we draw t
10b0: 68 69 73 20 57 61 67 6e 65 72 20 6d 61 74 72 69  his Wagner matri
10c0: 78 20 77 69 74 68 20 74 68 65 20 6f 72 69 67 69  x with the origi
10d0: 6e 20 61 74 20 74 68 65 20 6c 6f 77 65 72 20 0a  n at the lower .
10e0: 2a 2a 20 6c 65 66 74 20 77 68 65 72 65 61 73 20  ** left whereas 
10f0: 4d 79 65 72 73 20 75 73 65 73 20 74 68 65 20 6f  Myers uses the o
1100: 72 69 67 69 6e 20 61 74 20 74 68 65 20 75 70 70  rigin at the upp
1110: 65 72 20 6c 65 66 74 2e 20 20 4f 74 68 65 72 77  er left.  Otherw
1120: 69 73 65 2c 0a 2a 2a 20 74 68 65 79 20 61 72 65  ise,.** they are
1130: 20 74 68 65 20 73 61 6d 65 2e 29 0a 2a 2a 0a 2a   the same.).**.*
1140: 2a 20 4c 65 74 20 59 20 62 65 20 74 68 65 20 6d  * Let Y be the m
1150: 61 78 69 6d 75 6d 20 79 20 76 61 6c 75 65 20 6f  aximum y value o
1160: 72 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  r the number of 
1170: 63 68 61 72 61 63 74 65 72 73 20 69 6e 20 42 2e  characters in B.
1180: 0a 2a 2a 20 36 20 69 6e 20 74 68 69 73 20 65 78  .** 6 in this ex
1190: 61 6d 70 6c 65 2e 20 20 58 20 69 73 20 74 68 65  ample.  X is the
11a0: 20 6d 61 78 69 6d 75 6d 20 78 20 76 61 6c 75 65   maximum x value
11b0: 20 6f 72 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   or the number o
11c0: 66 0a 2a 2a 20 65 6c 65 6d 65 6e 74 73 20 69 6e  f.** elements in
11d0: 20 41 2e 20 20 48 65 72 65 20 37 2e 0a 2a 2a 0a   A.  Here 7..**.
11e0: 2a 2a 20 4f 75 72 20 67 6f 61 6c 20 69 73 20 74  ** Our goal is t
11f0: 6f 20 66 69 6e 64 20 61 20 70 61 74 68 20 66 72  o find a path fr
1200: 6f 6d 20 28 30 2c 30 29 20 74 6f 20 28 58 2c 59  om (0,0) to (X,Y
1210: 29 2e 20 20 54 68 65 20 70 61 74 68 20 63 61 6e  ).  The path can
1220: 0a 2a 2a 20 75 73 65 20 68 6f 72 69 7a 6f 6e 74  .** use horizont
1230: 61 6c 2c 20 76 65 72 74 69 63 61 6c 2c 20 6f 72  al, vertical, or
1240: 20 64 69 61 67 6f 6e 61 6c 20 73 74 65 70 73 2e   diagonal steps.
1250: 20 20 41 20 64 69 61 67 6f 6e 61 6c 20 66 72 6f    A diagonal fro
1260: 6d 0a 2a 2a 20 28 78 2d 31 2c 79 2d 31 29 20 74  m.** (x-1,y-1) t
1270: 6f 20 28 78 2c 79 29 20 69 73 20 6f 6e 6c 79 20  o (x,y) is only 
1280: 61 6c 6c 6f 77 65 64 20 69 66 20 41 5b 78 5d 3d  allowed if A[x]=
1290: 3d 42 5b 79 5d 2e 20 20 41 20 76 65 72 74 69 63  =B[y].  A vertic
12a0: 61 6c 0a 2a 2a 20 73 74 65 70 73 20 63 6f 72 72  al.** steps corr
12b0: 65 73 70 6f 6e 64 73 20 74 6f 20 61 6e 20 69 6e  esponds to an in
12c0: 73 65 72 74 69 6f 6e 2e 20 20 41 20 68 6f 72 69  sertion.  A hori
12d0: 7a 6f 6e 74 61 6c 20 73 74 65 70 20 63 6f 72 72  zontal step corr
12e0: 65 73 70 6f 6e 64 73 0a 2a 2a 20 74 6f 20 61 20  esponds.** to a 
12f0: 64 65 6c 65 74 69 6f 6e 2e 20 20 57 65 20 77 61  deletion.  We wa
1300: 6e 74 20 74 6f 20 66 69 6e 64 20 74 68 65 20 70  nt to find the p
1310: 61 74 68 20 77 69 74 68 20 74 68 65 20 66 65 77  ath with the few
1320: 65 73 74 0a 2a 2a 20 68 6f 72 69 7a 6f 6e 74 61  est.** horizonta
1330: 6c 20 61 6e 64 20 76 65 72 74 69 63 61 6c 20 73  l and vertical s
1340: 74 65 70 73 2e 0a 2a 2a 0a 2a 2a 20 44 69 61 67  teps..**.** Diag
1350: 6f 6e 61 6c 20 6b 20 63 6f 6e 73 69 73 74 73 20  onal k consists 
1360: 6f 66 20 61 6c 6c 20 70 6f 69 6e 74 73 20 73 75  of all points su
1370: 63 68 20 74 68 61 74 20 78 2d 79 3d 3d 6b 2e 20  ch that x-y==k. 
1380: 20 44 69 61 67 6f 6e 61 6c 0a 2a 2a 20 7a 65 72   Diagonal.** zer
1390: 6f 20 62 65 67 69 6e 73 20 61 74 20 74 68 65 20  o begins at the 
13a0: 6f 72 69 67 69 6e 2e 20 20 44 69 61 67 6f 6e 61  origin.  Diagona
13b0: 6c 20 31 20 62 65 67 69 6e 73 20 61 74 20 28 31  l 1 begins at (1
13c0: 2c 30 29 2e 20 20 0a 2a 2a 20 44 69 61 67 6f 6e  ,0).  .** Diagon
13d0: 61 6c 20 2d 31 20 62 65 67 69 6e 73 20 61 74 20  al -1 begins at 
13e0: 28 30 2c 31 29 2e 20 20 41 6c 6c 20 64 69 61 67  (0,1).  All diag
13f0: 6f 6e 61 6c 73 20 6d 6f 76 65 20 75 70 20 61 6e  onals move up an
1400: 64 20 74 6f 20 74 68 65 0a 2a 2a 20 72 69 67 68  d to the.** righ
1410: 74 20 61 74 20 34 35 20 64 65 67 72 65 65 73 2e  t at 45 degrees.
1420: 20 20 44 69 61 67 6f 6e 61 6c 20 6e 75 6d 62 65    Diagonal numbe
1430: 72 20 69 6e 63 72 65 61 73 65 20 66 72 6f 6d 20  r increase from 
1440: 75 70 70 65 72 20 6c 65 66 74 0a 2a 2a 20 74 6f  upper left.** to
1450: 20 6c 6f 77 65 72 20 72 69 67 68 74 2e 0a 2a 2a   lower right..**
1460: 20 0a 2a 2a 20 4d 79 65 72 73 20 6d 61 74 72 69   .** Myers matri
1470: 78 20 4d 20 69 73 20 61 20 6c 6f 77 65 72 20 72  x M is a lower r
1480: 69 67 68 74 20 74 72 69 61 6e 67 75 6c 61 72 20  ight triangular 
1490: 6d 61 74 72 69 78 20 77 69 74 68 20 69 6e 64 69  matrix with indi
14a0: 63 65 73 20 64 0a 2a 2a 20 61 6c 6f 6e 67 20 74  ces d.** along t
14b0: 68 65 20 62 6f 74 74 6f 6d 20 61 6e 64 20 69 20  he bottom and i 
14c0: 76 65 72 74 69 63 61 6c 6c 79 3a 0a 2a 2a 0a 2a  vertically:.**.*
14d0: 2a 20 0a 2a 2a 20 20 20 69 3d 34 20 7c 20 20 20  * .**   i=4 |   
14e0: 20 20 20 20 20 20 20 20 20 2b 34 20 20 5c 0a 2a           +4  \.*
14f0: 2a 20 20 20 20 20 33 20 7c 20 20 20 20 20 20 20  *     3 |       
1500: 20 20 2b 33 20 2b 32 20 20 20 7c 0a 2a 2a 20 20    +3 +2   |.**  
1510: 20 20 20 32 20 7c 20 20 20 20 20 20 2b 32 20 2b     2 |      +2 +
1520: 31 20 20 30 20 20 20 7c 2d 20 6b 20 76 61 6c 75  1  0   |- k valu
1530: 65 73 2e 20 20 20 6b 20 3d 20 32 2a 69 2d 64 0a  es.   k = 2*i-d.
1540: 2a 2a 20 20 20 20 20 31 20 7c 20 20 20 2b 31 20  **     1 |   +1 
1550: 20 30 20 2d 31 20 2d 32 20 20 20 7c 0a 2a 2a 20   0 -1 -2   |.** 
1560: 20 20 20 20 30 20 7c 20 30 20 2d 31 20 2d 32 20      0 | 0 -1 -2 
1570: 2d 33 20 2d 34 20 20 2f 0a 2a 2a 20 20 20 20 20  -3 -4  /.**     
1580: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
1590: 2d 0a 2a 2a 20 20 20 20 20 20 20 20 20 30 20 20  -.**         0  
15a0: 31 20 20 32 20 20 33 20 20 34 20 3d 20 64 0a 2a  1  2  3  4 = d.*
15b0: 2a 0a 2a 2a 20 45 61 63 68 20 65 6c 65 6d 65 6e  *.** Each elemen
15c0: 74 20 6f 66 20 74 68 65 20 4d 79 65 72 73 20 6d  t of the Myers m
15d0: 61 74 72 69 78 20 63 6f 72 72 65 73 70 6f 6e 64  atrix correspond
15e0: 73 20 74 6f 20 61 20 64 69 61 67 6f 6e 61 6c 2e  s to a diagonal.
15f0: 0a 2a 2a 20 54 68 65 20 64 69 61 67 6f 6e 61 6c  .** The diagonal
1600: 20 69 73 20 6b 3d 32 2a 69 2d 64 2e 20 20 54 68   is k=2*i-d.  Th
1610: 65 20 64 69 61 67 6f 6e 61 6c 20 76 61 6c 75 65  e diagonal value
1620: 73 20 61 72 65 20 73 68 6f 77 6e 0a 2a 2a 20 69  s are shown.** i
1630: 6e 20 74 68 65 20 74 65 6d 70 6c 61 74 65 20 61  n the template a
1640: 62 6f 76 65 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68  bove..**.** Each
1650: 20 65 6e 74 72 79 20 69 6e 20 4d 20 72 65 70 72   entry in M repr
1660: 65 73 65 6e 74 73 20 74 68 65 20 65 6e 64 2d 70  esents the end-p
1670: 6f 69 6e 74 20 6f 6e 20 61 20 70 61 74 68 20 66  oint on a path f
1680: 72 6f 6d 20 28 30 2c 30 29 2e 0a 2a 2a 20 54 68  rom (0,0)..** Th
1690: 65 20 65 6e 64 2d 70 6f 69 6e 74 20 69 73 20 6f  e end-point is o
16a0: 6e 20 64 69 61 67 6f 6e 61 6c 20 6b 2e 20 20 54  n diagonal k.  T
16b0: 68 65 20 76 61 6c 75 65 20 73 74 6f 72 65 64 20  he value stored 
16c0: 69 6e 20 4d 20 69 73 0a 2a 2a 20 71 3d 78 2b 79  in M is.** q=x+y
16d0: 20 77 68 65 72 65 20 28 78 2c 79 29 20 69 73 20   where (x,y) is 
16e0: 74 68 65 20 74 65 72 6d 69 6e 75 73 20 6f 66 20  the terminus of 
16f0: 74 68 65 20 70 61 74 68 2e 20 20 41 20 70 61 74  the path.  A pat
1700: 68 0a 2a 2a 20 74 6f 20 4d 5b 64 5d 5b 69 5d 20  h.** to M[d][i] 
1710: 77 69 6c 6c 20 63 6f 6d 65 20 74 68 72 6f 75 67  will come throug
1720: 68 20 65 69 74 68 65 72 20 4d 5b 64 2d 31 5d 5b  h either M[d-1][
1730: 69 2d 31 5d 20 6f 72 0a 2a 2a 20 74 68 6f 75 67  i-1] or.** thoug
1740: 68 20 4d 5b 64 2d 31 5d 5b 69 5d 2c 20 77 68 69  h M[d-1][i], whi
1750: 63 68 65 76 65 72 20 68 6f 6c 64 73 20 74 68 65  chever holds the
1760: 20 6c 61 72 67 65 73 74 20 76 61 6c 75 65 20 6f   largest value o
1770: 66 20 71 2e 0a 2a 2a 20 49 66 20 62 6f 74 68 20  f q..** If both 
1780: 65 6c 65 6d 65 6e 74 73 20 68 6f 6c 64 20 74 68  elements hold th
1790: 65 20 73 61 6d 65 20 76 61 6c 75 65 2c 20 74 68  e same value, th
17a0: 65 20 70 61 74 68 20 63 6f 6d 65 73 0a 2a 2a 20  e path comes.** 
17b0: 74 68 72 6f 75 67 68 20 4d 5b 64 2d 31 5d 5b 69  through M[d-1][i
17c0: 2d 31 5d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76  -1]..**.** The v
17d0: 61 6c 75 65 20 6f 66 20 64 20 69 73 20 74 68 65  alue of d is the
17e0: 20 6e 75 6d 62 65 72 20 6f 66 20 69 6e 73 65 72   number of inser
17f0: 74 69 6f 6e 73 20 61 6e 64 20 64 65 6c 65 74 69  tions and deleti
1800: 6f 6e 73 0a 2a 2a 20 6d 61 64 65 20 73 6f 20 66  ons.** made so f
1810: 61 72 20 6f 6e 20 74 68 65 20 70 61 74 68 2e 20  ar on the path. 
1820: 20 4d 20 67 72 6f 77 73 20 70 72 6f 67 72 65 73   M grows progres
1830: 73 69 76 65 6c 79 2e 20 20 53 6f 20 74 68 65 0a  sively.  So the.
1840: 2a 2a 20 73 69 7a 65 20 6f 66 20 74 68 65 20 4d  ** size of the M
1850: 20 6d 61 74 72 69 78 20 69 73 20 70 72 6f 70 6f   matrix is propo
1860: 72 74 69 6f 6e 61 6c 20 74 6f 20 64 2a 64 2e 20  rtional to d*d. 
1870: 20 46 6f 72 20 74 68 65 0a 2a 2a 20 63 6f 6d 6d   For the.** comm
1880: 6f 6e 20 63 61 73 65 20 77 68 65 72 65 20 41 20  on case where A 
1890: 61 6e 64 20 42 20 61 72 65 20 73 69 6d 69 6c 61  and B are simila
18a0: 72 2c 20 64 20 77 69 6c 6c 20 62 65 20 73 6d 61  r, d will be sma
18b0: 6c 6c 0a 2a 2a 20 63 6f 6d 70 61 72 65 64 20 74  ll.** compared t
18c0: 6f 20 58 20 61 6e 64 20 59 20 73 6f 20 6c 69 74  o X and Y so lit
18d0: 74 6c 65 20 6d 65 6d 6f 72 79 20 69 73 20 72 65  tle memory is re
18e0: 71 75 69 72 65 64 2e 20 20 54 68 65 0a 2a 2a 20  quired.  The.** 
18f0: 6f 72 69 67 69 6e 61 6c 20 57 61 67 6e 65 72 20  original Wagner 
1900: 61 6c 67 6f 72 69 74 68 6d 20 72 65 71 75 69 72  algorithm requir
1910: 65 73 20 58 2a 59 20 6d 65 6d 6f 72 79 2c 20 77  es X*Y memory, w
1920: 68 69 63 68 20 66 6f 72 0a 2a 2a 20 6c 61 72 67  hich for.** larg
1930: 65 72 20 66 69 6c 65 73 20 28 31 30 30 4b 20 6c  er files (100K l
1940: 69 6e 65 73 29 20 69 73 20 6d 6f 72 65 20 6d 65  ines) is more me
1950: 6d 6f 72 79 20 74 68 61 6e 20 77 65 20 68 61 76  mory than we hav
1960: 65 20 61 74 0a 2a 2a 20 68 61 6e 64 2e 0a 2a 2f  e at.** hand..*/
1970: 0a 69 6e 74 20 2a 74 65 78 74 5f 64 69 66 66 28  .int *text_diff(
1980: 0a 20 20 42 6c 6f 62 20 2a 70 41 5f 42 6c 6f 62  .  Blob *pA_Blob
1990: 2c 20 20 20 2f 2a 20 46 52 4f 4d 20 66 69 6c 65  ,   /* FROM file
19a0: 20 2a 2f 0a 20 20 42 6c 6f 62 20 2a 70 42 5f 42   */.  Blob *pB_B
19b0: 6c 6f 62 2c 20 20 20 2f 2a 20 54 4f 20 66 69 6c  lob,   /* TO fil
19c0: 65 20 2a 2f 0a 20 20 42 6c 6f 62 20 2a 70 4f 75  e */.  Blob *pOu
19d0: 74 2c 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65  t,      /* Write
19e0: 20 75 6e 69 66 69 65 64 20 64 69 66 66 20 68 65   unified diff he
19f0: 72 65 20 69 66 20 6e 6f 74 20 4e 55 4c 4c 20 2a  re if not NULL *
1a00: 2f 0a 20 20 69 6e 74 20 6e 43 6f 6e 74 65 78 74  /.  int nContext
1a10: 20 20 20 20 20 2f 2a 20 41 6d 6f 75 6e 74 20 6f       /* Amount o
1a20: 66 20 63 6f 6e 74 65 78 74 20 74 6f 20 75 6e 69  f context to uni
1a30: 66 69 65 64 20 64 69 66 66 20 2a 2f 0a 29 7b 0a  fied diff */.){.
1a40: 20 20 44 4c 69 6e 65 20 2a 41 2c 20 2a 42 3b 20    DLine *A, *B; 
1a50: 20 20 20 2f 2a 20 46 69 6c 65 73 20 62 65 69 6e     /* Files bein
1a60: 67 20 63 6f 6d 70 61 72 65 64 20 2a 2f 0a 20 20  g compared */.  
1a70: 69 6e 74 20 58 2c 20 59 3b 20 20 20 20 20 20 20  int X, Y;       
1a80: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c   /* Number of el
1a90: 65 6d 65 6e 74 73 20 69 6e 20 41 20 61 6e 64 20  ements in A and 
1aa0: 42 20 2a 2f 0a 20 20 69 6e 74 20 78 2c 20 79 3b  B */.  int x, y;
1ab0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 69 63          /* Indic
1ac0: 65 73 3a 20 20 41 5b 78 5d 20 61 6e 64 20 42 5b  es:  A[x] and B[
1ad0: 79 5d 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4d 20  y] */.  int szM 
1ae0: 3d 20 30 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62  = 0;     /* Numb
1af0: 65 72 20 6f 66 20 72 6f 77 73 20 61 6e 64 20 63  er of rows and c
1b00: 6f 6c 75 6d 6e 73 20 69 6e 20 4d 20 2a 2f 0a 20  olumns in M */. 
1b10: 20 69 6e 74 20 2a 2a 4d 20 3d 20 30 3b 20 20 20   int **M = 0;   
1b20: 20 20 2f 2a 20 4d 79 65 72 73 20 6d 61 74 72 69    /* Myers matri
1b30: 78 20 2a 2f 0a 20 20 69 6e 74 20 69 2c 20 64 3b  x */.  int i, d;
1b40: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 69 63          /* Indic
1b50: 65 73 20 6f 6e 20 4d 2e 20 20 4d 5b 64 5d 5b 69  es on M.  M[d][i
1b60: 5d 20 2a 2f 0a 20 20 69 6e 74 20 6b 2c 20 71 3b  ] */.  int k, q;
1b70: 20 20 20 20 20 20 20 20 2f 2a 20 44 69 61 67 6f          /* Diago
1b80: 6e 61 6c 20 6e 75 6d 62 65 72 20 61 6e 64 20 64  nal number and d
1b90: 69 73 74 69 6e 63 74 20 66 72 6f 6d 20 28 30 2c  istinct from (0,
1ba0: 30 29 20 2a 2f 0a 20 20 69 6e 74 20 4b 2c 20 44  0) */.  int K, D
1bb0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  ;        /* The 
1bc0: 64 69 61 67 6f 6e 61 6c 20 61 6e 64 20 64 20 66  diagonal and d f
1bd0: 6f 72 20 74 68 65 20 66 69 6e 61 6c 20 73 6f 6c  or the final sol
1be0: 75 74 69 6f 6e 20 2a 2f 20 20 20 20 20 20 20 20  ution */        
1bf0: 20 20 0a 20 20 69 6e 74 20 2a 52 20 3d 20 30 3b    .  int *R = 0;
1c00: 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20        /* Result 
1c10: 76 65 63 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  vector */.  int 
1c20: 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  r;           /* 
1c30: 4c 6f 6f 70 20 76 61 72 69 61 62 6c 65 73 20 2a  Loop variables *
1c40: 2f 0a 20 20 69 6e 74 20 67 6f 20 3d 20 31 3b 20  /.  int go = 1; 
1c50: 20 20 20 20 20 2f 2a 20 4f 75 74 65 72 20 6c 6f       /* Outer lo
1c60: 6f 70 20 63 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20  op control */.  
1c70: 69 6e 74 20 4d 41 58 3b 20 20 20 20 20 20 20 20  int MAX;        
1c80: 20 2f 2a 20 4c 61 72 67 65 73 74 20 6f 66 20 58   /* Largest of X
1c90: 20 61 6e 64 20 59 20 2a 2f 0a 0a 20 20 2f 2a 20   and Y */..  /* 
1ca0: 42 72 65 61 6b 20 74 68 65 20 74 77 6f 20 66 69  Break the two fi
1cb0: 6c 65 73 20 62 65 69 6e 67 20 64 69 66 66 65 64  les being diffed
1cc0: 20 69 6e 74 6f 20 69 6e 64 69 76 69 64 75 61 6c   into individual
1cd0: 20 6c 69 6e 65 73 2e 0a 20 20 2a 2a 20 43 6f 6d   lines..  ** Com
1ce0: 70 75 74 65 20 68 61 73 68 65 73 20 6f 6e 20 65  pute hashes on e
1cf0: 61 63 68 20 6c 69 6e 65 20 66 6f 72 20 66 61 73  ach line for fas
1d00: 74 20 63 6f 6d 70 61 72 69 73 6f 6e 2e 0a 20 20  t comparison..  
1d10: 2a 2f 0a 20 20 41 20 3d 20 62 72 65 61 6b 5f 69  */.  A = break_i
1d20: 6e 74 6f 5f 6c 69 6e 65 73 28 62 6c 6f 62 5f 73  nto_lines(blob_s
1d30: 74 72 28 70 41 5f 42 6c 6f 62 29 2c 20 26 58 29  tr(pA_Blob), &X)
1d40: 3b 0a 20 20 42 20 3d 20 62 72 65 61 6b 5f 69 6e  ;.  B = break_in
1d50: 74 6f 5f 6c 69 6e 65 73 28 62 6c 6f 62 5f 73 74  to_lines(blob_st
1d60: 72 28 70 42 5f 42 6c 6f 62 29 2c 20 26 59 29 3b  r(pB_Blob), &Y);
1d70: 0a 0a 20 20 69 66 28 20 41 3d 3d 30 20 7c 7c 20  ..  if( A==0 || 
1d80: 42 3d 3d 30 20 29 7b 0a 20 20 20 20 66 72 65 65  B==0 ){.    free
1d90: 28 41 29 3b 0a 20 20 20 20 66 72 65 65 28 42 29  (A);.    free(B)
1da0: 3b 0a 20 20 20 20 69 66 28 20 70 4f 75 74 20 29  ;.    if( pOut )
1db0: 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70  {.      blob_app
1dc0: 65 6e 64 66 28 70 4f 75 74 2c 20 22 63 61 6e 6e  endf(pOut, "cann
1dd0: 6f 74 20 63 6f 6d 70 75 74 65 20 64 69 66 66 65  ot compute diffe
1de0: 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 62 69  rence between bi
1df0: 6e 61 72 79 20 66 69 6c 65 73 5c 6e 22 29 3b 0a  nary files\n");.
1e00: 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e      }.    return
1e10: 20 30 3b 0a 20 20 7d 0a 0a 20 20 73 7a 4d 20 3d   0;.  }..  szM =
1e20: 20 30 3b 0a 20 20 4d 41 58 20 3d 20 58 3e 59 20   0;.  MAX = X>Y 
1e30: 3f 20 58 20 3a 20 59 3b 0a 20 20 66 6f 72 28 64  ? X : Y;.  for(d
1e40: 3d 30 3b 20 67 6f 20 26 26 20 64 3c 3d 4d 41 58  =0; go && d<=MAX
1e50: 3b 20 64 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; d++){.    if( 
1e60: 73 7a 4d 3c 64 2b 31 20 29 7b 0a 20 20 20 20 20  szM<d+1 ){.     
1e70: 20 73 7a 4d 20 2b 3d 20 73 7a 4d 20 2b 20 31 30   szM += szM + 10
1e80: 3b 0a 20 20 20 20 20 20 4d 20 3d 20 72 65 61 6c  ;.      M = real
1e90: 6c 6f 63 28 4d 2c 20 73 69 7a 65 6f 66 28 4d 5b  loc(M, sizeof(M[
1ea0: 30 5d 29 2a 73 7a 4d 29 3b 0a 20 20 20 20 20 20  0])*szM);.      
1eb0: 69 66 28 20 4d 3d 3d 30 20 29 7b 0a 20 20 20 20  if( M==0 ){.    
1ec0: 20 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63      fossil_panic
1ed0: 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22  ("out of memory"
1ee0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
1ef0: 0a 20 20 20 20 4d 5b 64 5d 20 3d 20 6d 61 6c 6c  .    M[d] = mall
1f00: 6f 63 28 20 73 69 7a 65 6f 66 28 4d 5b 64 5d 5b  oc( sizeof(M[d][
1f10: 30 5d 29 2a 28 64 2b 31 29 20 29 3b 0a 20 20 20  0])*(d+1) );.   
1f20: 20 69 66 28 20 4d 5b 64 5d 3d 3d 30 20 29 7b 0a   if( M[d]==0 ){.
1f30: 20 20 20 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e        fossil_pan
1f40: 69 63 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72  ic("out of memor
1f50: 79 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66  y");.    }.    f
1f60: 6f 72 28 69 3d 30 3b 20 69 3c 3d 64 3b 20 69 2b  or(i=0; i<=d; i+
1f70: 2b 29 7b 0a 20 20 20 20 20 20 6b 20 3d 20 32 2a  +){.      k = 2*
1f80: 69 20 2d 20 64 3b 0a 20 20 20 20 20 20 69 66 28  i - d;.      if(
1f90: 20 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20   d==0 ){.       
1fa0: 20 71 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65   q = 0;.      }e
1fb0: 6c 73 65 20 69 66 28 20 69 3d 3d 30 20 29 7b 0a  lse if( i==0 ){.
1fc0: 20 20 20 20 20 20 20 20 71 20 3d 20 4d 5b 64 2d          q = M[d-
1fd0: 31 5d 5b 30 5d 3b 0a 20 20 20 20 20 20 7d 65 6c  1][0];.      }el
1fe0: 73 65 20 69 66 28 20 69 3c 64 2d 31 20 26 26 20  se if( i<d-1 && 
1ff0: 4d 5b 64 2d 31 5d 5b 69 2d 31 5d 20 3c 20 4d 5b  M[d-1][i-1] < M[
2000: 64 2d 31 5d 5b 69 5d 20 29 7b 0a 20 20 20 20 20  d-1][i] ){.     
2010: 20 20 20 71 20 3d 20 4d 5b 64 2d 31 5d 5b 69 5d     q = M[d-1][i]
2020: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
2030: 20 20 20 20 20 20 20 71 20 3d 20 4d 5b 64 2d 31         q = M[d-1
2040: 5d 5b 69 2d 31 5d 3b 0a 20 20 20 20 20 20 7d 0a  ][i-1];.      }.
2050: 20 20 20 20 20 20 78 20 3d 20 28 6b 20 2b 20 71        x = (k + q
2060: 20 2b 20 31 29 2f 32 3b 0a 20 20 20 20 20 20 79   + 1)/2;.      y
2070: 20 3d 20 78 20 2d 20 6b 3b 0a 20 20 20 20 20 20   = x - k;.      
2080: 69 66 28 20 78 3c 30 20 7c 7c 20 78 3e 58 20 7c  if( x<0 || x>X |
2090: 7c 20 79 3c 30 20 7c 7c 20 79 3e 59 20 29 7b 0a  | y<0 || y>Y ){.
20a0: 20 20 20 20 20 20 20 20 78 20 3d 20 79 20 3d 20          x = y = 
20b0: 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  0;.      }else{.
20c0: 20 20 20 20 20 20 20 20 77 68 69 6c 65 28 20 78          while( x
20d0: 3c 58 20 26 26 20 79 3c 59 20 26 26 20 73 61 6d  <X && y<Y && sam
20e0: 65 5f 64 6c 69 6e 65 28 26 41 5b 78 5d 2c 26 42  e_dline(&A[x],&B
20f0: 5b 79 5d 29 20 29 7b 20 78 2b 2b 3b 20 79 2b 2b  [y]) ){ x++; y++
2100: 3b 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ; }.      }.    
2110: 20 20 4d 5b 64 5d 5b 69 5d 20 3d 20 78 20 2b 20    M[d][i] = x + 
2120: 79 3b 0a 20 20 20 20 20 20 44 45 42 55 47 28 20  y;.      DEBUG( 
2130: 70 72 69 6e 74 66 28 22 4d 5b 25 64 5d 5b 25 69  printf("M[%d][%i
2140: 5d 20 3d 20 25 64 20 20 6b 3d 25 64 20 28 25 64  ] = %d  k=%d (%d
2150: 2c 25 64 29 5c 6e 22 2c 20 64 2c 20 69 2c 20 78  ,%d)\n", d, i, x
2160: 2b 79 2c 20 6b 2c 20 78 2c 20 79 29 3b 20 29 0a  +y, k, x, y); ).
2170: 20 20 20 20 20 20 69 66 28 20 78 3d 3d 58 20 26        if( x==X &
2180: 26 20 79 3d 3d 59 20 29 7b 0a 20 20 20 20 20 20  & y==Y ){.      
2190: 20 20 67 6f 20 3d 20 30 3b 0a 20 20 20 20 20 20    go = 0;.      
21a0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
21b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
21c0: 20 64 3e 4d 41 58 20 29 7b 0a 20 20 20 20 52 20   d>MAX ){.    R 
21d0: 3d 20 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66  = malloc( sizeof
21e0: 28 52 5b 30 5d 29 2a 36 20 29 3b 0a 20 20 20 20  (R[0])*6 );.    
21f0: 52 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 52 5b  R[0] = 0;.    R[
2200: 31 5d 20 3d 20 58 3b 0a 20 20 20 20 52 5b 32 5d  1] = X;.    R[2]
2210: 20 3d 20 59 3b 0a 20 20 20 20 52 5b 33 5d 20 3d   = Y;.    R[3] =
2220: 20 30 3b 0a 20 20 20 20 52 5b 34 5d 20 3d 20 30   0;.    R[4] = 0
2230: 3b 0a 20 20 20 20 52 5b 35 5d 20 3d 20 30 3b 0a  ;.    R[5] = 0;.
2240: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20    }else{.    /* 
2250: 52 65 75 73 65 20 4d 5b 5d 20 61 73 20 66 6f 6c  Reuse M[] as fol
2260: 6c 6f 77 73 3a 0a 20 20 20 20 2a 2a 0a 20 20 20  lows:.    **.   
2270: 20 2a 2a 20 20 20 20 20 4d 5b 64 5d 5b 31 5d 20   **     M[d][1] 
2280: 3d 20 31 20 69 66 20 61 20 6c 69 6e 65 20 69 73  = 1 if a line is
2290: 20 69 6e 73 65 72 74 65 64 20 6f 72 20 30 20 69   inserted or 0 i
22a0: 66 20 61 20 6c 69 6e 65 20 69 73 20 64 65 6c 65  f a line is dele
22b0: 74 65 64 2e 0a 20 20 20 20 2a 2a 20 20 20 20 20  ted..    **     
22c0: 4d 5b 64 5d 5b 30 5d 20 3d 20 6e 75 6d 62 65 72  M[d][0] = number
22d0: 20 6f 66 20 6c 69 6e 65 73 20 63 6f 70 69 65 64   of lines copied
22e0: 20 61 66 74 65 72 20 74 68 65 20 69 6e 73 20 6f   after the ins o
22f0: 72 20 64 65 6c 20 61 62 6f 76 65 2e 0a 20 20 20  r del above..   
2300: 20 2a 2a 0a 20 20 20 20 2a 2f 0a 20 20 20 20 44   **.    */.    D
2310: 20 3d 20 64 20 2d 20 31 3b 0a 20 20 20 20 4b 20   = d - 1;.    K 
2320: 3d 20 58 20 2d 20 59 3b 0a 20 20 20 20 66 6f 72  = X - Y;.    for
2330: 28 64 3d 44 2c 20 69 3d 28 4b 2b 44 29 2f 32 3b  (d=D, i=(K+D)/2;
2340: 20 64 3e 30 3b 20 64 2d 2d 29 7b 0a 20 20 20 20   d>0; d--){.    
2350: 20 20 44 45 42 55 47 28 20 70 72 69 6e 74 66 28    DEBUG( printf(
2360: 22 64 3d 25 64 20 69 3d 25 64 5c 6e 22 2c 20 64  "d=%d i=%d\n", d
2370: 2c 20 69 29 3b 20 29 0a 20 20 20 20 20 20 69 66  , i); ).      if
2380: 28 20 69 3d 3d 64 20 7c 7c 20 28 69 3e 30 20 26  ( i==d || (i>0 &
2390: 26 20 4d 5b 64 2d 31 5d 5b 69 2d 31 5d 20 3e 20  & M[d-1][i-1] > 
23a0: 4d 5b 64 2d 31 5d 5b 69 5d 29 20 29 7b 0a 20 20  M[d-1][i]) ){.  
23b0: 20 20 20 20 20 20 4d 5b 64 5d 5b 30 5d 20 3d 20        M[d][0] = 
23c0: 4d 5b 64 5d 5b 69 5d 20 2d 20 4d 5b 64 2d 31 5d  M[d][i] - M[d-1]
23d0: 5b 69 2d 31 5d 20 2d 20 31 3b 0a 20 20 20 20 20  [i-1] - 1;.     
23e0: 20 20 20 4d 5b 64 5d 5b 31 5d 20 3d 20 30 3b 0a     M[d][1] = 0;.
23f0: 20 20 20 20 20 20 20 20 69 2d 2d 3b 0a 20 20 20          i--;.   
2400: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2410: 20 20 4d 5b 64 5d 5b 30 5d 20 3d 20 4d 5b 64 5d    M[d][0] = M[d]
2420: 5b 69 5d 20 2d 20 4d 5b 64 2d 31 5d 5b 69 5d 20  [i] - M[d-1][i] 
2430: 2d 20 31 3b 0a 20 20 20 20 20 20 20 20 4d 5b 64  - 1;.        M[d
2440: 5d 5b 31 5d 20 3d 20 31 3b 0a 20 20 20 20 20 20  ][1] = 1;.      
2450: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 0a 20 20 20  }.    }.    .   
2460: 20 44 45 42 55 47 28 0a 20 20 20 20 20 20 70 72   DEBUG(.      pr
2470: 69 6e 74 66 28 22 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  intf("----------
2480: 2d 2d 2d 2d 2d 5c 6e 4d 5b 30 5d 5b 30 5d 20 3d  -----\nM[0][0] =
2490: 20 25 35 64 5c 6e 22 2c 20 4d 5b 30 5d 5b 30 5d   %5d\n", M[0][0]
24a0: 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 64 3d 31  );.      for(d=1
24b0: 3b 20 64 3c 3d 44 3b 20 64 2b 2b 29 7b 0a 20 20  ; d<=D; d++){.  
24c0: 20 20 20 20 20 20 70 72 69 6e 74 66 28 22 4d 5b        printf("M[
24d0: 25 64 5d 5b 30 5d 20 3d 20 25 35 64 20 20 20 20  %d][0] = %5d    
24e0: 4d 5b 25 64 5d 5b 31 5d 20 3d 20 25 64 5c 6e 22  M[%d][1] = %d\n"
24f0: 2c 64 2c 4d 5b 64 5d 5b 30 5d 2c 64 2c 4d 5b 64  ,d,M[d][0],d,M[d
2500: 5d 5b 31 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ][1]);.      }. 
2510: 20 20 20 29 0a 20 20 20 20 0a 20 20 20 20 2f 2a     ).    .    /*
2520: 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 6f 75   Allocate the ou
2530: 74 70 75 74 20 76 65 63 74 6f 72 0a 20 20 20 20  tput vector.    
2540: 2a 2f 0a 20 20 20 20 52 20 3d 20 6d 61 6c 6c 6f  */.    R = mallo
2550: 63 28 20 73 69 7a 65 6f 66 28 52 5b 30 5d 29 2a  c( sizeof(R[0])*
2560: 28 44 2b 32 29 2a 33 20 29 3b 0a 20 20 20 20 69  (D+2)*3 );.    i
2570: 66 28 20 52 3d 3d 30 20 29 7b 0a 20 20 20 20 20  f( R==0 ){.     
2580: 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 6f   fossil_fatal("o
2590: 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22 29 3b 0a  ut of memory");.
25a0: 20 20 20 20 7d 0a 20 20 20 20 0a 20 20 20 20 2f      }.    .    /
25b0: 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 65 20 6f  * Populate the o
25c0: 75 74 70 75 74 20 76 65 63 74 6f 72 0a 20 20 20  utput vector.   
25d0: 20 2a 2f 0a 20 20 20 20 64 20 3d 20 72 20 3d 20   */.    d = r = 
25e0: 30 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 64 3c  0;.    while( d<
25f0: 3d 44 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  =D ){.      int 
2600: 6e 3b 0a 20 20 20 20 20 20 52 5b 72 2b 2b 5d 20  n;.      R[r++] 
2610: 3d 20 4d 5b 64 2b 2b 5d 5b 30 5d 2f 32 3b 20 20  = M[d++][0]/2;  
2620: 20 2f 2a 20 43 4f 50 59 20 2a 2f 0a 20 20 20 20   /* COPY */.    
2630: 20 20 69 66 28 20 64 3e 44 20 29 7b 0a 20 20 20    if( d>D ){.   
2640: 20 20 20 20 20 52 5b 72 2b 2b 5d 20 3d 20 30 3b       R[r++] = 0;
2650: 0a 20 20 20 20 20 20 20 20 52 5b 72 2b 2b 5d 20  .        R[r++] 
2660: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 0;.        bre
2670: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
2680: 20 20 69 66 28 20 4d 5b 64 5d 5b 31 5d 3d 3d 30    if( M[d][1]==0
2690: 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 20 3d 20   ){.        n = 
26a0: 31 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65  1;.        while
26b0: 28 20 4d 5b 64 5d 5b 30 5d 3d 3d 30 20 26 26 20  ( M[d][0]==0 && 
26c0: 64 3c 44 20 26 26 20 4d 5b 64 2b 31 5d 5b 31 5d  d<D && M[d+1][1]
26d0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
26e0: 20 64 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20   d++;.          
26f0: 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  n++;.        }. 
2700: 20 20 20 20 20 20 20 52 5b 72 2b 2b 5d 20 3d 20         R[r++] = 
2710: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  n;           /* 
2720: 44 45 4c 45 54 45 20 2a 2f 0a 20 20 20 20 20 20  DELETE */.      
2730: 20 20 69 66 28 20 64 3d 3d 44 20 7c 7c 20 4d 5b    if( d==D || M[
2740: 64 5d 5b 30 5d 3e 30 20 29 7b 0a 20 20 20 20 20  d][0]>0 ){.     
2750: 20 20 20 20 20 52 5b 72 2b 2b 5d 20 3d 20 30 3b       R[r++] = 0;
2760: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 53 45           /* INSE
2770: 52 54 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  RT */.          
2780: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
2790: 20 20 7d 0a 20 20 20 20 20 20 20 20 64 2b 2b 3b    }.        d++;
27a0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
27b0: 20 20 20 20 20 20 52 5b 72 2b 2b 5d 20 3d 20 30        R[r++] = 0
27c0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44  ;           /* D
27d0: 45 4c 45 54 45 20 2a 2f 0a 20 20 20 20 20 20 7d  ELETE */.      }
27e0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 4d  .      assert( M
27f0: 5b 64 5d 5b 31 5d 3d 3d 31 20 29 3b 0a 20 20 20  [d][1]==1 );.   
2800: 20 20 20 6e 20 3d 20 31 3b 0a 20 20 20 20 20 20     n = 1;.      
2810: 77 68 69 6c 65 28 20 4d 5b 64 5d 5b 30 5d 3d 3d  while( M[d][0]==
2820: 30 20 26 26 20 64 3c 44 20 26 26 20 4d 5b 64 2b  0 && d<D && M[d+
2830: 31 5d 5b 31 5d 3d 3d 31 20 29 7b 0a 20 20 20 20  1][1]==1 ){.    
2840: 20 20 20 20 64 2b 2b 3b 0a 20 20 20 20 20 20 20      d++;.       
2850: 20 6e 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20   n++;.      }.  
2860: 20 20 20 20 52 5b 72 2b 2b 5d 20 3d 20 6e 3b 20      R[r++] = n; 
2870: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
2880: 53 45 52 54 20 2a 2f 0a 20 20 20 20 7d 0a 20 20  SERT */.    }.  
2890: 20 20 52 5b 72 2b 2b 5d 20 3d 20 30 3b 0a 20 20    R[r++] = 0;.  
28a0: 20 20 52 5b 72 2b 2b 5d 20 3d 20 30 3b 0a 20 20    R[r++] = 0;.  
28b0: 20 20 52 5b 72 2b 2b 5d 20 3d 20 30 3b 0a 20 20    R[r++] = 0;.  
28c0: 7d 0a 20 20 20 20 0a 20 20 2f 2a 20 46 72 65 65  }.    .  /* Free
28d0: 20 74 68 65 20 4d 79 65 72 73 20 6d 61 74 72 69   the Myers matri
28e0: 78 20 2a 2f 0a 20 20 66 6f 72 28 64 3d 30 3b 20  x */.  for(d=0; 
28f0: 64 3c 3d 44 3b 20 64 2b 2b 29 7b 0a 20 20 20 20  d<=D; d++){.    
2900: 66 72 65 65 28 4d 5b 64 5d 29 3b 0a 20 20 7d 0a  free(M[d]);.  }.
2910: 20 20 66 72 65 65 28 4d 29 3b 0a 0a 20 20 2f 2a    free(M);..  /*
2920: 20 49 66 20 70 4f 75 74 20 69 73 20 64 65 66 69   If pOut is defi
2930: 6e 65 64 2c 20 63 6f 6e 73 74 72 75 63 74 20 61  ned, construct a
2940: 20 75 6e 69 66 69 65 64 20 64 69 66 66 20 69 6e   unified diff in
2950: 74 6f 20 70 4f 75 74 20 61 6e 64 0a 20 20 2a 2a  to pOut and.  **
2960: 20 64 65 6c 65 74 65 20 52 0a 20 20 2a 2f 0a 20   delete R.  */. 
2970: 20 69 66 28 20 70 4f 75 74 20 29 7b 0a 20 20 20   if( pOut ){.   
2980: 20 69 6e 74 20 61 20 3d 20 30 3b 20 20 20 20 2f   int a = 0;    /
2990: 2a 20 49 6e 64 65 78 20 6f 66 20 6e 65 78 74 20  * Index of next 
29a0: 6c 69 6e 65 20 69 6e 20 41 5b 5d 20 2a 2f 0a 20  line in A[] */. 
29b0: 20 20 20 69 6e 74 20 62 20 3d 20 30 3b 20 20 20     int b = 0;   
29c0: 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6e 65 78   /* Index of nex
29d0: 74 20 6c 69 6e 65 20 69 6e 20 42 5b 5d 20 2a 2f  t line in B[] */
29e0: 0a 20 20 20 20 69 6e 74 20 6e 72 3b 20 20 20 20  .    int nr;    
29f0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
2a00: 43 4f 50 59 2f 44 45 4c 45 54 45 2f 49 4e 53 45  COPY/DELETE/INSE
2a10: 52 54 20 74 72 69 70 6c 65 73 20 74 6f 20 70 72  RT triples to pr
2a20: 6f 63 65 73 73 20 2a 2f 0a 20 20 20 20 69 6e 74  ocess */.    int
2a30: 20 6e 61 2c 20 6e 62 3b 20 20 20 2f 2a 20 4e 75   na, nb;   /* Nu
2a40: 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 73 68  mber of lines sh
2a50: 6f 77 6e 20 66 72 6f 6d 20 41 20 61 6e 64 20 42  own from A and B
2a60: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 2c 20 6a   */.    int i, j
2a70: 3b 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f  ;     /* Loop co
2a80: 75 6e 74 65 72 73 20 2a 2f 0a 20 20 20 20 69 6e  unters */.    in
2a90: 74 20 6d 3b 20 20 20 20 20 20 20 20 2f 2a 20 4e  t m;        /* N
2aa0: 75 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 74  umber of lines t
2ab0: 6f 20 6f 75 74 70 75 74 20 2a 2f 0a 20 20 20 20  o output */.    
2ac0: 69 6e 74 20 73 6b 69 70 3b 20 20 20 20 20 2f 2a  int skip;     /*
2ad0: 20 4e 75 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73   Number of lines
2ae0: 20 74 6f 20 73 6b 69 70 20 2a 2f 0a 0a 20 20 20   to skip */..   
2af0: 20 66 6f 72 28 72 3d 30 3b 20 52 5b 72 2b 31 5d   for(r=0; R[r+1]
2b00: 20 7c 7c 20 52 5b 72 2b 32 5d 20 7c 7c 20 52 5b   || R[r+2] || R[
2b10: 72 2b 33 5d 3b 20 72 20 2b 3d 20 33 2a 6e 72 29  r+3]; r += 3*nr)
2b20: 7b 0a 20 20 20 20 20 20 2f 2a 20 46 69 67 75 72  {.      /* Figur
2b30: 65 20 6f 75 74 20 68 6f 77 20 6d 61 6e 79 20 74  e out how many t
2b40: 72 69 70 6c 65 73 20 74 6f 20 73 68 6f 77 20 69  riples to show i
2b50: 6e 20 61 20 73 69 6e 67 6c 65 20 62 6c 6f 63 6b  n a single block
2b60: 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 6e 72   */.      for(nr
2b70: 3d 31 3b 20 52 5b 72 2b 6e 72 2a 33 5d 3e 30 20  =1; R[r+nr*3]>0 
2b80: 26 26 20 52 5b 72 2b 6e 72 2a 33 5d 3c 6e 43 6f  && R[r+nr*3]<nCo
2b90: 6e 74 65 78 74 2a 32 3b 20 6e 72 2b 2b 29 7b 7d  ntext*2; nr++){}
2ba0: 0a 20 20 20 20 20 20 44 45 42 55 47 28 20 70 72  .      DEBUG( pr
2bb0: 69 6e 74 66 28 22 72 3d 25 64 20 6e 72 3d 25 64  intf("r=%d nr=%d
2bc0: 5c 6e 22 2c 20 72 2c 20 6e 72 29 3b 20 29 0a 0a  \n", r, nr); )..
2bd0: 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 74 68 65        /* For the
2be0: 20 63 75 72 72 65 6e 74 20 62 6c 6f 63 6b 20 63   current block c
2bf0: 6f 6d 70 72 69 73 69 6e 67 20 6e 72 20 74 72 69  omprising nr tri
2c00: 70 6c 65 73 2c 20 66 69 67 75 72 65 20 6f 75 74  ples, figure out
2c10: 0a 20 20 20 20 20 20 2a 2a 20 68 6f 77 20 6d 61  .      ** how ma
2c20: 6e 79 20 6c 69 6e 65 73 20 6f 66 20 41 20 61 6e  ny lines of A an
2c30: 64 20 42 20 61 72 65 20 74 6f 20 62 65 20 64 69  d B are to be di
2c40: 73 70 6c 61 79 65 64 0a 20 20 20 20 20 20 2a 2f  splayed.      */
2c50: 0a 20 20 20 20 20 20 69 66 28 20 52 5b 72 5d 3e  .      if( R[r]>
2c60: 6e 43 6f 6e 74 65 78 74 20 29 7b 0a 20 20 20 20  nContext ){.    
2c70: 20 20 20 20 6e 61 20 3d 20 6e 62 20 3d 20 6e 43      na = nb = nC
2c80: 6f 6e 74 65 78 74 3b 0a 20 20 20 20 20 20 20 20  ontext;.        
2c90: 73 6b 69 70 20 3d 20 52 5b 72 5d 20 2d 20 6e 43  skip = R[r] - nC
2ca0: 6f 6e 74 65 78 74 3b 0a 20 20 20 20 20 20 7d 65  ontext;.      }e
2cb0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e 61 20  lse{.        na 
2cc0: 3d 20 6e 62 20 3d 20 52 5b 72 5d 3b 0a 20 20 20  = nb = R[r];.   
2cd0: 20 20 20 20 20 73 6b 69 70 20 3d 20 30 3b 0a 20       skip = 0;. 
2ce0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66 6f 72       }.      for
2cf0: 28 69 3d 30 3b 20 69 3c 6e 72 3b 20 69 2b 2b 29  (i=0; i<nr; i++)
2d00: 7b 0a 20 20 20 20 20 20 20 20 6e 61 20 2b 3d 20  {.        na += 
2d10: 52 5b 72 2b 69 2a 33 2b 31 5d 3b 0a 20 20 20 20  R[r+i*3+1];.    
2d20: 20 20 20 20 6e 62 20 2b 3d 20 52 5b 72 2b 69 2a      nb += R[r+i*
2d30: 33 2b 32 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  3+2];.      }.  
2d40: 20 20 20 20 69 66 28 20 52 5b 72 2b 6e 72 2a 33      if( R[r+nr*3
2d50: 5d 3e 6e 43 6f 6e 74 65 78 74 20 29 7b 0a 20 20  ]>nContext ){.  
2d60: 20 20 20 20 20 20 6e 61 20 2b 3d 20 6e 43 6f 6e        na += nCon
2d70: 74 65 78 74 3b 0a 20 20 20 20 20 20 20 20 6e 62  text;.        nb
2d80: 20 2b 3d 20 6e 43 6f 6e 74 65 78 74 3b 0a 20 20   += nContext;.  
2d90: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2da0: 20 20 20 6e 61 20 2b 3d 20 52 5b 72 2b 6e 72 2a     na += R[r+nr*
2db0: 33 5d 3b 0a 20 20 20 20 20 20 20 20 6e 62 20 2b  3];.        nb +
2dc0: 3d 20 52 5b 72 2b 6e 72 2a 33 5d 3b 0a 20 20 20  = R[r+nr*3];.   
2dd0: 20 20 20 7d 0a 20 20 20 20 20 20 66 6f 72 28 69     }.      for(i
2de0: 3d 31 3b 20 69 3c 6e 72 3b 20 69 2b 2b 29 7b 0a  =1; i<nr; i++){.
2df0: 20 20 20 20 20 20 20 20 6e 61 20 2b 3d 20 52 5b          na += R[
2e00: 72 2b 69 2a 33 5d 3b 0a 20 20 20 20 20 20 20 20  r+i*3];.        
2e10: 6e 62 20 2b 3d 20 52 5b 72 2b 69 2a 33 5d 3b 0a  nb += R[r+i*3];.
2e20: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 6c        }.      bl
2e30: 6f 62 5f 61 70 70 65 6e 64 66 28 70 4f 75 74 2c  ob_appendf(pOut,
2e40: 22 40 40 20 2d 25 64 2c 25 64 20 2b 25 64 2c 25  "@@ -%d,%d +%d,%
2e50: 64 20 40 40 5c 6e 22 2c 20 61 2b 73 6b 69 70 2b  d @@\n", a+skip+
2e60: 31 2c 20 6e 61 2c 20 62 2b 73 6b 69 70 2b 31 2c  1, na, b+skip+1,
2e70: 20 6e 62 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20   nb);..      /* 
2e80: 53 68 6f 77 20 74 68 65 20 69 6e 69 74 69 61 6c  Show the initial
2e90: 20 63 6f 6d 6d 6f 6e 20 61 72 65 61 20 2a 2f 0a   common area */.
2ea0: 20 20 20 20 20 20 61 20 2b 3d 20 73 6b 69 70 3b        a += skip;
2eb0: 0a 20 20 20 20 20 20 62 20 2b 3d 20 73 6b 69 70  .      b += skip
2ec0: 3b 0a 20 20 20 20 20 20 6d 20 3d 20 52 5b 72 5d  ;.      m = R[r]
2ed0: 20 2d 20 73 6b 69 70 3b 0a 20 20 20 20 20 20 66   - skip;.      f
2ee0: 6f 72 28 6a 3d 30 3b 20 6a 3c 6d 3b 20 6a 2b 2b  or(j=0; j<m; j++
2ef0: 29 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  ){.        blob_
2f00: 61 70 70 65 6e 64 66 28 70 4f 75 74 2c 22 20 25  appendf(pOut," %
2f10: 2e 2a 73 5c 6e 22 2c 20 41 5b 61 2b 6a 5d 2e 68  .*s\n", A[a+j].h
2f20: 20 26 20 4c 45 4e 47 54 48 5f 4d 41 53 4b 2c 20   & LENGTH_MASK, 
2f30: 41 5b 61 2b 6a 5d 2e 7a 29 3b 0a 20 20 20 20 20  A[a+j].z);.     
2f40: 20 7d 0a 20 20 20 20 20 20 61 20 2b 3d 20 6d 3b   }.      a += m;
2f50: 0a 20 20 20 20 20 20 62 20 2b 3d 20 6d 3b 0a 0a  .      b += m;..
2f60: 20 20 20 20 20 20 2f 2a 20 53 68 6f 77 20 74 68        /* Show th
2f70: 65 20 64 69 66 66 65 72 65 6e 63 65 73 20 2a 2f  e differences */
2f80: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
2f90: 69 3c 6e 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  i<nr; i++){.    
2fa0: 20 20 20 20 6d 20 3d 20 52 5b 72 2b 69 2a 33 2b      m = R[r+i*3+
2fb0: 31 5d 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  1];.        for(
2fc0: 6a 3d 30 3b 20 6a 3c 6d 3b 20 6a 2b 2b 29 7b 0a  j=0; j<m; j++){.
2fd0: 20 20 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 61            blob_a
2fe0: 70 70 65 6e 64 66 28 70 4f 75 74 2c 22 2d 25 2e  ppendf(pOut,"-%.
2ff0: 2a 73 5c 6e 22 2c 20 41 5b 61 2b 6a 5d 2e 68 20  *s\n", A[a+j].h 
3000: 26 20 4c 45 4e 47 54 48 5f 4d 41 53 4b 2c 20 41  & LENGTH_MASK, A
3010: 5b 61 2b 6a 5d 2e 7a 29 3b 0a 20 20 20 20 20 20  [a+j].z);.      
3020: 20 20 7d 0a 20 20 20 20 20 20 20 20 61 20 2b 3d    }.        a +=
3030: 20 6d 3b 0a 20 20 20 20 20 20 20 20 6d 20 3d 20   m;.        m = 
3040: 52 5b 72 2b 69 2a 33 2b 32 5d 3b 0a 20 20 20 20  R[r+i*3+2];.    
3050: 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6d      for(j=0; j<m
3060: 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; j++){.        
3070: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70    blob_appendf(p
3080: 4f 75 74 2c 22 2b 25 2e 2a 73 5c 6e 22 2c 20 42  Out,"+%.*s\n", B
3090: 5b 62 2b 6a 5d 2e 68 20 26 20 4c 45 4e 47 54 48  [b+j].h & LENGTH
30a0: 5f 4d 41 53 4b 2c 20 42 5b 62 2b 6a 5d 2e 7a 29  _MASK, B[b+j].z)
30b0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
30c0: 20 20 20 20 62 20 2b 3d 20 6d 3b 0a 20 20 20 20      b += m;.    
30d0: 20 20 20 20 69 66 28 20 69 3c 6e 72 2d 31 20 29      if( i<nr-1 )
30e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20  {.          m = 
30f0: 52 5b 72 2b 69 2a 33 2b 33 5d 3b 0a 20 20 20 20  R[r+i*3+3];.    
3100: 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a        for(j=0; j
3110: 3c 6d 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20  <m; j++){.      
3120: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
3130: 64 66 28 70 4f 75 74 2c 22 20 25 2e 2a 73 5c 6e  df(pOut," %.*s\n
3140: 22 2c 20 42 5b 62 2b 6a 5d 2e 68 20 26 20 4c 45  ", B[b+j].h & LE
3150: 4e 47 54 48 5f 4d 41 53 4b 2c 20 42 5b 62 2b 6a  NGTH_MASK, B[b+j
3160: 5d 2e 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ].z);.          
3170: 7d 0a 20 20 20 20 20 20 20 20 20 20 62 20 2b 3d  }.          b +=
3180: 20 6d 3b 0a 20 20 20 20 20 20 20 20 20 20 61 20   m;.          a 
3190: 2b 3d 20 6d 3b 0a 20 20 20 20 20 20 20 20 7d 0a  += m;.        }.
31a0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
31b0: 2a 20 53 68 6f 77 20 74 68 65 20 66 69 6e 61 6c  * Show the final
31c0: 20 63 6f 6d 6d 6f 6e 20 61 72 65 61 20 2a 2f 0a   common area */.
31d0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 72        assert( nr
31e0: 3d 3d 69 20 29 3b 0a 20 20 20 20 20 20 6d 20 3d  ==i );.      m =
31f0: 20 52 5b 72 2b 6e 72 2a 33 5d 3b 0a 20 20 20 20   R[r+nr*3];.    
3200: 20 20 69 66 28 20 6d 3e 6e 43 6f 6e 74 65 78 74    if( m>nContext
3210: 20 29 20 6d 20 3d 20 6e 43 6f 6e 74 65 78 74 3b   ) m = nContext;
3220: 0a 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20  .      for(j=0; 
3230: 6a 3c 6d 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  j<m; j++){.     
3240: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28     blob_appendf(
3250: 70 4f 75 74 2c 22 20 25 2e 2a 73 5c 6e 22 2c 20  pOut," %.*s\n", 
3260: 42 5b 62 2b 6a 5d 2e 68 20 26 20 4c 45 4e 47 54  B[b+j].h & LENGT
3270: 48 5f 4d 41 53 4b 2c 20 42 5b 62 2b 6a 5d 2e 7a  H_MASK, B[b+j].z
3280: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
3290: 0a 20 20 20 20 66 72 65 65 28 52 29 3b 0a 20 20  .    free(R);.  
32a0: 20 20 52 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20    R = 0;.  }..  
32b0: 2f 2a 20 57 65 20 6e 6f 20 6c 6f 6e 67 65 72 20  /* We no longer 
32c0: 6e 65 65 64 20 74 68 65 20 41 5b 5d 20 61 6e 64  need the A[] and
32d0: 20 42 5b 5d 20 76 65 63 74 6f 72 73 20 2a 2f 0a   B[] vectors */.
32e0: 20 20 66 72 65 65 28 41 29 3b 0a 20 20 66 72 65    free(A);.  fre
32f0: 65 28 42 29 3b 0a 0a 20 20 2f 2a 20 52 65 74 75  e(B);..  /* Retu
3300: 72 6e 20 74 68 65 20 72 65 73 75 6c 74 20 2a 2f  rn the result */
3310: 0a 20 20 72 65 74 75 72 6e 20 52 3b 0a 7d 0a 0a  .  return R;.}..
3320: 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74  /*.** COMMAND: t
3330: 65 73 74 2d 72 61 77 64 69 66 66 0a 2a 2f 0a 76  est-rawdiff.*/.v
3340: 6f 69 64 20 74 65 73 74 5f 72 61 77 64 69 66 66  oid test_rawdiff
3350: 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20 42 6c  _cmd(void){.  Bl
3360: 6f 62 20 61 2c 20 62 3b 0a 20 20 69 6e 74 20 72  ob a, b;.  int r
3370: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74  ;.  int i;.  int
3380: 20 2a 52 3b 0a 20 20 69 66 28 20 67 2e 61 72 67   *R;.  if( g.arg
3390: 63 3c 34 20 29 20 75 73 61 67 65 28 22 46 49 4c  c<4 ) usage("FIL
33a0: 45 31 20 46 49 4c 45 32 20 2e 2e 2e 22 29 3b 0a  E1 FILE2 ...");.
33b0: 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d    blob_read_from
33c0: 5f 66 69 6c 65 28 26 61 2c 20 67 2e 61 72 67 76  _file(&a, g.argv
33d0: 5b 32 5d 29 3b 0a 20 20 66 6f 72 28 69 3d 33 3b  [2]);.  for(i=3;
33e0: 20 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b   i<g.argc; i++){
33f0: 0a 20 20 20 20 69 66 28 20 69 3e 33 20 29 20 70  .    if( i>3 ) p
3400: 72 69 6e 74 66 28 22 2d 2d 2d 2d 2d 2d 2d 2d 2d  rintf("---------
3410: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3420: 2d 2d 2d 2d 2d 2d 5c 6e 22 29 3b 0a 20 20 20 20  ------\n");.    
3430: 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66  blob_read_from_f
3440: 69 6c 65 28 26 62 2c 20 67 2e 61 72 67 76 5b 69  ile(&b, g.argv[i
3450: 5d 29 3b 0a 20 20 20 20 52 20 3d 20 74 65 78 74  ]);.    R = text
3460: 5f 64 69 66 66 28 26 61 2c 20 26 62 2c 20 30 2c  _diff(&a, &b, 0,
3470: 20 30 29 3b 0a 20 20 20 20 66 6f 72 28 72 3d 30   0);.    for(r=0
3480: 3b 20 52 5b 72 5d 20 7c 7c 20 52 5b 72 2b 31 5d  ; R[r] || R[r+1]
3490: 20 7c 7c 20 52 5b 72 2b 32 5d 3b 20 72 20 2b 3d   || R[r+2]; r +=
34a0: 20 33 29 7b 0a 20 20 20 20 20 20 70 72 69 6e 74   3){.      print
34b0: 66 28 22 20 63 6f 70 79 20 25 34 64 20 20 64 65  f(" copy %4d  de
34c0: 6c 65 74 65 20 25 34 64 20 20 69 6e 73 65 72 74  lete %4d  insert
34d0: 20 25 34 64 5c 6e 22 2c 20 52 5b 72 5d 2c 20 52   %4d\n", R[r], R
34e0: 5b 72 2b 31 5d 2c 20 52 5b 72 2b 32 5d 29 3b 0a  [r+1], R[r+2]);.
34f0: 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 66 72 65      }.    /* fre
3500: 65 28 52 29 3b 20 2a 2f 0a 20 20 20 20 62 6c 6f  e(R); */.    blo
3510: 62 5f 72 65 73 65 74 28 26 62 29 3b 0a 20 20 7d  b_reset(&b);.  }
3520: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e  .}../*.** COMMAN
3530: 44 3a 20 74 65 73 74 2d 75 64 69 66 66 0a 2a 2f  D: test-udiff.*/
3540: 0a 76 6f 69 64 20 74 65 73 74 5f 75 64 69 66 66  .void test_udiff
3550: 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20 42 6c  _cmd(void){.  Bl
3560: 6f 62 20 61 2c 20 62 2c 20 6f 75 74 3b 0a 20 20  ob a, b, out;.  
3570: 69 66 28 20 67 2e 61 72 67 63 21 3d 34 20 29 20  if( g.argc!=4 ) 
3580: 75 73 61 67 65 28 22 46 49 4c 45 31 20 46 49 4c  usage("FILE1 FIL
3590: 45 32 22 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 61  E2");.  blob_rea
35a0: 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 61 2c 20  d_from_file(&a, 
35b0: 67 2e 61 72 67 76 5b 32 5d 29 3b 0a 20 20 62 6c  g.argv[2]);.  bl
35c0: 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c  ob_read_from_fil
35d0: 65 28 26 62 2c 20 67 2e 61 72 67 76 5b 33 5d 29  e(&b, g.argv[3])
35e0: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 6f  ;.  blob_zero(&o
35f0: 75 74 29 3b 0a 20 20 74 65 78 74 5f 64 69 66 66  ut);.  text_diff
3600: 28 26 61 2c 20 26 62 2c 20 26 6f 75 74 2c 20 33  (&a, &b, &out, 3
3610: 29 3b 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f  );.  blob_write_
3620: 74 6f 5f 66 69 6c 65 28 26 6f 75 74 2c 20 22 2d  to_file(&out, "-
3630: 22 29 3b 0a 7d 0a                                ");.}.