summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/diff.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-01-26 03:09:57 +0000
committerpeter <peter@FreeBSD.org>1998-01-26 03:09:57 +0000
commite6e45661e44f15cb8c5c6f063080509bd910b98d (patch)
treea9812ba7ade0fde6f62c1626b45d522ba104c314 /contrib/cvs/src/diff.c
parent571cfa0005d94d99d1341bf8ab02be04d4df5f9f (diff)
downloadFreeBSD-src-e6e45661e44f15cb8c5c6f063080509bd910b98d.zip
FreeBSD-src-e6e45661e44f15cb8c5c6f063080509bd910b98d.tar.gz
Import cvs-1.9.23 as at 19980123. There are a number of really nice
things fixed in here, including the '-ko' vs. -A problem with remote cvs which caused all files with -ko to be resent each time (which is damn painful over a modem, I can tell you). It also found a heap of stray empty directories that should have been pruned with the -P flag to cvs update but were not for some reason. It also has the fully integrated rcs and diff, so no more fork/exec overheads for rcs,ci,patch,diff,etc. This means that it parses the control data in the rcs files only once rather than twice or more. If the 'cvs diff' vs. Index thing is going to be fixed for future patch compatability, this is the place to do it.
Diffstat (limited to 'contrib/cvs/src/diff.c')
-rw-r--r--contrib/cvs/src/diff.c144
1 files changed, 103 insertions, 41 deletions
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index 608a00f..a894c5b 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -3,7 +3,7 @@
* Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
+ * specified in the README file that comes with the CVS source distribution.
*
* Difference
*
@@ -43,6 +43,7 @@ static void diff_mark_errors PROTO((int err));
static char *diff_rev1, *diff_rev2;
static char *diff_date1, *diff_date2;
static char *use_rev1, *use_rev2;
+static int have_rev1_label, have_rev2_label;
/* Revision of the user file, if it is unchanged from something in the
repository and we want to use that fact. */
@@ -71,6 +72,7 @@ static const char *const diff_usage[] =
"\t--ifdef=arg\tOutput diffs in ifdef format.\n",
"(consult the documentation for your diff program for rcsdiff-options.\n",
"The most popular is -c for context diffs but there are many more).\n",
+ "(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -103,13 +105,13 @@ static struct option const longopts[] =
{
{"ignore-blank-lines", 0, 0, 'B'},
{"context", 2, 0, 143},
- {"ifdef", 1, 0, 147},
+ {"ifdef", 1, 0, 131},
{"show-function-line", 1, 0, 'F'},
{"speed-large-files", 0, 0, 'H'},
{"ignore-matching-lines", 1, 0, 'I'},
{"label", 1, 0, 'L'},
{"new-file", 0, 0, 'N'},
- {"initial-tab", 0, 0, 'T'},
+ {"initial-tab", 0, 0, 148},
{"width", 1, 0, 'W'},
{"text", 0, 0, 'a'},
{"ignore-space-change", 0, 0, 'b'},
@@ -130,7 +132,7 @@ static struct option const longopts[] =
{"report-identical-files", 0, 0, 's'},
{"expand-tabs", 0, 0, 't'},
{"ignore-all-space", 0, 0, 'w'},
- {"side-by-side", 0, 0, 'y'},
+ {"side-by-side", 0, 0, 147},
{"unified", 2, 0, 146},
{"left-column", 0, 0, 129},
{"suppress-common-lines", 0, 0, 130},
@@ -147,6 +149,37 @@ static struct option const longopts[] =
{0, 0, 0, 0}
};
+/* CVS 1.9 and similar versions seemed to have pretty weird handling
+ of -y and -T. In the cases where it called rcsdiff,
+ they would have the meanings mentioned below. In the cases where it
+ called diff, they would have the meanings mentioned in "longopts".
+ Noone seems to have missed them, so I think the right thing to do is
+ just to remove the options altogether (which I have done).
+
+ In the case of -z and -q, "cvs diff" did not accept them even back
+ when we called rcsdiff (at least, it hasn't accepted them
+ recently).
+
+ In comparing rcsdiff to the new CVS implementation, I noticed that
+ the following rcsdiff flags are not handled by CVS diff:
+
+ -y: perform diff even when the requested revisions are the
+ same revision number
+ -q: run quietly
+ -T: preserve modification time on the RCS file
+ -z: specify timezone for use in file labels
+
+ I think these are not really relevant. -y is undocumented even in
+ RCS 5.7, and seems like a minor change at best. According to RCS
+ documentation, -T only applies when a RCS file has been modified
+ because of lock changes; doesn't CVS sidestep RCS's entire lock
+ structure? -z seems to be unsupported by CVS diff, and has a
+ different meaning as a global option anyway. (Adding it could be
+ a feature, but if it is left out for now, it should not break
+ anything.) For the purposes of producing output, CVS diff appears
+ mostly to ignore -q. Maybe this should be fixed, but I think it's
+ a larger issue than the changes included here. */
+
static void strcat_and_allocate PROTO ((char **, size_t *, const char *));
/* *STR is a pointer to a malloc'd string. *LENP is its allocated
@@ -183,6 +216,8 @@ diff (argc, argv)
if (argc == -1)
usage (diff_usage);
+ have_rev1_label = have_rev2_label = 0;
+
/*
* Note that we catch all the valid arguments here, so that we can
* intercept the -r arguments for doing revision diffs; and -l/-R for a
@@ -201,33 +236,44 @@ diff (argc, argv)
optind = 0;
while ((c = getopt_long (argc, argv,
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
+ "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:",
longopts, &option_index)) != -1)
{
switch (c)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'i': case 'n': case 'p': case 's': case 't':
- case 'u': case 'w': case 'y': case '0': case '1': case '2':
+ case 'u': case 'w': case '0': case '1': case '2':
case '3': case '4': case '5': case '6': case '7': case '8':
- case '9': case 'B': case 'H': case 'T':
+ case '9': case 'B': case 'H':
(void) sprintf (tmp, " -%c", (char) c);
strcat_and_allocate (&opts, &opts_allocated, tmp);
break;
- case 'C': case 'F': case 'I': case 'L': case 'U': case 'V':
- case 'W':
+ case 'L':
+ if (have_rev1_label++)
+ if (have_rev2_label++)
+ {
+ error (0, 0, "extra -L arguments ignored");
+ break;
+ }
+
+ strcat_and_allocate (&opts, &opts_allocated, " -L");
+ strcat_and_allocate (&opts, &opts_allocated, optarg);
+ break;
+ case 'C': case 'F': case 'I': case 'U': case 'V': case 'W':
(void) sprintf (tmp, " -%c", (char) c);
strcat_and_allocate (&opts, &opts_allocated, tmp);
strcat_and_allocate (&opts, &opts_allocated, optarg);
break;
- case 147:
+ case 131:
/* --ifdef. */
strcat_and_allocate (&opts, &opts_allocated, " -D");
strcat_and_allocate (&opts, &opts_allocated, optarg);
break;
- case 129: case 130: case 131: case 132: case 133: case 134:
+ case 129: case 130: case 132: case 133: case 134:
case 135: case 136: case 137: case 138: case 139: case 140:
case 141: case 142: case 143: case 144: case 145: case 146:
+ case 147: case 148:
strcat_and_allocate (&opts, &opts_allocated, " --");
strcat_and_allocate (&opts, &opts_allocated,
longopts[option_index].name);
@@ -359,6 +405,11 @@ diff_fileproc (callerdat, finfo)
char *tocvsPath;
char *fname;
+ /* Initialize these solely to avoid warnings from gcc -Wall about
+ variables that might be used uninitialized. */
+ tmp = NULL;
+ fname = NULL;
+
user_file_rev = 0;
vers = Version_TS (finfo, NULL, NULL, NULL, 1, 0);
@@ -534,9 +585,9 @@ diff_fileproc (callerdat, finfo)
}
/* Output an "Index:" line for patch to use */
- (void) fflush (stdout);
- (void) printf ("Index: %s\n", finfo->fullname);
- (void) fflush (stdout);
+ cvs_output ("Index: ", 0);
+ cvs_output (finfo->fullname, 0);
+ cvs_output ("\n", 1);
tocvsPath = wrap_tocvs_process_file(finfo->file);
if (tocvsPath)
@@ -559,14 +610,20 @@ diff_fileproc (callerdat, finfo)
{
/* This is file, not fullname, because it is the "Index:" line which
is supposed to contain the directory. */
- (void) printf ("===================================================================\nRCS file: %s\n",
- finfo->file);
- (void) printf ("diff -N %s\n", finfo->file);
+ cvs_output ("\
+===================================================================\n\
+RCS file: ", 0);
+ cvs_output (finfo->file, 0);
+ cvs_output ("\n", 1);
+
+ cvs_output ("diff -N ", 0);
+ cvs_output (finfo->file, 0);
+ cvs_output ("\n", 1);
if (empty_file == DIFF_ADDED)
{
if (use_rev2 == NULL)
- run_setup ("%s %s %s %s", DIFF, opts, DEVNULL, finfo->file);
+ status = diff_exec (DEVNULL, finfo->file, opts, RUN_TTY);
else
{
int retcode;
@@ -587,7 +644,7 @@ diff_fileproc (callerdat, finfo)
}
/* FIXME: what if retcode > 0? */
- run_setup ("%s %s %s %s", DIFF, opts, DEVNULL, tmp);
+ status = diff_exec (DEVNULL, tmp, opts, RUN_TTY);
}
}
else
@@ -608,30 +665,36 @@ diff_fileproc (callerdat, finfo)
}
/* FIXME: what if retcode > 0? */
- run_setup ("%s %s %s %s", DIFF, opts, tmp, DEVNULL);
+ status = diff_exec (tmp, DEVNULL, opts, RUN_TTY);
}
}
else
{
- if (use_rev2)
- {
- run_setup ("%s%s -x,v/ %s %s -r%s -r%s", Rcsbin, RCS_DIFF,
- opts, *options ? options : vers->options,
- use_rev1, use_rev2);
- }
- else
- {
- run_setup ("%s%s -x,v/ %s %s -r%s", Rcsbin, RCS_DIFF, opts,
- *options ? options : vers->options, use_rev1);
- }
- run_arg (vers->srcfile->path);
+ char *label1 = NULL;
+ char *label2 = NULL;
+
+ if (!have_rev1_label)
+ label1 =
+ make_file_label (finfo->fullname, use_rev1, vers->srcfile);
+
+ if (!have_rev2_label)
+ label2 =
+ make_file_label (finfo->fullname, use_rev2, vers->srcfile);
+
+ status = RCS_exec_rcsdiff (vers->srcfile, opts,
+ *options ? options : vers->options,
+ use_rev1, use_rev2,
+ label1, label2,
+ finfo->file);
+
+ if (label1) free (label1);
+ if (label2) free (label2);
}
- switch ((status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
- RUN_REALLY|RUN_COMBINED)))
+ switch (status)
{
case -1: /* fork failed */
- error (1, errno, "fork failed during rcsdiff of %s",
+ error (1, errno, "fork failed while diffing %s",
vers->srcfile->path);
case 0: /* everything ok */
err = 0;
@@ -660,7 +723,6 @@ diff_fileproc (callerdat, finfo)
free (tmp);
}
- (void) fflush (stdout);
freevers_ts (&vers);
diff_mark_errors (err);
return (err);
@@ -694,9 +756,9 @@ diff_dirproc (callerdat, dir, pos_repos, update_dir, entries)
/* XXX - check for dirs we don't want to process??? */
/* YES ... for instance dirs that don't exist!!! -- DW */
- if (!isdir (dir) )
- return (R_SKIP_ALL);
-
+ if (!isdir (dir))
+ return (R_SKIP_ALL);
+
if (!quiet)
error (0, 0, "Diffing %s", update_dir);
return (R_PROCESS);
@@ -853,9 +915,9 @@ diff_file_nodiff (finfo, vers, empty_file)
{
/* drop user_file_rev into first unused use_rev */
if (!use_rev1)
- use_rev1 = xstrdup (user_file_rev);
+ use_rev1 = xstrdup (user_file_rev);
else if (!use_rev2)
- use_rev2 = xstrdup (user_file_rev);
+ use_rev2 = xstrdup (user_file_rev);
/* and if not, it wasn't needed anyhow */
user_file_rev = 0;
}
OpenPOWER on IntegriCloud