summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/diff
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-03-18 09:21:42 +0000
committerpeter <peter@FreeBSD.org>1999-03-18 09:21:42 +0000
commit308b60f66831aa65a459a7b347ea6ca14b6e4799 (patch)
tree1b2cd3bad90a2dd8ccb449f73ddfb9e295c0737d /contrib/cvs/diff
parent0c111e2b51cac7eead56494b30c5977e4ec9a8ea (diff)
downloadFreeBSD-src-308b60f66831aa65a459a7b347ea6ca14b6e4799.zip
FreeBSD-src-308b60f66831aa65a459a7b347ea6ca14b6e4799.tar.gz
Import cvs-1.10 onto vendor branch. Merge to follow shortly.
Obtained from: cyclic.com
Diffstat (limited to 'contrib/cvs/diff')
-rw-r--r--contrib/cvs/diff/ChangeLog53
-rw-r--r--contrib/cvs/diff/Makefile.in7
-rw-r--r--contrib/cvs/diff/context.c54
-rw-r--r--contrib/cvs/diff/diff.c97
-rw-r--r--contrib/cvs/diff/diff.h13
-rw-r--r--contrib/cvs/diff/diff3.c344
-rw-r--r--contrib/cvs/diff/diffrun.h69
-rw-r--r--contrib/cvs/diff/ed.c40
-rw-r--r--contrib/cvs/diff/ifdef.c70
-rw-r--r--contrib/cvs/diff/normal.c8
-rw-r--r--contrib/cvs/diff/side.c44
-rw-r--r--contrib/cvs/diff/util.c145
12 files changed, 662 insertions, 282 deletions
diff --git a/contrib/cvs/diff/ChangeLog b/contrib/cvs/diff/ChangeLog
index 34aa707..3ebde5d 100644
--- a/contrib/cvs/diff/ChangeLog
+++ b/contrib/cvs/diff/ChangeLog
@@ -1,3 +1,56 @@
+1998-08-06 David Masterson of kla-tencor.com
+
+ * util.c (flush_output): Don't prototype.
+
+Thu Jul 2 16:34:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Simplify the callback interface:
+ * diffrun.h: Don't include <stdarg.h> or <varargs.h>.
+ (struct diff_callbacks): Remove printf_output field.
+ * util.c: Include <stdarg.h> or <varargs.h>.
+ (printf_output): Use vasprintf and write_output callback rather
+ than printf_output callback.
+ * diff3.c (read_diff): Don't set my_callbacks.printf_output.
+
+Thu Jun 18 12:43:53 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * diffrun.h: New file.
+ * diff.h: Include diffrun.h.
+ (callbacks): New EXTERN variable.
+ (write_output, printf_output, flush_output): Declare.
+ * diff.c (diff_run): Add parameter callbacks_arg. Use callback
+ functions rather than writing to stdout. Don't open a file if
+ there is a write_output callback. Call perror_with_name rather
+ than perror.
+ (usage): Use callbacks if defined rather than writing to stdout.
+ (compare_files): Call flush_output rather than fflush (outfile).
+ * diff3.c: Include diffrun.h. Change several functions to use
+ output functions from util.c rather than direct printing. Use
+ diff_error and friends rather than printing to stderr. Set global
+ variable outfile.
+ (outfile, callbacks): Declare.
+ (write_output, printf_output, flush_output): Declare.
+ (diff3_run): Add parameter callbacks_arg. Use callback functions
+ rather than writing to stdout.
+ (usage): Use callbacks if defined rather than writing to stdout.
+ (read_diff): Preserve callbacks and outfile around call to
+ diff_run.
+ * util.c (perror_with_name): Use error callback if defined.
+ (pfatal_with_name, diff_error): Likewise.
+ (message5): Use printf_output and write_output.
+ (print_message_queue, print_1_line, output_1_line): Likewise.
+ (begin_output): Reject paginate_flag if there are output
+ callbacks.
+ (write_output, printf_output, flush_output): New functions.
+ * context.c: Change all output to outfile to use printf_output and
+ write_output.
+ * ed.c: Likewise.
+ * ifdef.c: Likewise.
+ * normal.c: Likewise.
+ * side.c: Likewise.
+ * Makefile.in (SOURCES): Add diffrun.h.
+ ($(OBJECTS)): Depend upon diffrun.h.
+
Fri Jan 16 14:58:19 1998 Larry Jones <larry.jones@sdrc.com>
* diff.c, diff3.c: Plug memory leaks.
diff --git a/contrib/cvs/diff/Makefile.in b/contrib/cvs/diff/Makefile.in
index 333d4d9..b47d4c1 100644
--- a/contrib/cvs/diff/Makefile.in
+++ b/contrib/cvs/diff/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for GNU DIFF
-# Copyright (C) 1988,1989,1991,1992,1993,1994,1997 Free Software Foundation, Inc.
+# Copyright (C) 1988,1989,1991,1992,1993,1994,1997,1998 Free Software Foundation, Inc.
#
# This file is part of GNU DIFF.
#
@@ -43,7 +43,8 @@ SHELL = /bin/sh
# The source files for all of the programs.
SOURCES = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c \
- normal.c ifdef.c util.c dir.c version.c diff.h side.c system.h
+ normal.c ifdef.c util.c dir.c version.c diff.h side.c system.h \
+ diffrun.h
OBJECTS = diff.o diff3.o analyze.o cmpbuf.o dir.o io.o util.o \
context.o ed.o ifdef.o normal.o side.o version.o
DISTFILES = $(SOURCES) ChangeLog build_diff.com Makefile.in
@@ -66,7 +67,7 @@ libdiff libdiff.a: $(OBJECTS)
$(AR) cr libdiff.a $(OBJECTS)
-$(RANLIB) libdiff.a
-$(OBJECTS): diff.h system.h
+$(OBJECTS): diff.h diffrun.h system.h
analyze.o cmpbuf.o: cmpbuf.h
util.o: util.c
diff --git a/contrib/cvs/diff/context.c b/contrib/cvs/diff/context.c
index 14f950c..e843734 100644
--- a/contrib/cvs/diff/context.c
+++ b/contrib/cvs/diff/context.c
@@ -1,5 +1,5 @@
/* Context-format output routines for GNU DIFF.
- Copyright (C) 1988,1989,1991,1992,1993,1994 Free Software Foundation, Inc.
+ Copyright (C) 1988,1989,1991,1992,1993,1994,1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -43,14 +43,14 @@ print_context_label (mark, inf, label)
char const *label;
{
if (label)
- fprintf (outfile, "%s %s\n", mark, label);
+ printf_output ("%s %s\n", mark, label);
else
{
char const *ct = ctime (&inf->stat.st_mtime);
if (!ct)
ct = "?\n";
/* See Posix.2 section 4.17.6.1.4 for this format. */
- fprintf (outfile, "%s %s\t%s", mark, inf->name, ct);
+ printf_output ("%s %s\t%s", mark, inf->name, ct);
}
}
@@ -116,9 +116,9 @@ print_context_number_range (file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b > trans_a)
- fprintf (outfile, "%d,%d", trans_a, trans_b);
+ printf_output ("%d,%d", trans_a, trans_b);
else
- fprintf (outfile, "%d", trans_b);
+ printf_output ("%d", trans_b);
}
/* Print a portion of an edit script in context format.
@@ -137,7 +137,6 @@ pr_context_hunk (hunk)
char const *prefix;
char const *function;
size_t function_length;
- FILE *out;
/* Determine range of line numbers involved in each file. */
@@ -160,21 +159,20 @@ pr_context_hunk (hunk)
find_function (&files[0], first0, &function, &function_length);
begin_output ();
- out = outfile;
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
- fprintf (out, "***************");
+ printf_output ("***************");
if (function)
{
- fprintf (out, " ");
- fwrite (function, 1, min (function_length - 1, 40), out);
+ printf_output (" ");
+ write_output (function, min (function_length - 1, 40));
}
- fprintf (out, "\n*** ");
+ printf_output ("\n*** ");
print_context_number_range (&files[0], first0, last0);
- fprintf (out, " ****\n");
+ printf_output (" ****\n");
if (show_from)
{
@@ -201,9 +199,9 @@ pr_context_hunk (hunk)
}
}
- fprintf (out, "--- ");
+ printf_output ("--- ");
print_context_number_range (&files[1], first1, last1);
- fprintf (out, " ----\n");
+ printf_output (" ----\n");
if (show_to)
{
@@ -250,9 +248,9 @@ print_unidiff_number_range (file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b <= trans_a)
- fprintf (outfile, trans_b == trans_a ? "%d" : "%d,0", trans_b);
+ printf_output (trans_b == trans_a ? "%d" : "%d,0", trans_b);
else
- fprintf (outfile, "%d,%d", trans_a, trans_b - trans_a + 1);
+ printf_output ("%d,%d", trans_a, trans_b - trans_a + 1);
}
/* Print a portion of an edit script in unidiff format.
@@ -270,7 +268,6 @@ pr_unidiff_hunk (hunk)
struct change *next;
char const *function;
size_t function_length;
- FILE *out;
/* Determine range of line numbers involved in each file. */
@@ -293,23 +290,22 @@ pr_unidiff_hunk (hunk)
find_function (&files[0], first0, &function, &function_length);
begin_output ();
- out = outfile;
- fprintf (out, "@@ -");
+ printf_output ("@@ -");
print_unidiff_number_range (&files[0], first0, last0);
- fprintf (out, " +");
+ printf_output (" +");
print_unidiff_number_range (&files[1], first1, last1);
- fprintf (out, " @@");
+ printf_output (" @@");
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
if (function)
{
- putc (' ', out);
- fwrite (function, 1, min (function_length - 1, 40), out);
+ write_output (" ", 1);
+ write_output (function, min (function_length - 1, 40));
}
- putc ('\n', out);
+ write_output ("\n", 1);
next = hunk;
i = first0;
@@ -322,7 +318,7 @@ pr_unidiff_hunk (hunk)
if (!next || i < next->line0)
{
- putc (tab_align_flag ? '\t' : ' ', out);
+ write_output (tab_align_flag ? "\t" : " ", 1);
print_1_line (0, &files[0].linbuf[i++]);
j++;
}
@@ -333,9 +329,9 @@ pr_unidiff_hunk (hunk)
k = next->deleted;
while (k--)
{
- putc ('-', out);
+ write_output ("-", 1);
if (tab_align_flag)
- putc ('\t', out);
+ write_output ("\t", 1);
print_1_line (0, &files[0].linbuf[i++]);
}
@@ -344,9 +340,9 @@ pr_unidiff_hunk (hunk)
k = next->inserted;
while (k--)
{
- putc ('+', out);
+ write_output ("+", 1);
if (tab_align_flag)
- putc ('\t', out);
+ write_output ("\t", 1);
print_1_line (0, &files[1].linbuf[j++]);
}
diff --git a/contrib/cvs/diff/diff.c b/contrib/cvs/diff/diff.c
index c0e37d7..3467b53 100644
--- a/contrib/cvs/diff/diff.c
+++ b/contrib/cvs/diff/diff.c
@@ -1,5 +1,5 @@
/* GNU DIFF entry routine.
- Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -231,10 +231,11 @@ static struct option const longopts[] =
};
int
-diff_run (argc, argv, out)
+diff_run (argc, argv, out, callbacks_arg)
int argc;
char *argv[];
char *out;
+ const struct diff_callbacks *callbacks_arg;
{
int val;
int c;
@@ -242,6 +243,9 @@ diff_run (argc, argv, out)
int width = DEFAULT_WIDTH;
int show_c_function = 0;
int optind_old;
+ int opened_file = 0;
+
+ callbacks = callbacks_arg;
/* Do our initializations. */
initialize_main (&argc, &argv);
@@ -476,7 +480,14 @@ diff_run (argc, argv, out)
break;
case 'v':
- printf ("diff - GNU diffutils version %s\n", diff_version_string);
+ if (callbacks && callbacks->write_stdout)
+ {
+ (*callbacks->write_stdout) ("diff - GNU diffutils version ");
+ (*callbacks->write_stdout) (diff_version_string);
+ (*callbacks->write_stdout) ("\n");
+ }
+ else
+ printf ("diff - GNU diffutils version %s\n", diff_version_string);
return 0;
case 'w':
@@ -555,7 +566,8 @@ diff_run (argc, argv, out)
case 141:
usage ();
- check_output (stdout);
+ if (! callbacks || ! callbacks->write_stdout)
+ check_output (stdout);
return 0;
case 142:
@@ -645,23 +657,35 @@ diff_run (argc, argv, out)
switch_string = option_list (argv + 1, optind - 1);
- if (out == NULL)
- outfile = stdout;
+ if (callbacks && callbacks->write_output)
+ {
+ if (out != NULL)
+ {
+ diff_error ("write callback with output file", 0, 0);
+ return 2;
+ }
+ }
else
{
-#if HAVE_SETMODE
- /* A diff which is full of ^Z and such isn't going to work
- very well in text mode. */
- if (binary_I_O)
- outfile = fopen (out, "wb");
+ if (out == NULL)
+ outfile = stdout;
else
+ {
+#if HAVE_SETMODE
+ /* A diff which is full of ^Z and such isn't going to work
+ very well in text mode. */
+ if (binary_I_O)
+ outfile = fopen (out, "wb");
+ else
#endif
- outfile = fopen (out, "w");
- if (outfile == NULL)
- {
- perror_with_name ("could not open output file");
- return 2;
- }
+ outfile = fopen (out, "w");
+ if (outfile == NULL)
+ {
+ perror_with_name ("could not open output file");
+ return 2;
+ }
+ opened_file = 1;
+ }
}
/* Set the jump buffer, so that diff may abort execution without
@@ -669,7 +693,7 @@ diff_run (argc, argv, out)
if ((val = setjmp (diff_abort_buf)) != 0)
{
optind = optind_old;
- if (outfile != stdout)
+ if (opened_file)
fclose (outfile);
return val;
}
@@ -682,10 +706,14 @@ diff_run (argc, argv, out)
free (switch_string);
optind = optind_old;
- check_output (outfile);
- if (outfile != stdout)
+
+ if (! callbacks || ! callbacks->write_output)
+ check_output (outfile);
+
+ if (opened_file)
if (fclose (outfile) != 0)
- perror ("close error on output file");
+ perror_with_name ("close error on output file");
+
return val;
}
@@ -799,10 +827,27 @@ usage ()
{
char const * const *p;
- printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", diff_program_name);
- for (p = option_help; *p; p++)
- printf (" %s\n", *p);
- printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
+ if (callbacks && callbacks->write_stdout)
+ {
+ (*callbacks->write_stdout) ("Usage: ");
+ (*callbacks->write_stdout) (diff_program_name);
+ (*callbacks->write_stdout) (" [OPTION]... FILE1 FILE2\n\n");
+ for (p = option_help; *p; p++)
+ {
+ (*callbacks->write_stdout) (" ");
+ (*callbacks->write_stdout) (*p);
+ (*callbacks->write_stdout) ("\n");
+ }
+ (*callbacks->write_stdout)
+ ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
+ }
+ else
+ {
+ printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", diff_program_name);
+ for (p = option_help; *p; p++)
+ printf (" %s\n", *p);
+ printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
+ }
}
static int
@@ -1147,7 +1192,7 @@ compare_files (dir0, name0, dir1, name1, depth)
inf[0].name, inf[1].name);
}
else
- fflush (outfile);
+ flush_output ();
if (free0)
free (free0);
diff --git a/contrib/cvs/diff/diff.h b/contrib/cvs/diff/diff.h
index fba26a7..6107e62 100644
--- a/contrib/cvs/diff/diff.h
+++ b/contrib/cvs/diff/diff.h
@@ -1,5 +1,5 @@
/* Shared definitions for GNU DIFF
- Copyright (C) 1988, 89, 91, 92, 93, 97 Free Software Foundation, Inc.
+ Copyright (C) 1988, 89, 91, 92, 93, 97, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -21,6 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <setjmp.h>
#include "regex.h"
+#include "diffrun.h"
#define TAB_WIDTH 8
@@ -32,6 +33,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define EXTERN
#endif
+/* The callbacks to use for output. */
+EXTERN const struct diff_callbacks *callbacks;
+
enum output_style {
/* Default output style. */
OUTPUT_NORMAL,
@@ -329,6 +333,13 @@ void debug_script PARAMS((struct change *));
void diff_error PARAMS((char const *, char const *, char const *));
void fatal PARAMS((char const *));
void finish_output PARAMS((void));
+void write_output PARAMS((char const *, size_t));
+void printf_output PARAMS((char const *, ...))
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
+ __attribute__ ((__format__ (__printf__, 1, 2)))
+#endif
+ ;
+void flush_output PARAMS((void));
void message PARAMS((char const *, char const *, char const *));
void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
void output_1_line PARAMS((char const *, char const *, char const *, char const *));
diff --git a/contrib/cvs/diff/diff3.c b/contrib/cvs/diff/diff3.c
index 533214c..64867f4 100644
--- a/contrib/cvs/diff/diff3.c
+++ b/contrib/cvs/diff/diff3.c
@@ -1,5 +1,5 @@
/* Three way file comparison program (diff3) for Project GNU.
- Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <setjmp.h>
#include "getopt.h"
+#include "diffrun.h"
/* diff3.c has a real initialize_main function. */
#ifdef initialize_main
@@ -30,6 +31,18 @@
extern char const diff_version_string[];
+extern FILE *outfile;
+
+extern const struct diff_callbacks *callbacks;
+
+void write_output PARAMS((char const *, size_t));
+void printf_output PARAMS((char const *, ...))
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
+ __attribute__ ((__format__ (__printf__, 1, 2)))
+#endif
+ ;
+void flush_output PARAMS((void));
+
/*
* Internal data structures and macros for the diff3 program; includes
* data structures for both diff3 diffs and normal diffs.
@@ -186,9 +199,9 @@ static char *scan_diff_line PARAMS((char *, char **, size_t *, char *, int));
static enum diff_type process_diff_control PARAMS((char **, struct diff_block *));
static int compare_line_list PARAMS((char * const[], size_t const[], char * const[], size_t const[], int));
static int copy_stringlist PARAMS((char * const[], size_t const[], char *[], size_t[], int));
-static int dotlines PARAMS((FILE *, struct diff3_block *, int));
-static int output_diff3_edscript PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
-static int output_diff3_merge PARAMS((FILE *, FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
+static int dotlines PARAMS((struct diff3_block *, int));
+static int output_diff3_edscript PARAMS((struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
+static int output_diff3_merge PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
static size_t myread PARAMS((int, char *, size_t));
static struct diff3_block *create_diff3_block PARAMS((int, int, int, int, int, int));
static struct diff3_block *make_3way_diff PARAMS((struct diff_block *, struct diff_block *));
@@ -197,17 +210,16 @@ static struct diff3_block *using_to_diff3_block PARAMS((struct diff_block *[2],
static struct diff_block *process_diff PARAMS((char const *, char const *, struct diff_block **, char **));
static void check_output PARAMS((FILE *));
static void diff3_fatal PARAMS((char const *));
-static void output_diff3 PARAMS((FILE *, struct diff3_block *, int const[3], int const[3]));
+static void output_diff3 PARAMS((struct diff3_block *, int const[3], int const[3]));
static void diff3_perror_with_exit PARAMS((char const *));
static int try_help PARAMS((char const *));
-static void undotlines PARAMS((FILE *, int, int, int));
+static void undotlines PARAMS((int, int, int));
static void usage PARAMS((void));
static void initialize_main PARAMS((int *, char ***));
static void free_diff_blocks PARAMS((struct diff_block *));
static void free_diff3_blocks PARAMS((struct diff3_block *));
/* Functions provided in libdiff.a or other external sources. */
-int diff_run PARAMS((int, char **, char *));
VOID *xmalloc PARAMS((size_t));
VOID *xrealloc PARAMS((VOID *, size_t));
void perror_with_name PARAMS((char const *));
@@ -238,10 +250,11 @@ static struct option const longopts[] =
* combines the two diffs, and outputs them.
*/
int
-diff3_run (argc, argv, outfile)
+diff3_run (argc, argv, out, callbacks_arg)
int argc;
char **argv;
- char *outfile;
+ char *out;
+ const struct diff_callbacks *callbacks_arg;
{
int c, i;
int mapping[3];
@@ -258,7 +271,9 @@ diff3_run (argc, argv, outfile)
char **file;
struct stat statb;
int optind_old;
- FILE *outstream;
+ int opened_file = 0;
+
+ callbacks = callbacks_arg;
initialize_main (&argc, &argv);
@@ -303,11 +318,19 @@ diff3_run (argc, argv, outfile)
tab_align_flag = 1;
break;
case 'v':
- printf ("diff3 - GNU diffutils version %s\n", diff_version_string);
+ if (callbacks && callbacks->write_stdout)
+ {
+ (*callbacks->write_stdout) ("diff3 - GNU diffutils version ");
+ (*callbacks->write_stdout) (diff_version_string);
+ (*callbacks->write_stdout) ("\n");
+ }
+ else
+ printf ("diff3 - GNU diffutils version %s\n", diff_version_string);
return 0;
case 129:
usage ();
- check_output (stdout);
+ if (! callbacks || ! callbacks->write_stdout)
+ check_output (stdout);
return 0;
case 'L':
/* Handle up to three -L options. */
@@ -383,22 +406,33 @@ diff3_run (argc, argv, outfile)
}
else if (S_ISDIR(statb.st_mode))
{
- fprintf (stderr, "%s: %s: Is a directory\n",
- diff_program_name, file[i]);
+ diff_error ("%s: Is a directory", file[i], 0);
return 2;
}
}
- if (outfile == NULL)
- outstream = stdout;
- else
+ if (callbacks && callbacks->write_output)
{
- outstream = fopen (outfile, "w");
- if (outstream == NULL)
- {
- perror_with_name ("could not open output file");
+ if (out != NULL)
+ {
+ diff_error ("write callback with output file", 0, 0);
return 2;
- }
+ }
+ }
+ else
+ {
+ if (out == NULL)
+ outfile = stdout;
+ else
+ {
+ outfile = fopen (out, "w");
+ if (outfile == NULL)
+ {
+ perror_with_name ("could not open output file");
+ return 2;
+ }
+ opened_file = 1;
+ }
}
/* Set the jump buffer, so that diff may abort execution without
@@ -421,21 +455,21 @@ diff3_run (argc, argv, outfile)
diff3 = make_3way_diff (thread0, thread1);
if (edscript)
conflicts_found
- = output_diff3_edscript (outstream, diff3, mapping, rev_mapping,
+ = output_diff3_edscript (diff3, mapping, rev_mapping,
tag_strings[0], tag_strings[1], tag_strings[2]);
else if (merge)
{
if (! freopen (file[rev_mapping[FILE0]], "r", stdin))
diff3_perror_with_exit (file[rev_mapping[FILE0]]);
conflicts_found
- = output_diff3_merge (stdin, outstream, diff3, mapping, rev_mapping,
+ = output_diff3_merge (stdin, diff3, mapping, rev_mapping,
tag_strings[0], tag_strings[1], tag_strings[2]);
if (ferror (stdin))
diff3_fatal ("read error");
}
else
{
- output_diff3 (outstream, diff3, mapping, rev_mapping);
+ output_diff3 (diff3, mapping, rev_mapping);
conflicts_found = 0;
}
@@ -445,10 +479,13 @@ diff3_run (argc, argv, outfile)
free_diff_blocks(thread1);
free_diff3_blocks(diff3);
- check_output (outstream);
- if (outstream != stdout)
- if (fclose (outstream) != 0)
- perror ("close error on output file");
+ if (! callbacks || ! callbacks->write_output)
+ check_output (outfile);
+
+ if (opened_file)
+ if (fclose (outfile) != 0)
+ perror_with_name ("close error on output file");
+
return conflicts_found;
}
@@ -457,9 +494,8 @@ try_help (reason)
char const *reason;
{
if (reason)
- fprintf (stderr, "%s: %s\n", diff_program_name, reason);
- fprintf (stderr, "%s: Try `%s --help' for more information.\n",
- diff_program_name, diff_program_name);
+ diff_error ("%s", reason, 0);
+ diff_error ("Try `%s --help' for more information.", diff_program_name, 0);
return 2;
}
@@ -477,25 +513,52 @@ check_output (stream)
static void
usage ()
{
- printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", diff_program_name);
+ if (callbacks && callbacks->write_stdout)
+ {
+ (*callbacks->write_stdout) ("Usage: ");
+ (*callbacks->write_stdout) (diff_program_name);
+ (*callbacks->write_stdout) (" [OPTION]... MYFILE OLDFILE YOURFILE\n\n");
- printf ("%s", "\
+ (*callbacks->write_stdout) ("\
-e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
-E --show-overlap Output unmerged changes, bracketing conflicts.\n\
-A --show-all Output all changes, bracketing conflicts.\n\
-x --overlap-only Output overlapping changes.\n\
-X Output overlapping changes, bracketing them.\n\
-3 --easy-only Output unmerged nonoverlapping changes.\n\n");
- printf ("%s", "\
+ (*callbacks->write_stdout) ("\
-m --merge Output merged file instead of ed script (default -A).\n\
-L LABEL --label=LABEL Use LABEL instead of file name.\n\
-i Append `w' and `q' commands to ed scripts.\n\
-a --text Treat all files as text.\n\
-T --initial-tab Make tabs line up by prepending a tab.\n\n");
- printf ("%s", "\
+ (*callbacks->write_stdout) ("\
-v --version Output version info.\n\
--help Output this help.\n\n");
- printf ("If a FILE is `-', read standard input.\n");
+ (*callbacks->write_stdout) ("If a FILE is `-', read standard input.\n");
+ }
+ else
+ {
+ printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", diff_program_name);
+
+ printf ("%s", "\
+ -e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
+ -E --show-overlap Output unmerged changes, bracketing conflicts.\n\
+ -A --show-all Output all changes, bracketing conflicts.\n\
+ -x --overlap-only Output overlapping changes.\n\
+ -X Output overlapping changes, bracketing them.\n\
+ -3 --easy-only Output unmerged nonoverlapping changes.\n\n");
+ printf ("%s", "\
+ -m --merge Output merged file instead of ed script (default -A).\n\
+ -L LABEL --label=LABEL Use LABEL instead of file name.\n\
+ -i Append `w' and `q' commands to ed scripts.\n\
+ -a --text Treat all files as text.\n\
+ -T --initial-tab Make tabs line up by prepending a tab.\n\n");
+ printf ("%s", "\
+ -v --version Output version info.\n\
+ --help Output this help.\n\n");
+ printf ("If a FILE is `-', read standard input.\n");
+ }
}
/*
@@ -1011,12 +1074,13 @@ process_diff (filea, fileb, last_block, diff_contents)
dt = process_diff_control (&scan_diff, bptr);
if (dt == ERROR || *scan_diff != '\n')
{
- fprintf (stderr, "%s: diff error: ", diff_program_name);
- do
- {
- putc (*scan_diff, stderr);
- }
- while (*scan_diff++ != '\n');
+ char *serr;
+
+ for (serr = scan_diff; *serr != '\n'; serr++)
+ ;
+ *serr = '\0';
+ diff_error ("diff error: %s", scan_diff, 0);
+ *serr = '\n';
DIFF3_ABORT (2);
}
scan_diff++;
@@ -1185,6 +1249,10 @@ read_diff (filea, fileb, output_placement)
size_t bytes, current_chunk_size, total;
int fd, wstatus;
struct stat pipestat;
+ FILE *outfile_hold;
+ const struct diff_callbacks *callbacks_hold;
+ struct diff_callbacks my_callbacks;
+ struct diff_callbacks *my_callbacks_arg;
/* 302 / 1000 is log10(2.0) rounded up. Subtract 1 for the sign bit;
add 1 for integer division truncation; add 1 more for a minus sign. */
@@ -1207,7 +1275,30 @@ read_diff (filea, fileb, output_placement)
*ap = 0;
diffout = tmpnam(NULL);
- wstatus = diff_run (ap - argv, (char **) argv, diffout);
+
+ outfile_hold = outfile;
+ callbacks_hold = callbacks;
+
+ /* We want to call diff_run preserving any stdout and stderr
+ callbacks, but discarding any callbacks to handle file output,
+ since we want the file output to go to our temporary file.
+ FIXME: We should use callbacks to just read it into a memory
+ buffer; that's we do with the temporary file just below anyhow. */
+ if (callbacks == NULL)
+ my_callbacks_arg = NULL;
+ else
+ {
+ my_callbacks = *callbacks;
+ my_callbacks.write_output = NULL;
+ my_callbacks.flush_output = NULL;
+ my_callbacks_arg = &my_callbacks;
+ }
+
+ wstatus = diff_run (ap - argv, (char **) argv, diffout, my_callbacks_arg);
+
+ outfile = outfile_hold;
+ callbacks = callbacks_hold;
+
if (wstatus == 2)
diff3_fatal ("subsidiary diff failed");
@@ -1282,17 +1373,25 @@ scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar)
*set_length = line_ptr - *set_start;
if (line_ptr < limit && *line_ptr == '\\')
{
- if (edscript)
- fprintf (stderr, "%s:", diff_program_name);
+ if (! edscript)
+ {
+ --*set_length;
+ line_ptr++;
+ while (*line_ptr++ != '\n')
+ ;
+ }
else
- --*set_length;
- line_ptr++;
- do
{
- if (edscript)
- putc (*line_ptr, stderr);
+ char *serr;
+
+ line_ptr++;
+ serr = line_ptr;
+ while (*line_ptr++ != '\n')
+ ;
+ line_ptr[-1] = '\0';
+ diff_error ("%s", serr, 0);
+ line_ptr[-1] = '\n';
}
- while (*line_ptr++ != '\n');
}
return line_ptr;
@@ -1310,8 +1409,7 @@ scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar)
* REV_MAPPING is the inverse of MAPPING.
*/
static void
-output_diff3 (outputfile, diff, mapping, rev_mapping)
- FILE *outputfile;
+output_diff3 (diff, mapping, rev_mapping)
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
{
@@ -1348,7 +1446,7 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
default:
diff3_fatal ("internal error: invalid diff type passed to output");
}
- fprintf (outputfile, "====%s\n", x);
+ printf_output ("====%s\n", x);
/* Go 0, 2, 1 if the first and third outputs are equivalent. */
for (i = 0; i < 3;
@@ -1359,17 +1457,17 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
lowt = D_LOWLINE (ptr, realfile),
hight = D_HIGHLINE (ptr, realfile);
- fprintf (outputfile, "%d:", i + 1);
+ printf_output ("%d:", i + 1);
switch (lowt - hight)
{
case 1:
- fprintf (outputfile, "%da\n", lowt - 1);
+ printf_output ("%da\n", lowt - 1);
break;
case 0:
- fprintf (outputfile, "%dc\n", lowt);
+ printf_output ("%dc\n", lowt);
break;
default:
- fprintf (outputfile, "%d,%dc\n", lowt, hight);
+ printf_output ("%d,%dc\n", lowt, hight);
break;
}
@@ -1380,14 +1478,14 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
line = 0;
do
{
- fprintf (outputfile, line_prefix);
+ printf_output (line_prefix);
cp = D_RELNUM (ptr, realfile, line);
length = D_RELLEN (ptr, realfile, line);
- fwrite (cp, sizeof (char), length, outputfile);
+ write_output (cp, length);
}
while (++line < hight - lowt + 1);
if (cp[length - 1] != '\n')
- fprintf (outputfile, "\n\\ No newline at end of file\n");
+ printf_output ("\n\\ No newline at end of file\n");
}
}
}
@@ -1395,12 +1493,11 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
/*
- * Output to OUTPUTFILE the lines of B taken from FILENUM.
+ * Output the lines of B taken from FILENUM.
* Double any initial '.'s; yield nonzero if any initial '.'s were doubled.
*/
static int
-dotlines (outputfile, b, filenum)
- FILE *outputfile;
+dotlines (b, filenum)
struct diff3_block *b;
int filenum;
{
@@ -1415,10 +1512,9 @@ dotlines (outputfile, b, filenum)
if (line[0] == '.')
{
leading_dot = 1;
- fprintf (outputfile, ".");
+ write_output (".", 1);
}
- fwrite (line, sizeof (char),
- D_RELLEN (b, filenum, i), outputfile);
+ write_output (line, D_RELLEN (b, filenum, i));
}
return leading_dot;
@@ -1430,16 +1526,15 @@ dotlines (outputfile, b, filenum)
* starting with line START and continuing for NUM lines.
*/
static void
-undotlines (outputfile, leading_dot, start, num)
- FILE *outputfile;
+undotlines (leading_dot, start, num)
int leading_dot, start, num;
{
- fprintf (outputfile, ".\n");
+ write_output (".\n", 2);
if (leading_dot)
if (num == 1)
- fprintf (outputfile, "%ds/^\\.//\n", start);
+ printf_output ("%ds/^\\.//\n", start);
else
- fprintf (outputfile, "%d,%ds/^\\.//\n", start, start + num - 1);
+ printf_output ("%d,%ds/^\\.//\n", start, start + num - 1);
}
/*
@@ -1465,9 +1560,7 @@ undotlines (outputfile, leading_dot, start, num)
*/
static int
-output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
- file0, file1, file2)
- FILE *outputfile;
+output_diff3_edscript (diff, mapping, rev_mapping, file0, file1, file2)
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
char const *file0, *file1, *file2;
@@ -1502,22 +1595,22 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Mark end of conflict. */
- fprintf (outputfile, "%da\n", D_HIGHLINE (b, mapping[FILE0]));
+ printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0]));
leading_dot = 0;
if (type == DIFF_ALL)
{
if (show_2nd)
{
/* Append lines from FILE1. */
- fprintf (outputfile, "||||||| %s\n", file1);
- leading_dot = dotlines (outputfile, b, mapping[FILE1]);
+ printf_output ("||||||| %s\n", file1);
+ leading_dot = dotlines (b, mapping[FILE1]);
}
/* Append lines from FILE2. */
- fprintf (outputfile, "=======\n");
- leading_dot |= dotlines (outputfile, b, mapping[FILE2]);
+ printf_output ("=======\n");
+ leading_dot |= dotlines (b, mapping[FILE2]);
}
- fprintf (outputfile, ">>>>>>> %s\n", file2);
- undotlines (outputfile, leading_dot,
+ printf_output (">>>>>>> %s\n", file2);
+ undotlines (leading_dot,
D_HIGHLINE (b, mapping[FILE0]) + 2,
(D_NUMLINES (b, mapping[FILE1])
+ D_NUMLINES (b, mapping[FILE2]) + 1));
@@ -1525,17 +1618,17 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Mark start of conflict. */
- fprintf (outputfile, "%da\n<<<<<<< %s\n",
- D_LOWLINE (b, mapping[FILE0]) - 1,
- type == DIFF_ALL ? file0 : file1);
+ printf_output ("%da\n<<<<<<< %s\n",
+ D_LOWLINE (b, mapping[FILE0]) - 1,
+ type == DIFF_ALL ? file0 : file1);
leading_dot = 0;
if (type == DIFF_2ND)
{
/* Prepend lines from FILE1. */
- leading_dot = dotlines (outputfile, b, mapping[FILE1]);
- fprintf (outputfile, "=======\n");
+ leading_dot = dotlines (b, mapping[FILE1]);
+ printf_output ("=======\n");
}
- undotlines (outputfile, leading_dot,
+ undotlines (leading_dot,
D_LOWLINE (b, mapping[FILE0]) + 1,
D_NUMLINES (b, mapping[FILE1]));
}
@@ -1543,12 +1636,11 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Write out a delete */
{
if (D_NUMLINES (b, mapping[FILE0]) == 1)
- fprintf (outputfile, "%dd\n",
- D_LOWLINE (b, mapping[FILE0]));
+ printf_output ("%dd\n", D_LOWLINE (b, mapping[FILE0]));
else
- fprintf (outputfile, "%d,%dd\n",
- D_LOWLINE (b, mapping[FILE0]),
- D_HIGHLINE (b, mapping[FILE0]));
+ printf_output ("%d,%dd\n",
+ D_LOWLINE (b, mapping[FILE0]),
+ D_HIGHLINE (b, mapping[FILE0]));
}
else
/* Write out an add or change */
@@ -1556,33 +1648,32 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
switch (D_NUMLINES (b, mapping[FILE0]))
{
case 0:
- fprintf (outputfile, "%da\n",
- D_HIGHLINE (b, mapping[FILE0]));
+ printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0]));
break;
case 1:
- fprintf (outputfile, "%dc\n",
- D_HIGHLINE (b, mapping[FILE0]));
+ printf_output ("%dc\n", D_HIGHLINE (b, mapping[FILE0]));
break;
default:
- fprintf (outputfile, "%d,%dc\n",
- D_LOWLINE (b, mapping[FILE0]),
- D_HIGHLINE (b, mapping[FILE0]));
+ printf_output ("%d,%dc\n",
+ D_LOWLINE (b, mapping[FILE0]),
+ D_HIGHLINE (b, mapping[FILE0]));
break;
}
- undotlines (outputfile, dotlines (outputfile, b, mapping[FILE2]),
+ undotlines (dotlines (b, mapping[FILE2]),
D_LOWLINE (b, mapping[FILE0]),
D_NUMLINES (b, mapping[FILE2]));
}
}
- if (finalwrite) fprintf (outputfile, "w\nq\n");
+ if (finalwrite) printf_output ("w\nq\n");
return conflicts_found;
}
/*
- * Read from INFILE and output to OUTPUTFILE a set of diff3_ blocks DIFF
- * as a merged file. This acts like 'ed file0 <[output_diff3_edscript]',
- * except that it works even for binary data or incomplete lines.
+ * Read from INFILE and output to the standard output file a set of
+ * diff3_ blocks DIFF as a merged file. This acts like 'ed file0
+ * <[output_diff3_edscript]', except that it works even for binary
+ * data or incomplete lines.
*
* As before, MAPPING maps from arg list file number to diff file number,
* REV_MAPPING is its inverse,
@@ -1592,14 +1683,15 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
*/
static int
-output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
+output_diff3_merge (infile, diff, mapping, rev_mapping,
file0, file1, file2)
- FILE *infile, *outputfile;
+ FILE *infile;
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
char const *file0, *file1, *file2;
{
int c, i;
+ char cc;
int conflicts_found = 0, conflict;
struct diff3_block *b;
int linesread = 0;
@@ -1638,7 +1730,8 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
diff3_perror_with_exit ("input file");
else if (feof (infile))
diff3_fatal ("input file shrank");
- putc (c, outputfile);
+ cc = c;
+ write_output (&cc, 1);
}
while (c != '\n');
@@ -1649,37 +1742,37 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
if (type == DIFF_ALL)
{
/* Put in lines from FILE0 with bracket. */
- fprintf (outputfile, "<<<<<<< %s\n", file0);
+ printf_output ("<<<<<<< %s\n", file0);
for (i = 0;
i < D_NUMLINES (b, mapping[FILE0]);
i++)
- fwrite (D_RELNUM (b, mapping[FILE0], i), sizeof (char),
- D_RELLEN (b, mapping[FILE0], i), outputfile);
+ write_output (D_RELNUM (b, mapping[FILE0], i),
+ D_RELLEN (b, mapping[FILE0], i));
}
if (show_2nd)
{
/* Put in lines from FILE1 with bracket. */
- fprintf (outputfile, format_2nd, file1);
+ printf_output (format_2nd, file1);
for (i = 0;
i < D_NUMLINES (b, mapping[FILE1]);
i++)
- fwrite (D_RELNUM (b, mapping[FILE1], i), sizeof (char),
- D_RELLEN (b, mapping[FILE1], i), outputfile);
+ write_output (D_RELNUM (b, mapping[FILE1], i),
+ D_RELLEN (b, mapping[FILE1], i));
}
- fprintf (outputfile, "=======\n");
+ printf_output ("=======\n");
}
/* Put in lines from FILE2. */
for (i = 0;
i < D_NUMLINES (b, mapping[FILE2]);
i++)
- fwrite (D_RELNUM (b, mapping[FILE2], i), sizeof (char),
- D_RELLEN (b, mapping[FILE2], i), outputfile);
+ write_output (D_RELNUM (b, mapping[FILE2], i),
+ D_RELLEN (b, mapping[FILE2], i));
if (conflict)
- fprintf (outputfile, ">>>>>>> %s\n", file2);
+ printf_output (">>>>>>> %s\n", file2);
/* Skip I lines in file 0. */
i = D_NUMLINES (b, FILE0);
@@ -1698,7 +1791,10 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
}
/* Copy rest of common file. */
while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile)))
- putc (c, outputfile);
+ {
+ cc = c;
+ write_output (&cc, 1);
+ }
return conflicts_found;
}
@@ -1737,7 +1833,7 @@ static void
diff3_fatal (string)
char const *string;
{
- fprintf (stderr, "%s: %s\n", diff_program_name, string);
+ diff_error ("%s", string, 0);
DIFF3_ABORT (2);
}
@@ -1745,10 +1841,7 @@ static void
diff3_perror_with_exit (string)
char const *string;
{
- int e = errno;
- fprintf (stderr, "%s: ", diff_program_name);
- errno = e;
- perror (string);
+ perror_with_name (string);
DIFF3_ABORT (2);
}
@@ -1768,6 +1861,7 @@ initialize_main (argcp, argvp)
finalwrite = 0;
merge = 0;
diff_program_name = (*argvp)[0];
+ outfile = NULL;
}
static void
diff --git a/contrib/cvs/diff/diffrun.h b/contrib/cvs/diff/diffrun.h
new file mode 100644
index 0000000..28c1f45
--- /dev/null
+++ b/contrib/cvs/diff/diffrun.h
@@ -0,0 +1,69 @@
+/* Interface header file for GNU DIFF library.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU DIFF.
+
+GNU DIFF is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU DIFF is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU DIFF; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef DIFFRUN_H
+#define DIFFRUN_H
+
+/* This header file defines the interfaces used by the diff library.
+ It should be included by programs which use the diff library. */
+
+#include <sys/types.h>
+
+#if defined __STDC__ && __STDC__
+#define DIFFPARAMS(args) args
+#else
+#define DIFFPARAMS(args) ()
+#endif
+
+/* The diff_callbacks structure is used to handle callbacks from the
+ diff library. All output goes through these callbacks. When a
+ pointer to this structure is passed in, it may be NULL. Also, any
+ of the individual callbacks may be NULL. This means that the
+ default action should be taken. */
+
+struct diff_callbacks
+{
+ /* Write output. This function just writes a string of a given
+ length to the output file. The default is to fwrite to OUTFILE.
+ If this callback is defined, flush_output must also be defined. */
+ void (*write_output) DIFFPARAMS((char const *, size_t));
+ /* Flush output. The default is to fflush OUTFILE. If this
+ callback is defined, write_output must also be defined. */
+ void (*flush_output) DIFFPARAMS((void));
+ /* Write to stdout. This is called for version and help messages. */
+ void (*write_stdout) DIFFPARAMS((char const *));
+ /* Print an error message. The first argument is a printf format,
+ and the next two are parameters. The default is to print a
+ message on stderr. */
+ void (*error) DIFFPARAMS((char const *, char const *, char const *));
+};
+
+/* Run a diff. */
+
+extern int diff_run DIFFPARAMS((int, char **, char *,
+ const struct diff_callbacks *));
+
+/* Run a diff3. */
+
+extern int diff3_run DIFFPARAMS((int, char **, char *,
+ const struct diff_callbacks *));
+
+#undef DIFFPARAMS
+
+#endif /* DIFFRUN_H */
diff --git a/contrib/cvs/diff/ed.c b/contrib/cvs/diff/ed.c
index 717ef35..6b00d13 100644
--- a/contrib/cvs/diff/ed.c
+++ b/contrib/cvs/diff/ed.c
@@ -1,5 +1,5 @@
/* Output routines for ed-script format.
- Copyright (C) 1988, 89, 91, 92, 93 Free Software Foundation, Inc.
+ Copyright (C) 1988, 89, 91, 92, 93, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -57,7 +57,7 @@ print_ed_hunk (hunk)
/* Print out the line number header for this hunk */
print_number_range (',', &files[0], f0, l0);
- fprintf (outfile, "%c\n", change_letter (inserts, deletes));
+ printf_output ("%c\n", change_letter (inserts, deletes));
/* Print new/changed lines from second file, if needed */
if (inserts)
@@ -68,8 +68,8 @@ print_ed_hunk (hunk)
{
/* Resume the insert, if we stopped. */
if (! inserting)
- fprintf (outfile, "%da\n",
- i - f1 + translate_line_number (&files[0], f0) - 1);
+ printf_output ("%da\n",
+ i - f1 + translate_line_number (&files[0], f0) - 1);
inserting = 1;
/* If the file's line is just a dot, it would confuse `ed'.
@@ -80,11 +80,11 @@ print_ed_hunk (hunk)
if (files[1].linbuf[i][0] == '.'
&& files[1].linbuf[i][1] == '\n')
{
- fprintf (outfile, "..\n");
- fprintf (outfile, ".\n");
+ printf_output ("..\n");
+ printf_output (".\n");
/* Now change that double dot to the desired single dot. */
- fprintf (outfile, "%ds/^\\.\\././\n",
- i - f1 + translate_line_number (&files[0], f0));
+ printf_output ("%ds/^\\.\\././\n",
+ i - f1 + translate_line_number (&files[0], f0));
inserting = 0;
}
else
@@ -94,7 +94,7 @@ print_ed_hunk (hunk)
/* End insert mode, if we are still in it. */
if (inserting)
- fprintf (outfile, ".\n");
+ printf_output (".\n");
}
}
@@ -124,9 +124,9 @@ pr_forward_ed_hunk (hunk)
begin_output ();
- fprintf (outfile, "%c", change_letter (inserts, deletes));
+ printf_output ("%c", change_letter (inserts, deletes));
print_number_range (' ', files, f0, l0);
- fprintf (outfile, "\n");
+ printf_output ("\n");
/* If deletion only, print just the number range. */
@@ -139,7 +139,7 @@ pr_forward_ed_hunk (hunk)
for (i = f1; i <= l1; i++)
print_1_line ("", &files[1].linbuf[i]);
- fprintf (outfile, ".\n");
+ printf_output (".\n");
}
/* Print in a format somewhat like ed commands
@@ -175,23 +175,23 @@ print_rcs_hunk (hunk)
if (deletes)
{
- fprintf (outfile, "d");
+ printf_output ("d");
/* For deletion, print just the starting line number from file 0
and the number of lines deleted. */
- fprintf (outfile, "%d %d\n",
- tf0,
- (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
+ printf_output ("%d %d\n",
+ tf0,
+ (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
}
if (inserts)
{
- fprintf (outfile, "a");
+ printf_output ("a");
/* Take last-line-number from file 0 and # lines from file 1. */
translate_range (&files[1], f1, l1, &tf1, &tl1);
- fprintf (outfile, "%d %d\n",
- tl0,
- (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
+ printf_output ("%d %d\n",
+ tl0,
+ (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
/* Print the inserted lines. */
for (i = f1; i <= l1; i++)
diff --git a/contrib/cvs/diff/ifdef.c b/contrib/cvs/diff/ifdef.c
index 2834cbd..94fcfb5 100644
--- a/contrib/cvs/diff/ifdef.c
+++ b/contrib/cvs/diff/ifdef.c
@@ -1,5 +1,5 @@
/* #ifdef-format output routines for GNU DIFF.
- Copyright (C) 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1991, 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -27,13 +27,13 @@ struct group
int from, upto; /* start and limit lines for this group of lines */
};
-static char *format_group PARAMS((FILE *, char *, int, struct group const *));
+static char *format_group PARAMS((int, char *, int, struct group const *));
static char *scan_char_literal PARAMS((char *, int *));
static char *scan_printf_spec PARAMS((char *));
static int groups_letter_value PARAMS((struct group const *, int));
static void format_ifdef PARAMS((char *, int, int, int, int));
static void print_ifdef_hunk PARAMS((struct change *));
-static void print_ifdef_lines PARAMS((FILE *, char *, struct group const *));
+static void print_ifdef_lines PARAMS((int, char *, struct group const *));
static int next_line;
@@ -103,18 +103,18 @@ format_ifdef (format, beg0, end0, beg1, end1)
groups[1].file = &files[1];
groups[1].from = beg1;
groups[1].upto = end1;
- format_group (outfile, format, '\0', groups);
+ format_group (1, format, '\0', groups);
}
-/* Print to file OUT a set of lines according to FORMAT.
+/* If DOIT is non-zero, output a set of lines according to FORMAT.
The format ends at the first free instance of ENDCHAR.
Yield the address of the terminating character.
GROUPS specifies which lines to print.
If OUT is zero, do not actually print anything; just scan the format. */
static char *
-format_group (out, format, endchar, groups)
- register FILE *out;
+format_group (doit, format, endchar, groups)
+ int doit;
char *format;
int endchar;
struct group const *groups;
@@ -137,7 +137,7 @@ format_group (out, format, endchar, groups)
/* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */
{
int i, value[2];
- FILE *thenout, *elseout;
+ int thendoit, elsedoit;
for (i = 0; i < 2; i++)
{
@@ -159,13 +159,13 @@ format_group (out, format, endchar, groups)
goto bad_format;
}
if (value[0] == value[1])
- thenout = out, elseout = 0;
+ thendoit = doit, elsedoit = 0;
else
- thenout = 0, elseout = out;
- f = format_group (thenout, f, ':', groups);
+ thendoit = 0, elsedoit = doit;
+ f = format_group (thendoit, f, ':', groups);
if (*f)
{
- f = format_group (elseout, f + 1, ')', groups);
+ f = format_group (elsedoit, f + 1, ')', groups);
if (*f)
f++;
}
@@ -174,17 +174,17 @@ format_group (out, format, endchar, groups)
case '<':
/* Print lines deleted from first file. */
- print_ifdef_lines (out, line_format[OLD], &groups[0]);
+ print_ifdef_lines (doit, line_format[OLD], &groups[0]);
continue;
case '=':
/* Print common lines. */
- print_ifdef_lines (out, line_format[UNCHANGED], &groups[0]);
+ print_ifdef_lines (doit, line_format[UNCHANGED], &groups[0]);
continue;
case '>':
/* Print lines inserted from second file. */
- print_ifdef_lines (out, line_format[NEW], &groups[1]);
+ print_ifdef_lines (doit, line_format[NEW], &groups[1]);
continue;
default:
@@ -211,11 +211,11 @@ format_group (out, format, endchar, groups)
goto bad_format;
break;
}
- if (out)
+ if (doit)
{
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
*speclim = 0;
- fprintf (out, spec - 1, value);
+ printf_output (spec - 1, value);
/* Undo the temporary replacement. */
*speclim = c;
}
@@ -228,8 +228,12 @@ format_group (out, format, endchar, groups)
break;
}
}
- if (out)
- putc (c, out);
+ if (doit)
+ {
+ /* Don't take the address of a register variable. */
+ char cc = c;
+ write_output (&cc, 1);
+ }
}
return f;
}
@@ -257,11 +261,11 @@ groups_letter_value (g, letter)
}
}
-/* Print to file OUT, using FORMAT to print the line group GROUP.
- But do nothing if OUT is zero. */
+/* Output using FORMAT to print the line group GROUP.
+ But do nothing if DOIT is zero. */
static void
-print_ifdef_lines (out, format, group)
- register FILE *out;
+print_ifdef_lines (doit, format, group)
+ int doit;
char *format;
struct group const *group;
{
@@ -269,7 +273,7 @@ print_ifdef_lines (out, format, group)
char const * const *linbuf = file->linbuf;
int from = group->from, upto = group->upto;
- if (!out)
+ if (!doit)
return;
/* If possible, use a single fwrite; it's faster. */
@@ -277,15 +281,15 @@ print_ifdef_lines (out, format, group)
{
if (format[1] == 'l' && format[2] == '\n' && !format[3])
{
- fwrite (linbuf[from], sizeof (char),
- linbuf[upto] + (linbuf[upto][-1] != '\n') - linbuf[from],
- out);
+ write_output (linbuf[from],
+ (linbuf[upto] + (linbuf[upto][-1] != '\n')
+ - linbuf[from]));
return;
}
if (format[1] == 'L' && !format[2])
{
- fwrite (linbuf[from], sizeof (char),
- linbuf[upto] - linbuf[from], out);
+ write_output (linbuf[from],
+ linbuf[upto] - linbuf[from]);
return;
}
}
@@ -294,6 +298,7 @@ print_ifdef_lines (out, format, group)
{
register char c;
register char *f = format;
+ char cc;
while ((c = *f++) != 0)
{
@@ -342,7 +347,7 @@ print_ifdef_lines (out, format, group)
}
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
*speclim = 0;
- fprintf (out, spec - 1, value);
+ printf_output (spec - 1, value);
/* Undo the temporary replacement. */
*speclim = c;
}
@@ -354,7 +359,10 @@ print_ifdef_lines (out, format, group)
break;
}
}
- putc (c, out);
+
+ /* Don't take the address of a register variable. */
+ cc = c;
+ write_output (&cc, 1);
}
}
}
diff --git a/contrib/cvs/diff/normal.c b/contrib/cvs/diff/normal.c
index 4d9e23c..75dae88 100644
--- a/contrib/cvs/diff/normal.c
+++ b/contrib/cvs/diff/normal.c
@@ -1,5 +1,5 @@
/* Normal-format output routines for GNU DIFF.
- Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1993, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -52,9 +52,9 @@ print_normal_hunk (hunk)
/* Print out the line number header for this hunk */
print_number_range (',', &files[0], first0, last0);
- fprintf (outfile, "%c", change_letter (inserts, deletes));
+ printf_output ("%c", change_letter (inserts, deletes));
print_number_range (',', &files[1], first1, last1);
- fprintf (outfile, "\n");
+ printf_output ("\n");
/* Print the lines that the first file has. */
if (deletes)
@@ -62,7 +62,7 @@ print_normal_hunk (hunk)
print_1_line ("<", &files[0].linbuf[i]);
if (inserts && deletes)
- fprintf (outfile, "---\n");
+ printf_output ("---\n");
/* Print the lines that the second file has. */
if (inserts)
diff --git a/contrib/cvs/diff/side.c b/contrib/cvs/diff/side.c
index a150b5e..d776e77 100644
--- a/contrib/cvs/diff/side.c
+++ b/contrib/cvs/diff/side.c
@@ -1,5 +1,5 @@
/* sdiff-format output routines for GNU DIFF.
- Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1992, 1993, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -50,17 +50,16 @@ static unsigned
tab_from_to (from, to)
unsigned from, to;
{
- FILE *out = outfile;
unsigned tab;
if (! tab_expand_flag)
for (tab = from + TAB_WIDTH - from % TAB_WIDTH; tab <= to; tab += TAB_WIDTH)
{
- putc ('\t', out);
+ write_output ("\t", 1);
from = tab;
}
while (from++ < to)
- putc (' ', out);
+ write_output (" ", 1);
return to;
}
@@ -74,7 +73,6 @@ print_half_line (line, indent, out_bound)
char const * const *line;
unsigned indent, out_bound;
{
- FILE *out = outfile;
register unsigned in_position = 0, out_position = 0;
register char const
*text_pointer = line[0],
@@ -83,6 +81,9 @@ print_half_line (line, indent, out_bound)
while (text_pointer < text_limit)
{
register unsigned char c = *text_pointer++;
+ /* We use CC to avoid taking the address of the register
+ variable C. */
+ char cc;
switch (c)
{
@@ -97,13 +98,14 @@ print_half_line (line, indent, out_bound)
if (out_bound < tabstop)
tabstop = out_bound;
for (; out_position < tabstop; out_position++)
- putc (' ', out);
+ write_output (" ", 1);
}
else
if (tabstop < out_bound)
{
out_position = tabstop;
- putc (c, out);
+ cc = c;
+ write_output (&cc, 1);
}
}
in_position += spaces;
@@ -112,7 +114,8 @@ print_half_line (line, indent, out_bound)
case '\r':
{
- putc (c, out);
+ cc = c;
+ write_output (&cc, 1);
tab_from_to (0, indent);
in_position = out_position = 0;
}
@@ -123,11 +126,12 @@ print_half_line (line, indent, out_bound)
if (out_position <= in_position)
/* Add spaces to make up for suppressed tab past out_bound. */
for (; out_position < in_position; out_position++)
- putc (' ', out);
+ write_output (" ", 1);
else
{
out_position = in_position;
- putc (c, out);
+ cc = c;
+ write_output (&cc, 1);
}
break;
@@ -135,7 +139,10 @@ print_half_line (line, indent, out_bound)
case '\v':
control_char:
if (in_position < out_bound)
- putc (c, out);
+ {
+ cc = c;
+ write_output (&cc, 1);
+ }
break;
default:
@@ -146,7 +153,8 @@ print_half_line (line, indent, out_bound)
if (in_position++ < out_bound)
{
out_position = in_position;
- putc (c, out);
+ cc = c;
+ write_output (&cc, 1);
}
break;
@@ -170,7 +178,6 @@ print_1sdiff_line (left, sep, right)
int sep;
char const * const *right;
{
- FILE *out = outfile;
unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset;
unsigned col = 0;
int put_newline = 0;
@@ -184,10 +191,13 @@ print_1sdiff_line (left, sep, right)
if (sep != ' ')
{
+ char cc;
+
col = tab_from_to (col, (hw + c2o - 1) / 2) + 1;
if (sep == '|' && put_newline != (right[1][-1] == '\n'))
sep = put_newline ? '/' : '\\';
- putc (sep, out);
+ cc = sep;
+ write_output (&cc, 1);
}
if (right)
@@ -202,7 +212,7 @@ print_1sdiff_line (left, sep, right)
}
if (put_newline)
- putc ('\n', out);
+ write_output ("\n", 1);
}
/* Print lines common to both files in side-by-side format. */
@@ -215,7 +225,7 @@ print_sdiff_common_lines (limit0, limit1)
if (! sdiff_skip_common_lines && (i0 != limit0 || i1 != limit1))
{
if (sdiff_help_sdiff)
- fprintf (outfile, "i%d,%d\n", limit0 - i0, limit1 - i1);
+ printf_output ("i%d,%d\n", limit0 - i0, limit1 - i1);
if (! sdiff_left_only)
{
@@ -252,7 +262,7 @@ print_sdiff_hunk (hunk)
print_sdiff_common_lines (first0, first1);
if (sdiff_help_sdiff)
- fprintf (outfile, "c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
+ printf_output ("c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
/* Print ``xxx | xxx '' lines */
if (inserts && deletes)
diff --git a/contrib/cvs/diff/util.c b/contrib/cvs/diff/util.c
index 89cc274..1b28170 100644
--- a/contrib/cvs/diff/util.c
+++ b/contrib/cvs/diff/util.c
@@ -1,5 +1,5 @@
/* Support routines for GNU DIFF.
- Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@@ -19,6 +19,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "diff.h"
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifndef strerror
+extern char *strerror ();
+#endif
+
/* Queue up one-line messages to be printed at the end,
when -l is specified. Each message is recorded with a `struct msg'. */
@@ -48,9 +58,15 @@ perror_with_name (text)
char const *text;
{
int e = errno;
- fprintf (stderr, "%s: ", diff_program_name);
- errno = e;
- perror (text);
+
+ if (callbacks && callbacks->error)
+ (*callbacks->error) ("%s: %s", text, strerror (e));
+ else
+ {
+ fprintf (stderr, "%s: ", diff_program_name);
+ errno = e;
+ perror (text);
+ }
}
/* Use when a system call returns non-zero status and that is fatal. */
@@ -61,9 +77,14 @@ pfatal_with_name (text)
{
int e = errno;
print_message_queue ();
- fprintf (stderr, "%s: ", diff_program_name);
- errno = e;
- perror (text);
+ if (callbacks && callbacks->error)
+ (*callbacks->error) ("%s: %s", text, strerror (e));
+ else
+ {
+ fprintf (stderr, "%s: ", diff_program_name);
+ errno = e;
+ perror (text);
+ }
DIFF_ABORT (2);
}
@@ -74,9 +95,14 @@ void
diff_error (format, arg, arg1)
char const *format, *arg, *arg1;
{
- fprintf (stderr, "%s: ", diff_program_name);
- fprintf (stderr, format, arg, arg1);
- fprintf (stderr, "\n");
+ if (callbacks && callbacks->error)
+ (*callbacks->error) (format, arg, arg1);
+ else
+ {
+ fprintf (stderr, "%s: ", diff_program_name);
+ fprintf (stderr, format, arg, arg1);
+ fprintf (stderr, "\n");
+ }
}
/* Print an error message containing the string TEXT, then exit. */
@@ -119,8 +145,8 @@ message5 (format, arg1, arg2, arg3, arg4)
else
{
if (sdiff_help_sdiff)
- putc (' ', outfile);
- fprintf (outfile, format, arg1, arg2, arg3, arg4);
+ write_output (" ", 1);
+ printf_output (format, arg1, arg2, arg3, arg4);
}
}
@@ -132,7 +158,7 @@ print_message_queue ()
struct msg *m;
for (m = msg_chain; m; m = m->next)
- fprintf (outfile, m->format, m->arg1, m->arg2, m->arg3, m->arg4);
+ printf_output (m->format, m->arg1, m->arg2, m->arg3, m->arg4);
}
/* Call before outputting the results of comparing files NAME0 and NAME1
@@ -180,6 +206,9 @@ begin_output ()
This requirement is silly and does not match historical practice. */
sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
+ if (paginate_flag && callbacks && callbacks->write_output)
+ fatal ("can't paginate when using library callbacks");
+
if (paginate_flag)
{
/* Make OUTFILE a pipe to a subsidiary `pr'. */
@@ -243,7 +272,7 @@ begin_output ()
/* If handling multiple files (because scanning a directory),
print which files the following output is about. */
if (current_depth > 0)
- fprintf (outfile, "%s\n", name);
+ printf_output ("%s\n", name);
}
free (name);
@@ -293,6 +322,68 @@ finish_output ()
output_in_progress = 0;
}
+
+/* Write something to the output file. */
+
+void
+write_output (text, len)
+ char const *text;
+ size_t len;
+{
+ if (callbacks && callbacks->write_output)
+ (*callbacks->write_output) (text, len);
+ else if (len == 1)
+ putc (*text, outfile);
+ else
+ fwrite (text, sizeof (char), len, outfile);
+}
+
+/* Printf something to the output file. */
+
+#ifdef __STDC__
+#define VA_START(args, lastarg) va_start(args, lastarg)
+#else /* ! __STDC__ */
+#define VA_START(args, lastarg) va_start(args)
+#endif /* __STDC__ */
+
+void
+#if defined (__STDC__)
+printf_output (const char *format, ...)
+#else
+printf_output (format, va_alist)
+ char const *format;
+ va_dcl
+#endif
+{
+ va_list args;
+
+ VA_START (args, format);
+ if (callbacks && callbacks->write_output)
+ {
+ char *p;
+
+ p = NULL;
+ vasprintf (&p, format, args);
+ if (p == NULL)
+ fatal ("out of memory");
+ (*callbacks->write_output) (p, strlen (p));
+ free (p);
+ }
+ else
+ vfprintf (outfile, format, args);
+ va_end (args);
+}
+
+/* Flush the output file. */
+
+void
+flush_output ()
+{
+ if (callbacks && callbacks->flush_output)
+ (*callbacks->flush_output) ();
+ else
+ fflush (outfile);
+}
/* Compare two lines (typically one from each input file)
according to the command line options.
@@ -469,7 +560,6 @@ print_1_line (line_flag, line)
char const * const *line;
{
char const *text = line[0], *limit = line[1]; /* Help the compiler. */
- FILE *out = outfile; /* Help the compiler some more. */
char const *flag_format = 0;
/* If -T was specified, use a Tab between the line-flag and the text.
@@ -479,13 +569,13 @@ print_1_line (line_flag, line)
if (line_flag && *line_flag)
{
flag_format = tab_align_flag ? "%s\t" : "%s ";
- fprintf (out, flag_format, line_flag);
+ printf_output (flag_format, line_flag);
}
output_1_line (text, limit, flag_format, line_flag);
if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
- fprintf (out, "\n\\ No newline at end of file\n");
+ printf_output ("\n\\ No newline at end of file\n");
}
/* Output a line from TEXT up to LIMIT. Without -t, output verbatim.
@@ -498,13 +588,15 @@ output_1_line (text, limit, flag_format, line_flag)
char const *text, *limit, *flag_format, *line_flag;
{
if (!tab_expand_flag)
- fwrite (text, sizeof (char), limit - text, outfile);
+ write_output (text, limit - text);
else
{
- register FILE *out = outfile;
register unsigned char c;
register char const *t = text;
register unsigned column = 0;
+ /* CC is used to avoid taking the address of the register
+ variable C. */
+ char cc;
while (t < limit)
switch ((c = *t++))
@@ -514,15 +606,15 @@ output_1_line (text, limit, flag_format, line_flag)
unsigned spaces = TAB_WIDTH - column % TAB_WIDTH;
column += spaces;
do
- putc (' ', out);
+ write_output (" ", 1);
while (--spaces);
}
break;
case '\r':
- putc (c, out);
+ write_output ("\r", 1);
if (flag_format && t < limit && *t != '\n')
- fprintf (out, flag_format, line_flag);
+ printf_output (flag_format, line_flag);
column = 0;
break;
@@ -530,13 +622,14 @@ output_1_line (text, limit, flag_format, line_flag)
if (column == 0)
continue;
column--;
- putc (c, out);
+ write_output ("\b", 1);
break;
default:
if (ISPRINT (c))
column++;
- putc (c, out);
+ cc = c;
+ write_output (&cc, 1);
break;
}
}
@@ -598,9 +691,9 @@ print_number_range (sepchar, file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b > trans_a)
- fprintf (outfile, "%d%c%d", trans_a, sepchar, trans_b);
+ printf_output ("%d%c%d", trans_a, sepchar, trans_b);
else
- fprintf (outfile, "%d", trans_b);
+ printf_output ("%d", trans_b);
}
/* Look at a hunk of edit script and report the range of lines in each file
OpenPOWER on IntegriCloud