[BACK]Return to diff.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rcs

Diff for /src/usr.bin/rcs/diff.c between version 1.8 and 1.9

version 1.8, 2006/08/14 23:52:36 version 1.9, 2006/09/21 15:30:07
Line 162 
Line 162 
         char    *date2;          char    *date2;
 };  };
   
 static void      output(FILE *, FILE *);  static void      output(FILE *, FILE *, int);
 static void      check(FILE *, FILE *);  static void      check(FILE *, FILE *, int);
 static void      range(int, int, char *);  static void      range(int, int, char *);
 static void      uni_range(int, int);  static void      uni_range(int, int);
 static void      dump_context_vec(FILE *, FILE *);  static void      dump_context_vec(FILE *, FILE *, int);
 static void      dump_unified_vec(FILE *, FILE *);  static void      dump_unified_vec(FILE *, FILE *, int);
 static int       prepare(int, FILE *, off_t);  static int       prepare(int, FILE *, off_t, int);
 static void      prune(void);  static void      prune(void);
 static void      equiv(struct line *, int, struct line *, int, int *);  static void      equiv(struct line *, int, struct line *, int, int *);
 static void      unravel(int);  static void      unravel(int);
 static void      unsort(struct line *, int, int *);  static void      unsort(struct line *, int, int *);
 static void      change(FILE *, FILE *, int, int, int, int);  static void      change(FILE *, FILE *, int, int, int, int, int);
 static void      sort(struct line *, int);  static void      sort(struct line *, int);
 static int       ignoreline(char *);  static int       ignoreline(char *);
 static int       asciifile(FILE *);  static int       asciifile(FILE *);
 static void      fetch(long *, int, int, FILE *, int, int);  static void      fetch(long *, int, int, FILE *, int, int, int);
 static int       newcand(int, int, int);  static int       newcand(int, int, int);
 static int       search(int *, int, int);  static int       search(int *, int, int);
 static int       skipline(FILE *);  static int       skipline(FILE *);
 static int       isqrt(int);  static int       isqrt(int);
 static int       stone(int *, int, int *, int *);  static int       stone(int *, int, int *, int *, int);
 static int       readhash(FILE *);  static int       readhash(FILE *, int);
 static int       files_differ(FILE *, FILE *);  static int       files_differ(FILE *, FILE *);
 static char     *match_function(const long *, int, FILE *);  static char     *match_function(const long *, int, FILE *);
 static char     *preadline(int, size_t, off_t);  static char     *preadline(int, size_t, off_t);
   
   
 static int aflag, bflag, dflag, iflag, pflag, tflag, Tflag, wflag;  int diff_context = 3;
 static int context = 3;  
 int diff_format = D_NORMAL;  int diff_format = D_NORMAL;
 char *diff_file = NULL;  char *diff_file = NULL;
 RCSNUM *diff_rev1 = NULL;  RCSNUM *diff_rev1 = NULL;
 RCSNUM *diff_rev2 = NULL;  RCSNUM *diff_rev2 = NULL;
 char diffargs[128];  char diffargs[512]; /* XXX */
 static struct stat stb1, stb2;  static struct stat stb1, stb2;
 static char *ifdefname, *ignore_pats;  static char *ifdefname;
 regex_t ignore_re;  regex_t *diff_ignore_re;
   
 static int  *J;                 /* will be overlaid on class */  static int  *J;                 /* will be overlaid on class */
 static int  *class;             /* will be overlaid on file[0] */  static int  *class;             /* will be overlaid on file[0] */
Line 285 
Line 284 
 };  };
   
 int  int
 rcs_diffreg(const char *file1, const char *file2, BUF *out)  rcs_diffreg(const char *file1, const char *file2, BUF *out, int flags)
 {  {
         FILE *f1, *f2;          FILE *f1, *f2;
         int i, rval;          int i, rval;
Line 297 
Line 296 
         lastline = 0;          lastline = 0;
         lastmatchline = 0;          lastmatchline = 0;
         context_vec_ptr = context_vec_start - 1;          context_vec_ptr = context_vec_start - 1;
         chrtran = (iflag ? cup2low : clow2low);          if (flags & D_IGNORECASE)
                   chrtran = cup2low;
           else
                   chrtran = clow2low;
         if (out != NULL)          if (out != NULL)
                 diffbuf = out;                  diffbuf = out;
   
Line 335 
Line 337 
                 errx(D_ERROR, "files_differ: invalid case");                  errx(D_ERROR, "files_differ: invalid case");
         }          }
   
         if (!asciifile(f1) || !asciifile(f2)) {          if ((flags & D_FORCEASCII) == 0 &&
               (!asciifile(f1) || !asciifile(f2))) {
                 rval = D_ERROR;                  rval = D_ERROR;
                 goto closem;                  goto closem;
         }          }
   
         if (prepare(0, f1, stb1.st_size) < 0 ||          if (prepare(0, f1, stb1.st_size, flags) < 0 ||
             prepare(1, f2, stb2.st_size) < 0) {              prepare(1, f2, stb2.st_size, flags) < 0) {
                 goto closem;                  goto closem;
         }          }
   
Line 364 
Line 367 
         clistlen = 100;          clistlen = 100;
         clist = xcalloc(clistlen, sizeof(*clist));          clist = xcalloc(clistlen, sizeof(*clist));
   
         if ((i = stone(class, slen[0], member, klist)) < 0)          if ((i = stone(class, slen[0], member, klist, flags)) < 0)
                 goto closem;                  goto closem;
   
         xfree(member);          xfree(member);
Line 381 
Line 384 
   
         tmp = xrealloc(ixnew, diff_len[1] + 2, sizeof(*ixnew));          tmp = xrealloc(ixnew, diff_len[1] + 2, sizeof(*ixnew));
         ixnew = tmp;          ixnew = tmp;
         check(f1, f2);          check(f1, f2, flags);
         output(f1, f2);          output(f1, f2, flags);
   
 closem:  closem:
         if (anychange == 1) {          if (anychange == 1) {
Line 426 
Line 429 
 }  }
   
 static int  static int
 prepare(int i, FILE *fd, off_t filesize)  prepare(int i, FILE *fd, off_t filesize, int flags)
 {  {
         void *tmp;          void *tmp;
         struct line *p;          struct line *p;
Line 440 
Line 443 
                 sz = 100;                  sz = 100;
   
         p = xcalloc(sz + 3, sizeof(*p));          p = xcalloc(sz + 3, sizeof(*p));
         for (j = 0; (h = readhash(fd));) {          for (j = 0; (h = readhash(fd, flags));) {
                 if (j == (int)sz) {                  if (j == (int)sz) {
                         sz = sz * 3 / 2;                          sz = sz * 3 / 2;
                         tmp = xrealloc(p, sz + 3, sizeof(*p));                          tmp = xrealloc(p, sz + 3, sizeof(*p));
Line 525 
Line 528 
 }  }
   
 static int  static int
 stone(int *a, int n, int *b, int *c)  stone(int *a, int n, int *b, int *c, int flags)
 {  {
         int ret;          int ret;
         int i, k, y, j, l;          int i, k, y, j, l;
Line 533 
Line 536 
         u_int numtries;          u_int numtries;
   
         /* XXX move the isqrt() out of the macro to avoid multiple calls */          /* XXX move the isqrt() out of the macro to avoid multiple calls */
         const u_int bound = dflag ? UINT_MAX : MAX(256, (u_int)isqrt(n));          const u_int bound = (flags & D_MINIMAL) ? UINT_MAX : MAX(256, isqrt(n));
   
         k = 0;          k = 0;
         if ((ret = newcand(0, 0, 0)) < 0)          if ((ret = newcand(0, 0, 0)) < 0)
Line 638 
Line 641 
  *  2.  collect random access indexes to the two files   *  2.  collect random access indexes to the two files
  */   */
 static void  static void
 check(FILE *f1, FILE *f2)  check(FILE *f1, FILE *f2, int flags)
 {  {
         int i, j, jackpot, c, d;          int i, j, jackpot, c, d;
         long ctold, ctnew;          long ctold, ctnew;
Line 658 
Line 661 
                         ixnew[j] = ctnew += skipline(f2);                          ixnew[j] = ctnew += skipline(f2);
                         j++;                          j++;
                 }                  }
                 if (bflag == 1 || wflag == 1 || iflag == 1) {                  if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE)) {
                         for (;;) {                          for (;;) {
                                 c = getc(f1);                                  c = getc(f1);
                                 d = getc(f2);                                  d = getc(f2);
                                 /*                                  /*
                                  * GNU diff ignores a missing newline                                   * GNU diff ignores a missing newline
                                  * in one file if bflag || wflag.                                   * in one file for -b or -w.
                                  */                                   */
                                 if ((bflag == 1 || wflag == 1) &&                                  if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) &&
                                     ((c == EOF && d == '\n') ||                                      ((c == EOF && d == '\n') ||
                                     (c == '\n' && d == EOF))) {                                      (c == '\n' && d == EOF))) {
                                         break;                                          break;
                                 }                                  }
                                 ctold++;                                  ctold++;
                                 ctnew++;                                  ctnew++;
                                 if (bflag == 1 && isspace(c) && isspace(d)) {                                  if ((flags & D_FOLDBLANKS) && isspace(c) &&
                                       isspace(d)) {
                                         do {                                          do {
                                                 if (c == '\n')                                                  if (c == '\n')
                                                         break;                                                          break;
Line 684 
Line 688 
                                                         break;                                                          break;
                                                 ctnew++;                                                  ctnew++;
                                         } while (isspace(d = getc(f2)));                                          } while (isspace(d = getc(f2)));
                                 } else if (wflag == 1) {                                  } else if ((flags & D_IGNOREBLANKS)) {
                                         while (isspace(c) && c != '\n') {                                          while (isspace(c) && c != '\n') {
                                                 c = getc(f1);                                                  c = getc(f1);
                                                 ctold++;                                                  ctold++;
Line 792 
Line 796 
 }  }
   
 static void  static void
 output(FILE *f1, FILE *f2)  output(FILE *f1, FILE *f2, int flags)
 {  {
         int m, i0, i1, j0, j1;          int m, i0, i1, j0, j1;
   
Line 810 
Line 814 
                         i1++;                          i1++;
                 j1 = J[i1 + 1] - 1;                  j1 = J[i1 + 1] - 1;
                 J[i1] = j1;                  J[i1] = j1;
                 change(f1, f2, i0, i1, j0, j1);                  change(f1, f2, i0, i1, j0, j1, flags);
         }          }
         if (m == 0)          if (m == 0)
                 change(f1, f2, 1, 0, 1, diff_len[1]);                  change(f1, f2, 1, 0, 1, diff_len[1], flags);
         if (diff_format == D_IFDEF) {          if (diff_format == D_IFDEF) {
                 for (;;) {                  for (;;) {
 #define c i0  #define c i0
Line 825 
Line 829 
         }          }
         if (anychange != 0) {          if (anychange != 0) {
                 if (diff_format == D_CONTEXT)                  if (diff_format == D_CONTEXT)
                         dump_context_vec(f1, f2);                          dump_context_vec(f1, f2, flags);
                 else if (diff_format == D_UNIFIED)                  else if (diff_format == D_UNIFIED)
                         dump_unified_vec(f1, f2);                          dump_unified_vec(f1, f2, flags);
         }          }
 }  }
   
Line 870 
Line 874 
 {  {
         int ret;          int ret;
   
         ret = regexec(&ignore_re, line, 0, NULL, 0);          ret = regexec(diff_ignore_re, line, 0, NULL, 0);
         xfree(line);          xfree(line);
         return (ret == 0);      /* if it matched, it should be ignored. */          return (ret == 0);      /* if it matched, it should be ignored. */
 }  }
Line 883 
Line 887 
  * lines missing from the to file.   * lines missing from the to file.
  */   */
 static void  static void
 change(FILE *f1, FILE *f2, int a, int b, int c, int d)  change(FILE *f1, FILE *f2, int a, int b, int c, int d, int flags)
 {  {
         int i;          int i;
         static size_t max_context = 64;          static size_t max_context = 64;
Line 892 
Line 896 
   
         if (diff_format != D_IFDEF && a > b && c > d)          if (diff_format != D_IFDEF && a > b && c > d)
                 return;                  return;
         if (ignore_pats != NULL) {          if (diff_ignore_re != NULL) {
                 char *line;                  char *line;
                 /*                  /*
                  * All lines in the change, insert, or delete must                   * All lines in the change, insert, or delete must
Line 966 
Line 970 
   
                         printf("\n");                          printf("\n");
                         anychange = 1;                          anychange = 1;
                 } else if (a > context_vec_ptr->b + (2 * context) + 1 &&                  } else if (a > context_vec_ptr->b + (2 * diff_context) + 1 &&
                     c > context_vec_ptr->d + (2 * context) + 1) {                      c > context_vec_ptr->d + (2 * diff_context) + 1) {
                         /*                          /*
                          * If this change is more than 'context' lines from the                           * If this change is more than 'diff_context' lines
                          * previous change, dump the record and reset it.                           * from the previous change, dump the record and reset it.
                          */                           */
                         if (diff_format == D_CONTEXT)                          if (diff_format == D_CONTEXT)
                                 dump_context_vec(f1, f2);                                  dump_context_vec(f1, f2, flags);
                         else                          else
                                 dump_unified_vec(f1, f2);                                  dump_unified_vec(f1, f2, flags);
                 }                  }
                 context_vec_ptr++;                  context_vec_ptr++;
                 context_vec_ptr->a = a;                  context_vec_ptr->a = a;
Line 1008 
Line 1012 
                 break;                  break;
         }          }
         if (diff_format == D_NORMAL || diff_format == D_IFDEF) {          if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
                 fetch(ixold, a, b, f1, '<', 1);                  fetch(ixold, a, b, f1, '<', 1, flags);
                 if (a <= b && c <= d && diff_format == D_NORMAL)                  if (a <= b && c <= d && diff_format == D_NORMAL)
                         diff_output("---\n");                          diff_output("---\n");
         }          }
         fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0);          fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, flags);
         if (inifdef) {          if (inifdef) {
                 diff_output("#endif /* %s */\n", ifdefname);                  diff_output("#endif /* %s */\n", ifdefname);
                 inifdef = 0;                  inifdef = 0;
Line 1020 
Line 1024 
 }  }
   
 static void  static void
 fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile)  fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
 {  {
         long j, nc;          long j, nc;
         int i, c, col;          int i, c, col;
Line 1055 
Line 1059 
                 nc = f[i] - f[i - 1];                  nc = f[i] - f[i - 1];
                 if (diff_format != D_IFDEF && ch != '\0') {                  if (diff_format != D_IFDEF && ch != '\0') {
                         diff_output("%c", ch);                          diff_output("%c", ch);
                         if (Tflag == 1 && (diff_format == D_NORMAL ||                          if (diff_format != D_UNIFIED)
                             diff_format == D_CONTEXT ||  
                             diff_format == D_UNIFIED))  
                                 diff_output("\t");  
                         else if (diff_format != D_UNIFIED)  
                                 diff_output(" ");                                  diff_output(" ");
                 }                  }
                 col = 0;                  col = 0;
Line 1072 
Line 1072 
                                             "file");                                              "file");
                                 return;                                  return;
                         }                          }
                         if (c == '\t' && tflag == 1) {                          if (c == '\t' && (flags & D_EXPANDTABS)) {
                                 do {                                  do {
                                         diff_output(" ");                                          diff_output(" ");
                                 } while (++col & 7);                                  } while (++col & 7);
Line 1088 
Line 1088 
  * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.   * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
  */   */
 static int  static int
 readhash(FILE *f)  readhash(FILE *f, int flags)
 {  {
         int i, t, space;          int i, t, space;
         int sum;          int sum;
   
         sum = 1;          sum = 1;
         space = 0;          space = 0;
         if (bflag != 1 && wflag != 1) {          if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) == 0) {
                 if (iflag == 1)                  if (flags & D_IGNORECASE)
                         for (i = 0; (t = getc(f)) != '\n'; i++) {                          for (i = 0; (t = getc(f)) != '\n'; i++) {
                                 if (t == EOF) {                                  if (t == EOF) {
                                         if (i == 0)                                          if (i == 0)
Line 1122 
Line 1122 
                                 space++;                                  space++;
                                 continue;                                  continue;
                         default:                          default:
                                 if (space != 0 && wflag != 1) {                                  if (space && (flags & D_IGNOREBLANKS) == 0) {
                                         i++;                                          i++;
                                         space = 0;                                          space = 0;
                                 }                                  }
Line 1152 
Line 1152 
         char buf[BUFSIZ];          char buf[BUFSIZ];
         size_t i, cnt;          size_t i, cnt;
   
         if (aflag == 1 || f == NULL)          if (f == NULL)
                 return (1);                  return (1);
   
         rewind(f);          rewind(f);
Line 1199 
Line 1199 
   
 /* dump accumulated "context" diff changes */  /* dump accumulated "context" diff changes */
 static void  static void
 dump_context_vec(FILE *f1, FILE *f2)  dump_context_vec(FILE *f1, FILE *f2, int flags)
 {  {
         struct context_vec *cvp = context_vec_start;          struct context_vec *cvp = context_vec_start;
         int lowa, upb, lowc, upd, do_output;          int lowa, upb, lowc, upd, do_output;
Line 1210 
Line 1210 
                 return;                  return;
   
         b = d = 0;              /* gcc */          b = d = 0;              /* gcc */
         lowa = MAX(1, cvp->a - context);          lowa = MAX(1, cvp->a - diff_context);
         upb = MIN(diff_len[0], context_vec_ptr->b + context);          upb = MIN(diff_len[0], context_vec_ptr->b + diff_context);
         lowc = MAX(1, cvp->c - context);          lowc = MAX(1, cvp->c - diff_context);
         upd = MIN(diff_len[1], context_vec_ptr->d + context);          upd = MIN(diff_len[1], context_vec_ptr->d + diff_context);
   
         diff_output("***************");          diff_output("***************");
         if (pflag == 1) {          if ((flags & D_PROTOTYPE)) {
                 f = match_function(ixold, lowa - 1, f1);                  f = match_function(ixold, lowa - 1, f1);
                 if (f != NULL) {                  if (f != NULL) {
                         diff_output(" ");                          diff_output(" ");
Line 1252 
Line 1252 
                                 ch = (a <= b) ? 'd' : 'a';                                  ch = (a <= b) ? 'd' : 'a';
   
                         if (ch == 'a')                          if (ch == 'a')
                                 fetch(ixold, lowa, b, f1, ' ', 0);                                  fetch(ixold, lowa, b, f1, ' ', 0, flags);
                         else {                          else {
                                 fetch(ixold, lowa, a - 1, f1, ' ', 0);                                  fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
                                 fetch(ixold, a, b, f1,                                  fetch(ixold, a, b, f1,
                                     ch == 'c' ? '!' : '-', 0);                                      ch == 'c' ? '!' : '-', 0, flags);
                         }                          }
                         lowa = b + 1;                          lowa = b + 1;
                         cvp++;                          cvp++;
                 }                  }
                 fetch(ixold, b + 1, upb, f1, ' ', 0);                  fetch(ixold, b + 1, upb, f1, ' ', 0, flags);
         }          }
         /* output changes to the "new" file */          /* output changes to the "new" file */
         diff_output("--- ");          diff_output("--- ");
Line 1288 
Line 1288 
                                 ch = (a <= b) ? 'd' : 'a';                                  ch = (a <= b) ? 'd' : 'a';
   
                         if (ch == 'd')                          if (ch == 'd')
                                 fetch(ixnew, lowc, d, f2, ' ', 0);                                  fetch(ixnew, lowc, d, f2, ' ', 0, flags);
                         else {                          else {
                                 fetch(ixnew, lowc, c - 1, f2, ' ', 0);                                  fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
                                 fetch(ixnew, c, d, f2,                                  fetch(ixnew, c, d, f2,
                                     ch == 'c' ? '!' : '+', 0);                                      ch == 'c' ? '!' : '+', 0, flags);
                         }                          }
                         lowc = d + 1;                          lowc = d + 1;
                         cvp++;                          cvp++;
                 }                  }
                 fetch(ixnew, d + 1, upd, f2, ' ', 0);                  fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
         }          }
         context_vec_ptr = context_vec_start - 1;          context_vec_ptr = context_vec_start - 1;
 }  }
   
 /* dump accumulated "unified" diff changes */  /* dump accumulated "unified" diff changes */
 static void  static void
 dump_unified_vec(FILE *f1, FILE *f2)  dump_unified_vec(FILE *f1, FILE *f2, int flags)
 {  {
         struct context_vec *cvp = context_vec_start;          struct context_vec *cvp = context_vec_start;
         int lowa, upb, lowc, upd;          int lowa, upb, lowc, upd;
Line 1315 
Line 1315 
                 return;                  return;
   
         b = d = 0;              /* gcc */          b = d = 0;              /* gcc */
         lowa = MAX(1, cvp->a - context);          lowa = MAX(1, cvp->a - diff_context);
         upb = MIN(diff_len[0], context_vec_ptr->b + context);          upb = MIN(diff_len[0], context_vec_ptr->b + diff_context);
         lowc = MAX(1, cvp->c - context);          lowc = MAX(1, cvp->c - diff_context);
         upd = MIN(diff_len[1], context_vec_ptr->d + context);          upd = MIN(diff_len[1], context_vec_ptr->d + diff_context);
   
         diff_output("@@ -");          diff_output("@@ -");
         uni_range(lowa, upb);          uni_range(lowa, upb);
         diff_output(" +");          diff_output(" +");
         uni_range(lowc, upd);          uni_range(lowc, upd);
         diff_output(" @@");          diff_output(" @@");
         if (pflag == 1) {          if ((flags & D_PROTOTYPE)) {
                 f = match_function(ixold, lowa - 1, f1);                  f = match_function(ixold, lowa - 1, f1);
                 if (f != NULL) {                  if (f != NULL) {
                         diff_output(" ");                          diff_output(" ");
Line 1356 
Line 1356 
   
                 switch (ch) {                  switch (ch) {
                 case 'c':                  case 'c':
                         fetch(ixold, lowa, a - 1, f1, ' ', 0);                          fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
                         fetch(ixold, a, b, f1, '-', 0);                          fetch(ixold, a, b, f1, '-', 0, flags);
                         fetch(ixnew, c, d, f2, '+', 0);                          fetch(ixnew, c, d, f2, '+', 0, flags);
                         break;                          break;
                 case 'd':                  case 'd':
                         fetch(ixold, lowa, a - 1, f1, ' ', 0);                          fetch(ixold, lowa, a - 1, f1, ' ', 0, flags);
                         fetch(ixold, a, b, f1, '-', 0);                          fetch(ixold, a, b, f1, '-', 0, flags);
                         break;                          break;
                 case 'a':                  case 'a':
                         fetch(ixnew, lowc, c - 1, f2, ' ', 0);                          fetch(ixnew, lowc, c - 1, f2, ' ', 0, flags);
                         fetch(ixnew, c, d, f2, '+', 0);                          fetch(ixnew, c, d, f2, '+', 0, flags);
                         break;                          break;
                 }                  }
                 lowa = b + 1;                  lowa = b + 1;
                 lowc = d + 1;                  lowc = d + 1;
         }          }
         fetch(ixnew, d + 1, upd, f2, ' ', 0);          fetch(ixnew, d + 1, upd, f2, ' ', 0, flags);
   
         context_vec_ptr = context_vec_start - 1;          context_vec_ptr = context_vec_start - 1;
 }  }

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9