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

Diff for /src/usr.bin/cvs/diff.c between version 1.3 and 1.4

version 1.3, 2004/07/14 04:32:42 version 1.4, 2004/07/30 01:49:23
Line 146 
Line 146 
 #include "cvs.h"  #include "cvs.h"
 #include "log.h"  #include "log.h"
 #include "buf.h"  #include "buf.h"
   #include "proto.h"
   
   
 #define CVS_DIFF_DEFCTX    3   /* default context length */  #define CVS_DIFF_DEFCTX    3   /* default context length */
Line 197 
Line 198 
         int d;                  /* end line in new file */          int d;                  /* end line in new file */
 };  };
   
   struct diff_arg {
           char  *rev1;
           char  *rev2;
           char  *date1;
           char  *date2;
   };
   
   
 struct excludes {  struct excludes {
         char *pattern;          char *pattern;
         struct excludes *next;          struct excludes *next;
Line 206 
Line 214 
   
 char    *splice(char *, char *);  char    *splice(char *, char *);
 int  cvs_diffreg(const char *, const char *);  int  cvs_diffreg(const char *, const char *);
 int  cvs_diff_file  (const char *, const char *, const char *);  int  cvs_diff_file  (struct cvs_file *, void *);
 int  cvs_diff_dir   (const char *, int);  
 static void output(const char *, FILE *, const char *, FILE *);  static void output(const char *, FILE *, const char *, FILE *);
 static void check(FILE *, FILE *);  static void check(FILE *, FILE *);
 static void range(int, int, char *);  static void range(int, int, char *);
Line 231 
Line 238 
 static int  stone(int *, int, int *, int *);  static int  stone(int *, int, int *, int *);
 static int  readhash(FILE *);  static int  readhash(FILE *);
 static int  files_differ(FILE *, FILE *);  static int  files_differ(FILE *, FILE *);
 static __inline int min(int, int);  
 static __inline int max(int, int);  
 static char *match_function(const long *, int, FILE *);  
 static char *preadline(int, size_t, off_t);  static char *preadline(int, size_t, off_t);
   
   
   
 extern int cvs_client;  extern int cvs_client;
 extern struct cvsroot *cvs_root;  
   
   
   
 static int aflag, bflag, dflag, iflag, tflag, Tflag, wflag;  static int aflag, bflag, dflag, iflag, tflag, Tflag, wflag;
 static int context, status;  static int context, status;
 static int format = D_NORMAL;  static int format = D_NORMAL;
Line 272 
Line 273 
 static struct context_vec *context_vec_ptr;  static struct context_vec *context_vec_ptr;
   
 #define FUNCTION_CONTEXT_SIZE   41  #define FUNCTION_CONTEXT_SIZE   41
 static char lastbuf[FUNCTION_CONTEXT_SIZE];  
 static int lastline;  static int lastline;
 static int lastmatchline;  static int lastmatchline;
   
Line 350 
Line 350 
 int  int
 cvs_diff(int argc, char **argv)  cvs_diff(int argc, char **argv)
 {  {
         int i, ch, recurse;          int ch, recurse, flags;
         size_t dalen;          struct cvs_file *files;
         char dir[MAXPATHLEN], file[MAXPATHLEN], *d1, *d2, *r1, *r2;          struct diff_arg darg;
           struct cvsroot *root;
   
         context = CVS_DIFF_DEFCTX;          context = CVS_DIFF_DEFCTX;
         strlcpy(diffargs, argv[0], sizeof(diffargs));          flags = CF_RECURSE|CF_IGNORE|CF_SORT|CF_KNOWN;
   
         d1 = d2 = NULL;  
         r1 = r2 = NULL;  
         recurse = 1;          recurse = 1;
   
           memset(&darg, 0, sizeof(darg));
           strlcpy(diffargs, argv[0], sizeof(diffargs));
   
         while ((ch = getopt(argc, argv, "cD:lir:u")) != -1) {          while ((ch = getopt(argc, argv, "cD:lir:u")) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'c':                  case 'c':
Line 368 
Line 369 
                         format = D_CONTEXT;                          format = D_CONTEXT;
                         break;                          break;
                 case 'D':                  case 'D':
                         if (d1 == NULL && r1 == NULL)                          if (darg.date1 == NULL && darg.rev1 == NULL)
                                 d1 = optarg;                                  darg.date1 = optarg;
                         else if (d2 == NULL && r2 == NULL)                          else if (darg.date2 == NULL && darg.rev2 == NULL)
                                 d2 = optarg;                                  darg.date2 = optarg;
                         else {                          else {
                                 cvs_log(LP_ERR,                                  cvs_log(LP_ERR,
                                     "no more than two revisions/dates can "                                      "no more than two revisions/dates can "
Line 381 
Line 382 
                 case 'l':                  case 'l':
                         strlcat(diffargs, " -l", sizeof(diffargs));                          strlcat(diffargs, " -l", sizeof(diffargs));
                         recurse = 0;                          recurse = 0;
                           flags &= ~CF_RECURSE;
                         break;                          break;
                 case 'i':                  case 'i':
                         strlcat(diffargs, " -i", sizeof(diffargs));                          strlcat(diffargs, " -i", sizeof(diffargs));
                         iflag = 1;                          iflag = 1;
                         break;                          break;
                 case 'r':                  case 'r':
                         if ((r1 == NULL) && (d1 == NULL))                          if ((darg.rev1 == NULL) && (darg.date1 == NULL))
                                 r1 = optarg;                                  darg.rev1 = optarg;
                         else if ((r2 == NULL) && (d2 == NULL))                          else if ((darg.rev2 == NULL) && (darg.date2 == NULL))
                                 r2 = optarg;                                  darg.rev2 = optarg;
                         else {                          else {
                                 cvs_log(LP_ERR,                                  cvs_log(LP_ERR,
                                     "no more than two revisions/dates can "                                      "no more than two revisions/dates can "
Line 411 
Line 413 
         argv += optind;          argv += optind;
   
         if (argc == 0) {          if (argc == 0) {
                 /* get the CVSROOT from current dir */                  files = cvs_file_get(".", flags);
                 strlcpy(dir, ".", sizeof(dir));          }
           else
                   files = cvs_file_getspec(argv, argc, 0);
   
                 cvs_root = cvsroot_get(dir);          cvs_file_examine(files, cvs_diff_file, &darg);
                 if (cvs_root == NULL)  
                         return (EX_USAGE);  
   
                 if (cvs_root->cr_method != CVS_METHOD_LOCAL) {          root = files->cf_ddat->cd_root;
                         cvs_client_connect();          if (root->cr_method != CVS_METHOD_LOCAL)
                   cvs_sendreq(root, CVS_REQ_DIFF, NULL);
   
                         /* send the flags */          return (0);
                         if (format == D_CONTEXT)  }
                                 cvs_client_sendarg("-c", 0);  
                         else if (format == D_UNIFIED)  
                                 cvs_client_sendarg("-u", 0);  
   
                         if (r1 != NULL) {  
                                 cvs_client_sendarg("-r", 0);  
                                 cvs_client_sendarg(r1, 1);  
                         }  
                         else if (d1 != NULL) {  
                                 cvs_client_sendarg("-D", 0);  
                                 cvs_client_sendarg(d1, 1);  
                         }  
                         if (r2 != NULL) {  
                                 cvs_client_sendarg("-r", 0);  
                                 cvs_client_sendarg(r2, 1);  
                         }  
                         else if (d2 != NULL) {  
                                 cvs_client_sendarg("-D", 0);  
                                 cvs_client_sendarg(d2, 1);  
                         }  
                 }  
   
                 cvs_diff_dir(dir, recurse);  /*
         }   * cvs_diff_sendflags()
         else {   *
                 for (i = 0; i < argc; i++) {   */
                         cvs_splitpath(argv[i], dir, sizeof(dir),  
                             file, sizeof(file));  
                         cvs_root = cvsroot_get(dir);  
                         if (cvs_root == NULL)  
                                 return (EX_USAGE);  
   
                         if (cvs_root->cr_method != CVS_METHOD_LOCAL) {  int
                                 cvs_client_connect();  cvs_diff_sendflags(struct cvsroot *root, struct diff_arg *dap)
   {
           /* send the flags */
           if (format == D_CONTEXT)
                   cvs_sendarg(root, "-c", 0);
           else if (format == D_UNIFIED)
                   cvs_sendarg(root, "-u", 0);
   
                                 if (i == 0) {          if (dap->rev1 != NULL) {
                                         /* send the flags */                  cvs_sendarg(root, "-r", 0);
                                         if (format == D_CONTEXT)                  cvs_sendarg(root, dap->rev1, 1);
                                                 cvs_client_sendarg("-c", 0);  
                                         else if (format == D_UNIFIED)  
                                                 cvs_client_sendarg("-u", 0);  
                                 }  
                         }  
   
                         cvs_diff_file(argv[i], r1, r2);  
                 }  
         }          }
           else if (dap->date1 != NULL) {
                   cvs_sendarg(root, "-D", 0);
                   cvs_sendarg(root, dap->date1, 1);
           }
           if (dap->rev2 != NULL) {
                   cvs_sendarg(root, "-r", 0);
                   cvs_sendarg(root, dap->rev2, 1);
           }
           else if (dap->date2 != NULL) {
                   cvs_sendarg(root, "-D", 0);
                   cvs_sendarg(root, dap->date2, 1);
           }
   
         if (cvs_root->cr_method != CVS_METHOD_LOCAL)  
                 cvs_client_sendreq(CVS_REQ_DIFF, NULL, 1);  
   
         return (0);          return (0);
 }  }
   
Line 485 
Line 470 
  */   */
   
 int  int
 cvs_diff_file(const char *path, const char *rev1, const char *rev2)  cvs_diff_file(struct cvs_file *cfp, void *arg)
 {  {
         int modif;          char *dir, *repo, rcspath[MAXPATHLEN], buf[64];
         char dir[MAXPATHLEN], file[MAXPATHLEN], rcspath[MAXPATHLEN];  
         char repo[MAXPATHLEN], buf[64];  
         time_t tsec;  
         BUF *b1, *b2;          BUF *b1, *b2;
         RCSNUM *r1, *r2;          RCSNUM *r1, *r2;
         RCSFILE *rf;          RCSFILE *rf;
         CVSENTRIES *entf;          struct diff_arg *dap;
         struct tm tmstamp;  
         struct stat fst;  
         struct cvs_ent *entp;          struct cvs_ent *entp;
           struct cvsroot *root;
   
         rf = NULL;          dap = (struct diff_arg *)arg;
         diff_file = path;  
   
         if (stat(path, &fst) == -1) {          cvs_log(LP_DEBUG, "%s: diffing %s", __func__, cfp->cf_path);
                 cvs_log(LP_ERRNO, "cannot find %s", path);  
                 return (-1);  
         }  
   
         cvs_splitpath(path, dir, sizeof(dir), file, sizeof(file));          if (cfp->cf_type == DT_DIR) {
         cvs_readrepo(dir, repo, sizeof(repo));                  root = cfp->cf_ddat->cd_root;
                   if ((cfp->cf_parent == NULL) ||
                       (root != cfp->cf_parent->cf_ddat->cd_root)) {
                           cvs_connect(root);
                           cvs_diff_sendflags(root, dap);
                   }
   
         entf = cvs_ent_open(dir, O_RDONLY);                  cvs_senddir(root, cfp);
         if (entf == NULL) {                  return (0);
                 cvs_log(LP_ERR, "no CVS/Entries file in `%s'", dir);  
                 return (-1);  
         }          }
           else    /* take the root of parent directory */
                   root = cfp->cf_parent->cf_ddat->cd_root;
   
         entp = cvs_ent_get(entf, file);          rf = NULL;
         if ((entp == NULL) && (cvs_root->cr_method == CVS_METHOD_LOCAL)) {          diff_file = cfp->cf_path;
                 cvs_log(LP_WARN, "I know nothing about %s", path);          if (cfp->cf_parent != NULL) {
                 return (-1);                  dir = cfp->cf_parent->cf_path;
                   repo = cfp->cf_parent->cf_ddat->cd_repo;
         }          }
           else {
                   dir = ".";
                   repo = NULL;
           }
   
         if (cvs_root->cr_method != CVS_METHOD_LOCAL) {          if (cfp->cf_cvstat == CVS_FST_UNKNOWN) {
                 if (cvs_client_senddir(dir) < 0)                  if (root->cr_method == CVS_METHOD_LOCAL)
                         return (-1);                          cvs_log(LP_WARN, "I know nothing about %s", diff_file);
                   else
                           cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name);
                   return (0);
         }          }
   
         tsec = (time_t)fst.st_mtimespec.tv_sec;          entp = cvs_ent_getent(diff_file);
           if (entp == NULL)
         if ((gmtime_r(&tsec, &tmstamp) == NULL) ||  
             (asctime_r(&tmstamp, buf) == NULL)) {  
                 cvs_log(LP_ERR, "failed to generate file timestamp");  
                 return (-1);                  return (-1);
   
           if (root->cr_method != CVS_METHOD_LOCAL) {
                   if (cvs_sendentry(root, entp) < 0) {
                           cvs_ent_free(entp);
                           return (-1);
                   }
         }          }
         modif = (strcmp(buf, entp->ce_timestamp) == 0) ? 0 : 1;  
   
         if (cvs_root->cr_method != CVS_METHOD_LOCAL)          if (cfp->cf_cvstat == CVS_FST_UPTODATE) {
                 cvs_client_sendentry(entp);                  if (root->cr_method != CVS_METHOD_LOCAL)
                           cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name);
         if (!modif) {                  cvs_ent_free(entp);
                 if (cvs_root->cr_method != CVS_METHOD_LOCAL)  
                         cvs_client_sendreq(CVS_REQ_UNCHANGED, file, 0);  
                 cvs_ent_close(entf);  
                 return (0);                  return (0);
         }          }
   
         /* at this point, the file is modified */          /* at this point, the file is modified */
         if (cvs_root->cr_method != CVS_METHOD_LOCAL) {          if (root->cr_method != CVS_METHOD_LOCAL) {
                 cvs_client_sendreq(CVS_REQ_MODIFIED, file, 0);                  cvs_sendreq(root, CVS_REQ_MODIFIED, cfp->cf_name);
                 cvs_sendfile(path);                  cvs_sendfile(root, diff_file);
         }          }
         else {          else {
                 snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s",                  snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s",
                     cvs_root->cr_dir, repo, path, RCS_FILE_EXT);                      root->cr_dir, repo, diff_file, RCS_FILE_EXT);
   
                 rf = rcs_open(rcspath, RCS_MODE_READ);                  rf = rcs_open(rcspath, RCS_MODE_READ);
                 if (rf == NULL)                  if (rf == NULL) {
                           cvs_ent_free(entp);
                         return (-1);                          return (-1);
                   }
   
                 printf("Index: %s\n%s\nRCS file: %s\n", path,                  cvs_printf("Index: %s\n%s\nRCS file: %s\n", diff_file,
                     RCS_DIFF_DIV, rcspath);                      RCS_DIFF_DIV, rcspath);
   
                 if (rev1 == NULL)                  if (dap->rev1 == NULL)
                         r1 = entp->ce_rev;                          r1 = entp->ce_rev;
                 else {                  else {
                         r1 = rcsnum_alloc();                          r1 = rcsnum_alloc();
                         rcsnum_aton(rev1, NULL, r1);                          rcsnum_aton(dap->rev1, NULL, r1);
                 }                  }
   
                 printf("retrieving revision %s\n",                  cvs_printf("retrieving revision %s\n",
                     rcsnum_tostr(r1, buf, sizeof(buf)));                      rcsnum_tostr(r1, buf, sizeof(buf)));
                 b1 = rcs_getrev(rf, r1);                  b1 = rcs_getrev(rf, r1);
   
                 if (rev2 != NULL) {                  if (dap->rev2 != NULL) {
                         printf("retrieving revision %s\n", rev2);                          cvs_printf("retrieving revision %s\n", dap->rev2);
                         r2 = rcsnum_alloc();                          r2 = rcsnum_alloc();
                         rcsnum_aton(rev2, NULL, r2);                          rcsnum_aton(dap->rev2, NULL, r2);
                         b2 = rcs_getrev(rf, r2);                          b2 = rcs_getrev(rf, r2);
                 }                  }
                 else {                  else {
                         b2 = cvs_buf_load(path, BUF_AUTOEXT);                          b2 = cvs_buf_load(diff_file, BUF_AUTOEXT);
                 }                  }
   
                   rcs_close(rf);
   
                 printf("%s", diffargs);                  printf("%s", diffargs);
                 printf(" -r%s", buf);                  printf(" -r%s", buf);
                 if (rev2 != NULL)                  if (dap->rev2 != NULL)
                         printf(" -r%s", rev2);                          printf(" -r%s", dap->rev2);
                 printf(" %s\n", path);                  printf(" %s\n", diff_file);
                 cvs_buf_write(b1, "/tmp/diff1", 0600);                  cvs_buf_write(b1, "/tmp/diff1", 0600);
                 cvs_buf_write(b2, "/tmp/diff2", 0600);                  cvs_buf_write(b2, "/tmp/diff2", 0600);
                 cvs_diffreg("/tmp/diff1", "/tmp/diff2");                  cvs_diffreg("/tmp/diff1", "/tmp/diff2");
         }          }
   
         cvs_ent_close(entf);          cvs_ent_free(entp);
   
         return (0);          return (0);
 }  }
   
   
 /*  
  * cvs_diff_dir()  
  *  
  */  
   
 int  int
 cvs_diff_dir(const char *dir, int recurse)  
 {  
         char path[MAXPATHLEN];  
         DIR *dirp;  
         CVSENTRIES *entf;  
         struct dirent *dentp;  
         struct cvs_ent *entp;  
   
         printf("cvs_diff_dir(%s)\n", dir);  
   
         dirp = opendir(dir);  
         if (dirp == NULL) {  
                 cvs_log(LP_ERRNO, "failed to open directory `%s'", dir);  
                 return (-1);  
         }  
   
         entf = cvs_ent_open(dir, O_RDONLY);  
         if (entf == NULL) {  
                 cvs_log(LP_ERR, "no CVS/Entries file in `%s'", dir);  
                 (void)closedir(dirp);  
                 return (-1);  
         }  
   
         while ((dentp = readdir(dirp)) != NULL) {  
                 if ((strcmp(dentp->d_name, "CVS") == 0) ||  
                     (dentp->d_name[0] == '.'))  
                         continue;  
   
                 if (strcmp(dir, ".") != 0) {  
                         strlcpy(path, dir, sizeof(path));  
                         strlcat(path, "/", sizeof(path));  
                 }  
                 else  
                         path[0] = '\0';  
                 strlcat(path, dentp->d_name, sizeof(path));  
                 if (dentp->d_type == DT_DIR) {  
                         if (!recurse)  
                                 continue;  
                         cvs_diff_dir(path, recurse);  
                 }  
                 else {  
                         entp = cvs_ent_get(entf, dentp->d_name);  
                         if (entp == NULL) {  
                                 cvs_client_sendreq(CVS_REQ_QUESTIONABLE, path,  
                                     0);  
                         }  
                         else {  
 #if 0  
                                 cvs_diff_file(path);  
 #endif  
                         }  
                 }  
         }  
   
         return (0);  
 }  
   
   
   
   
 int  
 cvs_diffreg(const char *file1, const char *file2)  cvs_diffreg(const char *file1, const char *file2)
 {  {
         FILE *f1, *f2;          FILE *f1, *f2;
Line 896 
Line 822 
         int oldc, tc, oldl;          int oldc, tc, oldl;
         u_int numtries;          u_int numtries;
   
         const u_int bound = dflag ? UINT_MAX : max(256, isqrt(n));          const u_int bound = dflag ? UINT_MAX : MAX(256, isqrt(n));
   
         k = 0;          k = 0;
         c[0] = newcand(0, 0, 0);          c[0] = newcand(0, 0, 0);
Line 1480 
Line 1406 
         return (1);          return (1);
 }  }
   
 static __inline int min(int a, int b)  
 {  
         return (a < b ? a : b);  
 }  
   
 static __inline int max(int a, int b)  
 {  
         return (a > b ? a : b);  
 }  
   
 static char *  
 match_function(const long *f, int pos, FILE *file)  
 {  
         char buf[FUNCTION_CONTEXT_SIZE];  
         size_t nc;  
         int last = lastline;  
         char *p;  
   
         lastline = pos;  
         while (pos > last) {  
                 fseek(file, f[pos - 1], SEEK_SET);  
                 nc = f[pos] - f[pos - 1];  
                 if (nc >= sizeof(buf))  
                         nc = sizeof(buf) - 1;  
                 nc = fread(buf, 1, nc, file);  
                 if (nc > 0) {  
                         buf[nc] = '\0';  
                         p = strchr(buf, '\n');  
                         if (p != NULL)  
                                 *p = '\0';  
                         if (isalpha(buf[0]) || buf[0] == '_' || buf[0] == '$') {  
                                 strlcpy(lastbuf, buf, sizeof lastbuf);  
                                 lastmatchline = pos;  
                                 return lastbuf;  
                         }  
                 }  
                 pos--;  
         }  
         return lastmatchline > 0 ? lastbuf : NULL;  
 }  
   
 /* 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)
Line 1528 
Line 1414 
         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;
         int a, b, c, d;          int a, b, c, d;
         char ch, *f;          char ch;
   
         if (context_vec_start > context_vec_ptr)          if (context_vec_start > context_vec_ptr)
                 return;                  return;
   
         b = d = 0;              /* gcc */          b = d = 0;              /* gcc */
         lowa = max(1, cvp->a - context);          lowa = MAX(1, cvp->a - context);
         upb = min(len[0], context_vec_ptr->b + context);          upb = MIN(len[0], context_vec_ptr->b + context);
         lowc = max(1, cvp->c - context);          lowc = MAX(1, cvp->c - context);
         upd = min(len[1], context_vec_ptr->d + context);          upd = MIN(len[1], context_vec_ptr->d + context);
   
         printf("***************");          printf("***************");
         printf("\n*** ");          printf("\n*** ");
Line 1626 
Line 1512 
         struct context_vec *cvp = context_vec_start;          struct context_vec *cvp = context_vec_start;
         int lowa, upb, lowc, upd;          int lowa, upb, lowc, upd;
         int a, b, c, d;          int a, b, c, d;
         char ch, *f;          char ch;
   
         if (context_vec_start > context_vec_ptr)          if (context_vec_start > context_vec_ptr)
                 return;                  return;
   
         b = d = 0;              /* gcc */          b = d = 0;              /* gcc */
         lowa = max(1, cvp->a - context);          lowa = MAX(1, cvp->a - context);
         upb = min(len[0], context_vec_ptr->b + context);          upb = MIN(len[0], context_vec_ptr->b + context);
         lowc = max(1, cvp->c - context);          lowc = MAX(1, cvp->c - context);
         upd = min(len[1], context_vec_ptr->d + context);          upd = MIN(len[1], context_vec_ptr->d + context);
   
         fputs("@@ -", stdout);          fputs("@@ -", stdout);
         uni_range(lowa, upb);          uni_range(lowa, upb);

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4