diff options
Diffstat (limited to 'contrib/cvs/src/diff.c')
-rw-r--r-- | contrib/cvs/src/diff.c | 215 |
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) |