summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/rcscmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/rcscmds.c')
-rw-r--r--contrib/cvs/src/rcscmds.c174
1 files changed, 80 insertions, 94 deletions
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index df91ff8..18182ff 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.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.
@@ -53,8 +58,8 @@
On a related note, see the comments at diff_exec, later in this file,
for more on the diff library. */
-static void RCS_output_diff_options PROTO ((const char *, const char *,
- const char *, const char *));
+static void RCS_output_diff_options PROTO ((int, char *const *, const char *,
+ const char *, const char *));
/* Stuff to deal with passing arguments the way libdiff.a wants to deal
@@ -66,17 +71,18 @@ static void RCS_output_diff_options PROTO ((const char *, const char *,
argument will be parsed into whitespace separated words and added
to the global call_diff_argv list.
- Then, optionally, call call_diff_arg for each additional argument
+ Then, optionally, call call_diff_add_arg for each additional argument
that you'd like to pass to the diff library.
Finally, call call_diff or call_diff3 to produce the diffs. */
static char **call_diff_argv;
static int call_diff_argc;
-static int call_diff_argc_allocated;
+static size_t call_diff_argc_allocated;
static void call_diff_add_arg PROTO ((const char *));
-static void call_diff_setup PROTO ((const char *prog));
+static void call_diff_setup PROTO ((const char *prog,
+ int argc, char * const *argv));
static int call_diff PROTO ((const char *out));
static int call_diff3 PROTO ((char *out));
@@ -85,62 +91,37 @@ static void call_diff_flush_output PROTO((void));
static void call_diff_write_stdout PROTO((const char *));
static void call_diff_error PROTO((const char *, const char *, const char *));
+
+
+static void
+call_diff_add_arg (s)
+ const char *s;
+{
+ run_add_arg_p (&call_diff_argc, &call_diff_argc_allocated, &call_diff_argv,
+ s);
+}
+
+
+
/* VARARGS */
static void
-call_diff_setup (prog)
+call_diff_setup (prog, argc, argv)
const char *prog;
+ int argc;
+ char * const *argv;
{
- char *cp;
int i;
- char *call_diff_prog;
/* clean out any malloc'ed values from call_diff_argv */
- for (i = 0; i < call_diff_argc; i++)
- {
- if (call_diff_argv[i])
- {
- free (call_diff_argv[i]);
- call_diff_argv[i] = (char *) 0;
- }
- }
+ run_arg_free_p (call_diff_argc, call_diff_argv);
call_diff_argc = 0;
- call_diff_prog = xstrdup (prog);
-
/* put each word into call_diff_argv, allocating it as we go */
- for (cp = strtok (call_diff_prog, " \t");
- cp != NULL;
- cp = strtok ((char *) NULL, " \t"))
- call_diff_add_arg (cp);
- free (call_diff_prog);
-}
-
-static void
-call_diff_arg (s)
- const char *s;
-{
- call_diff_add_arg (s);
+ call_diff_add_arg (prog);
+ for (i = 0; i < argc; i++)
+ call_diff_add_arg (argv[i]);
}
-static void
-call_diff_add_arg (s)
- const char *s;
-{
- /* allocate more argv entries if we've run out */
- if (call_diff_argc >= call_diff_argc_allocated)
- {
- call_diff_argc_allocated += 50;
- call_diff_argv = (char **)
- xrealloc ((char *) call_diff_argv,
- call_diff_argc_allocated * sizeof (char **));
- }
-
- if (s)
- call_diff_argv[call_diff_argc++] = xstrdup (s);
- else
- /* Not post-incremented on purpose! */
- call_diff_argv[call_diff_argc] = (char *) 0;
-}
/* Callback function for the diff library to write data to the output
file. This is used when we are producing output to stdout. */
@@ -213,6 +194,8 @@ static int
call_diff (out)
const char *out;
{
+ call_diff_add_arg (NULL);
+
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
@@ -264,6 +247,7 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
symbolic). */
xrev1 = RCS_gettag (rcs, rev1, 0, NULL);
xrev2 = RCS_gettag (rcs, rev2, 0, NULL);
+ assert (xrev1 && xrev2);
/* Check out chosen revisions. The error message when RCS_checkout
fails is not very informative -- it is taken verbatim from RCS 5.7,
@@ -304,21 +288,21 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
/* Remember that the first word in the `call_diff_setup' string is used now
only for diagnostic messages -- CVS no longer forks to run diff3. */
diffout = cvs_temp_name();
- call_diff_setup ("diff3");
- call_diff_arg ("-E");
- call_diff_arg ("-am");
-
- call_diff_arg ("-L");
- call_diff_arg (workfile);
- call_diff_arg ("-L");
- call_diff_arg (xrev1);
- call_diff_arg ("-L");
- call_diff_arg (xrev2);
-
- call_diff_arg ("--");
- call_diff_arg (workfile);
- call_diff_arg (tmp1);
- call_diff_arg (tmp2);
+ call_diff_setup ("diff3", 0, NULL);
+ call_diff_add_arg ("-E");
+ call_diff_add_arg ("-am");
+
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev1);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev2);
+
+ call_diff_add_arg ("--");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg (tmp1);
+ call_diff_add_arg (tmp2);
retval = call_diff3 (diffout);
@@ -384,10 +368,11 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
about this--any such features are undocumented in the context of
CVS, and I'm not sure how important to users. */
int
-RCS_exec_rcsdiff(rcsfile, opts, options, rev1, rev1_cache, rev2,
- label1, label2, workfile )
+RCS_exec_rcsdiff (rcsfile, diff_argc, diff_argv, options, rev1, rev1_cache,
+ rev2, label1, label2, workfile)
RCSNode *rcsfile;
- const char *opts;
+ int diff_argc;
+ char * const *diff_argv;
const char *options;
const char *rev1;
const char *rev1_cache;
@@ -467,8 +452,9 @@ RCS file: ", 0);
use_file2 = tmpfile2;
}
- RCS_output_diff_options (opts, rev1, rev2, workfile);
- status = diff_exec( use_file1, use_file2, label1, label2, opts, RUN_TTY );
+ RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile);
+ status = diff_exec (use_file1, use_file2, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
if (status >= 0)
{
retval = status;
@@ -547,16 +533,15 @@ RCS file: ", 0);
message on stderr. */
int
-diff_exec (file1, file2, label1, label2, options, out)
+diff_exec (file1, file2, label1, label2, dargc, dargv, out)
const char *file1;
const char *file2;
const char *label1;
const char *label2;
- const char *options;
+ int dargc;
+ char * const *dargv;
const char *out;
{
- char *args;
-
#ifdef PRESERVE_PERMISSIONS_SUPPORT
/* If either file1 or file2 are special files, pretend they are
/dev/null. Reason: suppose a file that represents a block
@@ -590,18 +575,15 @@ diff_exec (file1, file2, label1, label2, options, out)
}
#endif
- args = xmalloc (strlen (options) + 10);
- /* The first word in this string is used only for error reporting. */
- sprintf (args, "diff %s", options);
- call_diff_setup (args);
+ /* The first arg to call_diff_setup is used only for error reporting. */
+ call_diff_setup ("diff", dargc, dargv);
if (label1)
- call_diff_arg (label1);
+ call_diff_add_arg (label1);
if (label2)
- call_diff_arg (label2);
- call_diff_arg ("--");
- call_diff_arg (file1);
- call_diff_arg (file2);
- free (args);
+ call_diff_add_arg (label2);
+ call_diff_add_arg ("--");
+ call_diff_add_arg (file1);
+ call_diff_add_arg (file2);
return call_diff (out);
}
@@ -613,19 +595,23 @@ diff_exec (file1, file2, label1, label2, options, out)
that I have seen. */
static void
-RCS_output_diff_options (opts, rev1, rev2, workfile)
- const char *opts;
+RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile)
+ int diff_argc;
+ char * const *diff_argv;
const char *rev1;
const char *rev2;
const char *workfile;
{
- char *tmp;
-
- tmp = (char *) xmalloc (strlen (opts) + strlen (rev1) + 10);
-
- sprintf (tmp, "diff%s -r%s", opts, rev1);
- cvs_output (tmp, 0);
- free (tmp);
+ int i;
+
+ cvs_output ("diff", 0);
+ for (i = 0; i < diff_argc; i++)
+ {
+ cvs_output (" ", 1);
+ cvs_output (diff_argv[i], 0);
+ }
+ cvs_output (" -r", 3);
+ cvs_output (rev1, 0);
if (rev2)
{
OpenPOWER on IntegriCloud