Hex Artifact Content
Not logged in

Artifact 423e7bd7db1078eb33c89566182e93d6b589e342:

File src/diff.c part of check-in [7a2c37063a] - merge trunk into creole branch by bob on 2009-09-22 07:49:39. Also file src/diff.c part of check-in [713b8be852] - Deleted some obsolete "todo" files. Updated the FAQ. Modified the the "vinfo" page to show check-in differences and made "vinfo" the default display for check-ins instead of "vdiff". by drh on 2009-08-28 22:59:27.

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 2e 68 22 0a 23 69 6e 63  de "diff.h".#inc
03e0: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
03f0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 78 69 6d 75 6d 20  ../*.** Maximum 
0400: 6c 65 6e 67 74 68 20 6f 66 20 61 20 6c 69 6e 65  length of a line
0410: 20 69 6e 20 61 20 74 65 78 74 20 66 69 6c 65 2e   in a text file.
0420: 20 20 28 38 31 39 32 29 0a 2a 2f 0a 23 64 65 66    (8192).*/.#def
0430: 69 6e 65 20 4c 45 4e 47 54 48 5f 4d 41 53 4b 5f  ine LENGTH_MASK_
0440: 53 5a 20 20 31 33 0a 23 64 65 66 69 6e 65 20 4c  SZ  13.#define L
0450: 45 4e 47 54 48 5f 4d 41 53 4b 20 20 20 20 20 28  ENGTH_MASK     (
0460: 28 31 3c 3c 4c 45 4e 47 54 48 5f 4d 41 53 4b 5f  (1<<LENGTH_MASK_
0470: 53 5a 29 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20 49 6e  SZ)-1)../*.** In
0480: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
0490: 65 61 63 68 20 6c 69 6e 65 20 6f 66 20 61 20 66  each line of a f
04a0: 69 6c 65 20 62 65 69 6e 67 20 64 69 66 66 65 64  ile being diffed
04b0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 6f 77 65  ..**.** The lowe
04c0: 72 20 4c 45 4e 47 54 48 5f 4d 41 53 4b 5f 53 5a  r LENGTH_MASK_SZ
04d0: 20 62 69 74 73 20 6f 66 20 74 68 65 20 68 61 73   bits of the has
04e0: 68 20 28 44 4c 69 6e 65 2e 68 29 20 61 72 65 20  h (DLine.h) are 
04f0: 74 68 65 20 6c 65 6e 67 74 68 0a 2a 2a 20 6f 66  the length.** of
0500: 20 74 68 65 20 6c 69 6e 65 2e 20 20 49 66 20 61   the line.  If a
0510: 6e 79 20 6c 69 6e 65 20 69 73 20 6c 6f 6e 67 65  ny line is longe
0520: 72 20 74 68 61 6e 20 4c 45 4e 47 54 48 5f 4d 41  r than LENGTH_MA
0530: 53 4b 20 63 68 61 72 61 63 74 65 72 73 2c 0a 2a  SK characters,.*
0540: 2a 20 74 68 65 20 66 69 6c 65 20 69 73 20 63 6f  * the file is co
0550: 6e 73 69 64 65 72 65 64 20 62 69 6e 61 72 79 2e  nsidered binary.
0560: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
0570: 63 74 20 44 4c 69 6e 65 20 44 4c 69 6e 65 3b 0a  ct DLine DLine;.
0580: 73 74 72 75 63 74 20 44 4c 69 6e 65 20 7b 0a 20  struct DLine {. 
0590: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b 20   const char *z; 
05a0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74 65         /* The te
05b0: 78 74 20 6f 66 20 74 68 65 20 6c 69 6e 65 20 2a  xt of the line *
05c0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
05d0: 20 68 3b 20 20 20 20 20 20 20 2f 2a 20 48 61 73   h;       /* Has
05e0: 68 20 6f 66 20 74 68 65 20 6c 69 6e 65 20 2a 2f  h of the line */
05f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
0600: 69 4e 65 78 74 3b 20 20 20 2f 2a 20 31 2b 28 49  iNext;   /* 1+(I
0610: 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 6c 69 6e  ndex of next lin
0620: 65 20 77 69 74 68 20 73 61 6d 65 20 74 68 65 20  e with same the 
0630: 73 61 6d 65 20 68 61 73 68 29 20 2a 2f 0a 0a 20  same hash) */.. 
0640: 20 2f 2a 20 61 6e 20 61 72 72 61 79 20 6f 66 20   /* an array of 
0650: 44 4c 69 6e 65 20 65 6c 65 6d 65 6e 74 73 20 73  DLine elements s
0660: 65 72 76 69 63 65 73 20 74 77 6f 20 70 75 72 70  ervices two purp
0670: 6f 73 65 73 2e 20 20 54 68 65 20 66 69 65 6c 64  oses.  The field
0680: 73 0a 20 20 2a 2a 20 61 62 6f 76 65 20 61 72 65  s.  ** above are
0690: 20 6f 6e 65 20 70 65 72 20 6c 69 6e 65 20 6f 66   one per line of
06a0: 20 69 6e 70 75 74 20 74 65 78 74 2e 20 20 42 75   input text.  Bu
06b0: 74 20 65 61 63 68 20 65 6e 74 72 79 20 69 73 20  t each entry is 
06c0: 61 6c 73 6f 0a 20 20 2a 2a 20 61 20 62 75 63 6b  also.  ** a buck
06d0: 65 74 20 69 6e 20 61 20 68 61 73 68 20 74 61 62  et in a hash tab
06e0: 6c 65 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 20  le, as follows: 
06f0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0700: 74 20 69 48 61 73 68 3b 20 20 20 2f 2a 20 31 2b  t iHash;   /* 1+
0710: 28 66 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20  (first entry in 
0720: 74 68 65 20 68 61 73 68 20 63 68 61 69 6e 29 20  the hash chain) 
0730: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 63  */.};../*.** A c
0740: 6f 6e 74 65 78 74 20 66 6f 72 20 72 75 6e 6e 69  ontext for runni
0750: 6e 67 20 61 20 64 69 66 66 2e 0a 2a 2f 0a 74 79  ng a diff..*/.ty
0760: 70 65 64 65 66 20 73 74 72 75 63 74 20 44 43 6f  pedef struct DCo
0770: 6e 74 65 78 74 20 44 43 6f 6e 74 65 78 74 3b 0a  ntext DContext;.
0780: 73 74 72 75 63 74 20 44 43 6f 6e 74 65 78 74 20  struct DContext 
0790: 7b 0a 20 20 69 6e 74 20 2a 61 45 64 69 74 3b 20  {.  int *aEdit; 
07a0: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
07b0: 6f 66 20 63 6f 70 79 2f 64 65 6c 65 74 65 2f 69  of copy/delete/i
07c0: 6e 73 65 72 74 20 74 72 69 70 6c 65 73 20 2a 2f  nsert triples */
07d0: 0a 20 20 69 6e 74 20 6e 45 64 69 74 3b 20 20 20  .  int nEdit;   
07e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
07f0: 6f 66 20 69 6e 74 65 67 65 72 73 20 28 33 78 20  of integers (3x 
0800: 6e 75 6d 20 6f 66 20 74 72 69 70 6c 65 73 29 20  num of triples) 
0810: 69 6e 20 61 45 64 69 74 5b 5d 20 2a 2f 0a 20 20  in aEdit[] */.  
0820: 69 6e 74 20 6e 45 64 69 74 41 6c 6c 6f 63 3b 20  int nEditAlloc; 
0830: 20 20 20 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f     /* Space allo
0840: 63 61 74 65 64 20 66 6f 72 20 61 45 64 69 74 5b  cated for aEdit[
0850: 5d 20 2a 2f 0a 20 20 44 4c 69 6e 65 20 2a 61 46  ] */.  DLine *aF
0860: 72 6f 6d 3b 20 20 20 20 20 20 2f 2a 20 46 69 6c  rom;      /* Fil
0870: 65 20 6f 6e 20 6c 65 66 74 20 73 69 64 65 20 6f  e on left side o
0880: 66 20 74 68 65 20 64 69 66 66 20 2a 2f 0a 20 20  f the diff */.  
0890: 69 6e 74 20 6e 46 72 6f 6d 3b 20 20 20 20 20 20  int nFrom;      
08a0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
08b0: 6c 69 6e 65 73 20 69 6e 20 61 46 72 6f 6d 5b 5d  lines in aFrom[]
08c0: 20 2a 2f 0a 20 20 44 4c 69 6e 65 20 2a 61 54 6f   */.  DLine *aTo
08d0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65  ;        /* File
08e0: 20 6f 6e 20 72 69 67 68 74 20 73 69 64 65 20 6f   on right side o
08f0: 66 20 74 68 65 20 64 69 66 66 20 2a 2f 0a 20 20  f the diff */.  
0900: 69 6e 74 20 6e 54 6f 3b 20 20 20 20 20 20 20 20  int nTo;        
0910: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0920: 6c 69 6e 65 73 20 69 6e 20 61 54 6f 5b 5d 20 2a  lines in aTo[] *
0930: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  /.};../*.** Retu
0940: 72 6e 20 61 6e 20 61 72 72 61 79 20 6f 66 20 44  rn an array of D
0950: 4c 69 6e 65 20 6f 62 6a 65 63 74 73 20 63 6f 6e  Line objects con
0960: 74 61 69 6e 69 6e 67 20 61 20 70 6f 69 6e 74 65  taining a pointe
0970: 72 20 74 6f 20 74 68 65 0a 2a 2a 20 73 74 61 72  r to the.** star
0980: 74 20 6f 66 20 65 61 63 68 20 6c 69 6e 65 20 61  t of each line a
0990: 6e 64 20 61 20 68 61 73 68 20 6f 66 20 74 68 61  nd a hash of tha
09a0: 74 20 6c 69 6e 65 2e 20 20 54 68 65 20 6c 6f 77  t line.  The low
09b0: 65 72 20 0a 2a 2a 20 62 69 74 73 20 6f 66 20 74  er .** bits of t
09c0: 68 65 20 68 61 73 68 20 73 74 6f 72 65 20 74 68  he hash store th
09d0: 65 20 6c 65 6e 67 74 68 20 6f 66 20 65 61 63 68  e length of each
09e0: 20 6c 69 6e 65 2e 0a 2a 2a 0a 2a 2a 20 54 72 61   line..**.** Tra
09f0: 69 6c 69 6e 67 20 77 68 69 74 65 73 70 61 63 65  iling whitespace
0a00: 20 69 73 20 72 65 6d 6f 76 65 64 20 66 72 6f 6d   is removed from
0a10: 20 65 61 63 68 20 6c 69 6e 65 2e 0a 2a 2a 0a 2a   each line..**.*
0a20: 2a 20 52 65 74 75 72 6e 20 30 20 69 66 20 74 68  * Return 0 if th
0a30: 65 20 66 69 6c 65 20 69 73 20 62 69 6e 61 72 79  e file is binary
0a40: 20 6f 72 20 63 6f 6e 74 61 69 6e 73 20 61 20 6c   or contains a l
0a50: 69 6e 65 20 74 68 61 74 20 69 73 0a 2a 2a 20 74  ine that is.** t
0a60: 6f 6f 20 6c 6f 6e 67 2e 0a 2a 2f 0a 73 74 61 74  oo long..*/.stat
0a70: 69 63 20 44 4c 69 6e 65 20 2a 62 72 65 61 6b 5f  ic DLine *break_
0a80: 69 6e 74 6f 5f 6c 69 6e 65 73 28 63 6f 6e 73 74  into_lines(const
0a90: 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6e 2c   char *z, int n,
0aa0: 20 69 6e 74 20 2a 70 6e 4c 69 6e 65 29 7b 0a 20   int *pnLine){. 
0ab0: 20 69 6e 74 20 6e 4c 69 6e 65 2c 20 69 2c 20 6a   int nLine, i, j
0ac0: 2c 20 6b 2c 20 78 3b 0a 20 20 75 6e 73 69 67 6e  , k, x;.  unsign
0ad0: 65 64 20 69 6e 74 20 68 2c 20 68 32 3b 0a 20 20  ed int h, h2;.  
0ae0: 44 4c 69 6e 65 20 2a 61 3b 0a 0a 20 20 2f 2a 20  DLine *a;..  /* 
0af0: 43 6f 75 6e 74 20 74 68 65 20 6e 75 6d 62 65 72  Count the number
0b00: 20 6f 66 20 6c 69 6e 65 73 2e 20 20 41 6c 6c 6f   of lines.  Allo
0b10: 63 61 74 65 20 73 70 61 63 65 20 74 6f 20 68 6f  cate space to ho
0b20: 6c 64 0a 20 20 2a 2a 20 74 68 65 20 72 65 74 75  ld.  ** the retu
0b30: 72 6e 65 64 20 61 72 72 61 79 2e 0a 20 20 2a 2f  rned array..  */
0b40: 0a 20 20 66 6f 72 28 69 3d 6a 3d 30 2c 20 6e 4c  .  for(i=j=0, nL
0b50: 69 6e 65 3d 31 3b 20 69 3c 6e 3b 20 69 2b 2b 2c  ine=1; i<n; i++,
0b60: 20 6a 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 63   j++){.    int c
0b70: 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20 69 66 28   = z[i];.    if(
0b80: 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72   c==0 ){.      r
0b90: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20  eturn 0;.    }. 
0ba0: 20 20 20 69 66 28 20 63 3d 3d 27 5c 6e 27 20 26     if( c=='\n' &
0bb0: 26 20 7a 5b 69 2b 31 5d 21 3d 30 20 29 7b 0a 20  & z[i+1]!=0 ){. 
0bc0: 20 20 20 20 20 6e 4c 69 6e 65 2b 2b 3b 0a 20 20       nLine++;.  
0bd0: 20 20 20 20 69 66 28 20 6a 3e 4c 45 4e 47 54 48      if( j>LENGTH
0be0: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 20 20 20  _MASK ){.       
0bf0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20   return 0;.     
0c00: 20 7d 0a 20 20 20 20 20 20 6a 20 3d 20 30 3b 0a   }.      j = 0;.
0c10: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
0c20: 6a 3e 4c 45 4e 47 54 48 5f 4d 41 53 4b 20 29 7b  j>LENGTH_MASK ){
0c30: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
0c40: 20 7d 0a 20 20 61 20 3d 20 6d 61 6c 6c 6f 63 28   }.  a = malloc(
0c50: 20 6e 4c 69 6e 65 2a 73 69 7a 65 6f 66 28 61 5b   nLine*sizeof(a[
0c60: 30 5d 29 20 29 3b 0a 20 20 69 66 28 20 61 3d 3d  0]) );.  if( a==
0c70: 30 20 29 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63  0 ) fossil_panic
0c80: 28 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22  ("out of memory"
0c90: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20 30  );.  memset(a, 0
0ca0: 2c 20 6e 4c 69 6e 65 2a 73 69 7a 65 6f 66 28 61  , nLine*sizeof(a
0cb0: 5b 30 5d 29 20 29 3b 0a 0a 20 20 2f 2a 20 46 69  [0]) );..  /* Fi
0cc0: 6c 6c 20 69 6e 20 74 68 65 20 61 72 72 61 79 20  ll in the array 
0cd0: 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  */.  for(i=0; i<
0ce0: 6e 4c 69 6e 65 3b 20 69 2b 2b 29 7b 0a 20 20 20  nLine; i++){.   
0cf0: 20 61 5b 69 5d 2e 7a 20 3d 20 7a 3b 0a 20 20 20   a[i].z = z;.   
0d00: 20 66 6f 72 28 6a 3d 30 3b 20 7a 5b 6a 5d 20 26   for(j=0; z[j] &
0d10: 26 20 7a 5b 6a 5d 21 3d 27 5c 6e 27 3b 20 6a 2b  & z[j]!='\n'; j+
0d20: 2b 29 7b 7d 0a 20 20 20 20 66 6f 72 28 6b 3d 6a  +){}.    for(k=j
0d30: 3b 20 6b 3e 30 20 26 26 20 69 73 73 70 61 63 65  ; k>0 && isspace
0d40: 28 7a 5b 6b 2d 31 5d 29 3b 20 6b 2d 2d 29 7b 7d  (z[k-1]); k--){}
0d50: 0a 20 20 20 20 66 6f 72 28 68 3d 30 2c 20 78 3d  .    for(h=0, x=
0d60: 30 3b 20 78 3c 6b 3b 20 78 2b 2b 29 7b 0a 20 20  0; x<k; x++){.  
0d70: 20 20 20 20 68 20 3d 20 68 20 5e 20 28 68 3c 3c      h = h ^ (h<<
0d80: 32 29 20 5e 20 7a 5b 78 5d 3b 0a 20 20 20 20 7d  2) ^ z[x];.    }
0d90: 0a 20 20 20 20 61 5b 69 5d 2e 68 20 3d 20 68 20  .    a[i].h = h 
0da0: 3d 20 28 68 3c 3c 4c 45 4e 47 54 48 5f 4d 41 53  = (h<<LENGTH_MAS
0db0: 4b 5f 53 5a 29 20 7c 20 6b 3b 3b 0a 20 20 20 20  K_SZ) | k;;.    
0dc0: 68 32 20 3d 20 68 20 25 20 6e 4c 69 6e 65 3b 0a  h2 = h % nLine;.
0dd0: 20 20 20 20 61 5b 69 5d 2e 69 4e 65 78 74 20 3d      a[i].iNext =
0de0: 20 61 5b 68 32 5d 2e 69 48 61 73 68 3b 0a 20 20   a[h2].iHash;.  
0df0: 20 20 61 5b 68 32 5d 2e 69 48 61 73 68 20 3d 20    a[h2].iHash = 
0e00: 69 2b 31 3b 0a 20 20 20 20 7a 20 2b 3d 20 6a 2b  i+1;.    z += j+
0e10: 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 74  1;.  }..  /* Ret
0e20: 75 72 6e 20 72 65 73 75 6c 74 73 20 2a 2f 0a 20  urn results */. 
0e30: 20 2a 70 6e 4c 69 6e 65 20 3d 20 6e 4c 69 6e 65   *pnLine = nLine
0e40: 3b 0a 20 20 72 65 74 75 72 6e 20 61 3b 0a 7d 0a  ;.  return a;.}.
0e50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  ./*.** Return tr
0e60: 75 65 20 69 66 20 74 77 6f 20 44 4c 69 6e 65 20  ue if two DLine 
0e70: 65 6c 65 6d 65 6e 74 73 20 61 72 65 20 69 64 65  elements are ide
0e80: 6e 74 69 63 61 6c 2e 0a 2a 2f 0a 73 74 61 74 69  ntical..*/.stati
0e90: 63 20 69 6e 74 20 73 61 6d 65 5f 64 6c 69 6e 65  c int same_dline
0ea0: 28 44 4c 69 6e 65 20 2a 70 41 2c 20 44 4c 69 6e  (DLine *pA, DLin
0eb0: 65 20 2a 70 42 29 7b 0a 20 20 72 65 74 75 72 6e  e *pB){.  return
0ec0: 20 70 41 2d 3e 68 3d 3d 70 42 2d 3e 68 20 26 26   pA->h==pB->h &&
0ed0: 20 6d 65 6d 63 6d 70 28 70 41 2d 3e 7a 2c 70 42   memcmp(pA->z,pB
0ee0: 2d 3e 7a 2c 70 41 2d 3e 68 20 26 20 4c 45 4e 47  ->z,pA->h & LENG
0ef0: 54 48 5f 4d 41 53 4b 29 3d 3d 30 3b 0a 7d 0a 0a  TH_MASK)==0;.}..
0f00: 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 61 20 73  /*.** Append a s
0f10: 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 22 64  ingle line of "d
0f20: 69 66 66 22 20 6f 75 74 70 75 74 20 74 6f 20 70  iff" output to p
0f30: 4f 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  Out..*/.static v
0f40: 6f 69 64 20 61 70 70 65 6e 64 44 69 66 66 4c 69  oid appendDiffLi
0f50: 6e 65 28 42 6c 6f 62 20 2a 70 4f 75 74 2c 20 63  ne(Blob *pOut, c
0f60: 68 61 72 20 2a 7a 50 72 65 66 69 78 2c 20 44 4c  har *zPrefix, DL
0f70: 69 6e 65 20 2a 70 4c 69 6e 65 29 7b 0a 20 20 62  ine *pLine){.  b
0f80: 6c 6f 62 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c  lob_append(pOut,
0f90: 20 7a 50 72 65 66 69 78 2c 20 31 29 3b 0a 20 20   zPrefix, 1);.  
0fa0: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 4f 75 74  blob_append(pOut
0fb0: 2c 20 70 4c 69 6e 65 2d 3e 7a 2c 20 70 4c 69 6e  , pLine->z, pLin
0fc0: 65 2d 3e 68 20 26 20 4c 45 4e 47 54 48 5f 4d 41  e->h & LENGTH_MA
0fd0: 53 4b 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65  SK);.  blob_appe
0fe0: 6e 64 28 70 4f 75 74 2c 20 22 5c 6e 22 2c 20 31  nd(pOut, "\n", 1
0ff0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 78 70 61  );.}../*.** Expa
1000: 6e 64 20 74 68 65 20 73 69 7a 65 20 6f 66 20 61  nd the size of a
1010: 45 64 69 74 5b 5d 20 61 72 72 61 79 20 74 6f 20  Edit[] array to 
1020: 68 6f 6c 64 20 6e 45 64 69 74 20 65 6c 65 6d 65  hold nEdit eleme
1030: 6e 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  nts..*/.static v
1040: 6f 69 64 20 65 78 70 61 6e 64 45 64 69 74 28 44  oid expandEdit(D
1050: 43 6f 6e 74 65 78 74 20 2a 70 2c 20 69 6e 74 20  Context *p, int 
1060: 6e 45 64 69 74 29 7b 0a 20 20 69 6e 74 20 2a 61  nEdit){.  int *a
1070: 3b 0a 20 20 61 20 3d 20 72 65 61 6c 6c 6f 63 28  ;.  a = realloc(
1080: 70 2d 3e 61 45 64 69 74 2c 20 6e 45 64 69 74 2a  p->aEdit, nEdit*
1090: 73 69 7a 65 6f 66 28 69 6e 74 29 29 3b 0a 20 20  sizeof(int));.  
10a0: 69 66 28 20 61 3d 3d 30 20 29 7b 0a 20 20 20 20  if( a==0 ){.    
10b0: 66 72 65 65 28 20 70 2d 3e 61 45 64 69 74 20 29  free( p->aEdit )
10c0: 3b 0a 20 20 20 20 70 2d 3e 6e 45 64 69 74 20 3d  ;.    p->nEdit =
10d0: 20 30 3b 0a 20 20 20 20 6e 45 64 69 74 20 3d 20   0;.    nEdit = 
10e0: 30 3b 0a 20 20 7d 0a 20 20 70 2d 3e 61 45 64 69  0;.  }.  p->aEdi
10f0: 74 20 3d 20 61 3b 0a 20 20 70 2d 3e 6e 45 64 69  t = a;.  p->nEdi
1100: 74 41 6c 6c 6f 63 20 3d 20 6e 45 64 69 74 3b 0a  tAlloc = nEdit;.
1110: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20  }../*.** Append 
1120: 61 20 6e 65 77 20 43 4f 50 59 2f 44 45 4c 45 54  a new COPY/DELET
1130: 45 2f 49 4e 53 45 52 54 20 74 72 69 70 6c 65 2e  E/INSERT triple.
1140: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1150: 61 70 70 65 6e 64 54 72 69 70 6c 65 28 44 43 6f  appendTriple(DCo
1160: 6e 74 65 78 74 20 2a 70 2c 20 69 6e 74 20 6e 43  ntext *p, int nC
1170: 6f 70 79 2c 20 69 6e 74 20 6e 44 65 6c 2c 20 69  opy, int nDel, i
1180: 6e 74 20 6e 49 6e 73 29 7b 0a 20 20 2f 2a 20 70  nt nIns){.  /* p
1190: 72 69 6e 74 66 28 22 41 50 50 45 4e 44 20 25 64  rintf("APPEND %d
11a0: 2f 25 64 2f 25 64 5c 6e 22 2c 20 6e 43 6f 70 79  /%d/%d\n", nCopy
11b0: 2c 20 6e 44 65 6c 2c 20 6e 49 6e 73 29 3b 20 2a  , nDel, nIns); *
11c0: 2f 0a 20 20 69 66 28 20 70 2d 3e 6e 45 64 69 74  /.  if( p->nEdit
11d0: 3e 3d 33 20 29 7b 0a 20 20 20 20 69 66 28 20 70  >=3 ){.    if( p
11e0: 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74  ->aEdit[p->nEdit
11f0: 2d 31 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  -1]==0 ){.      
1200: 69 66 28 20 70 2d 3e 61 45 64 69 74 5b 70 2d 3e  if( p->aEdit[p->
1210: 6e 45 64 69 74 2d 32 5d 3d 3d 30 20 29 7b 0a 20  nEdit-2]==0 ){. 
1220: 20 20 20 20 20 20 20 70 2d 3e 61 45 64 69 74 5b         p->aEdit[
1230: 70 2d 3e 6e 45 64 69 74 2d 33 5d 20 2b 3d 20 6e  p->nEdit-3] += n
1240: 43 6f 70 79 3b 0a 20 20 20 20 20 20 20 20 70 2d  Copy;.        p-
1250: 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74 2d  >aEdit[p->nEdit-
1260: 32 5d 20 2b 3d 20 6e 44 65 6c 3b 0a 20 20 20 20  2] += nDel;.    
1270: 20 20 20 20 70 2d 3e 61 45 64 69 74 5b 70 2d 3e      p->aEdit[p->
1280: 6e 45 64 69 74 2d 31 5d 20 2b 3d 20 6e 49 6e 73  nEdit-1] += nIns
1290: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
12a0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
12b0: 69 66 28 20 6e 43 6f 70 79 3d 3d 30 20 29 7b 0a  if( nCopy==0 ){.
12c0: 20 20 20 20 20 20 20 20 70 2d 3e 61 45 64 69 74          p->aEdit
12d0: 5b 70 2d 3e 6e 45 64 69 74 2d 32 5d 20 2b 3d 20  [p->nEdit-2] += 
12e0: 6e 44 65 6c 3b 0a 20 20 20 20 20 20 20 20 70 2d  nDel;.        p-
12f0: 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74 2d  >aEdit[p->nEdit-
1300: 31 5d 20 2b 3d 20 6e 49 6e 73 3b 0a 20 20 20 20  1] += nIns;.    
1310: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20      return;.    
1320: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
1330: 28 20 6e 43 6f 70 79 3d 3d 30 20 26 26 20 6e 44  ( nCopy==0 && nD
1340: 65 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70  el==0 ){.      p
1350: 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74  ->aEdit[p->nEdit
1360: 2d 31 5d 20 2b 3d 20 6e 49 6e 73 3b 0a 20 20 20  -1] += nIns;.   
1370: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d     return;.    }
1380: 0a 20 20 7d 20 20 0a 20 20 69 66 28 20 70 2d 3e  .  }  .  if( p->
1390: 6e 45 64 69 74 2b 33 3e 70 2d 3e 6e 45 64 69 74  nEdit+3>p->nEdit
13a0: 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 65 78 70  Alloc ){.    exp
13b0: 61 6e 64 45 64 69 74 28 70 2c 20 70 2d 3e 6e 45  andEdit(p, p->nE
13c0: 64 69 74 2a 32 20 2b 20 31 35 29 3b 0a 20 20 20  dit*2 + 15);.   
13d0: 20 69 66 28 20 70 2d 3e 61 45 64 69 74 3d 3d 30   if( p->aEdit==0
13e0: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20   ) return;.  }. 
13f0: 20 70 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64   p->aEdit[p->nEd
1400: 69 74 2b 2b 5d 20 3d 20 6e 43 6f 70 79 3b 0a 20  it++] = nCopy;. 
1410: 20 70 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64   p->aEdit[p->nEd
1420: 69 74 2b 2b 5d 20 3d 20 6e 44 65 6c 3b 0a 20 20  it++] = nDel;.  
1430: 70 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69  p->aEdit[p->nEdi
1440: 74 2b 2b 5d 20 3d 20 6e 49 6e 73 3b 0a 7d 0a 0a  t++] = nIns;.}..
1450: 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e 20 61 20 64  ./*.** Given a d
1460: 69 66 66 20 63 6f 6e 74 65 78 74 20 69 6e 20 77  iff context in w
1470: 68 69 63 68 20 74 68 65 20 61 45 64 69 74 5b 5d  hich the aEdit[]
1480: 20 61 72 72 61 79 20 68 61 73 20 62 65 65 6e 20   array has been 
1490: 66 69 6c 6c 65 64 0a 2a 2a 20 69 6e 2c 20 63 6f  filled.** in, co
14a0: 6d 70 75 74 65 20 61 20 63 6f 6e 74 65 78 74 20  mpute a context 
14b0: 64 69 66 66 20 69 6e 74 6f 20 70 4f 75 74 2e 0a  diff into pOut..
14c0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63  */.static void c
14d0: 6f 6e 74 65 78 74 44 69 66 66 28 44 43 6f 6e 74  ontextDiff(DCont
14e0: 65 78 74 20 2a 70 2c 20 42 6c 6f 62 20 2a 70 4f  ext *p, Blob *pO
14f0: 75 74 2c 20 69 6e 74 20 6e 43 6f 6e 74 65 78 74  ut, int nContext
1500: 29 7b 0a 20 20 44 4c 69 6e 65 20 2a 41 3b 20 20  ){.  DLine *A;  
1510: 20 20 20 2f 2a 20 4c 65 66 74 20 73 69 64 65 20     /* Left side 
1520: 6f 66 20 74 68 65 20 64 69 66 66 20 2a 2f 0a 20  of the diff */. 
1530: 20 44 4c 69 6e 65 20 2a 42 3b 20 20 20 20 20 2f   DLine *B;     /
1540: 2a 20 52 69 67 68 74 20 73 69 64 65 20 6f 66 20  * Right side of 
1550: 74 68 65 20 64 69 66 66 20 2a 2f 20 20 0a 20 20  the diff */  .  
1560: 69 6e 74 20 61 20 3d 20 30 3b 20 20 20 20 2f 2a  int a = 0;    /*
1570: 20 49 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 6c   Index of next l
1580: 69 6e 65 20 69 6e 20 41 5b 5d 20 2a 2f 0a 20 20  ine in A[] */.  
1590: 69 6e 74 20 62 20 3d 20 30 3b 20 20 20 20 2f 2a  int b = 0;    /*
15a0: 20 49 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 6c   Index of next l
15b0: 69 6e 65 20 69 6e 20 42 5b 5d 20 2a 2f 0a 20 20  ine in B[] */.  
15c0: 69 6e 74 20 2a 52 3b 20 20 20 20 20 20 20 2f 2a  int *R;       /*
15d0: 20 41 72 72 61 79 20 6f 66 20 43 4f 50 59 2f 44   Array of COPY/D
15e0: 45 4c 45 54 45 2f 49 4e 53 45 52 54 20 74 72 69  ELETE/INSERT tri
15f0: 70 6c 65 73 20 2a 2f 0a 20 20 69 6e 74 20 72 3b  ples */.  int r;
1600: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
1610: 20 69 6e 74 6f 20 52 5b 5d 20 2a 2f 0a 20 20 69   into R[] */.  i
1620: 6e 74 20 6e 72 3b 20 20 20 20 20 20 20 2f 2a 20  nt nr;       /* 
1630: 4e 75 6d 62 65 72 20 6f 66 20 43 4f 50 59 2f 44  Number of COPY/D
1640: 45 4c 45 54 45 2f 49 4e 53 45 52 54 20 74 72 69  ELETE/INSERT tri
1650: 70 6c 65 73 20 74 6f 20 70 72 6f 63 65 73 73 20  ples to process 
1660: 2a 2f 0a 20 20 69 6e 74 20 6d 78 72 3b 20 20 20  */.  int mxr;   
1670: 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 76 61     /* Maximum va
1680: 6c 75 65 20 66 6f 72 20 72 20 2a 2f 0a 20 20 69  lue for r */.  i
1690: 6e 74 20 6e 61 2c 20 6e 62 3b 20 20 20 2f 2a 20  nt na, nb;   /* 
16a0: 4e 75 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20  Number of lines 
16b0: 73 68 6f 77 6e 20 66 72 6f 6d 20 41 20 61 6e 64  shown from A and
16c0: 20 42 20 2a 2f 0a 20 20 69 6e 74 20 69 2c 20 6a   B */.  int i, j
16d0: 3b 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f  ;     /* Loop co
16e0: 75 6e 74 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20  unters */.  int 
16f0: 6d 3b 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d  m;        /* Num
1700: 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 74 6f 20  ber of lines to 
1710: 6f 75 74 70 75 74 20 2a 2f 0a 20 20 69 6e 74 20  output */.  int 
1720: 73 6b 69 70 3b 20 20 20 20 20 2f 2a 20 4e 75 6d  skip;     /* Num
1730: 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 74 6f 20  ber of lines to 
1740: 73 6b 69 70 20 2a 2f 0a 0a 20 20 41 20 3d 20 70  skip */..  A = p
1750: 2d 3e 61 46 72 6f 6d 3b 0a 20 20 42 20 3d 20 70  ->aFrom;.  B = p
1760: 2d 3e 61 54 6f 3b 0a 20 20 52 20 3d 20 70 2d 3e  ->aTo;.  R = p->
1770: 61 45 64 69 74 3b 0a 20 20 6d 78 72 20 3d 20 70  aEdit;.  mxr = p
1780: 2d 3e 6e 45 64 69 74 3b 0a 20 20 77 68 69 6c 65  ->nEdit;.  while
1790: 28 20 6d 78 72 3e 32 20 26 26 20 52 5b 6d 78 72  ( mxr>2 && R[mxr
17a0: 2d 31 5d 3d 3d 30 20 26 26 20 52 5b 6d 78 72 2d  -1]==0 && R[mxr-
17b0: 32 5d 3d 3d 30 20 29 7b 20 6d 78 72 20 2d 3d 20  2]==0 ){ mxr -= 
17c0: 33 3b 20 7d 0a 20 20 66 6f 72 28 72 3d 30 3b 20  3; }.  for(r=0; 
17d0: 72 3c 6d 78 72 3b 20 72 20 2b 3d 20 33 2a 6e 72  r<mxr; r += 3*nr
17e0: 29 7b 0a 20 20 20 20 2f 2a 20 46 69 67 75 72 65  ){.    /* Figure
17f0: 20 6f 75 74 20 68 6f 77 20 6d 61 6e 79 20 74 72   out how many tr
1800: 69 70 6c 65 73 20 74 6f 20 73 68 6f 77 20 69 6e  iples to show in
1810: 20 61 20 73 69 6e 67 6c 65 20 62 6c 6f 63 6b 20   a single block 
1820: 2a 2f 0a 20 20 20 20 66 6f 72 28 6e 72 3d 31 3b  */.    for(nr=1;
1830: 20 52 5b 72 2b 6e 72 2a 33 5d 3e 30 20 26 26 20   R[r+nr*3]>0 && 
1840: 52 5b 72 2b 6e 72 2a 33 5d 3c 6e 43 6f 6e 74 65  R[r+nr*3]<nConte
1850: 78 74 2a 32 3b 20 6e 72 2b 2b 29 7b 7d 0a 20 20  xt*2; nr++){}.  
1860: 20 20 2f 2a 20 70 72 69 6e 74 66 28 22 72 3d 25    /* printf("r=%
1870: 64 20 6e 72 3d 25 64 5c 6e 22 2c 20 72 2c 20 6e  d nr=%d\n", r, n
1880: 72 29 3b 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 46  r); */..    /* F
1890: 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 62  or the current b
18a0: 6c 6f 63 6b 20 63 6f 6d 70 72 69 73 69 6e 67 20  lock comprising 
18b0: 6e 72 20 74 72 69 70 6c 65 73 2c 20 66 69 67 75  nr triples, figu
18c0: 72 65 20 6f 75 74 0a 20 20 20 20 2a 2a 20 68 6f  re out.    ** ho
18d0: 77 20 6d 61 6e 79 20 6c 69 6e 65 73 20 6f 66 20  w many lines of 
18e0: 41 20 61 6e 64 20 42 20 61 72 65 20 74 6f 20 62  A and B are to b
18f0: 65 20 64 69 73 70 6c 61 79 65 64 0a 20 20 20 20  e displayed.    
1900: 2a 2f 0a 20 20 20 20 69 66 28 20 52 5b 72 5d 3e  */.    if( R[r]>
1910: 6e 43 6f 6e 74 65 78 74 20 29 7b 0a 20 20 20 20  nContext ){.    
1920: 20 20 6e 61 20 3d 20 6e 62 20 3d 20 6e 43 6f 6e    na = nb = nCon
1930: 74 65 78 74 3b 0a 20 20 20 20 20 20 73 6b 69 70  text;.      skip
1940: 20 3d 20 52 5b 72 5d 20 2d 20 6e 43 6f 6e 74 65   = R[r] - nConte
1950: 78 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  xt;.    }else{. 
1960: 20 20 20 20 20 6e 61 20 3d 20 6e 62 20 3d 20 52       na = nb = R
1970: 5b 72 5d 3b 0a 20 20 20 20 20 20 73 6b 69 70 20  [r];.      skip 
1980: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66  = 0;.    }.    f
1990: 6f 72 28 69 3d 30 3b 20 69 3c 6e 72 3b 20 69 2b  or(i=0; i<nr; i+
19a0: 2b 29 7b 0a 20 20 20 20 20 20 6e 61 20 2b 3d 20  +){.      na += 
19b0: 52 5b 72 2b 69 2a 33 2b 31 5d 3b 0a 20 20 20 20  R[r+i*3+1];.    
19c0: 20 20 6e 62 20 2b 3d 20 52 5b 72 2b 69 2a 33 2b    nb += R[r+i*3+
19d0: 32 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  2];.    }.    if
19e0: 28 20 52 5b 72 2b 6e 72 2a 33 5d 3e 6e 43 6f 6e  ( R[r+nr*3]>nCon
19f0: 74 65 78 74 20 29 7b 0a 20 20 20 20 20 20 6e 61  text ){.      na
1a00: 20 2b 3d 20 6e 43 6f 6e 74 65 78 74 3b 0a 20 20   += nContext;.  
1a10: 20 20 20 20 6e 62 20 2b 3d 20 6e 43 6f 6e 74 65      nb += nConte
1a20: 78 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  xt;.    }else{. 
1a30: 20 20 20 20 20 6e 61 20 2b 3d 20 52 5b 72 2b 6e       na += R[r+n
1a40: 72 2a 33 5d 3b 0a 20 20 20 20 20 20 6e 62 20 2b  r*3];.      nb +
1a50: 3d 20 52 5b 72 2b 6e 72 2a 33 5d 3b 0a 20 20 20  = R[r+nr*3];.   
1a60: 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20   }.    for(i=1; 
1a70: 69 3c 6e 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  i<nr; i++){.    
1a80: 20 20 6e 61 20 2b 3d 20 52 5b 72 2b 69 2a 33 5d    na += R[r+i*3]
1a90: 3b 0a 20 20 20 20 20 20 6e 62 20 2b 3d 20 52 5b  ;.      nb += R[
1aa0: 72 2b 69 2a 33 5d 3b 0a 20 20 20 20 7d 0a 20 20  r+i*3];.    }.  
1ab0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70    blob_appendf(p
1ac0: 4f 75 74 2c 22 40 40 20 2d 25 64 2c 25 64 20 2b  Out,"@@ -%d,%d +
1ad0: 25 64 2c 25 64 20 40 40 5c 6e 22 2c 20 61 2b 73  %d,%d @@\n", a+s
1ae0: 6b 69 70 2b 31 2c 20 6e 61 2c 20 62 2b 73 6b 69  kip+1, na, b+ski
1af0: 70 2b 31 2c 20 6e 62 29 3b 0a 0a 20 20 20 20 2f  p+1, nb);..    /
1b00: 2a 20 53 68 6f 77 20 74 68 65 20 69 6e 69 74 69  * Show the initi
1b10: 61 6c 20 63 6f 6d 6d 6f 6e 20 61 72 65 61 20 2a  al common area *
1b20: 2f 0a 20 20 20 20 61 20 2b 3d 20 73 6b 69 70 3b  /.    a += skip;
1b30: 0a 20 20 20 20 62 20 2b 3d 20 73 6b 69 70 3b 0a  .    b += skip;.
1b40: 20 20 20 20 6d 20 3d 20 52 5b 72 5d 20 2d 20 73      m = R[r] - s
1b50: 6b 69 70 3b 0a 20 20 20 20 66 6f 72 28 6a 3d 30  kip;.    for(j=0
1b60: 3b 20 6a 3c 6d 3b 20 6a 2b 2b 29 7b 0a 20 20 20  ; j<m; j++){.   
1b70: 20 20 20 61 70 70 65 6e 64 44 69 66 66 4c 69 6e     appendDiffLin
1b80: 65 28 70 4f 75 74 2c 20 22 20 22 2c 20 26 41 5b  e(pOut, " ", &A[
1b90: 61 2b 6a 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20  a+j]);.    }.   
1ba0: 20 61 20 2b 3d 20 6d 3b 0a 20 20 20 20 62 20 2b   a += m;.    b +
1bb0: 3d 20 6d 3b 0a 0a 20 20 20 20 2f 2a 20 53 68 6f  = m;..    /* Sho
1bc0: 77 20 74 68 65 20 64 69 66 66 65 72 65 6e 63 65  w the difference
1bd0: 73 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 30  s */.    for(i=0
1be0: 3b 20 69 3c 6e 72 3b 20 69 2b 2b 29 7b 0a 20 20  ; i<nr; i++){.  
1bf0: 20 20 20 20 6d 20 3d 20 52 5b 72 2b 69 2a 33 2b      m = R[r+i*3+
1c00: 31 5d 3b 0a 20 20 20 20 20 20 66 6f 72 28 6a 3d  1];.      for(j=
1c10: 30 3b 20 6a 3c 6d 3b 20 6a 2b 2b 29 7b 0a 20 20  0; j<m; j++){.  
1c20: 20 20 20 20 20 20 61 70 70 65 6e 64 44 69 66 66        appendDiff
1c30: 4c 69 6e 65 28 70 4f 75 74 2c 20 22 2d 22 2c 20  Line(pOut, "-", 
1c40: 26 41 5b 61 2b 6a 5d 29 3b 0a 20 20 20 20 20 20  &A[a+j]);.      
1c50: 7d 0a 20 20 20 20 20 20 61 20 2b 3d 20 6d 3b 0a  }.      a += m;.
1c60: 20 20 20 20 20 20 6d 20 3d 20 52 5b 72 2b 69 2a        m = R[r+i*
1c70: 33 2b 32 5d 3b 0a 20 20 20 20 20 20 66 6f 72 28  3+2];.      for(
1c80: 6a 3d 30 3b 20 6a 3c 6d 3b 20 6a 2b 2b 29 7b 0a  j=0; j<m; j++){.
1c90: 20 20 20 20 20 20 20 20 61 70 70 65 6e 64 44 69          appendDi
1ca0: 66 66 4c 69 6e 65 28 70 4f 75 74 2c 20 22 2b 22  ffLine(pOut, "+"
1cb0: 2c 20 26 42 5b 62 2b 6a 5d 29 3b 0a 20 20 20 20  , &B[b+j]);.    
1cc0: 20 20 7d 0a 20 20 20 20 20 20 62 20 2b 3d 20 6d    }.      b += m
1cd0: 3b 0a 20 20 20 20 20 20 69 66 28 20 69 3c 6e 72  ;.      if( i<nr
1ce0: 2d 31 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 20  -1 ){.        m 
1cf0: 3d 20 52 5b 72 2b 69 2a 33 2b 33 5d 3b 0a 20 20  = R[r+i*3+3];.  
1d00: 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a        for(j=0; j
1d10: 3c 6d 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20  <m; j++){.      
1d20: 20 20 20 20 61 70 70 65 6e 64 44 69 66 66 4c 69      appendDiffLi
1d30: 6e 65 28 70 4f 75 74 2c 20 22 20 22 2c 20 26 42  ne(pOut, " ", &B
1d40: 5b 62 2b 6a 5d 29 3b 0a 20 20 20 20 20 20 20 20  [b+j]);.        
1d50: 7d 0a 20 20 20 20 20 20 20 20 62 20 2b 3d 20 6d  }.        b += m
1d60: 3b 0a 20 20 20 20 20 20 20 20 61 20 2b 3d 20 6d  ;.        a += m
1d70: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
1d80: 0a 20 20 20 20 2f 2a 20 53 68 6f 77 20 74 68 65  .    /* Show the
1d90: 20 66 69 6e 61 6c 20 63 6f 6d 6d 6f 6e 20 61 72   final common ar
1da0: 65 61 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74  ea */.    assert
1db0: 28 20 6e 72 3d 3d 69 20 29 3b 0a 20 20 20 20 6d  ( nr==i );.    m
1dc0: 20 3d 20 52 5b 72 2b 6e 72 2a 33 5d 3b 0a 20 20   = R[r+nr*3];.  
1dd0: 20 20 69 66 28 20 6d 3e 6e 43 6f 6e 74 65 78 74    if( m>nContext
1de0: 20 29 20 6d 20 3d 20 6e 43 6f 6e 74 65 78 74 3b   ) m = nContext;
1df0: 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c  .    for(j=0; j<
1e00: 6d 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 61  m; j++){.      a
1e10: 70 70 65 6e 64 44 69 66 66 4c 69 6e 65 28 70 4f  ppendDiffLine(pO
1e20: 75 74 2c 20 22 20 22 2c 20 26 42 5b 62 2b 6a 5d  ut, " ", &B[b+j]
1e30: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  );.    }.  }.}..
1e40: 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72 65 20 74 77  /*.** Compare tw
1e50: 6f 20 62 6c 6f 63 6b 73 20 6f 66 20 74 65 78 74  o blocks of text
1e60: 20 6f 6e 20 6c 69 6e 65 73 20 69 53 31 20 74 68   on lines iS1 th
1e70: 72 6f 75 67 68 20 69 45 31 2d 31 20 6f 66 20 74  rough iE1-1 of t
1e80: 68 65 20 61 46 72 6f 6d 5b 5d 0a 2a 2a 20 66 69  he aFrom[].** fi
1e90: 6c 65 20 61 6e 64 20 6c 69 6e 65 73 20 69 53 32  le and lines iS2
1ea0: 20 74 68 72 6f 75 67 68 20 69 45 32 2d 31 20 6f   through iE2-1 o
1eb0: 66 20 74 68 65 20 61 54 6f 5b 5d 20 66 69 6c 65  f the aTo[] file
1ec0: 2e 20 20 4c 6f 63 61 74 65 20 61 20 73 65 71 75  .  Locate a sequ
1ed0: 65 6e 63 65 0a 2a 2a 20 6f 66 20 6c 69 6e 65 73  ence.** of lines
1ee0: 20 69 6e 20 74 68 65 73 65 20 74 77 6f 20 62 6c   in these two bl
1ef0: 6f 63 6b 73 20 74 68 61 74 20 61 72 65 20 65 78  ocks that are ex
1f00: 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65 2e 20  actly the same. 
1f10: 20 52 65 74 75 72 6e 0a 2a 2a 20 74 68 65 20 62   Return.** the b
1f20: 6f 75 6e 64 73 20 6f 66 20 74 68 65 20 6d 61 74  ounds of the mat
1f30: 63 68 69 6e 67 20 73 65 71 75 65 6e 63 65 2e 0a  ching sequence..
1f40: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6c  */.static void l
1f50: 6f 6e 67 65 73 74 43 6f 6d 6d 6f 6e 53 65 71 75  ongestCommonSequ
1f60: 65 6e 63 65 28 0a 20 20 44 43 6f 6e 74 65 78 74  ence(.  DContext
1f70: 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20   *p,            
1f80: 20 20 20 2f 2a 20 54 77 6f 20 66 69 6c 65 73 20     /* Two files 
1f90: 62 65 69 6e 67 20 63 6f 6d 70 61 72 65 64 20 2a  being compared *
1fa0: 2f 0a 20 20 69 6e 74 20 69 53 31 2c 20 69 6e 74  /.  int iS1, int
1fb0: 20 69 45 31 2c 20 20 20 20 20 20 20 20 20 20 2f   iE1,          /
1fc0: 2a 20 52 61 6e 67 65 20 6f 66 20 6c 69 6e 65 73  * Range of lines
1fd0: 20 69 6e 20 70 2d 3e 61 46 72 6f 6d 5b 5d 20 2a   in p->aFrom[] *
1fe0: 2f 0a 20 20 69 6e 74 20 69 53 32 2c 20 69 6e 74  /.  int iS2, int
1ff0: 20 69 45 32 2c 20 20 20 20 20 20 20 20 20 20 2f   iE2,          /
2000: 2a 20 52 61 6e 67 65 20 6f 66 20 6c 69 6e 65 73  * Range of lines
2010: 20 69 6e 20 70 2d 3e 61 54 6f 5b 5d 20 2a 2f 0a   in p->aTo[] */.
2020: 20 20 69 6e 74 20 2a 70 69 53 58 2c 20 69 6e 74    int *piSX, int
2030: 20 2a 70 69 45 58 2c 20 20 20 20 20 20 2f 2a 20   *piEX,      /* 
2040: 57 72 69 74 65 20 70 2d 3e 61 46 72 6f 6d 5b 5d  Write p->aFrom[]
2050: 20 63 6f 6d 6d 6f 6e 20 73 65 67 6d 65 6e 74 20   common segment 
2060: 68 65 72 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  here */.  int *p
2070: 69 53 59 2c 20 69 6e 74 20 2a 70 69 45 59 20 20  iSY, int *piEY  
2080: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 70 2d       /* Write p-
2090: 3e 61 54 6f 5b 5d 20 63 6f 6d 6d 6f 6e 20 73 65  >aTo[] common se
20a0: 67 6d 65 6e 74 20 68 65 72 65 20 2a 2f 0a 29 7b  gment here */.){
20b0: 0a 20 20 64 6f 75 62 6c 65 20 62 65 73 74 53 63  .  double bestSc
20c0: 6f 72 65 20 3d 20 2d 31 65 33 30 3b 20 20 2f 2a  ore = -1e30;  /*
20d0: 20 42 65 73 74 20 73 63 6f 72 65 20 73 65 65 6e   Best score seen
20e0: 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 69 6e 74   so far */.  int
20f0: 20 69 2c 20 6a 3b 20 20 20 20 20 20 20 20 20 20   i, j;          
2100: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
2110: 63 6f 75 6e 74 65 72 73 20 2a 2f 0a 20 20 69 6e  counters */.  in
2120: 74 20 69 53 58 2c 20 69 53 59 2c 20 69 45 58 2c  t iSX, iSY, iEX,
2130: 20 69 45 59 3b 20 20 20 20 2f 2a 20 43 75 72 72   iEY;    /* Curr
2140: 65 6e 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 64  ent match */.  d
2150: 6f 75 62 6c 65 20 73 63 6f 72 65 3b 20 20 20 20  ouble score;    
2160: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
2170: 72 65 6e 74 20 73 63 6f 72 65 20 2a 2f 0a 20 20  rent score */.  
2180: 69 6e 74 20 73 6b 65 77 3b 20 20 20 20 20 20 20  int skew;       
2190: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 6f             /* Ho
21a0: 77 20 6c 6f 70 73 69 64 65 64 20 69 73 20 74 68  w lopsided is th
21b0: 65 20 6d 61 74 63 68 20 2a 2f 0a 20 20 69 6e 74  e match */.  int
21c0: 20 64 69 73 74 3b 20 20 20 20 20 20 20 20 20 20   dist;          
21d0: 20 20 20 20 20 20 20 20 2f 2a 20 44 69 73 74 61          /* Dista
21e0: 6e 63 65 20 6f 66 20 6d 61 74 63 68 20 66 72 6f  nce of match fro
21f0: 6d 20 63 65 6e 74 65 72 20 2a 2f 0a 20 20 69 6e  m center */.  in
2200: 74 20 6d 69 64 3b 20 20 20 20 20 20 20 20 20 20  t mid;          
2210: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 65 6e 74           /* Cent
2220: 65 72 20 6f 66 20 74 68 65 20 73 70 61 6e 20 2a  er of the span *
2230: 2f 0a 20 20 69 6e 74 20 69 53 58 62 2c 20 69 53  /.  int iSXb, iS
2240: 59 62 2c 20 69 45 58 62 2c 20 69 45 59 62 3b 20  Yb, iEXb, iEYb; 
2250: 20 20 2f 2a 20 42 65 73 74 20 6d 61 74 63 68 20    /* Best match 
2260: 73 6f 20 66 61 72 20 2a 2f 0a 20 20 69 6e 74 20  so far */.  int 
2270: 69 53 58 70 2c 20 69 53 59 70 2c 20 69 45 58 70  iSXp, iSYp, iEXp
2280: 2c 20 69 45 59 70 3b 20 20 20 2f 2a 20 50 72 65  , iEYp;   /* Pre
2290: 76 69 6f 75 73 20 6d 61 74 63 68 20 2a 2f 0a 0a  vious match */..
22a0: 20 20 69 53 58 62 20 3d 20 69 53 58 70 20 3d 20    iSXb = iSXp = 
22b0: 69 53 31 3b 0a 20 20 69 45 58 62 20 3d 20 69 45  iS1;.  iEXb = iE
22c0: 58 70 20 3d 20 69 53 31 3b 0a 20 20 69 53 59 62  Xp = iS1;.  iSYb
22d0: 20 3d 20 69 53 59 70 20 3d 20 69 53 32 3b 0a 20   = iSYp = iS2;. 
22e0: 20 69 45 59 62 20 3d 20 69 45 59 70 20 3d 20 69   iEYb = iEYp = i
22f0: 53 32 3b 0a 20 20 6d 69 64 20 3d 20 28 69 45 31  S2;.  mid = (iE1
2300: 20 2b 20 69 53 31 29 2f 32 3b 0a 20 20 66 6f 72   + iS1)/2;.  for
2310: 28 69 3d 69 53 31 3b 20 69 3c 69 45 31 3b 20 69  (i=iS1; i<iE1; i
2320: 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6c 69 6d  ++){.    int lim
2330: 69 74 20 3d 20 30 3b 0a 20 20 20 20 6a 20 3d 20  it = 0;.    j = 
2340: 70 2d 3e 61 54 6f 5b 70 2d 3e 61 46 72 6f 6d 5b  p->aTo[p->aFrom[
2350: 69 5d 2e 68 20 25 20 70 2d 3e 6e 54 6f 5d 2e 69  i].h % p->nTo].i
2360: 48 61 73 68 3b 0a 20 20 20 20 77 68 69 6c 65 28  Hash;.    while(
2370: 20 6a 3e 30 20 0a 20 20 20 20 20 20 26 26 20 28   j>0 .      && (
2380: 6a 2d 31 3c 69 53 32 20 7c 7c 20 6a 3e 3d 69 45  j-1<iS2 || j>=iE
2390: 32 20 7c 7c 20 21 73 61 6d 65 5f 64 6c 69 6e 65  2 || !same_dline
23a0: 28 26 70 2d 3e 61 46 72 6f 6d 5b 69 5d 2c 20 26  (&p->aFrom[i], &
23b0: 70 2d 3e 61 54 6f 5b 6a 2d 31 5d 29 29 0a 20 20  p->aTo[j-1])).  
23c0: 20 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6c    ){.      if( l
23d0: 69 6d 69 74 2b 2b 20 3e 20 31 30 20 29 7b 0a 20  imit++ > 10 ){. 
23e0: 20 20 20 20 20 20 20 6a 20 3d 20 30 3b 0a 20 20         j = 0;.  
23f0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
2400: 20 20 20 7d 0a 20 20 20 20 20 20 6a 20 3d 20 70     }.      j = p
2410: 2d 3e 61 54 6f 5b 6a 2d 31 5d 2e 69 4e 65 78 74  ->aTo[j-1].iNext
2420: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
2430: 6a 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b  j==0 ) continue;
2440: 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 3e 3d  .    assert( i>=
2450: 69 53 58 62 20 26 26 20 69 3e 3d 69 53 58 70 20  iSXb && i>=iSXp 
2460: 29 3b 0a 20 20 20 20 69 66 28 20 69 3c 69 45 58  );.    if( i<iEX
2470: 62 20 26 26 20 6a 3e 3d 69 53 59 62 20 26 26 20  b && j>=iSYb && 
2480: 6a 3c 69 45 59 62 20 29 20 63 6f 6e 74 69 6e 75  j<iEYb ) continu
2490: 65 3b 0a 20 20 20 20 69 66 28 20 69 3c 69 45 58  e;.    if( i<iEX
24a0: 70 20 26 26 20 6a 3e 3d 69 53 59 70 20 26 26 20  p && j>=iSYp && 
24b0: 6a 3c 69 45 59 70 20 29 20 63 6f 6e 74 69 6e 75  j<iEYp ) continu
24c0: 65 3b 0a 20 20 20 20 69 53 58 20 3d 20 69 3b 0a  e;.    iSX = i;.
24d0: 20 20 20 20 69 53 59 20 3d 20 6a 2d 31 3b 0a 20      iSY = j-1;. 
24e0: 20 20 20 77 68 69 6c 65 28 20 69 53 58 3e 69 53     while( iSX>iS
24f0: 31 20 26 26 20 69 53 59 3e 69 53 32 20 26 26 20  1 && iSY>iS2 && 
2500: 73 61 6d 65 5f 64 6c 69 6e 65 28 26 70 2d 3e 61  same_dline(&p->a
2510: 46 72 6f 6d 5b 69 53 58 2d 31 5d 2c 26 70 2d 3e  From[iSX-1],&p->
2520: 61 54 6f 5b 69 53 59 2d 31 5d 29 20 29 7b 0a 20  aTo[iSY-1]) ){. 
2530: 20 20 20 20 20 69 53 58 2d 2d 3b 0a 20 20 20 20       iSX--;.    
2540: 20 20 69 53 59 2d 2d 3b 0a 20 20 20 20 7d 0a 20    iSY--;.    }. 
2550: 20 20 20 69 45 58 20 3d 20 69 2b 31 3b 0a 20 20     iEX = i+1;.  
2560: 20 20 69 45 59 20 3d 20 6a 3b 0a 20 20 20 20 77    iEY = j;.    w
2570: 68 69 6c 65 28 20 69 45 58 3c 69 45 31 20 26 26  hile( iEX<iE1 &&
2580: 20 69 45 59 3c 69 45 32 20 26 26 20 73 61 6d 65   iEY<iE2 && same
2590: 5f 64 6c 69 6e 65 28 26 70 2d 3e 61 46 72 6f 6d  _dline(&p->aFrom
25a0: 5b 69 45 58 5d 2c 26 70 2d 3e 61 54 6f 5b 69 45  [iEX],&p->aTo[iE
25b0: 59 5d 29 20 29 7b 0a 20 20 20 20 20 20 69 45 58  Y]) ){.      iEX
25c0: 2b 2b 3b 0a 20 20 20 20 20 20 69 45 59 2b 2b 3b  ++;.      iEY++;
25d0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 6b 65 77 20  .    }.    skew 
25e0: 3d 20 28 69 53 58 2d 69 53 31 29 20 2d 20 28 69  = (iSX-iS1) - (i
25f0: 53 59 2d 69 53 32 29 3b 0a 20 20 20 20 69 66 28  SY-iS2);.    if(
2600: 20 73 6b 65 77 3c 30 20 29 20 73 6b 65 77 20 3d   skew<0 ) skew =
2610: 20 2d 73 6b 65 77 3b 0a 20 20 20 20 64 69 73 74   -skew;.    dist
2620: 20 3d 20 28 69 53 58 2b 69 45 58 29 2f 32 20 2d   = (iSX+iEX)/2 -
2630: 20 6d 69 64 3b 0a 20 20 20 20 69 66 28 20 64 69   mid;.    if( di
2640: 73 74 3c 30 20 29 20 64 69 73 74 20 3d 20 2d 64  st<0 ) dist = -d
2650: 69 73 74 3b 0a 20 20 20 20 73 63 6f 72 65 20 3d  ist;.    score =
2660: 20 28 69 45 58 20 2d 20 69 53 58 29 20 2d 20 30   (iEX - iSX) - 0
2670: 2e 30 35 2a 73 6b 65 77 20 2d 20 30 2e 30 35 2a  .05*skew - 0.05*
2680: 64 69 73 74 3b 0a 20 20 20 20 69 66 28 20 73 63  dist;.    if( sc
2690: 6f 72 65 3e 62 65 73 74 53 63 6f 72 65 20 29 7b  ore>bestScore ){
26a0: 0a 20 20 20 20 20 20 62 65 73 74 53 63 6f 72 65  .      bestScore
26b0: 20 3d 20 73 63 6f 72 65 3b 0a 20 20 20 20 20 20   = score;.      
26c0: 69 53 58 62 20 3d 20 69 53 58 3b 0a 20 20 20 20  iSXb = iSX;.    
26d0: 20 20 69 53 59 62 20 3d 20 69 53 59 3b 0a 20 20    iSYb = iSY;.  
26e0: 20 20 20 20 69 45 58 62 20 3d 20 69 45 58 3b 0a      iEXb = iEX;.
26f0: 20 20 20 20 20 20 69 45 59 62 20 3d 20 69 45 59        iEYb = iEY
2700: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
2710: 20 20 20 69 53 58 70 20 3d 20 69 53 58 3b 0a 20     iSXp = iSX;. 
2720: 20 20 20 20 20 69 53 59 70 20 3d 20 69 53 59 3b       iSYp = iSY;
2730: 0a 20 20 20 20 20 20 69 45 58 70 20 3d 20 69 45  .      iEXp = iE
2740: 58 3b 0a 20 20 20 20 20 20 69 45 59 70 20 3d 20  X;.      iEYp = 
2750: 69 45 59 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  iEY;.    }.  }. 
2760: 20 2a 70 69 53 58 20 3d 20 69 53 58 62 3b 0a 20   *piSX = iSXb;. 
2770: 20 2a 70 69 53 59 20 3d 20 69 53 59 62 3b 0a 20   *piSY = iSYb;. 
2780: 20 2a 70 69 45 58 20 3d 20 69 45 58 62 3b 0a 20   *piEX = iEXb;. 
2790: 20 2a 70 69 45 59 20 3d 20 69 45 59 62 3b 0a 20   *piEY = iEYb;. 
27a0: 20 2f 2a 20 70 72 69 6e 74 66 28 22 4c 43 53 28   /* printf("LCS(
27b0: 25 64 2e 2e 25 64 2f 25 64 2e 2e 25 64 29 20 3d  %d..%d/%d..%d) =
27c0: 20 25 64 2e 2e 25 64 2f 25 64 2e 2e 25 64 5c 6e   %d..%d/%d..%d\n
27d0: 22 2c 20 0a 20 20 20 20 20 69 53 31 2c 20 69 45  ", .     iS1, iE
27e0: 31 2c 20 69 53 32 2c 20 69 45 32 2c 20 2a 70 69  1, iS2, iE2, *pi
27f0: 53 58 2c 20 2a 70 69 45 58 2c 20 2a 70 69 53 59  SX, *piEX, *piSY
2800: 2c 20 2a 70 69 45 59 29 3b 20 20 2a 2f 0a 7d 0a  , *piEY);  */.}.
2810: 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 73 69 6e 67  ./*.** Do a sing
2820: 6c 65 20 73 74 65 70 20 69 6e 20 74 68 65 20 64  le step in the d
2830: 69 66 66 65 72 65 6e 63 65 2e 20 20 43 6f 6d 70  ifference.  Comp
2840: 75 74 65 20 61 20 73 65 71 75 65 6e 63 65 20 6f  ute a sequence o
2850: 66 0a 2a 2a 20 63 6f 70 79 2f 64 65 6c 65 74 65  f.** copy/delete
2860: 2f 69 6e 73 65 72 74 20 73 74 65 70 73 20 74 68  /insert steps th
2870: 61 74 20 77 69 6c 6c 20 63 6f 6e 76 65 72 74 20  at will convert 
2880: 6c 69 6e 65 73 20 69 53 31 20 74 68 72 6f 75 67  lines iS1 throug
2890: 68 20 69 45 31 2d 31 20 6f 66 0a 2a 2a 20 74 68  h iE1-1 of.** th
28a0: 65 20 69 6e 70 75 74 20 69 6e 74 6f 20 6c 69 6e  e input into lin
28b0: 65 73 20 69 53 32 20 74 68 72 6f 75 67 68 20 69  es iS2 through i
28c0: 45 32 2d 31 20 6f 66 20 74 68 65 20 6f 75 74 70  E2-1 of the outp
28d0: 75 74 20 61 6e 64 20 77 72 69 74 65 0a 2a 2a 20  ut and write.** 
28e0: 74 68 61 74 20 73 65 71 75 65 6e 63 65 20 69 6e  that sequence in
28f0: 74 6f 20 74 68 65 20 64 69 66 66 65 72 65 6e 63  to the differenc
2900: 65 20 63 6f 6e 74 65 78 74 2e 0a 2a 2a 0a 2a 2a  e context..**.**
2910: 20 54 68 65 20 61 6c 67 6f 72 69 74 68 6d 20 69   The algorithm i
2920: 73 20 74 6f 20 66 69 6e 64 20 61 20 62 6c 6f 63  s to find a bloc
2930: 6b 20 6f 66 20 63 6f 6d 6d 6f 6e 20 74 65 78 74  k of common text
2940: 20 6e 65 61 72 20 74 68 65 20 6d 69 64 64 6c 65   near the middle
2950: 0a 2a 2a 20 6f 66 20 74 68 65 20 74 77 6f 20 73  .** of the two s
2960: 65 67 6d 65 6e 74 73 20 62 65 69 6e 67 20 64 69  egments being di
2970: 66 66 65 64 2e 20 20 54 68 65 6e 20 72 65 63 75  ffed.  Then recu
2980: 72 73 69 76 65 6c 79 20 63 6f 6d 70 75 74 65 0a  rsively compute.
2990: 2a 2a 20 64 69 66 66 65 72 65 6e 63 65 73 20 6f  ** differences o
29a0: 6e 20 74 68 65 20 62 6c 6f 63 6b 73 20 62 65 66  n the blocks bef
29b0: 6f 72 65 20 61 6e 64 20 61 66 74 65 72 20 74 68  ore and after th
29c0: 61 74 20 63 6f 6d 6d 6f 6e 20 73 65 67 6d 65 6e  at common segmen
29d0: 74 2e 0a 2a 2a 20 53 70 65 63 69 61 6c 20 63 61  t..** Special ca
29e0: 73 65 73 20 61 70 70 6c 79 20 69 66 20 65 69 74  ses apply if eit
29f0: 68 65 72 20 69 6e 70 75 74 20 73 65 67 6d 65 6e  her input segmen
2a00: 74 20 69 73 20 65 6d 70 74 79 20 6f 72 20 69 66  t is empty or if
2a10: 20 74 68 65 0a 2a 2a 20 74 77 6f 20 73 65 67 6d   the.** two segm
2a20: 65 6e 74 73 20 68 61 76 65 20 6e 6f 20 74 65 78  ents have no tex
2a30: 74 20 69 6e 20 63 6f 6d 6d 6f 6e 2e 0a 2a 2f 0a  t in common..*/.
2a40: 73 74 61 74 69 63 20 76 6f 69 64 20 64 69 66 66  static void diff
2a50: 5f 73 74 65 70 28 44 43 6f 6e 74 65 78 74 20 2a  _step(DContext *
2a60: 70 2c 20 69 6e 74 20 69 53 31 2c 20 69 6e 74 20  p, int iS1, int 
2a70: 69 45 31 2c 20 69 6e 74 20 69 53 32 2c 20 69 6e  iE1, int iS2, in
2a80: 74 20 69 45 32 29 7b 0a 20 20 69 6e 74 20 69 53  t iE2){.  int iS
2a90: 58 2c 20 69 45 58 2c 20 69 53 59 2c 20 69 45 59  X, iEX, iSY, iEY
2aa0: 3b 0a 0a 20 20 69 66 28 20 69 45 31 3c 3d 69 53  ;..  if( iE1<=iS
2ab0: 31 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20  1 ){.    /* The 
2ac0: 66 69 72 73 74 20 73 65 67 6d 65 6e 74 20 69 73  first segment is
2ad0: 20 65 6d 70 74 79 20 2a 2f 0a 20 20 20 20 69 66   empty */.    if
2ae0: 28 20 69 45 32 3e 69 53 32 20 29 7b 0a 20 20 20  ( iE2>iS2 ){.   
2af0: 20 20 20 61 70 70 65 6e 64 54 72 69 70 6c 65 28     appendTriple(
2b00: 70 2c 20 30 2c 20 30 2c 20 69 45 32 2d 69 53 32  p, 0, 0, iE2-iS2
2b10: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  );.    }.    ret
2b20: 75 72 6e 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69  urn;.  }.  if( i
2b30: 45 32 3c 3d 69 53 32 20 29 7b 0a 20 20 20 20 2f  E2<=iS2 ){.    /
2b40: 2a 20 54 68 65 20 73 65 63 6f 6e 64 20 73 65 67  * The second seg
2b50: 6d 65 6e 74 20 69 73 20 65 6d 70 74 79 20 2a 2f  ment is empty */
2b60: 0a 20 20 20 20 61 70 70 65 6e 64 54 72 69 70 6c  .    appendTripl
2b70: 65 28 70 2c 20 30 2c 20 69 45 31 2d 69 53 31 2c  e(p, 0, iE1-iS1,
2b80: 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b   0);.    return;
2b90: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 46 69 6e 64 20  .  }..  /* Find 
2ba0: 74 68 65 20 6c 6f 6e 67 65 73 74 20 6d 61 74 63  the longest matc
2bb0: 68 69 6e 67 20 73 65 67 6d 65 6e 74 20 62 65 74  hing segment bet
2bc0: 77 65 65 6e 20 74 68 65 20 74 77 6f 20 73 65 71  ween the two seq
2bd0: 75 65 6e 63 65 73 20 2a 2f 0a 20 20 6c 6f 6e 67  uences */.  long
2be0: 65 73 74 43 6f 6d 6d 6f 6e 53 65 71 75 65 6e 63  estCommonSequenc
2bf0: 65 28 70 2c 20 69 53 31 2c 20 69 45 31 2c 20 69  e(p, iS1, iE1, i
2c00: 53 32 2c 20 69 45 32 2c 20 26 69 53 58 2c 20 26  S2, iE2, &iSX, &
2c10: 69 45 58 2c 20 26 69 53 59 2c 20 26 69 45 59 29  iEX, &iSY, &iEY)
2c20: 3b 0a 0a 20 20 69 66 28 20 69 45 58 3e 69 53 58  ;..  if( iEX>iSX
2c30: 20 29 7b 0a 20 20 20 20 2f 2a 20 41 20 63 6f 6d   ){.    /* A com
2c40: 6d 6f 6e 20 73 65 67 65 6d 65 6e 74 20 68 61 73  mon segement has
2c50: 20 62 65 65 6e 20 66 6f 75 6e 64 2e 0a 20 20 20   been found..   
2c60: 20 2a 2a 20 52 65 63 75 72 73 69 76 65 6c 79 20   ** Recursively 
2c70: 64 69 66 66 20 65 69 74 68 65 72 20 73 69 64 65  diff either side
2c80: 20 6f 66 20 74 68 65 20 6d 61 74 63 68 69 6e 67   of the matching
2c90: 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20   segment */.    
2ca0: 64 69 66 66 5f 73 74 65 70 28 70 2c 20 69 53 31  diff_step(p, iS1
2cb0: 2c 20 69 53 58 2c 20 69 53 32 2c 20 69 53 59 29  , iSX, iS2, iSY)
2cc0: 3b 0a 20 20 20 20 69 66 28 20 69 45 58 3e 69 53  ;.    if( iEX>iS
2cd0: 58 20 29 7b 0a 20 20 20 20 20 20 61 70 70 65 6e  X ){.      appen
2ce0: 64 54 72 69 70 6c 65 28 70 2c 20 69 45 58 20 2d  dTriple(p, iEX -
2cf0: 20 69 53 58 2c 20 30 2c 20 30 29 3b 0a 20 20 20   iSX, 0, 0);.   
2d00: 20 7d 0a 20 20 20 20 64 69 66 66 5f 73 74 65 70   }.    diff_step
2d10: 28 70 2c 20 69 45 58 2c 20 69 45 31 2c 20 69 45  (p, iEX, iE1, iE
2d20: 59 2c 20 69 45 32 29 3b 0a 20 20 7d 65 6c 73 65  Y, iE2);.  }else
2d30: 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 74 77 6f  {.    /* The two
2d40: 20 73 65 67 6d 65 6e 74 73 20 68 61 76 65 20 6e   segments have n
2d50: 6f 74 68 69 6e 67 20 69 6e 20 63 6f 6d 6d 6f 6e  othing in common
2d60: 2e 20 20 44 65 6c 65 74 65 20 74 68 65 20 66 69  .  Delete the fi
2d70: 72 73 74 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20  rst then.    ** 
2d80: 69 6e 73 65 72 74 20 74 68 65 20 73 65 63 6f 6e  insert the secon
2d90: 64 2e 20 2a 2f 0a 20 20 20 20 61 70 70 65 6e 64  d. */.    append
2da0: 54 72 69 70 6c 65 28 70 2c 20 30 2c 20 69 45 31  Triple(p, 0, iE1
2db0: 2d 69 53 31 2c 20 69 45 32 2d 69 53 32 29 3b 0a  -iS1, iE2-iS2);.
2dc0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d    }.}../*.** Com
2dd0: 70 75 74 65 20 74 68 65 20 64 69 66 66 65 72 65  pute the differe
2de0: 6e 63 65 73 20 62 65 74 77 65 65 6e 20 74 77 6f  nces between two
2df0: 20 66 69 6c 65 73 20 61 6c 72 65 61 64 79 20 6c   files already l
2e00: 6f 61 64 65 64 20 69 6e 74 6f 0a 2a 2a 20 74 68  oaded into.** th
2e10: 65 20 44 43 6f 6e 74 65 78 74 20 73 74 72 75 63  e DContext struc
2e20: 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 64 69  ture..**.** A di
2e30: 76 69 64 65 20 61 6e 64 20 63 6f 6e 71 75 65 72  vide and conquer
2e40: 20 74 65 63 68 6e 69 71 75 65 20 69 73 20 75 73   technique is us
2e50: 65 64 2e 20 20 57 65 20 6c 6f 6f 6b 20 66 6f 72  ed.  We look for
2e60: 20 61 20 6c 61 72 67 65 0a 2a 2a 20 62 6c 6f 63   a large.** bloc
2e70: 6b 20 6f 66 20 63 6f 6d 6d 6f 6e 20 74 65 78 74  k of common text
2e80: 20 74 68 61 74 20 69 73 20 69 6e 20 74 68 65 20   that is in the 
2e90: 6d 69 64 64 6c 65 20 6f 66 20 62 6f 74 68 20 66  middle of both f
2ea0: 69 6c 65 73 2e 20 20 54 68 65 6e 0a 2a 2a 20 63  iles.  Then.** c
2eb0: 6f 6d 70 75 74 65 20 74 68 65 20 64 69 66 66 65  ompute the diffe
2ec0: 72 65 6e 63 65 20 6f 6e 20 74 68 6f 73 65 20 70  rence on those p
2ed0: 61 72 74 73 20 6f 66 20 74 68 65 20 66 69 6c 65  arts of the file
2ee0: 20 62 65 66 6f 72 65 20 61 6e 64 0a 2a 2a 20 61   before and.** a
2ef0: 66 74 65 72 20 74 68 65 20 63 6f 6d 6d 6f 6e 20  fter the common 
2f00: 62 6c 6f 63 6b 2e 20 20 54 68 69 73 20 74 65 63  block.  This tec
2f10: 68 6e 69 71 75 65 20 69 73 20 66 61 73 74 2c 20  hnique is fast, 
2f20: 62 75 74 20 69 74 20 64 6f 65 73 0a 2a 2a 20 6e  but it does.** n
2f30: 6f 74 20 6e 65 63 65 73 73 61 72 69 6c 79 20 67  ot necessarily g
2f40: 65 6e 65 72 61 74 65 20 74 68 65 20 6d 69 6e 69  enerate the mini
2f50: 6d 75 6d 20 64 69 66 66 65 72 65 6e 63 65 20 73  mum difference s
2f60: 65 74 2e 20 20 4f 6e 20 74 68 65 0a 2a 2a 20 6f  et.  On the.** o
2f70: 74 68 65 72 20 68 61 6e 64 2c 20 77 65 20 64 6f  ther hand, we do
2f80: 20 6e 6f 74 20 6e 65 65 64 20 61 20 6d 69 6e 69   not need a mini
2f90: 6d 75 6d 20 64 69 66 66 65 72 65 6e 63 65 20 73  mum difference s
2fa0: 65 74 2c 20 6f 6e 6c 79 20 6f 6e 65 0a 2a 2a 20  et, only one.** 
2fb0: 74 68 61 74 20 6d 61 6b 65 73 20 73 65 6e 73 65  that makes sense
2fc0: 20 74 6f 20 68 75 6d 61 6e 20 72 65 61 64 65 72   to human reader
2fd0: 73 2c 20 77 68 69 63 68 20 74 68 69 73 20 61 6c  s, which this al
2fe0: 67 6f 72 69 74 68 6d 20 64 6f 65 73 2e 0a 2a 2a  gorithm does..**
2ff0: 0a 2a 2a 20 41 6e 79 20 63 6f 6d 6d 6f 6e 20 74  .** Any common t
3000: 65 78 74 20 61 74 20 74 68 65 20 62 65 67 69 6e  ext at the begin
3010: 6e 69 6e 67 20 61 6e 64 20 65 6e 64 20 6f 66 20  ning and end of 
3020: 74 68 65 20 74 77 6f 20 66 69 6c 65 73 20 69 73  the two files is
3030: 0a 2a 2a 20 72 65 6d 6f 76 65 64 20 62 65 66 6f  .** removed befo
3040: 72 65 20 73 74 61 72 74 69 6e 67 20 74 68 65 20  re starting the 
3050: 64 69 76 69 64 65 2d 61 6e 64 2d 63 6f 6e 71 75  divide-and-conqu
3060: 65 72 20 61 6c 67 6f 72 69 74 68 6d 2e 0a 2a 2f  er algorithm..*/
3070: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 69 66  .static void dif
3080: 66 5f 61 6c 6c 28 44 43 6f 6e 74 65 78 74 20 2a  f_all(DContext *
3090: 70 29 7b 0a 20 20 69 6e 74 20 6d 6e 45 2c 20 69  p){.  int mnE, i
30a0: 53 2c 20 69 45 31 2c 20 69 45 32 3b 0a 0a 20 20  S, iE1, iE2;..  
30b0: 2f 2a 20 43 61 72 76 65 20 6f 66 66 20 74 68 65  /* Carve off the
30c0: 20 63 6f 6d 6d 6f 6e 20 68 65 61 64 65 72 20 61   common header a
30d0: 6e 64 20 66 6f 6f 74 65 72 20 2a 2f 0a 20 20 69  nd footer */.  i
30e0: 45 31 20 3d 20 70 2d 3e 6e 46 72 6f 6d 3b 0a 20  E1 = p->nFrom;. 
30f0: 20 69 45 32 20 3d 20 70 2d 3e 6e 54 6f 3b 0a 20   iE2 = p->nTo;. 
3100: 20 77 68 69 6c 65 28 20 69 45 31 3e 30 20 26 26   while( iE1>0 &&
3110: 20 69 45 32 3e 30 20 26 26 20 73 61 6d 65 5f 64   iE2>0 && same_d
3120: 6c 69 6e 65 28 26 70 2d 3e 61 46 72 6f 6d 5b 69  line(&p->aFrom[i
3130: 45 31 2d 31 5d 2c 20 26 70 2d 3e 61 54 6f 5b 69  E1-1], &p->aTo[i
3140: 45 32 2d 31 5d 29 20 29 7b 0a 20 20 20 20 69 45  E2-1]) ){.    iE
3150: 31 2d 2d 3b 0a 20 20 20 20 69 45 32 2d 2d 3b 0a  1--;.    iE2--;.
3160: 20 20 7d 0a 20 20 6d 6e 45 20 3d 20 69 45 31 3c    }.  mnE = iE1<
3170: 69 45 32 20 3f 20 69 45 31 20 3a 20 69 45 32 3b  iE2 ? iE1 : iE2;
3180: 0a 20 20 66 6f 72 28 69 53 3d 30 3b 20 69 53 3c  .  for(iS=0; iS<
3190: 6d 6e 45 20 26 26 20 73 61 6d 65 5f 64 6c 69 6e  mnE && same_dlin
31a0: 65 28 26 70 2d 3e 61 46 72 6f 6d 5b 69 53 5d 2c  e(&p->aFrom[iS],
31b0: 26 70 2d 3e 61 54 6f 5b 69 53 5d 29 3b 20 69 53  &p->aTo[iS]); iS
31c0: 2b 2b 29 7b 7d 0a 0a 20 20 2f 2a 20 64 6f 20 74  ++){}..  /* do t
31d0: 68 65 20 64 69 66 66 65 72 65 6e 63 65 20 2a 2f  he difference */
31e0: 0a 20 20 69 66 28 20 69 53 3e 30 20 29 7b 0a 20  .  if( iS>0 ){. 
31f0: 20 20 20 61 70 70 65 6e 64 54 72 69 70 6c 65 28     appendTriple(
3200: 70 2c 20 69 53 2c 20 30 2c 20 30 29 3b 0a 20 20  p, iS, 0, 0);.  
3210: 7d 0a 20 20 64 69 66 66 5f 73 74 65 70 28 70 2c  }.  diff_step(p,
3220: 20 69 53 2c 20 69 45 31 2c 20 69 53 2c 20 69 45   iS, iE1, iS, iE
3230: 32 29 3b 0a 20 20 69 66 28 20 69 45 31 3c 70 2d  2);.  if( iE1<p-
3240: 3e 6e 46 72 6f 6d 20 29 7b 0a 20 20 20 20 61 70  >nFrom ){.    ap
3250: 70 65 6e 64 54 72 69 70 6c 65 28 70 2c 20 70 2d  pendTriple(p, p-
3260: 3e 6e 46 72 6f 6d 20 2d 20 69 45 31 2c 20 30 2c  >nFrom - iE1, 0,
3270: 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54   0);.  }..  /* T
3280: 65 72 6d 69 6e 61 74 65 20 74 68 65 20 43 4f 50  erminate the COP
3290: 59 2f 44 45 4c 45 54 45 2f 49 4e 53 45 52 54 20  Y/DELETE/INSERT 
32a0: 74 72 69 70 6c 65 73 20 77 69 74 68 20 74 68 72  triples with thr
32b0: 65 65 20 7a 65 72 6f 73 20 2a 2f 0a 20 20 65 78  ee zeros */.  ex
32c0: 70 61 6e 64 45 64 69 74 28 70 2c 20 70 2d 3e 6e  pandEdit(p, p->n
32d0: 45 64 69 74 2b 33 29 3b 0a 20 20 69 66 28 20 70  Edit+3);.  if( p
32e0: 2d 3e 61 45 64 69 74 20 29 7b 0a 20 20 20 20 70  ->aEdit ){.    p
32f0: 2d 3e 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74  ->aEdit[p->nEdit
3300: 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e  ++] = 0;.    p->
3310: 61 45 64 69 74 5b 70 2d 3e 6e 45 64 69 74 2b 2b  aEdit[p->nEdit++
3320: 5d 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 61 45  ] = 0;.    p->aE
3330: 64 69 74 5b 70 2d 3e 6e 45 64 69 74 2b 2b 5d 20  dit[p->nEdit++] 
3340: 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  = 0;.  }.}../*.*
3350: 2a 20 47 65 6e 65 72 61 74 65 20 61 20 72 65 70  * Generate a rep
3360: 6f 72 74 20 6f 66 20 74 68 65 20 64 69 66 66 65  ort of the diffe
3370: 72 65 6e 63 65 73 20 62 65 74 77 65 65 6e 20 66  rences between f
3380: 69 6c 65 73 20 70 41 20 61 6e 64 20 70 42 2e 0a  iles pA and pB..
3390: 2a 2a 20 49 66 20 70 4f 75 74 20 69 73 20 6e 6f  ** If pOut is no
33a0: 74 20 4e 55 4c 4c 20 74 68 65 6e 20 61 20 75 6e  t NULL then a un
33b0: 69 66 69 65 64 20 64 69 66 66 20 69 73 20 61 70  ified diff is ap
33c0: 70 65 6e 64 65 64 20 74 68 65 72 65 2e 20 20 49  pended there.  I
33d0: 74 0a 2a 2a 20 69 73 20 61 73 73 75 6d 65 64 20  t.** is assumed 
33e0: 74 68 61 74 20 70 4f 75 74 20 68 61 73 20 61 6c  that pOut has al
33f0: 72 65 61 64 79 20 62 65 65 6e 20 69 6e 69 74 69  ready been initi
3400: 61 6c 69 7a 65 64 2e 20 20 49 66 20 70 4f 75 74  alized.  If pOut
3410: 20 69 73 0a 2a 2a 20 4e 55 4c 4c 2c 20 74 68 65   is.** NULL, the
3420: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  n a pointer to a
3430: 6e 20 61 72 72 61 79 20 6f 66 20 69 6e 74 65 67  n array of integ
3440: 65 72 73 20 69 73 20 72 65 74 75 72 6e 65 64 2e  ers is returned.
3450: 20 20 0a 2a 2a 20 54 68 65 20 69 6e 74 65 67 65    .** The intege
3460: 72 73 20 63 6f 6d 65 20 69 6e 20 74 72 69 70 6c  rs come in tripl
3470: 65 73 2e 20 20 46 6f 72 20 65 61 63 68 20 74 72  es.  For each tr
3480: 69 70 6c 65 2c 0a 2a 2a 20 74 68 65 20 65 6c 65  iple,.** the ele
3490: 6d 65 6e 74 73 20 61 72 65 20 74 68 65 20 6e 75  ments are the nu
34a0: 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 63 6f  mber of lines co
34b0: 70 69 65 64 2c 20 74 68 65 20 6e 75 6d 62 65 72  pied, the number
34c0: 20 6f 66 0a 2a 2a 20 6c 69 6e 65 73 20 64 65 6c   of.** lines del
34d0: 65 74 65 64 2c 20 61 6e 64 20 74 68 65 20 6e 75  eted, and the nu
34e0: 6d 62 65 72 20 6f 66 20 6c 69 6e 65 73 20 69 6e  mber of lines in
34f0: 73 65 72 74 65 64 2e 20 20 54 68 65 20 76 65 63  serted.  The vec
3500: 74 6f 72 0a 2a 2a 20 69 73 20 74 65 72 6d 69 6e  tor.** is termin
3510: 61 74 65 64 20 62 79 20 61 20 74 72 69 70 6c 65  ated by a triple
3520: 20 6f 66 20 61 6c 6c 20 7a 65 72 6f 73 2e 0a 2a   of all zeros..*
3530: 2a 0a 2a 2a 20 54 68 69 73 20 64 69 66 66 20 75  *.** This diff u
3540: 74 69 6c 69 74 79 20 64 6f 65 73 20 6e 6f 74 20  tility does not 
3550: 77 6f 72 6b 20 6f 6e 20 62 69 6e 61 72 79 20 66  work on binary f
3560: 69 6c 65 73 2e 20 20 49 66 20 61 20 62 69 6e 61  iles.  If a bina
3570: 72 79 0a 2a 2a 20 66 69 6c 65 20 69 73 20 65 6e  ry.** file is en
3580: 63 6f 75 6e 74 65 72 65 64 2c 20 30 20 69 73 20  countered, 0 is 
3590: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 70 4f 75  returned and pOu
35a0: 74 20 69 73 20 77 72 69 74 74 65 6e 20 77 69 74  t is written wit
35b0: 68 0a 2a 2a 20 74 65 78 74 20 22 63 61 6e 6e 6f  h.** text "canno
35c0: 74 20 63 6f 6d 70 75 74 65 20 64 69 66 66 65 72  t compute differ
35d0: 65 6e 63 65 20 62 65 74 77 65 65 6e 20 62 69 6e  ence between bin
35e0: 61 72 79 20 66 69 6c 65 73 22 2e 0a 2a 2f 0a 69  ary files"..*/.i
35f0: 6e 74 20 2a 74 65 78 74 5f 64 69 66 66 28 0a 20  nt *text_diff(. 
3600: 20 42 6c 6f 62 20 2a 70 41 5f 42 6c 6f 62 2c 20   Blob *pA_Blob, 
3610: 20 20 2f 2a 20 46 52 4f 4d 20 66 69 6c 65 20 2a    /* FROM file *
3620: 2f 0a 20 20 42 6c 6f 62 20 2a 70 42 5f 42 6c 6f  /.  Blob *pB_Blo
3630: 62 2c 20 20 20 2f 2a 20 54 4f 20 66 69 6c 65 20  b,   /* TO file 
3640: 2a 2f 0a 20 20 42 6c 6f 62 20 2a 70 4f 75 74 2c  */.  Blob *pOut,
3650: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 75        /* Write u
3660: 6e 69 66 69 65 64 20 64 69 66 66 20 68 65 72 65  nified diff here
3670: 20 69 66 20 6e 6f 74 20 4e 55 4c 4c 20 2a 2f 0a   if not NULL */.
3680: 20 20 69 6e 74 20 6e 43 6f 6e 74 65 78 74 20 20    int nContext  
3690: 20 20 20 2f 2a 20 41 6d 6f 75 6e 74 20 6f 66 20     /* Amount of 
36a0: 63 6f 6e 74 65 78 74 20 74 6f 20 75 6e 69 66 69  context to unifi
36b0: 65 64 20 64 69 66 66 20 2a 2f 0a 29 7b 0a 20 20  ed diff */.){.  
36c0: 44 43 6f 6e 74 65 78 74 20 63 3b 0a 20 0a 20 20  DContext c;. .  
36d0: 2f 2a 20 50 72 65 70 61 72 65 20 74 68 65 20 69  /* Prepare the i
36e0: 6e 70 75 74 20 66 69 6c 65 73 20 2a 2f 0a 20 20  nput files */.  
36f0: 6d 65 6d 73 65 74 28 26 63 2c 20 30 2c 20 73 69  memset(&c, 0, si
3700: 7a 65 6f 66 28 63 29 29 3b 0a 20 20 63 2e 61 46  zeof(c));.  c.aF
3710: 72 6f 6d 20 3d 20 62 72 65 61 6b 5f 69 6e 74 6f  rom = break_into
3720: 5f 6c 69 6e 65 73 28 62 6c 6f 62 5f 73 74 72 28  _lines(blob_str(
3730: 70 41 5f 42 6c 6f 62 29 2c 20 62 6c 6f 62 5f 73  pA_Blob), blob_s
3740: 69 7a 65 28 70 41 5f 42 6c 6f 62 29 2c 20 26 63  ize(pA_Blob), &c
3750: 2e 6e 46 72 6f 6d 29 3b 0a 20 20 63 2e 61 54 6f  .nFrom);.  c.aTo
3760: 20 3d 20 62 72 65 61 6b 5f 69 6e 74 6f 5f 6c 69   = break_into_li
3770: 6e 65 73 28 62 6c 6f 62 5f 73 74 72 28 70 42 5f  nes(blob_str(pB_
3780: 42 6c 6f 62 29 2c 20 62 6c 6f 62 5f 73 69 7a 65  Blob), blob_size
3790: 28 70 42 5f 42 6c 6f 62 29 2c 20 26 63 2e 6e 54  (pB_Blob), &c.nT
37a0: 6f 29 3b 0a 20 20 69 66 28 20 63 2e 61 46 72 6f  o);.  if( c.aFro
37b0: 6d 3d 3d 30 20 7c 7c 20 63 2e 61 54 6f 3d 3d 30  m==0 || c.aTo==0
37c0: 20 29 7b 0a 20 20 20 20 66 72 65 65 28 63 2e 61   ){.    free(c.a
37d0: 46 72 6f 6d 29 3b 0a 20 20 20 20 66 72 65 65 28  From);.    free(
37e0: 63 2e 61 54 6f 29 3b 0a 20 20 20 20 69 66 28 20  c.aTo);.    if( 
37f0: 70 4f 75 74 20 29 7b 0a 20 20 20 20 20 20 62 6c  pOut ){.      bl
3800: 6f 62 5f 61 70 70 65 6e 64 66 28 70 4f 75 74 2c  ob_appendf(pOut,
3810: 20 22 63 61 6e 6e 6f 74 20 63 6f 6d 70 75 74 65   "cannot compute
3820: 20 64 69 66 66 65 72 65 6e 63 65 20 62 65 74 77   difference betw
3830: 65 65 6e 20 62 69 6e 61 72 79 20 66 69 6c 65 73  een binary files
3840: 5c 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  \n");.    }.    
3850: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20  return 0;.  }.. 
3860: 20 2f 2a 20 43 6f 6d 70 75 74 65 20 74 68 65 20   /* Compute the 
3870: 64 69 66 66 65 72 65 6e 63 65 20 2a 2f 0a 20 20  difference */.  
3880: 64 69 66 66 5f 61 6c 6c 28 26 63 29 3b 0a 0a 20  diff_all(&c);.. 
3890: 20 69 66 28 20 70 4f 75 74 20 29 7b 0a 20 20 20   if( pOut ){.   
38a0: 20 2f 2a 20 43 6f 6d 70 75 74 65 20 61 20 63 6f   /* Compute a co
38b0: 6e 74 65 78 74 20 64 69 66 66 20 69 66 20 72 65  ntext diff if re
38c0: 71 75 65 73 74 65 64 20 2a 2f 0a 20 20 20 20 63  quested */.    c
38d0: 6f 6e 74 65 78 74 44 69 66 66 28 26 63 2c 20 70  ontextDiff(&c, p
38e0: 4f 75 74 2c 20 6e 43 6f 6e 74 65 78 74 29 3b 0a  Out, nContext);.
38f0: 20 20 20 20 66 72 65 65 28 63 2e 61 46 72 6f 6d      free(c.aFrom
3900: 29 3b 0a 20 20 20 20 66 72 65 65 28 63 2e 61 54  );.    free(c.aT
3910: 6f 29 3b 0a 20 20 20 20 66 72 65 65 28 63 2e 61  o);.    free(c.a
3920: 45 64 69 74 29 3b 0a 20 20 20 20 72 65 74 75 72  Edit);.    retur
3930: 6e 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  n 0;.  }else{.  
3940: 20 20 2f 2a 20 49 66 20 61 20 63 6f 6e 74 65 78    /* If a contex
3950: 74 20 64 69 66 66 20 69 73 20 6e 6f 74 20 72 65  t diff is not re
3960: 71 75 65 73 74 65 64 2c 20 74 68 65 6e 20 72 65  quested, then re
3970: 74 75 72 6e 20 74 68 65 0a 20 20 20 20 2a 2a 20  turn the.    ** 
3980: 61 72 72 61 79 20 6f 66 20 43 4f 50 59 2f 44 45  array of COPY/DE
3990: 4c 45 54 45 2f 49 4e 53 45 52 54 20 74 72 69 70  LETE/INSERT trip
39a0: 6c 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  les..    */.    
39b0: 66 72 65 65 28 63 2e 61 46 72 6f 6d 29 3b 0a 20  free(c.aFrom);. 
39c0: 20 20 20 66 72 65 65 28 63 2e 61 54 6f 29 3b 0a     free(c.aTo);.
39d0: 20 20 20 20 72 65 74 75 72 6e 20 63 2e 61 45 64      return c.aEd
39e0: 69 74 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  it;.  }.}../*.**
39f0: 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 72   COMMAND: test-r
3a00: 61 77 64 69 66 66 0a 2a 2f 0a 76 6f 69 64 20 74  awdiff.*/.void t
3a10: 65 73 74 5f 72 61 77 64 69 66 66 5f 63 6d 64 28  est_rawdiff_cmd(
3a20: 76 6f 69 64 29 7b 0a 20 20 42 6c 6f 62 20 61 2c  void){.  Blob a,
3a30: 20 62 3b 0a 20 20 69 6e 74 20 72 3b 0a 20 20 69   b;.  int r;.  i
3a40: 6e 74 20 69 3b 0a 20 20 69 6e 74 20 2a 52 3b 0a  nt i;.  int *R;.
3a50: 20 20 69 66 28 20 67 2e 61 72 67 63 3c 34 20 29    if( g.argc<4 )
3a60: 20 75 73 61 67 65 28 22 46 49 4c 45 31 20 46 49   usage("FILE1 FI
3a70: 4c 45 32 20 2e 2e 2e 22 29 3b 0a 20 20 62 6c 6f  LE2 ...");.  blo
3a80: 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65  b_read_from_file
3a90: 28 26 61 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b  (&a, g.argv[2]);
3aa0: 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c 67 2e  .  for(i=3; i<g.
3ab0: 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  argc; i++){.    
3ac0: 69 66 28 20 69 3e 33 20 29 20 70 72 69 6e 74 66  if( i>3 ) printf
3ad0: 28 22 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ("--------------
3ae0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3af0: 2d 5c 6e 22 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  -\n");.    blob_
3b00: 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26  read_from_file(&
3b10: 62 2c 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20  b, g.argv[i]);. 
3b20: 20 20 20 52 20 3d 20 74 65 78 74 5f 64 69 66 66     R = text_diff
3b30: 28 26 61 2c 20 26 62 2c 20 30 2c 20 30 29 3b 0a  (&a, &b, 0, 0);.
3b40: 20 20 20 20 66 6f 72 28 72 3d 30 3b 20 52 5b 72      for(r=0; R[r
3b50: 5d 20 7c 7c 20 52 5b 72 2b 31 5d 20 7c 7c 20 52  ] || R[r+1] || R
3b60: 5b 72 2b 32 5d 3b 20 72 20 2b 3d 20 33 29 7b 0a  [r+2]; r += 3){.
3b70: 20 20 20 20 20 20 70 72 69 6e 74 66 28 22 20 63        printf(" c
3b80: 6f 70 79 20 25 34 64 20 20 64 65 6c 65 74 65 20  opy %4d  delete 
3b90: 25 34 64 20 20 69 6e 73 65 72 74 20 25 34 64 5c  %4d  insert %4d\
3ba0: 6e 22 2c 20 52 5b 72 5d 2c 20 52 5b 72 2b 31 5d  n", R[r], R[r+1]
3bb0: 2c 20 52 5b 72 2b 32 5d 29 3b 0a 20 20 20 20 7d  , R[r+2]);.    }
3bc0: 0a 20 20 20 20 2f 2a 20 66 72 65 65 28 52 29 3b  .    /* free(R);
3bd0: 20 2a 2f 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73   */.    blob_res
3be0: 65 74 28 26 62 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  et(&b);.  }.}../
3bf0: 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65  *.** COMMAND: te
3c00: 73 74 2d 75 64 69 66 66 0a 2a 2f 0a 76 6f 69 64  st-udiff.*/.void
3c10: 20 74 65 73 74 5f 75 64 69 66 66 5f 63 6d 64 28   test_udiff_cmd(
3c20: 76 6f 69 64 29 7b 0a 20 20 42 6c 6f 62 20 61 2c  void){.  Blob a,
3c30: 20 62 2c 20 6f 75 74 3b 0a 20 20 69 66 28 20 67   b, out;.  if( g
3c40: 2e 61 72 67 63 21 3d 34 20 29 20 75 73 61 67 65  .argc!=4 ) usage
3c50: 28 22 46 49 4c 45 31 20 46 49 4c 45 32 22 29 3b  ("FILE1 FILE2");
3c60: 0a 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f  .  blob_read_fro
3c70: 6d 5f 66 69 6c 65 28 26 61 2c 20 67 2e 61 72 67  m_file(&a, g.arg
3c80: 76 5b 32 5d 29 3b 0a 20 20 62 6c 6f 62 5f 72 65  v[2]);.  blob_re
3c90: 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 62 2c  ad_from_file(&b,
3ca0: 20 67 2e 61 72 67 76 5b 33 5d 29 3b 0a 20 20 62   g.argv[3]);.  b
3cb0: 6c 6f 62 5f 7a 65 72 6f 28 26 6f 75 74 29 3b 0a  lob_zero(&out);.
3cc0: 20 20 74 65 78 74 5f 64 69 66 66 28 26 61 2c 20    text_diff(&a, 
3cd0: 26 62 2c 20 26 6f 75 74 2c 20 33 29 3b 0a 20 20  &b, &out, 3);.  
3ce0: 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f 66 69  blob_write_to_fi
3cf0: 6c 65 28 26 6f 75 74 2c 20 22 2d 22 29 3b 0a 7d  le(&out, "-");.}
3d00: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
3d10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a  *************.**
3d50: 20 54 68 65 20 62 61 73 69 63 20 64 69 66 66 65   The basic diffe
3d60: 72 65 6e 63 65 20 65 6e 67 69 6e 65 20 69 73 20  rence engine is 
3d70: 61 62 6f 76 65 2e 20 20 57 68 61 74 20 66 6f 6c  above.  What fol
3d80: 6c 6f 77 73 20 69 73 20 74 68 65 20 61 6e 6e 6f  lows is the anno
3d90: 74 61 74 69 6f 6e 0a 2a 2a 20 65 6e 67 69 6e 65  tation.** engine
3da0: 2e 20 20 42 6f 74 68 20 61 72 65 20 69 6e 20 74  .  Both are in t
3db0: 68 65 20 73 61 6d 65 20 66 69 6c 65 20 73 69 6e  he same file sin
3dc0: 63 65 20 74 68 65 79 20 73 68 61 72 65 20 6d 61  ce they share ma
3dd0: 6e 79 20 63 6f 6d 70 6f 6e 65 6e 74 73 2e 0a 2a  ny components..*
3de0: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 73 74 61  /../*.** The sta
3df0: 74 75 73 20 6f 66 20 61 6e 20 61 6e 6e 6f 74 61  tus of an annota
3e00: 74 69 6f 6e 20 6f 70 65 72 61 74 69 6f 6e 20 69  tion operation i
3e10: 73 20 72 65 63 6f 72 64 65 64 20 62 79 20 61 6e  s recorded by an
3e20: 20 69 6e 73 74 61 6e 63 65 0a 2a 2a 20 6f 66 20   instance.** of 
3e30: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74  the following st
3e40: 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65  ructure..*/.type
3e50: 64 65 66 20 73 74 72 75 63 74 20 41 6e 6e 6f 74  def struct Annot
3e60: 61 74 6f 72 20 41 6e 6e 6f 74 61 74 6f 72 3b 0a  ator Annotator;.
3e70: 73 74 72 75 63 74 20 41 6e 6e 6f 74 61 74 6f 72  struct Annotator
3e80: 20 7b 0a 20 20 44 43 6f 6e 74 65 78 74 20 63 3b   {.  DContext c;
3e90: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 64 69         /* The di
3ea0: 66 66 2d 65 6e 67 69 6e 65 20 63 6f 6e 74 65 78  ff-engine contex
3eb0: 74 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 7b 20  t */.  struct { 
3ec0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 65           /* Line
3ed0: 73 20 6f 66 20 74 68 65 20 6f 72 69 67 69 6e 61  s of the origina
3ee0: 6c 20 66 69 6c 65 73 2e 2e 2e 20 2a 2f 0a 20 20  l files... */.  
3ef0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b    const char *z;
3f00: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74 65         /* The te
3f10: 78 74 20 6f 66 20 74 68 65 20 6c 69 6e 65 20 2a  xt of the line *
3f20: 2f 0a 20 20 20 20 69 6e 74 20 6e 3b 20 20 20 20  /.    int n;    
3f30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
3f40: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 28 6f  mber of bytes (o
3f50: 6d 69 74 74 69 6e 67 20 74 72 61 69 6c 69 6e 67  mitting trailing
3f60: 20 73 70 61 63 65 20 61 6e 64 20 5c 6e 29 20 2a   space and \n) *
3f70: 2f 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  /.    const char
3f80: 20 2a 7a 53 72 63 3b 20 20 20 20 2f 2a 20 54 61   *zSrc;    /* Ta
3f90: 67 20 73 68 6f 77 69 6e 67 20 6f 72 69 67 69 6e  g showing origin
3fa0: 20 6f 66 20 74 68 69 73 20 6c 69 6e 65 20 2a 2f   of this line */
3fb0: 0a 20 20 7d 20 2a 61 4f 72 69 67 3b 0a 20 20 69  .  } *aOrig;.  i
3fc0: 6e 74 20 6e 4f 72 69 67 3b 20 20 20 20 20 20 20  nt nOrig;       
3fd0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c   /* Number of el
3fe0: 65 6d 65 6e 74 73 20 69 6e 20 61 4f 72 69 67 5b  ements in aOrig[
3ff0: 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 6f 53 72  ] */.  int nNoSr
4000: 63 3b 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62  c;       /* Numb
4010: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 77 68  er of entries wh
4020: 65 72 65 20 61 4f 72 69 67 5b 5d 2e 7a 53 72 63  ere aOrig[].zSrc
4030: 3d 3d 4e 55 4c 4c 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  ==NULL */.};../*
4040: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74  .** Initialize t
4050: 68 65 20 61 6e 6e 6f 74 61 74 69 6f 6e 20 70 72  he annotation pr
4060: 6f 63 65 73 73 20 62 79 20 73 70 65 63 69 66 79  ocess by specify
4070: 69 6e 67 20 74 68 65 20 66 69 6c 65 20 74 68 61  ing the file tha
4080: 74 20 69 73 0a 2a 2a 20 74 6f 20 62 65 20 61 6e  t is.** to be an
4090: 6e 6f 74 61 74 65 64 2e 20 20 54 68 65 20 61 6e  notated.  The an
40a0: 6e 6f 74 61 74 6f 72 20 74 61 6b 65 73 20 63 6f  notator takes co
40b0: 6e 74 72 6f 6c 20 6f 66 20 74 68 65 20 69 6e 70  ntrol of the inp
40c0: 75 74 20 42 6c 6f 62 20 61 6e 64 0a 2a 2a 20 77  ut Blob and.** w
40d0: 69 6c 6c 20 72 65 6c 65 61 73 65 20 69 74 20 77  ill release it w
40e0: 68 65 6e 20 69 74 20 69 73 20 66 69 6e 69 73 68  hen it is finish
40f0: 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f 0a 73  ed with it..*/.s
4100: 74 61 74 69 63 20 69 6e 74 20 61 6e 6e 6f 74 61  tatic int annota
4110: 74 69 6f 6e 5f 73 74 61 72 74 28 41 6e 6e 6f 74  tion_start(Annot
4120: 61 74 6f 72 20 2a 70 2c 20 42 6c 6f 62 20 2a 70  ator *p, Blob *p
4130: 49 6e 70 75 74 29 7b 0a 20 20 69 6e 74 20 69 3b  Input){.  int i;
4140: 0a 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c  ..  memset(p, 0,
4150: 20 73 69 7a 65 6f 66 28 2a 70 29 29 3b 0a 20 20   sizeof(*p));.  
4160: 70 2d 3e 63 2e 61 54 6f 20 3d 20 62 72 65 61 6b  p->c.aTo = break
4170: 5f 69 6e 74 6f 5f 6c 69 6e 65 73 28 62 6c 6f 62  _into_lines(blob
4180: 5f 73 74 72 28 70 49 6e 70 75 74 29 2c 20 62 6c  _str(pInput), bl
4190: 6f 62 5f 73 69 7a 65 28 70 49 6e 70 75 74 29 2c  ob_size(pInput),
41a0: 20 26 70 2d 3e 63 2e 6e 54 6f 29 3b 0a 20 20 69   &p->c.nTo);.  i
41b0: 66 28 20 70 2d 3e 63 2e 61 54 6f 3d 3d 30 20 29  f( p->c.aTo==0 )
41c0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a  {.    return 1;.
41d0: 20 20 7d 0a 20 20 70 2d 3e 61 4f 72 69 67 20 3d    }.  p->aOrig =
41e0: 20 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28   malloc( sizeof(
41f0: 70 2d 3e 61 4f 72 69 67 5b 30 5d 29 2a 70 2d 3e  p->aOrig[0])*p->
4200: 63 2e 6e 54 6f 20 29 3b 0a 20 20 69 66 28 20 70  c.nTo );.  if( p
4210: 2d 3e 61 4f 72 69 67 3d 3d 30 20 29 20 66 6f 73  ->aOrig==0 ) fos
4220: 73 69 6c 5f 70 61 6e 69 63 28 22 6f 75 74 20 6f  sil_panic("out o
4230: 66 20 6d 65 6d 6f 72 79 22 29 3b 0a 20 20 66 6f  f memory");.  fo
4240: 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 63 2e 6e 54  r(i=0; i<p->c.nT
4250: 6f 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 2d 3e  o; i++){.    p->
4260: 61 4f 72 69 67 5b 69 5d 2e 7a 20 3d 20 70 2d 3e  aOrig[i].z = p->
4270: 63 2e 61 54 6f 5b 69 5d 2e 7a 3b 0a 20 20 20 20  c.aTo[i].z;.    
4280: 70 2d 3e 61 4f 72 69 67 5b 69 5d 2e 6e 20 3d 20  p->aOrig[i].n = 
4290: 70 2d 3e 63 2e 61 54 6f 5b 69 5d 2e 68 20 26 20  p->c.aTo[i].h & 
42a0: 4c 45 4e 47 54 48 5f 4d 41 53 4b 3b 0a 20 20 20  LENGTH_MASK;.   
42b0: 20 70 2d 3e 61 4f 72 69 67 5b 69 5d 2e 7a 53 72   p->aOrig[i].zSr
42c0: 63 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 2d 3e  c = 0;.  }.  p->
42d0: 6e 4f 72 69 67 20 3d 20 70 2d 3e 63 2e 6e 54 6f  nOrig = p->c.nTo
42e0: 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ;.  return 0;.}.
42f0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74  ./*.** The input
4300: 20 70 50 61 72 65 6e 74 20 69 73 20 74 68 65 20   pParent is the 
4310: 6e 65 78 74 20 6d 6f 73 74 20 72 65 63 65 6e 74  next most recent
4320: 20 61 6e 63 65 73 74 6f 72 20 6f 66 20 74 68 65   ancestor of the
4330: 20 66 69 6c 65 0a 2a 2a 20 62 65 69 6e 67 20 61   file.** being a
4340: 6e 6e 6f 74 61 74 65 64 2e 20 20 44 6f 20 61 6e  nnotated.  Do an
4350: 6f 74 68 65 72 20 73 74 65 70 20 6f 66 20 74 68  other step of th
4360: 65 20 61 6e 6e 6f 74 61 74 69 6f 6e 2e 20 20 52  e annotation.  R
4370: 65 74 75 72 6e 20 74 72 75 65 0a 2a 2a 20 69 66  eturn true.** if
4380: 20 61 64 64 69 74 69 6f 6e 61 6c 20 61 6e 6e 6f   additional anno
4390: 74 61 74 69 6f 6e 20 69 73 20 72 65 71 75 69 72  tation is requir
43a0: 65 64 2e 20 20 7a 50 4e 61 6d 65 20 69 73 20 74  ed.  zPName is t
43b0: 68 65 20 74 61 67 20 74 6f 20 69 6e 73 65 72 74  he tag to insert
43c0: 0a 2a 2a 20 6f 6e 20 65 61 63 68 20 6c 69 6e 65  .** on each line
43d0: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 62 65 69   of the file bei
43e0: 6e 67 20 61 6e 6e 6f 74 61 74 65 64 20 74 68 61  ng annotated tha
43f0: 74 20 77 61 73 20 63 6f 6e 74 72 69 62 75 74 65  t was contribute
4400: 64 20 62 79 0a 2a 2a 20 70 50 61 72 65 6e 74 2e  d by.** pParent.
4410: 20 20 4d 65 6d 6f 72 79 20 74 6f 20 68 6f 6c 64    Memory to hold
4420: 20 7a 50 4e 61 6d 65 20 69 73 20 6c 65 61 6b 65   zPName is leake
4430: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
4440: 20 61 6e 6e 6f 74 61 74 69 6f 6e 5f 73 74 65 70   annotation_step
4450: 28 41 6e 6e 6f 74 61 74 6f 72 20 2a 70 2c 20 42  (Annotator *p, B
4460: 6c 6f 62 20 2a 70 50 61 72 65 6e 74 2c 20 63 68  lob *pParent, ch
4470: 61 72 20 2a 7a 50 4e 61 6d 65 29 7b 0a 20 20 69  ar *zPName){.  i
4480: 6e 74 20 69 2c 20 6a 3b 0a 20 20 69 6e 74 20 6c  nt i, j;.  int l
4490: 6e 54 6f 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61  nTo;..  /* Prepa
44a0: 72 65 20 74 68 65 20 70 61 72 65 6e 74 20 66 69  re the parent fi
44b0: 6c 65 20 74 6f 20 62 65 20 64 69 66 66 65 64 20  le to be diffed 
44c0: 2a 2f 0a 20 20 70 2d 3e 63 2e 61 46 72 6f 6d 20  */.  p->c.aFrom 
44d0: 3d 20 62 72 65 61 6b 5f 69 6e 74 6f 5f 6c 69 6e  = break_into_lin
44e0: 65 73 28 62 6c 6f 62 5f 73 74 72 28 70 50 61 72  es(blob_str(pPar
44f0: 65 6e 74 29 2c 20 62 6c 6f 62 5f 73 69 7a 65 28  ent), blob_size(
4500: 70 50 61 72 65 6e 74 29 2c 0a 20 20 20 20 20 20  pParent),.      
4510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4520: 20 20 20 20 20 20 20 20 20 20 26 70 2d 3e 63 2e            &p->c.
4530: 6e 46 72 6f 6d 29 3b 0a 20 20 69 66 28 20 70 2d  nFrom);.  if( p-
4540: 3e 63 2e 61 46 72 6f 6d 3d 3d 30 20 29 7b 0a 20  >c.aFrom==0 ){. 
4550: 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d     return 1;.  }
4560: 0a 0a 20 20 2f 2a 20 43 6f 6d 70 75 74 65 20 74  ..  /* Compute t
4570: 68 65 20 64 69 66 66 65 72 65 6e 63 65 73 20 67  he differences g
4580: 6f 69 6e 67 20 66 72 6f 6d 20 70 50 61 72 65 6e  oing from pParen
4590: 74 20 74 6f 20 74 68 65 20 66 69 6c 65 20 62 65  t to the file be
45a0: 69 6e 67 0a 20 20 2a 2a 20 61 6e 6e 6f 74 61 74  ing.  ** annotat
45b0: 65 64 2e 20 2a 2f 0a 20 20 64 69 66 66 5f 61 6c  ed. */.  diff_al
45c0: 6c 28 26 70 2d 3e 63 29 3b 0a 0a 20 20 2f 2a 20  l(&p->c);..  /* 
45d0: 57 68 65 72 65 20 6e 65 77 20 6c 69 6e 65 73 20  Where new lines 
45e0: 61 72 65 20 69 6e 73 65 72 74 65 64 20 6f 6e 20  are inserted on 
45f0: 74 68 69 73 20 64 69 66 66 65 72 65 6e 63 65 2c  this difference,
4600: 20 72 65 63 6f 72 64 20 74 68 65 0a 20 20 2a 2a   record the.  **
4610: 20 7a 50 4e 61 6d 65 20 61 73 20 74 68 65 20 73   zPName as the s
4620: 6f 75 72 63 65 20 6f 66 20 74 68 65 20 6e 65 77  ource of the new
4630: 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 66 6f   line..  */.  fo
4640: 72 28 69 3d 6c 6e 54 6f 3d 30 3b 20 69 3c 70 2d  r(i=lnTo=0; i<p-
4650: 3e 63 2e 6e 45 64 69 74 3b 20 69 2b 3d 33 29 7b  >c.nEdit; i+=3){
4660: 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c  .    for(j=0; j<
4670: 70 2d 3e 63 2e 61 45 64 69 74 5b 69 5d 3b 20 6a  p->c.aEdit[i]; j
4680: 2b 2b 2c 20 6c 6e 54 6f 2b 2b 29 7b 0a 20 20 20  ++, lnTo++){.   
4690: 20 20 20 70 2d 3e 61 4f 72 69 67 5b 6c 6e 54 6f     p->aOrig[lnTo
46a0: 5d 2e 7a 53 72 63 20 3d 20 7a 50 4e 61 6d 65 3b  ].zSrc = zPName;
46b0: 0a 20 20 20 20 7d 0a 20 20 20 20 6c 6e 54 6f 20  .    }.    lnTo 
46c0: 2b 3d 20 70 2d 3e 63 2e 61 45 64 69 74 5b 69 2b  += p->c.aEdit[i+
46d0: 32 5d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6c  2];.  }..  /* Cl
46e0: 65 61 72 20 6f 75 74 20 74 68 65 20 64 69 66 66  ear out the diff
46f0: 20 72 65 73 75 6c 74 73 20 2a 2f 0a 20 20 66 72   results */.  fr
4700: 65 65 28 70 2d 3e 63 2e 61 45 64 69 74 29 3b 0a  ee(p->c.aEdit);.
4710: 20 20 70 2d 3e 63 2e 61 45 64 69 74 20 3d 20 30    p->c.aEdit = 0
4720: 3b 0a 20 20 70 2d 3e 63 2e 6e 45 64 69 74 20 3d  ;.  p->c.nEdit =
4730: 20 30 3b 0a 20 20 70 2d 3e 63 2e 6e 45 64 69 74   0;.  p->c.nEdit
4740: 41 6c 6c 6f 63 20 3d 20 30 3b 0a 0a 20 20 2f 2a  Alloc = 0;..  /*
4750: 20 43 6c 65 61 72 20 6f 75 74 20 74 68 65 20 66   Clear out the f
4760: 72 6f 6d 20 66 69 6c 65 20 2a 2f 0a 20 20 66 72  rom file */.  fr
4770: 65 65 28 70 2d 3e 63 2e 61 46 72 6f 6d 29 3b 20  ee(p->c.aFrom); 
4780: 20 20 20 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28     .  blob_zero(
4790: 70 50 61 72 65 6e 74 29 3b 0a 0a 20 20 2f 2a 20  pParent);..  /* 
47a0: 52 65 74 75 72 6e 20 6e 6f 20 65 72 72 6f 72 73  Return no errors
47b0: 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a   */.  return 0;.
47c0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e  }.../*.** COMMAN
47d0: 44 3a 20 74 65 73 74 2d 61 6e 6e 6f 74 61 74 65  D: test-annotate
47e0: 2d 73 74 65 70 0a 2a 2f 0a 76 6f 69 64 20 74 65  -step.*/.void te
47f0: 73 74 5f 61 6e 6e 6f 74 61 74 65 5f 73 74 65 70  st_annotate_step
4800: 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20 42 6c  _cmd(void){.  Bl
4810: 6f 62 20 6f 72 69 67 2c 20 62 3b 0a 20 20 41 6e  ob orig, b;.  An
4820: 6e 6f 74 61 74 6f 72 20 78 3b 0a 20 20 69 6e 74  notator x;.  int
4830: 20 69 3b 0a 0a 20 20 69 66 28 20 67 2e 61 72 67   i;..  if( g.arg
4840: 63 3c 34 20 29 20 75 73 61 67 65 28 22 52 49 44  c<4 ) usage("RID
4850: 31 20 52 49 44 32 20 2e 2e 2e 22 29 3b 0a 20 20  1 RID2 ...");.  
4860: 64 62 5f 6d 75 73 74 5f 62 65 5f 77 69 74 68 69  db_must_be_withi
4870: 6e 5f 74 72 65 65 28 29 3b 0a 20 20 62 6c 6f 62  n_tree();.  blob
4880: 5f 7a 65 72 6f 28 26 62 29 3b 0a 20 20 63 6f 6e  _zero(&b);.  con
4890: 74 65 6e 74 5f 67 65 74 28 6e 61 6d 65 5f 74 6f  tent_get(name_to
48a0: 5f 72 69 64 28 67 2e 61 72 67 76 5b 32 5d 29 2c  _rid(g.argv[2]),
48b0: 20 26 6f 72 69 67 29 3b 0a 20 20 69 66 28 20 61   &orig);.  if( a
48c0: 6e 6e 6f 74 61 74 69 6f 6e 5f 73 74 61 72 74 28  nnotation_start(
48d0: 26 78 2c 20 26 6f 72 69 67 29 20 29 7b 0a 20 20  &x, &orig) ){.  
48e0: 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22    fossil_fatal("
48f0: 62 69 6e 61 72 79 20 66 69 6c 65 22 29 3b 0a 20  binary file");. 
4900: 20 7d 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c   }.  for(i=3; i<
4910: 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  g.argc; i++){.  
4920: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 62 29 3b    blob_zero(&b);
4930: 0a 20 20 20 20 63 6f 6e 74 65 6e 74 5f 67 65 74  .    content_get
4940: 28 6e 61 6d 65 5f 74 6f 5f 72 69 64 28 67 2e 61  (name_to_rid(g.a
4950: 72 67 76 5b 69 5d 29 2c 20 26 62 29 3b 0a 20 20  rgv[i]), &b);.  
4960: 20 20 69 66 28 20 61 6e 6e 6f 74 61 74 69 6f 6e    if( annotation
4970: 5f 73 74 65 70 28 26 78 2c 20 26 62 2c 20 67 2e  _step(&x, &b, g.
4980: 61 72 67 76 5b 69 2d 31 5d 29 20 29 7b 0a 20 20  argv[i-1]) ){.  
4990: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c      fossil_fatal
49a0: 28 22 62 69 6e 61 72 79 20 66 69 6c 65 22 29 3b  ("binary file");
49b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 6f 72  .    }.  }.  for
49c0: 28 69 3d 30 3b 20 69 3c 78 2e 6e 4f 72 69 67 3b  (i=0; i<x.nOrig;
49d0: 20 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74   i++){.    const
49e0: 20 63 68 61 72 20 2a 7a 53 72 63 20 3d 20 78 2e   char *zSrc = x.
49f0: 61 4f 72 69 67 5b 69 5d 2e 7a 53 72 63 3b 0a 20  aOrig[i].zSrc;. 
4a00: 20 20 20 69 66 28 20 7a 53 72 63 3d 3d 30 20 29     if( zSrc==0 )
4a10: 20 7a 53 72 63 20 3d 20 67 2e 61 72 67 76 5b 67   zSrc = g.argv[g
4a20: 2e 61 72 67 63 2d 31 5d 3b 0a 20 20 20 20 70 72  .argc-1];.    pr
4a30: 69 6e 74 66 28 22 25 31 30 73 3a 20 25 2e 2a 73  intf("%10s: %.*s
4a40: 5c 6e 22 2c 20 7a 53 72 63 2c 20 78 2e 61 4f 72  \n", zSrc, x.aOr
4a50: 69 67 5b 69 5d 2e 6e 2c 20 78 2e 61 4f 72 69 67  ig[i].n, x.aOrig
4a60: 5b 69 5d 2e 7a 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  [i].z);.  }.}../
4a70: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 63  *.** Compute a c
4a80: 6f 6d 70 6c 65 74 65 20 61 6e 6e 6f 74 61 74 69  omplete annotati
4a90: 6f 6e 20 6f 6e 20 61 20 66 69 6c 65 2e 20 20 54  on on a file.  T
4aa0: 68 65 20 66 69 6c 65 20 69 73 20 69 64 65 6e 74  he file is ident
4ab0: 69 66 69 65 64 0a 2a 2a 20 62 79 20 69 74 73 20  ified.** by its 
4ac0: 66 69 6c 65 6e 61 6d 65 20 6e 75 6d 62 65 72 20  filename number 
4ad0: 28 66 69 6c 65 6e 61 6d 65 2e 66 6e 69 64 29 20  (filename.fnid) 
4ae0: 61 6e 64 20 74 68 65 20 62 61 73 65 6c 69 6e 65  and the baseline
4af0: 20 69 6e 20 77 68 69 63 68 0a 2a 2a 20 69 74 20   in which.** it 
4b00: 77 61 73 20 63 68 65 63 6b 65 64 20 69 6e 20 28  was checked in (
4b10: 6d 6c 69 6e 6b 2e 6d 69 64 29 2e 0a 2a 2f 0a 73  mlink.mid)..*/.s
4b20: 74 61 74 69 63 20 76 6f 69 64 20 61 6e 6e 6f 74  tatic void annot
4b30: 61 74 65 5f 66 69 6c 65 28 41 6e 6e 6f 74 61 74  ate_file(Annotat
4b40: 6f 72 20 2a 70 2c 20 69 6e 74 20 66 6e 69 64 2c  or *p, int fnid,
4b50: 20 69 6e 74 20 6d 69 64 2c 20 69 6e 74 20 77 65   int mid, int we
4b60: 62 4c 61 62 65 6c 29 7b 0a 20 20 42 6c 6f 62 20  bLabel){.  Blob 
4b70: 74 6f 41 6e 6e 6f 74 61 74 65 3b 20 20 20 20 20  toAnnotate;     
4b80: 2f 2a 20 54 65 78 74 20 6f 66 20 74 68 65 20 66  /* Text of the f
4b90: 69 6e 61 6c 20 76 65 72 73 69 6f 6e 20 6f 66 20  inal version of 
4ba0: 74 68 65 20 66 69 6c 65 20 2a 2f 0a 20 20 42 6c  the file */.  Bl
4bb0: 6f 62 20 73 74 65 70 3b 20 20 20 20 20 20 20 20  ob step;        
4bc0: 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 70 72     /* Text of pr
4bd0: 65 76 69 6f 75 73 20 72 65 76 69 73 69 6f 6e 20  evious revision 
4be0: 2a 2f 0a 20 20 69 6e 74 20 72 69 64 3b 20 20 20  */.  int rid;   
4bf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 74            /* Art
4c00: 69 66 61 63 74 20 49 44 20 6f 66 20 74 68 65 20  ifact ID of the 
4c10: 66 69 6c 65 20 62 65 69 6e 67 20 61 6e 6e 6f 74  file being annot
4c20: 61 74 65 64 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ated */.  char *
4c30: 7a 4c 61 62 65 6c 3b 20 20 20 20 20 20 20 20 2f  zLabel;        /
4c40: 2a 20 4c 61 62 65 6c 20 74 6f 20 61 70 70 6c 79  * Label to apply
4c50: 20 74 6f 20 61 20 6c 69 6e 65 20 2a 2f 0a 20 20   to a line */.  
4c60: 53 74 6d 74 20 71 3b 20 20 20 20 20 20 20 20 20  Stmt q;         
4c70: 20 20 20 20 20 2f 2a 20 51 75 65 72 79 20 72 65       /* Query re
4c80: 74 75 72 6e 69 6e 67 20 61 6c 6c 20 61 6e 63 65  turning all ance
4c90: 73 74 6f 72 20 76 65 72 73 69 6f 6e 73 20 2a 2f  stor versions */
4ca0: 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a  ..  /* Initializ
4cb0: 65 20 74 68 65 20 61 6e 6e 6f 74 61 74 69 6f 6e  e the annotation
4cc0: 20 2a 2f 0a 20 20 72 69 64 20 3d 20 64 62 5f 69   */.  rid = db_i
4cd0: 6e 74 28 30 2c 20 22 53 45 4c 45 43 54 20 66 69  nt(0, "SELECT fi
4ce0: 64 20 46 52 4f 4d 20 6d 6c 69 6e 6b 20 57 48 45  d FROM mlink WHE
4cf0: 52 45 20 6d 69 64 3d 25 64 20 41 4e 44 20 66 6e  RE mid=%d AND fn
4d00: 69 64 3d 25 64 22 2c 6d 69 64 2c 66 6e 69 64 29  id=%d",mid,fnid)
4d10: 3b 0a 20 20 69 66 28 20 72 69 64 3d 3d 30 20 29  ;.  if( rid==0 )
4d20: 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e  {.    fossil_pan
4d30: 69 63 28 22 66 69 6c 65 20 23 25 64 20 69 73 20  ic("file #%d is 
4d40: 75 6e 63 68 61 6e 67 65 64 20 69 6e 20 6d 61 6e  unchanged in man
4d50: 69 66 65 73 74 20 23 25 64 22 2c 20 66 6e 69 64  ifest #%d", fnid
4d60: 2c 20 6d 69 64 29 3b 0a 20 20 7d 0a 20 20 69 66  , mid);.  }.  if
4d70: 28 20 21 63 6f 6e 74 65 6e 74 5f 67 65 74 28 72  ( !content_get(r
4d80: 69 64 2c 20 26 74 6f 41 6e 6e 6f 74 61 74 65 29  id, &toAnnotate)
4d90: 20 29 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70   ){.    fossil_p
4da0: 61 6e 69 63 28 22 75 6e 61 62 6c 65 20 74 6f 20  anic("unable to 
4db0: 72 65 74 72 69 65 76 65 20 63 6f 6e 74 65 6e 74  retrieve content
4dc0: 20 6f 66 20 61 72 74 69 66 61 63 74 20 23 25 64   of artifact #%d
4dd0: 22 2c 20 72 69 64 29 3b 0a 20 20 7d 0a 20 20 64  ", rid);.  }.  d
4de0: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 22 43 52  b_multi_exec("CR
4df0: 45 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45 20  EATE TEMP TABLE 
4e00: 6f 6b 28 72 69 64 20 49 4e 54 45 47 45 52 20 50  ok(rid INTEGER P
4e10: 52 49 4d 41 52 59 20 4b 45 59 29 22 29 3b 0a 20  RIMARY KEY)");. 
4e20: 20 63 6f 6d 70 75 74 65 5f 61 6e 63 65 73 74 6f   compute_ancesto
4e30: 72 73 28 6d 69 64 2c 20 31 30 30 30 30 30 30 30  rs(mid, 10000000
4e40: 30 30 29 3b 0a 20 20 61 6e 6e 6f 74 61 74 69 6f  00);.  annotatio
4e50: 6e 5f 73 74 61 72 74 28 70 2c 20 26 74 6f 41 6e  n_start(p, &toAn
4e60: 6e 6f 74 61 74 65 29 3b 0a 0a 20 20 64 62 5f 70  notate);..  db_p
4e70: 72 65 70 61 72 65 28 26 71 2c 20 0a 20 20 20 20  repare(&q, .    
4e80: 22 53 45 4c 45 43 54 20 6d 6c 69 6e 6b 2e 66 69  "SELECT mlink.fi
4e90: 64 2c 20 62 6c 6f 62 2e 75 75 69 64 2c 20 64 61  d, blob.uuid, da
4ea0: 74 65 28 65 76 65 6e 74 2e 6d 74 69 6d 65 29 2c  te(event.mtime),
4eb0: 20 65 76 65 6e 74 2e 75 73 65 72 20 22 0a 20 20   event.user ".  
4ec0: 20 20 22 20 20 46 52 4f 4d 20 6d 6c 69 6e 6b 2c    "  FROM mlink,
4ed0: 20 62 6c 6f 62 2c 20 65 76 65 6e 74 22 0a 20 20   blob, event".  
4ee0: 20 20 22 20 57 48 45 52 45 20 6d 6c 69 6e 6b 2e    " WHERE mlink.
4ef0: 66 6e 69 64 3d 25 64 22 0a 20 20 20 20 22 20 20  fnid=%d".    "  
4f00: 20 41 4e 44 20 6d 6c 69 6e 6b 2e 6d 69 64 20 49   AND mlink.mid I
4f10: 4e 20 6f 6b 22 0a 20 20 20 20 22 20 20 20 41 4e  N ok".    "   AN
4f20: 44 20 62 6c 6f 62 2e 72 69 64 3d 6d 6c 69 6e 6b  D blob.rid=mlink
4f30: 2e 6d 69 64 22 0a 20 20 20 20 22 20 20 20 41 4e  .mid".    "   AN
4f40: 44 20 65 76 65 6e 74 2e 6f 62 6a 69 64 3d 6d 6c  D event.objid=ml
4f50: 69 6e 6b 2e 6d 69 64 22 0a 20 20 20 20 22 20 4f  ink.mid".    " O
4f60: 52 44 45 52 20 42 59 20 65 76 65 6e 74 2e 6d 74  RDER BY event.mt
4f70: 69 6d 65 20 44 45 53 43 22 2c 0a 20 20 20 20 66  ime DESC",.    f
4f80: 6e 69 64 0a 20 20 29 3b 0a 20 20 77 68 69 6c 65  nid.  );.  while
4f90: 28 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53  ( db_step(&q)==S
4fa0: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
4fb0: 20 69 6e 74 20 70 69 64 20 3d 20 64 62 5f 63 6f   int pid = db_co
4fc0: 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c 20 30 29 3b  lumn_int(&q, 0);
4fd0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
4fe0: 2a 7a 55 75 69 64 20 3d 20 64 62 5f 63 6f 6c 75  *zUuid = db_colu
4ff0: 6d 6e 5f 74 65 78 74 28 26 71 2c 20 31 29 3b 0a  mn_text(&q, 1);.
5000: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
5010: 7a 44 61 74 65 20 3d 20 64 62 5f 63 6f 6c 75 6d  zDate = db_colum
5020: 6e 5f 74 65 78 74 28 26 71 2c 20 32 29 3b 0a 20  n_text(&q, 2);. 
5030: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
5040: 55 73 65 72 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e  User = db_column
5050: 5f 74 65 78 74 28 26 71 2c 20 33 29 3b 0a 20 20  _text(&q, 3);.  
5060: 20 20 69 66 28 20 67 2e 6f 6b 48 69 73 74 6f 72    if( g.okHistor
5070: 79 20 29 7b 0a 20 20 20 20 20 20 7a 4c 61 62 65  y ){.      zLabe
5080: 6c 20 3d 20 6d 70 72 69 6e 74 66 28 22 3c 61 20  l = mprintf("<a 
5090: 68 72 65 66 3d 27 25 73 2f 69 6e 66 6f 2f 25 73  href='%s/info/%s
50a0: 27 3e 25 2e 31 30 73 3c 2f 61 3e 20 25 73 20 25  '>%.10s</a> %s %
50b0: 39 2e 39 73 22 2c 20 0a 20 20 20 20 20 20 20 20  9.9s", .        
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 67                 g
50d0: 2e 7a 42 61 73 65 55 52 4c 2c 20 7a 55 75 69 64  .zBaseURL, zUuid
50e0: 2c 20 7a 55 75 69 64 2c 20 7a 44 61 74 65 2c 20  , zUuid, zDate, 
50f0: 7a 55 73 65 72 29 3b 0a 20 20 20 20 7d 65 6c 73  zUser);.    }els
5100: 65 7b 0a 20 20 20 20 20 20 7a 4c 61 62 65 6c 20  e{.      zLabel 
5110: 3d 20 6d 70 72 69 6e 74 66 28 22 25 2e 31 30 73  = mprintf("%.10s
5120: 20 25 73 20 25 39 2e 39 73 22 2c 20 7a 55 75 69   %s %9.9s", zUui
5130: 64 2c 20 7a 44 61 74 65 2c 20 7a 55 73 65 72 29  d, zDate, zUser)
5140: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 6f 6e 74  ;.    }.    cont
5150: 65 6e 74 5f 67 65 74 28 70 69 64 2c 20 26 73 74  ent_get(pid, &st
5160: 65 70 29 3b 0a 20 20 20 20 61 6e 6e 6f 74 61 74  ep);.    annotat
5170: 69 6f 6e 5f 73 74 65 70 28 70 2c 20 26 73 74 65  ion_step(p, &ste
5180: 70 2c 20 7a 4c 61 62 65 6c 29 3b 0a 20 20 20 20  p, zLabel);.    
5190: 62 6c 6f 62 5f 72 65 73 65 74 28 26 73 74 65 70  blob_reset(&step
51a0: 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 66 69 6e 61  );.  }.  db_fina
51b0: 6c 69 7a 65 28 26 71 29 3b 0a 7d 0a 0a 2f 2a 0a  lize(&q);.}../*.
51c0: 2a 2a 20 57 45 42 50 41 47 45 3a 20 61 6e 6e 6f  ** WEBPAGE: anno
51d0: 74 61 74 65 0a 2a 2a 0a 2a 2a 20 51 75 65 72 79  tate.**.** Query
51e0: 20 70 61 72 61 6d 65 74 65 72 73 3a 0a 2a 2a 0a   parameters:.**.
51f0: 2a 2a 20 20 20 20 6d 69 64 3d 4e 55 4d 20 20 20  **    mid=NUM   
5200: 20 20 20 54 68 65 20 6d 61 6e 69 66 65 73 74 20     The manifest 
5210: 49 44 20 61 74 20 77 68 69 63 68 20 74 6f 20 73  ID at which to s
5220: 74 61 72 74 20 74 68 65 20 61 6e 6e 6f 74 61 74  tart the annotat
5230: 69 6f 6e 0a 2a 2a 20 20 20 20 66 6e 69 64 3d 4e  ion.**    fnid=N
5240: 55 4d 20 20 20 20 20 54 68 65 20 66 69 6c 65 6e  UM     The filen
5250: 61 6d 65 20 49 44 2e 0a 2a 2f 0a 76 6f 69 64 20  ame ID..*/.void 
5260: 61 6e 6e 6f 74 61 74 69 6f 6e 5f 70 61 67 65 28  annotation_page(
5270: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 6d 69 64  void){.  int mid
5280: 20 3d 20 61 74 6f 69 28 50 44 28 22 6d 69 64 22   = atoi(PD("mid"
5290: 2c 22 30 22 29 29 3b 0a 20 20 69 6e 74 20 66 6e  ,"0"));.  int fn
52a0: 69 64 20 3d 20 61 74 6f 69 28 50 44 28 22 66 6e  id = atoi(PD("fn
52b0: 69 64 22 2c 22 30 22 29 29 3b 0a 20 20 69 6e 74  id","0"));.  int
52c0: 20 69 3b 0a 20 20 41 6e 6e 6f 74 61 74 6f 72 20   i;.  Annotator 
52d0: 61 6e 6e 3b 0a 0a 20 20 6c 6f 67 69 6e 5f 63 68  ann;..  login_ch
52e0: 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c 73 28  eck_credentials(
52f0: 29 3b 0a 20 20 69 66 28 20 21 67 2e 6f 6b 52 65  );.  if( !g.okRe
5300: 61 64 20 29 7b 20 6c 6f 67 69 6e 5f 6e 65 65 64  ad ){ login_need
5310: 65 64 28 29 3b 20 72 65 74 75 72 6e 3b 20 7d 0a  ed(); return; }.
5320: 20 20 69 66 28 20 6d 69 64 3d 3d 30 20 7c 7c 20    if( mid==0 || 
5330: 66 6e 69 64 3d 3d 30 20 29 7b 20 66 6f 73 73 69  fnid==0 ){ fossi
5340: 6c 5f 72 65 64 69 72 65 63 74 5f 68 6f 6d 65 28  l_redirect_home(
5350: 29 3b 20 7d 0a 20 20 69 66 28 20 21 64 62 5f 65  ); }.  if( !db_e
5360: 78 69 73 74 73 28 22 53 45 4c 45 43 54 20 31 20  xists("SELECT 1 
5370: 46 52 4f 4d 20 6d 6c 69 6e 6b 20 57 48 45 52 45  FROM mlink WHERE
5380: 20 6d 69 64 3d 25 64 20 41 4e 44 20 66 6e 69 64   mid=%d AND fnid
5390: 3d 25 64 22 2c 6d 69 64 2c 66 6e 69 64 29 20 29  =%d",mid,fnid) )
53a0: 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 72 65 64  {.    fossil_red
53b0: 69 72 65 63 74 5f 68 6f 6d 65 28 29 3b 0a 20 20  irect_home();.  
53c0: 7d 0a 20 20 73 74 79 6c 65 5f 68 65 61 64 65 72  }.  style_header
53d0: 28 22 46 69 6c 65 20 41 6e 6e 6f 74 61 74 69 6f  ("File Annotatio
53e0: 6e 22 29 3b 0a 20 20 61 6e 6e 6f 74 61 74 65 5f  n");.  annotate_
53f0: 66 69 6c 65 28 26 61 6e 6e 2c 20 66 6e 69 64 2c  file(&ann, fnid,
5400: 20 6d 69 64 2c 20 31 29 3b 0a 20 20 40 20 3c 70   mid, 1);.  @ <p
5410: 72 65 3e 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  re>.  for(i=0; i
5420: 3c 61 6e 6e 2e 6e 4f 72 69 67 3b 20 69 2b 2b 29  <ann.nOrig; i++)
5430: 7b 0a 20 20 20 20 28 28 63 68 61 72 2a 29 61 6e  {.    ((char*)an
5440: 6e 2e 61 4f 72 69 67 5b 69 5d 2e 7a 29 5b 61 6e  n.aOrig[i].z)[an
5450: 6e 2e 61 4f 72 69 67 5b 69 5d 2e 6e 5d 20 3d 20  n.aOrig[i].n] = 
5460: 30 3b 0a 20 20 20 20 40 20 25 73 28 61 6e 6e 2e  0;.    @ %s(ann.
5470: 61 4f 72 69 67 5b 69 5d 2e 7a 53 72 63 29 3a 20  aOrig[i].zSrc): 
5480: 25 68 28 61 6e 6e 2e 61 4f 72 69 67 5b 69 5d 2e  %h(ann.aOrig[i].
5490: 7a 29 0a 20 20 7d 0a 20 20 40 20 3c 2f 70 72 65  z).  }.  @ </pre
54a0: 3e 0a 20 20 73 74 79 6c 65 5f 66 6f 6f 74 65 72  >.  style_footer
54b0: 28 29 3b 0a 7d 0a                                ();.}.