[comp.os.minix] Fixes for eof handling in diff.c

rbthomas@athos.rutgers.edu (Rick Thomas) (08/14/89)

The diff distributed with Minix 1.3PH (Prentice Hall) has problems
with changes near the end of one or the other input file.  I have
fixed that problem.  The cdiffs are enclosed.

The fix consists of considering all lines beyond the end of file as
matching one another.  The tricky part comes in making sure that the
algorithm terminates correctly after looking at all records of both
files, not just at all records of one or the other file.

    CRCs

16917   5383 diff.c.ORIG
57766   5351 diff.c

Rick

PS -- note that there is one long line in the cdif enclosed, the
	#define equal_line()
is longer than 80 characters.  Incase it gets truncated by some
well-meaning mailer, it should look like this (except for the line
break and extra tabs).

	! #define equal_line(l1,l2) ((l1==0||l2==0)?(l1==l2):
		(strcmp((l1)->l_text,(l2)->l_text)==0))

PPS -- I have not tested this extensively.  I encourage you to try it
out and post comments.

================================== Cut Here =============================
*** diff.c.ORIG	Sun Aug 13 15:05:29 1989
--- diff.c	Sun Aug 13 16:23:21 1989
***************
*** 57,62 ****
--- 57,63 ----
  };
  
  struct line *freelist = 0;
+ #define stepup(ll) (ll ? ll->l_next : ll)
  
  struct line *
  new_line()
***************
*** 78,95 ****
  	freelist = l;
  }
  
! #define equal_line(l1, l2) (strcmp((l1)->l_text, (l2)->l_text) == 0)
  
  int equal_3(l1, l2)
  	struct line *l1, *l2;
  {
  	register int i;
  
! 	for (i=0; i<3 && l1 && l2; ++i, l1=l1->l_next, l2=l2->l_next) {
! 		if (!equal_line(l1, l2))
! 			return 0;
! 	}
! 	return (i==3);
  }
  
  struct line *
--- 79,98 ----
  	freelist = l;
  }
  
! #define equal_line(l1,l2) ((l1==0||l2==0)?(l1==l2):(strcmp((l1)->l_text,(l2)->l_text)==0))
  
  int equal_3(l1, l2)
  	struct line *l1, *l2;
  {
  	register int i;
  
! 	for (i=0; i<3; ++i) {
! 		if (!equal_line(l1, l2))
! 			return 0;
! 		l1 = stepup(l1);
! 		l2 = stepup(l2);
! 	}
! 	return (1);
  }
  
  struct line *
***************
*** 143,148 ****
--- 146,152 ----
  {
  	register struct line *ll;
  
+ 	if (l == 0) return;
  	if (ll = l->l_next) {
  		while (ll->l_next)
  			ll = ll->l_next;
***************
*** 207,213 ****
  	init_f(&f2, fp2);
  	l1 = next(&f1);
  	l2 = next(&f2);
! 	while (l1 && l2) {
  		if (equal_line(l1, l2)) {
  equal:
  			advance(&f1);
--- 211,217 ----
  	init_f(&f2, fp2);
  	l1 = next(&f1);
  	l2 = next(&f2);
! 	while (l1 || l2) {
  		if (equal_line(l1, l2)) {
  equal:
  			advance(&f1);
***************
*** 223,232 ****
  		next(&f2); next(&f2);
  		/* start searching */
  search:
! 		if ((l2 = next(&f2)) == 0)
! 			continue;
! 		ll = s1;
! 		b2 = b2->l_next;
  		do {
  			if (equal_3(ll, b2)) {
  				aside(&f1, ll);
--- 227,234 ----
  		next(&f2); next(&f2);
  		/* start searching */
  search:
! 		l2 = next(&f2);
! 		ll = s1;
  		do {
  			if (equal_3(ll, b2)) {
  				aside(&f1, ll);
***************
*** 234,244 ****
  				differ(&f1, &f2);
  				goto equal;
  			}
! 		} while (ll = ll->l_next);
! 		if ((l1 = next(&f1)) == 0)
! 			continue;
! 		ll = s2;
! 		b1 = b1->l_next;
  		do {
  			if (equal_3(ll, b1)) {
  				aside(&f2, ll);
--- 236,247 ----
  				differ(&f1, &f2);
  				goto equal;
  			}
! 			ll = stepup(ll);
! 		} while (ll);
! 		b2 = stepup(b2);
! 
! 		l1 = next(&f1);
! 		ll = s2;
  		do {
  			if (equal_3(ll, b1)) {
  				aside(&f2, ll);
***************
*** 246,259 ****
  				differ(&f1, &f2);
  				goto equal;
  			}
! 		} while (ll = ll->l_next);
! 		goto search;
! 	}
! 	/* one of the files reached EOF */
! 	if (l1) /* eof on 2 */
! 		while (next(&f1)) {}
! 	if (l2)
! 		while (next(&f2)) {}
  	f1.f_ewin = 0;
  	f2.f_ewin = 0;
  	differ(&f1, &f2);
--- 249,261 ----
  				differ(&f1, &f2);
  				goto equal;
  			}
! 			ll = stepup(ll);
! 		} while (ll);
! 		b1 = stepup(b1);
! 
! 		goto search;
! 	}
! 	/* both of the files reached EOF */
  	f1.f_ewin = 0;
  	f2.f_ewin = 0;
  	differ(&f1, &f2);
================================== Cut Here =============================
-- 

Rick Thomas
uucp: {ames, att, harvard}!rutgers!jove.rutgers.edu!rbthomas
internet: rbthomas@JOVE.RUTGERS.EDU
bitnet: rbthomas@zodiac.bitnet
Phone: (201) 932-4301