summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/diff.c')
-rw-r--r--contrib/cvs/src/diff.c215
1 files changed, 107 insertions, 108 deletions
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index a5ca2d0..7faaae8 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -1,11 +1,6 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
- *
- * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
- * and others.
- *
- * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
- * Portions Copyright (C) 1989-1992, Brian Berliner
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * 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 source distribution.
@@ -17,6 +12,8 @@
*
* Without any file arguments, runs diff against all the currently modified
* files.
+ *
+ * $FreeBSD$
*/
#include <assert.h>
@@ -57,6 +54,7 @@ static void diff_mark_errors PROTO((int err));
static char *diff_rev1, *diff_rev2;
/* Command line dates, from -D option. Malloc'd. */
static char *diff_date1, *diff_date2;
+static char *diff_join1, *diff_join2;
static char *use_rev1, *use_rev2;
static int have_rev1_label, have_rev2_label;
@@ -65,9 +63,8 @@ static int have_rev1_label, have_rev2_label;
static char *user_file_rev;
static char *options;
-static char **diff_argv;
-static int diff_argc;
-static size_t diff_arg_allocated;
+static char *opts;
+static size_t opts_allocated = 1;
static int diff_errors;
static int empty_files = 0;
@@ -212,54 +209,6 @@ static struct option const longopts[] =
{0, 0, 0, 0}
};
-
-
-/* Add one of OPT or LONGOPT, and ARGUMENT, when present, to global DIFF_ARGV.
- *
- * INPUTS
- * opt A character option representation.
- * longopt A long option name.
- * argument Optional option argument.
- *
- * GLOBALS
- * diff_argc The number of arguments in DIFF_ARGV.
- * diff_argv Array of argument strings.
- * diff_arg_allocated Allocated length of DIFF_ARGV.
- *
- * NOTES
- * Behavior when both OPT & LONGOPT are provided is undefined.
- *
- * RETURNS
- * Nothing.
- */
-static void
-add_diff_args (char opt, const char *longopt, const char *argument)
-{
- char *tmp;
-
- /* Add opt or longopt to diff_arv. */
- assert (opt || (longopt && *longopt));
- assert (!(opt && (longopt && *longopt)));
- if (opt)
- {
- tmp = xmalloc (3);
- sprintf (tmp, "-%c", opt);
- }
- else
- {
- tmp = xmalloc (3 + strlen (longopt));
- sprintf (tmp, "--%s", longopt);
- }
- run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, tmp);
- free (tmp);
-
- /* When present, add ARGUMENT to DIFF_ARGV. */
- if (argument)
- run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, argument);
-}
-
-
-
/* 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
@@ -296,6 +245,7 @@ diff (argc, argv)
int argc;
char **argv;
{
+ char tmp[50];
int c, err = 0;
int local = 0;
int which;
@@ -315,15 +265,18 @@ diff (argc, argv)
/* Clean out our global variables (multiroot can call us multiple
times and the server can too, if the client sends several
diff commands). */
- if (diff_argc)
+ if (opts == NULL)
{
- run_arg_free_p (diff_argc, diff_argv);
- diff_argc = 0;
+ opts_allocated = 1;
+ opts = xmalloc (opts_allocated);
}
+ opts[0] = '\0';
diff_rev1 = NULL;
diff_rev2 = NULL;
diff_date1 = NULL;
diff_date2 = NULL;
+ diff_join1 = NULL;
+ diff_join2 = NULL;
optind = 0;
/* FIXME: This should really be allocating an argv to be passed to diff
@@ -334,13 +287,13 @@ diff (argc, argv)
* to diff.
*/
while ((c = getopt_long (argc, argv,
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
+ "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:j:",
longopts, &option_index)) != -1)
{
switch (c)
{
case 'y':
- add_diff_args (0, "side-by-side", NULL);
+ xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side");
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'i': case 'n': case 'p': case 's': case 't':
@@ -348,7 +301,8 @@ diff (argc, argv)
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':
- add_diff_args (c, NULL, NULL);
+ (void) sprintf (tmp, " -%c", (char) c);
+ xrealloc_and_strcat (&opts, &opts_allocated, tmp);
break;
case 'L':
if (have_rev1_label++)
@@ -357,15 +311,33 @@ diff (argc, argv)
error (0, 0, "extra -L arguments ignored");
break;
}
- /* Fall through. */
+
+ xrealloc_and_strcat (&opts, &opts_allocated, " -L");
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
+ break;
case 'C': case 'F': case 'I': case 'U': case 'W':
- add_diff_args (c, NULL, optarg);
+ (void) sprintf (tmp, " -%c", (char) c);
+ xrealloc_and_strcat (&opts, &opts_allocated, tmp);
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
+ break;
+ case 131:
+ /* --ifdef. */
+ xrealloc_and_strcat (&opts, &opts_allocated, " --ifdef=");
+ xrealloc_and_strcat (&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 145: case 146:
- add_diff_args (0, longopts[option_index].name,
- longopts[option_index].has_arg ? optarg : NULL);
+ xrealloc_and_strcat (&opts, &opts_allocated, " --");
+ xrealloc_and_strcat (&opts, &opts_allocated,
+ longopts[option_index].name);
+ if (longopts[option_index].has_arg == 1
+ || (longopts[option_index].has_arg == 2
+ && optarg != NULL))
+ {
+ xrealloc_and_strcat (&opts, &opts_allocated, "=");
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
+ }
break;
case 'R':
local = 0;
@@ -378,6 +350,27 @@ diff (argc, argv)
free (options);
options = RCS_check_kflag (optarg);
break;
+ case 'j':
+ {
+ char *ptr;
+ char *cpy = strdup(optarg);
+
+ if ((ptr = strchr(optarg, ':')) != NULL)
+ *ptr++ = 0;
+ if (diff_rev2 != NULL || diff_date2 != NULL)
+ error (1, 0,
+ "no more than two revisions/dates can be specified");
+ if (diff_rev1 != NULL || diff_date1 != NULL) {
+ diff_join2 = cpy;
+ diff_rev2 = optarg;
+ diff_date2 = ptr ? Make_Date(ptr) : NULL;
+ } else {
+ diff_join1 = cpy;
+ diff_rev1 = optarg;
+ diff_date1 = ptr ? Make_Date(ptr) : NULL;
+ }
+ }
+ break;
case 'r':
if (diff_rev2 != NULL || diff_date2 != NULL)
error (1, 0,
@@ -423,16 +416,21 @@ diff (argc, argv)
send_arg("-l");
if (empty_files)
send_arg("-N");
- send_options (diff_argc, diff_argv);
+ send_option_string (opts);
if (options[0] != '\0')
send_arg (options);
- if (diff_rev1)
+ if (diff_join1)
+ option_with_arg ("-j", diff_join1);
+ else if (diff_rev1)
option_with_arg ("-r", diff_rev1);
- if (diff_date1)
+ else if (diff_date1)
client_senddate (diff_date1);
- if (diff_rev2)
+
+ if (diff_join2)
+ option_with_arg ("-j", diff_join2);
+ else if (diff_rev2)
option_with_arg ("-r", diff_rev2);
- if (diff_date2)
+ else if (diff_date2)
client_senddate (diff_date2);
send_arg ("--");
@@ -446,28 +444,26 @@ diff (argc, argv)
send_to_server ("diff\012", 0);
err = get_responses_and_close ();
- free (options);
- options = NULL;
- return (err);
- }
+ } else
#endif
-
- if (diff_rev1 != NULL)
- tag_check_valid (diff_rev1, argc, argv, local, 0, "");
- if (diff_rev2 != NULL)
- tag_check_valid (diff_rev2, argc, argv, local, 0, "");
-
- which = W_LOCAL;
- if (diff_rev1 != NULL || diff_date1 != NULL)
- which |= W_REPOS | W_ATTIC;
-
- wrap_setup ();
-
- /* start the recursion processor */
- err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
- diff_dirleaveproc, NULL, argc, argv, local,
- which, 0, CVS_LOCK_READ, (char *) NULL, 1,
- (char *) NULL);
+ {
+ if (diff_rev1 != NULL)
+ tag_check_valid (diff_rev1, argc, argv, local, 0, "");
+ if (diff_rev2 != NULL)
+ tag_check_valid (diff_rev2, argc, argv, local, 0, "");
+
+ which = W_LOCAL;
+ if (diff_rev1 != NULL || diff_date1 != NULL)
+ which |= W_REPOS | W_ATTIC;
+
+ wrap_setup ();
+
+ /* start the recursion processor */
+ err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
+ diff_dirleaveproc, NULL, argc, argv, local,
+ which, 0, CVS_LOCK_READ, (char *) NULL, 1,
+ (char *) NULL);
+ }
/* clean up */
free (options);
@@ -477,6 +473,10 @@ diff (argc, argv)
free (diff_date1);
if (diff_date2 != NULL)
free (diff_date2);
+ if (diff_join1 != NULL)
+ free (diff_join1);
+ if (diff_join2 != NULL)
+ free (diff_join2);
return (err);
}
@@ -522,7 +522,7 @@ diff_fileproc (callerdat, finfo)
int exists;
exists = 0;
- /* special handling for TAG_HEAD */
+ /* special handling for TAG_HEAD XXX */
if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
{
char *head =
@@ -733,8 +733,8 @@ RCS file: ", 0);
if (empty_file == DIFF_ADDED)
{
if (use_rev2 == NULL)
- status = diff_exec (DEVNULL, finfo->file, label1, label2,
- diff_argc, diff_argv, RUN_TTY);
+ status = diff_exec (DEVNULL, finfo->file, label1, label2, opts,
+ RUN_TTY);
else
{
int retcode;
@@ -750,8 +750,7 @@ RCS file: ", 0);
if( retcode != 0 )
goto out;
- status = diff_exec (DEVNULL, tmp, label1, label2,
- diff_argc, diff_argv, RUN_TTY);
+ status = diff_exec (DEVNULL, tmp, label1, label2, opts, RUN_TTY);
}
}
else
@@ -767,16 +766,16 @@ RCS file: ", 0);
if (retcode != 0)
goto out;
- status = diff_exec (tmp, DEVNULL, label1, label2,
- diff_argc, diff_argv, RUN_TTY);
+ status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY);
}
}
else
{
- status = RCS_exec_rcsdiff (vers->srcfile, diff_argc, diff_argv,
- *options ? options : vers->options,
- use_rev1, rev1_cache, use_rev2,
- label1, label2, finfo->file);
+ status = RCS_exec_rcsdiff(vers->srcfile, opts,
+ *options ? options : vers->options,
+ use_rev1, rev1_cache, use_rev2,
+ label1, label2,
+ finfo->file);
}
@@ -920,7 +919,7 @@ diff_file_nodiff( finfo, vers, empty_file, rev1_cache )
if (diff_rev1 || diff_date1)
{
- /* special handling for TAG_HEAD */
+ /* special handling for TAG_HEAD XXX */
if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
{
if (vers->vn_rcs != NULL && vers->srcfile != NULL)
@@ -936,7 +935,7 @@ diff_file_nodiff( finfo, vers, empty_file, rev1_cache )
}
if (diff_rev2 || diff_date2)
{
- /* special handling for TAG_HEAD */
+ /* special handling for TAG_HEAD XXX */
if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
{
if (vers->vn_rcs != NULL && vers->srcfile != NULL)
OpenPOWER on IntegriCloud