diff options
Diffstat (limited to 'contrib/cvs/src/diff.c')
-rw-r--r-- | contrib/cvs/src/diff.c | 124 |
1 files changed, 79 insertions, 45 deletions
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c index 2e7aea2..a5ca2d0 100644 --- a/contrib/cvs/src/diff.c +++ b/contrib/cvs/src/diff.c @@ -1,6 +1,11 @@ /* - * Copyright (c) 1992, Brian Berliner and Jeff Polk - * Copyright (c) 1989-1992, Brian Berliner + * 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 * * 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. @@ -60,8 +65,9 @@ static int have_rev1_label, have_rev2_label; static char *user_file_rev; static char *options; -static char *opts; -static size_t opts_allocated = 1; +static char **diff_argv; +static int diff_argc; +static size_t diff_arg_allocated; static int diff_errors; static int empty_files = 0; @@ -206,6 +212,54 @@ 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 @@ -242,7 +296,6 @@ diff (argc, argv) int argc; char **argv; { - char tmp[50]; int c, err = 0; int local = 0; int which; @@ -262,12 +315,11 @@ 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 (opts == NULL) + if (diff_argc) { - opts_allocated = 1; - opts = xmalloc (opts_allocated); + run_arg_free_p (diff_argc, diff_argv); + diff_argc = 0; } - opts[0] = '\0'; diff_rev1 = NULL; diff_rev2 = NULL; diff_date1 = NULL; @@ -288,7 +340,7 @@ diff (argc, argv) switch (c) { case 'y': - xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side"); + add_diff_args (0, "side-by-side", NULL); 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': @@ -296,8 +348,7 @@ 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': - (void) sprintf (tmp, " -%c", (char) c); - xrealloc_and_strcat (&opts, &opts_allocated, tmp); + add_diff_args (c, NULL, NULL); break; case 'L': if (have_rev1_label++) @@ -306,33 +357,15 @@ diff (argc, argv) error (0, 0, "extra -L arguments ignored"); break; } - - xrealloc_and_strcat (&opts, &opts_allocated, " -L"); - xrealloc_and_strcat (&opts, &opts_allocated, optarg); - break; + /* Fall through. */ case 'C': case 'F': case 'I': case 'U': case 'W': - (void) sprintf (tmp, " -%c", (char) c); - xrealloc_and_strcat (&opts, &opts_allocated, tmp); - xrealloc_and_strcat (&opts, &opts_allocated, optarg); + add_diff_args (c, NULL, 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 132: case 133: case 134: + case 129: case 130: case 131: 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: - 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); - } + add_diff_args (0, longopts[option_index].name, + longopts[option_index].has_arg ? optarg : NULL); break; case 'R': local = 0; @@ -390,7 +423,7 @@ diff (argc, argv) send_arg("-l"); if (empty_files) send_arg("-N"); - send_option_string (opts); + send_options (diff_argc, diff_argv); if (options[0] != '\0') send_arg (options); if (diff_rev1) @@ -700,8 +733,8 @@ RCS file: ", 0); if (empty_file == DIFF_ADDED) { if (use_rev2 == NULL) - status = diff_exec (DEVNULL, finfo->file, label1, label2, opts, - RUN_TTY); + status = diff_exec (DEVNULL, finfo->file, label1, label2, + diff_argc, diff_argv, RUN_TTY); else { int retcode; @@ -717,7 +750,8 @@ RCS file: ", 0); if( retcode != 0 ) goto out; - status = diff_exec (DEVNULL, tmp, label1, label2, opts, RUN_TTY); + status = diff_exec (DEVNULL, tmp, label1, label2, + diff_argc, diff_argv, RUN_TTY); } } else @@ -733,16 +767,16 @@ RCS file: ", 0); if (retcode != 0) goto out; - status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY); + status = diff_exec (tmp, DEVNULL, label1, label2, + diff_argc, diff_argv, RUN_TTY); } } else { - status = RCS_exec_rcsdiff(vers->srcfile, opts, - *options ? options : vers->options, - use_rev1, rev1_cache, use_rev2, - label1, label2, - finfo->file); + status = RCS_exec_rcsdiff (vers->srcfile, diff_argc, diff_argv, + *options ? options : vers->options, + use_rev1, rev1_cache, use_rev2, + label1, label2, finfo->file); } |