Remove files that were taken off vendor branch. Difference
against vendor branch is now maintained in patchsets.
This commit is contained in:
parent
019bb6b05e
commit
2a4f71e2a0
1121
contrib/diff/diff.c
1121
contrib/diff/diff.c
File diff suppressed because it is too large
Load Diff
@ -1,341 +0,0 @@
|
||||
/* Shared definitions for GNU DIFF
|
||||
Copyright (C) 1988, 89, 91, 92, 93 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. */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include "regex.h"
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
/* Variables for command line options */
|
||||
|
||||
#ifndef GDIFF_MAIN
|
||||
#define EXTERN extern
|
||||
#else
|
||||
#define EXTERN
|
||||
#endif
|
||||
|
||||
enum output_style {
|
||||
/* Default output style. */
|
||||
OUTPUT_NORMAL,
|
||||
/* Output the differences with lines of context before and after (-c). */
|
||||
OUTPUT_CONTEXT,
|
||||
/* Output the differences in a unified context diff format (-u). */
|
||||
OUTPUT_UNIFIED,
|
||||
/* Output the differences as commands suitable for `ed' (-e). */
|
||||
OUTPUT_ED,
|
||||
/* Output the diff as a forward ed script (-f). */
|
||||
OUTPUT_FORWARD_ED,
|
||||
/* Like -f, but output a count of changed lines in each "command" (-n). */
|
||||
OUTPUT_RCS,
|
||||
/* Output merged #ifdef'd file (-D). */
|
||||
OUTPUT_IFDEF,
|
||||
/* Output sdiff style (-y). */
|
||||
OUTPUT_SDIFF
|
||||
};
|
||||
|
||||
/* True for output styles that are robust,
|
||||
i.e. can handle a file that ends in a non-newline. */
|
||||
#define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
|
||||
|
||||
EXTERN enum output_style output_style;
|
||||
|
||||
/* Nonzero if output cannot be generated for identical files. */
|
||||
EXTERN int no_diff_means_no_output;
|
||||
|
||||
/* Number of lines of context to show in each set of diffs.
|
||||
This is zero when context is not to be shown. */
|
||||
EXTERN int context;
|
||||
|
||||
/* Consider all files as text files (-a).
|
||||
Don't interpret codes over 0177 as implying a "binary file". */
|
||||
EXTERN int always_text_flag;
|
||||
|
||||
/* Number of lines to keep in identical prefix and suffix. */
|
||||
EXTERN int horizon_lines;
|
||||
|
||||
/* Ignore changes in horizontal white space (-b). */
|
||||
EXTERN int ignore_space_change_flag;
|
||||
|
||||
/* Ignore all horizontal white space (-w). */
|
||||
EXTERN int ignore_all_space_flag;
|
||||
|
||||
/* Ignore changes that affect only blank lines (-B). */
|
||||
EXTERN int ignore_blank_lines_flag;
|
||||
|
||||
/* 1 if lines may match even if their contents do not match exactly.
|
||||
This depends on various options. */
|
||||
EXTERN int ignore_some_line_changes;
|
||||
|
||||
/* 1 if files may match even if their contents are not byte-for-byte identical.
|
||||
This depends on various options. */
|
||||
EXTERN int ignore_some_changes;
|
||||
|
||||
/* Ignore differences in case of letters (-i). */
|
||||
EXTERN int ignore_case_flag;
|
||||
|
||||
/* File labels for `-c' output headers (-L). */
|
||||
EXTERN char *file_label[2];
|
||||
|
||||
struct regexp_list
|
||||
{
|
||||
struct re_pattern_buffer buf;
|
||||
struct regexp_list *next;
|
||||
};
|
||||
|
||||
/* Regexp to identify function-header lines (-F). */
|
||||
EXTERN struct regexp_list *function_regexp_list;
|
||||
|
||||
/* Ignore changes that affect only lines matching this regexp (-I). */
|
||||
EXTERN struct regexp_list *ignore_regexp_list;
|
||||
|
||||
/* Say only whether files differ, not how (-q). */
|
||||
EXTERN int no_details_flag;
|
||||
|
||||
/* Report files compared that match (-s).
|
||||
Normally nothing is output when that happens. */
|
||||
EXTERN int print_file_same_flag;
|
||||
|
||||
/* Output the differences with exactly 8 columns added to each line
|
||||
so that any tabs in the text line up properly (-T). */
|
||||
EXTERN int tab_align_flag;
|
||||
|
||||
/* Expand tabs in the output so the text lines up properly
|
||||
despite the characters added to the front of each line (-t). */
|
||||
EXTERN int tab_expand_flag;
|
||||
|
||||
/* In directory comparison, specify file to start with (-S).
|
||||
All file names less than this name are ignored. */
|
||||
EXTERN char *dir_start_file;
|
||||
|
||||
/* If a file is new (appears in only one dir)
|
||||
include its entire contents (-N).
|
||||
Then `patch' would create the file with appropriate contents. */
|
||||
EXTERN int entire_new_file_flag;
|
||||
|
||||
/* If a file is new (appears in only the second dir)
|
||||
include its entire contents (-P).
|
||||
Then `patch' would create the file with appropriate contents. */
|
||||
EXTERN int unidirectional_new_file_flag;
|
||||
|
||||
/* Pipe each file's output through pr (-l). */
|
||||
EXTERN int paginate_flag;
|
||||
|
||||
enum line_class {
|
||||
/* Lines taken from just the first file. */
|
||||
OLD,
|
||||
/* Lines taken from just the second file. */
|
||||
NEW,
|
||||
/* Lines common to both files. */
|
||||
UNCHANGED,
|
||||
/* A hunk containing both old and new lines (line groups only). */
|
||||
CHANGED
|
||||
};
|
||||
|
||||
/* Line group formats for old, new, unchanged, and changed groups. */
|
||||
EXTERN char *group_format[CHANGED + 1];
|
||||
|
||||
/* Line formats for old, new, and unchanged lines. */
|
||||
EXTERN char *line_format[UNCHANGED + 1];
|
||||
|
||||
/* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
|
||||
EXTERN int sdiff_help_sdiff;
|
||||
|
||||
/* Tell OUTPUT_SDIFF to show only the left version of common lines. */
|
||||
EXTERN int sdiff_left_only;
|
||||
|
||||
/* Tell OUTPUT_SDIFF to not show common lines. */
|
||||
EXTERN int sdiff_skip_common_lines;
|
||||
|
||||
/* The half line width and column 2 offset for OUTPUT_SDIFF. */
|
||||
EXTERN unsigned sdiff_half_width;
|
||||
EXTERN unsigned sdiff_column2_offset;
|
||||
|
||||
/* String containing all the command options diff received,
|
||||
with spaces between and at the beginning but none at the end.
|
||||
If there were no options given, this string is empty. */
|
||||
EXTERN char * switch_string;
|
||||
|
||||
/* Nonzero means use heuristics for better speed. */
|
||||
EXTERN int heuristic;
|
||||
|
||||
/* Name of program the user invoked (for error messages). */
|
||||
EXTERN char *program_name;
|
||||
|
||||
/* The result of comparison is an "edit script": a chain of `struct change'.
|
||||
Each `struct change' represents one place where some lines are deleted
|
||||
and some are inserted.
|
||||
|
||||
LINE0 and LINE1 are the first affected lines in the two files (origin 0).
|
||||
DELETED is the number of lines deleted here from file 0.
|
||||
INSERTED is the number of lines inserted here in file 1.
|
||||
|
||||
If DELETED is 0 then LINE0 is the number of the line before
|
||||
which the insertion was done; vice versa for INSERTED and LINE1. */
|
||||
|
||||
struct change
|
||||
{
|
||||
struct change *link; /* Previous or next edit command */
|
||||
int inserted; /* # lines of file 1 changed here. */
|
||||
int deleted; /* # lines of file 0 changed here. */
|
||||
int line0; /* Line number of 1st deleted line. */
|
||||
int line1; /* Line number of 1st inserted line. */
|
||||
char ignore; /* Flag used in context.c */
|
||||
};
|
||||
|
||||
/* Structures that describe the input files. */
|
||||
|
||||
/* Data on one input file being compared. */
|
||||
|
||||
struct file_data {
|
||||
int desc; /* File descriptor */
|
||||
char const *name; /* File name */
|
||||
struct stat stat; /* File status from fstat() */
|
||||
int dir_p; /* nonzero if file is a directory */
|
||||
|
||||
/* Buffer in which text of file is read. */
|
||||
char * buffer;
|
||||
/* Allocated size of buffer. */
|
||||
size_t bufsize;
|
||||
/* Number of valid characters now in the buffer. */
|
||||
size_t buffered_chars;
|
||||
|
||||
/* Array of pointers to lines in the file. */
|
||||
char const **linbuf;
|
||||
|
||||
/* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
|
||||
linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
|
||||
linebuf[linbuf_base ... valid_lines - 1] contain valid data.
|
||||
linebuf[linbuf_base ... alloc_lines - 1] are allocated. */
|
||||
int linbuf_base, buffered_lines, valid_lines, alloc_lines;
|
||||
|
||||
/* Pointer to end of prefix of this file to ignore when hashing. */
|
||||
char const *prefix_end;
|
||||
|
||||
/* Count of lines in the prefix.
|
||||
There are this many lines in the file before linbuf[0]. */
|
||||
int prefix_lines;
|
||||
|
||||
/* Pointer to start of suffix of this file to ignore when hashing. */
|
||||
char const *suffix_begin;
|
||||
|
||||
/* Vector, indexed by line number, containing an equivalence code for
|
||||
each line. It is this vector that is actually compared with that
|
||||
of another file to generate differences. */
|
||||
int *equivs;
|
||||
|
||||
/* Vector, like the previous one except that
|
||||
the elements for discarded lines have been squeezed out. */
|
||||
int *undiscarded;
|
||||
|
||||
/* Vector mapping virtual line numbers (not counting discarded lines)
|
||||
to real ones (counting those lines). Both are origin-0. */
|
||||
int *realindexes;
|
||||
|
||||
/* Total number of nondiscarded lines. */
|
||||
int nondiscarded_lines;
|
||||
|
||||
/* Vector, indexed by real origin-0 line number,
|
||||
containing 1 for a line that is an insertion or a deletion.
|
||||
The results of comparison are stored here. */
|
||||
char *changed_flag;
|
||||
|
||||
/* 1 if file ends in a line with no final newline. */
|
||||
int missing_newline;
|
||||
|
||||
/* 1 more than the maximum equivalence value used for this or its
|
||||
sibling file. */
|
||||
int equiv_max;
|
||||
};
|
||||
|
||||
/* Describe the two files currently being compared. */
|
||||
|
||||
EXTERN struct file_data files[2];
|
||||
|
||||
/* Stdio stream to output diffs to. */
|
||||
|
||||
EXTERN FILE *outfile;
|
||||
|
||||
/* Declare various functions. */
|
||||
|
||||
/* analyze.c */
|
||||
int diff_2_files PARAMS((struct file_data[], int));
|
||||
|
||||
/* context.c */
|
||||
void print_context_header PARAMS((struct file_data[], int));
|
||||
void print_context_script PARAMS((struct change *, int));
|
||||
|
||||
/* diff.c */
|
||||
int excluded_filename PARAMS((char const *));
|
||||
|
||||
/* dir.c */
|
||||
int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int));
|
||||
|
||||
/* ed.c */
|
||||
void print_ed_script PARAMS((struct change *));
|
||||
void pr_forward_ed_script PARAMS((struct change *));
|
||||
|
||||
/* ifdef.c */
|
||||
void print_ifdef_script PARAMS((struct change *));
|
||||
|
||||
/* io.c */
|
||||
int read_files PARAMS((struct file_data[], int));
|
||||
int sip PARAMS((struct file_data *, int));
|
||||
void slurp PARAMS((struct file_data *));
|
||||
|
||||
/* normal.c */
|
||||
void print_normal_script PARAMS((struct change *));
|
||||
|
||||
/* rcs.c */
|
||||
void print_rcs_script PARAMS((struct change *));
|
||||
|
||||
/* side.c */
|
||||
void print_sdiff_script PARAMS((struct change *));
|
||||
|
||||
/* util.c */
|
||||
VOID *xmalloc PARAMS((size_t));
|
||||
VOID *xrealloc PARAMS((VOID *, size_t));
|
||||
char *concat PARAMS((char const *, char const *, char const *));
|
||||
char *dir_file_pathname PARAMS((char const *, char const *));
|
||||
int change_letter PARAMS((int, int));
|
||||
int line_cmp PARAMS((char const *, char const *));
|
||||
int translate_line_number PARAMS((struct file_data const *, int));
|
||||
struct change *find_change PARAMS((struct change *));
|
||||
struct change *find_reverse_change PARAMS((struct change *));
|
||||
void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *));
|
||||
void begin_output PARAMS((void));
|
||||
void debug_script PARAMS((struct change *));
|
||||
void error PARAMS((char const *, char const *, char const *));
|
||||
void fatal PARAMS((char const *));
|
||||
void finish_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 *));
|
||||
void perror_with_name PARAMS((char const *));
|
||||
void pfatal_with_name PARAMS((char const *));
|
||||
void print_1_line PARAMS((char const *, char const * const *));
|
||||
void print_message_queue PARAMS((void));
|
||||
void print_number_range PARAMS((int, struct file_data *, int, int));
|
||||
void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *))));
|
||||
void setup_output PARAMS((char const *, char const *, int));
|
||||
void translate_range PARAMS((struct file_data const *, int, int, int *, int *));
|
||||
|
||||
/* version.c */
|
||||
extern char const version_string[];
|
@ -1,87 +0,0 @@
|
||||
/* prepend_args.c - utilility programs for manpiulating argv[]
|
||||
Copyright (C) 1999 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "system.h"
|
||||
#include "diff.h"
|
||||
#include "prepend_args.h"
|
||||
|
||||
|
||||
/* Find the white-space-separated options specified by OPTIONS, and
|
||||
using BUF to store copies of these options, set ARGV[0], ARGV[1],
|
||||
etc. to the option copies. Return the number N of options found.
|
||||
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
|
||||
etc. Backslash can be used to escape whitespace (and backslashes). */
|
||||
static int
|
||||
prepend_args (options, buf, argv)
|
||||
char const *options;
|
||||
char *buf;
|
||||
char **argv;
|
||||
{
|
||||
char const *o = options;
|
||||
char *b = buf;
|
||||
int n = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (ISSPACE ((unsigned char) *o))
|
||||
o++;
|
||||
if (!*o)
|
||||
return n;
|
||||
if (argv)
|
||||
argv[n] = b;
|
||||
n++;
|
||||
|
||||
do
|
||||
if ((*b++ = *o++) == '\\' && *o)
|
||||
b[-1] = *o++;
|
||||
while (*o && ! ISSPACE ((unsigned char) *o));
|
||||
|
||||
*b++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepend the whitespace-separated options in OPTIONS to the argument
|
||||
vector of a main program with argument count *PARGC and argument
|
||||
vector *PARGV. */
|
||||
void
|
||||
prepend_default_options (options, pargc, pargv)
|
||||
char const *options;
|
||||
int *pargc;
|
||||
char ***pargv;
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
char *buf = xmalloc (strlen (options) + 1);
|
||||
int prepended = prepend_args (options, buf, (char **) NULL);
|
||||
int argc = *pargc;
|
||||
char * const *argv = *pargv;
|
||||
char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
|
||||
*pargc = prepended + argc;
|
||||
*pargv = pp;
|
||||
*pp++ = *argv++;
|
||||
pp += prepend_args (options, buf, pp);
|
||||
while ((*pp++ = *argv++))
|
||||
continue;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/* prepend_args.h - utilility programs for manpiulating argv[]
|
||||
Copyright (C) 1999 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
void prepend_default_options PARAMS ((char const *, int *, char ***));
|
1109
contrib/diff/sdiff.c
1109
contrib/diff/sdiff.c
File diff suppressed because it is too large
Load Diff
@ -1,759 +0,0 @@
|
||||
/* Support routines for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 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. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
#ifndef PR_PROGRAM
|
||||
#define PR_PROGRAM "/bin/pr"
|
||||
#endif
|
||||
|
||||
/* Queue up one-line messages to be printed at the end,
|
||||
when -l is specified. Each message is recorded with a `struct msg'. */
|
||||
|
||||
struct msg
|
||||
{
|
||||
struct msg *next;
|
||||
char const *format;
|
||||
char const *arg1;
|
||||
char const *arg2;
|
||||
char const *arg3;
|
||||
char const *arg4;
|
||||
};
|
||||
|
||||
/* Head of the chain of queues messages. */
|
||||
|
||||
static struct msg *msg_chain;
|
||||
|
||||
/* Tail of the chain of queues messages. */
|
||||
|
||||
static struct msg **msg_chain_end = &msg_chain;
|
||||
|
||||
/* Use when a system call returns non-zero status.
|
||||
TEXT should normally be the file name. */
|
||||
|
||||
void
|
||||
perror_with_name (text)
|
||||
char const *text;
|
||||
{
|
||||
int e = errno;
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
}
|
||||
|
||||
/* Use when a system call returns non-zero status and that is fatal. */
|
||||
|
||||
void
|
||||
pfatal_with_name (text)
|
||||
char const *text;
|
||||
{
|
||||
int e = errno;
|
||||
print_message_queue ();
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* Print an error message from the format-string FORMAT
|
||||
with args ARG1 and ARG2. */
|
||||
|
||||
void
|
||||
error (format, arg, arg1)
|
||||
char const *format, *arg, *arg1;
|
||||
{
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
fprintf (stderr, format, arg, arg1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print an error message containing the string TEXT, then exit. */
|
||||
|
||||
void
|
||||
fatal (m)
|
||||
char const *m;
|
||||
{
|
||||
print_message_queue ();
|
||||
error ("%s", m, 0);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* Like printf, except if -l in effect then save the message and print later.
|
||||
This is used for things like "binary files differ" and "Only in ...". */
|
||||
|
||||
void
|
||||
message (format, arg1, arg2)
|
||||
char const *format, *arg1, *arg2;
|
||||
{
|
||||
message5 (format, arg1, arg2, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
message5 (format, arg1, arg2, arg3, arg4)
|
||||
char const *format, *arg1, *arg2, *arg3, *arg4;
|
||||
{
|
||||
if (paginate_flag)
|
||||
{
|
||||
struct msg *new = (struct msg *) xmalloc (sizeof (struct msg));
|
||||
new->format = format;
|
||||
new->arg1 = concat (arg1, "", "");
|
||||
new->arg2 = concat (arg2, "", "");
|
||||
new->arg3 = arg3 ? concat (arg3, "", "") : 0;
|
||||
new->arg4 = arg4 ? concat (arg4, "", "") : 0;
|
||||
new->next = 0;
|
||||
*msg_chain_end = new;
|
||||
msg_chain_end = &new->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sdiff_help_sdiff)
|
||||
putchar (' ');
|
||||
printf (format, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output all the messages that were saved up by calls to `message'. */
|
||||
|
||||
void
|
||||
print_message_queue ()
|
||||
{
|
||||
struct msg *m;
|
||||
|
||||
for (m = msg_chain; m; m = m->next)
|
||||
printf (m->format, m->arg1, m->arg2, m->arg3, m->arg4);
|
||||
}
|
||||
|
||||
/* Call before outputting the results of comparing files NAME0 and NAME1
|
||||
to set up OUTFILE, the stdio stream for the output to go to.
|
||||
|
||||
Usually, OUTFILE is just stdout. But when -l was specified
|
||||
we fork off a `pr' and make OUTFILE a pipe to it.
|
||||
`pr' then outputs to our stdout. */
|
||||
|
||||
static char const *current_name0;
|
||||
static char const *current_name1;
|
||||
static int current_depth;
|
||||
|
||||
void
|
||||
setup_output (name0, name1, depth)
|
||||
char const *name0, *name1;
|
||||
int depth;
|
||||
{
|
||||
current_name0 = name0;
|
||||
current_name1 = name1;
|
||||
current_depth = depth;
|
||||
outfile = 0;
|
||||
}
|
||||
|
||||
#if HAVE_FORK
|
||||
static pid_t pr_pid;
|
||||
#endif
|
||||
|
||||
void
|
||||
begin_output ()
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (outfile != 0)
|
||||
return;
|
||||
|
||||
/* Construct the header of this piece of diff. */
|
||||
name = xmalloc (strlen (current_name0) + strlen (current_name1)
|
||||
+ strlen (switch_string) + 7);
|
||||
/* Posix.2 section 4.17.6.1.1 specifies this format. But there is a
|
||||
bug in the first printing (IEEE Std 1003.2-1992 p 251 l 3304):
|
||||
it says that we must print only the last component of the pathnames.
|
||||
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)
|
||||
{
|
||||
/* Make OUTFILE a pipe to a subsidiary `pr'. */
|
||||
|
||||
#if HAVE_FORK
|
||||
int pipes[2];
|
||||
|
||||
if (pipe (pipes) != 0)
|
||||
pfatal_with_name ("pipe");
|
||||
|
||||
fflush (stdout);
|
||||
|
||||
pr_pid = vfork ();
|
||||
if (pr_pid < 0)
|
||||
pfatal_with_name ("vfork");
|
||||
|
||||
if (pr_pid == 0)
|
||||
{
|
||||
close (pipes[1]);
|
||||
if (pipes[0] != STDIN_FILENO)
|
||||
{
|
||||
if (dup2 (pipes[0], STDIN_FILENO) < 0)
|
||||
pfatal_with_name ("dup2");
|
||||
close (pipes[0]);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
execl (PR_PROGRAM, PR_PROGRAM, "-F", "-h", name, (char *)NULL);
|
||||
#else
|
||||
execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, (char *)NULL);
|
||||
#endif
|
||||
pfatal_with_name (PR_PROGRAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
close (pipes[0]);
|
||||
outfile = fdopen (pipes[1], "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name ("fdopen");
|
||||
}
|
||||
#else /* ! HAVE_FORK */
|
||||
char *command = xmalloc (4 * strlen (name) + strlen (PR_PROGRAM) + 10);
|
||||
char *p;
|
||||
char const *a = name;
|
||||
sprintf (command, "%s -f -h ", PR_PROGRAM);
|
||||
p = command + strlen (command);
|
||||
SYSTEM_QUOTE_ARG (p, a);
|
||||
*p = 0;
|
||||
outfile = popen (command, "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name (command);
|
||||
free (command);
|
||||
#endif /* ! HAVE_FORK */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* If -l was not specified, output the diff straight to `stdout'. */
|
||||
|
||||
outfile = stdout;
|
||||
|
||||
/* If handling multiple files (because scanning a directory),
|
||||
print which files the following output is about. */
|
||||
if (current_depth > 0)
|
||||
printf ("%s\n", name);
|
||||
}
|
||||
|
||||
free (name);
|
||||
|
||||
/* A special header is needed at the beginning of context output. */
|
||||
switch (output_style)
|
||||
{
|
||||
case OUTPUT_CONTEXT:
|
||||
print_context_header (files, 0);
|
||||
break;
|
||||
|
||||
case OUTPUT_UNIFIED:
|
||||
print_context_header (files, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call after the end of output of diffs for one file.
|
||||
Close OUTFILE and get rid of the `pr' subfork. */
|
||||
|
||||
void
|
||||
finish_output ()
|
||||
{
|
||||
if (outfile != 0 && outfile != stdout)
|
||||
{
|
||||
int wstatus;
|
||||
if (ferror (outfile))
|
||||
fatal ("write error");
|
||||
#if ! HAVE_FORK
|
||||
wstatus = pclose (outfile);
|
||||
#else /* HAVE_FORK */
|
||||
if (fclose (outfile) != 0)
|
||||
pfatal_with_name ("write error");
|
||||
if (waitpid (pr_pid, &wstatus, 0) < 0)
|
||||
pfatal_with_name ("waitpid");
|
||||
#endif /* HAVE_FORK */
|
||||
if (wstatus != 0)
|
||||
fatal ("subsidiary pr failed");
|
||||
}
|
||||
|
||||
outfile = 0;
|
||||
}
|
||||
|
||||
/* Compare two lines (typically one from each input file)
|
||||
according to the command line options.
|
||||
For efficiency, this is invoked only when the lines do not match exactly
|
||||
but an option like -i might cause us to ignore the difference.
|
||||
Return nonzero if the lines differ. */
|
||||
|
||||
int
|
||||
line_cmp (s1, s2)
|
||||
char const *s1, *s2;
|
||||
{
|
||||
register unsigned char const *t1 = (unsigned char const *) s1;
|
||||
register unsigned char const *t2 = (unsigned char const *) s2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
register unsigned char c1 = *t1++;
|
||||
register unsigned char c2 = *t2++;
|
||||
|
||||
/* Test for exact char equality first, since it's a common case. */
|
||||
if (c1 != c2)
|
||||
{
|
||||
/* Ignore horizontal white space if -b or -w is specified. */
|
||||
|
||||
if (ignore_all_space_flag)
|
||||
{
|
||||
/* For -w, just skip past any white space. */
|
||||
while (ISSPACE (c1) && c1 != '\n') c1 = *t1++;
|
||||
while (ISSPACE (c2) && c2 != '\n') c2 = *t2++;
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
{
|
||||
/* For -b, advance past any sequence of white space in line 1
|
||||
and consider it just one Space, or nothing at all
|
||||
if it is at the end of the line. */
|
||||
if (ISSPACE (c1))
|
||||
{
|
||||
while (c1 != '\n')
|
||||
{
|
||||
c1 = *t1++;
|
||||
if (! ISSPACE (c1))
|
||||
{
|
||||
--t1;
|
||||
c1 = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Likewise for line 2. */
|
||||
if (ISSPACE (c2))
|
||||
{
|
||||
while (c2 != '\n')
|
||||
{
|
||||
c2 = *t2++;
|
||||
if (! ISSPACE (c2))
|
||||
{
|
||||
--t2;
|
||||
c2 = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
/* If we went too far when doing the simple test
|
||||
for equality, go back to the first non-white-space
|
||||
character in both sides and try again. */
|
||||
if (c2 == ' ' && c1 != '\n'
|
||||
&& (unsigned char const *) s1 + 1 < t1
|
||||
&& ISSPACE(t1[-2]))
|
||||
{
|
||||
--t1;
|
||||
continue;
|
||||
}
|
||||
if (c1 == ' ' && c2 != '\n'
|
||||
&& (unsigned char const *) s2 + 1 < t2
|
||||
&& ISSPACE(t2[-2]))
|
||||
{
|
||||
--t2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lowercase all letters if -i is specified. */
|
||||
|
||||
if (ignore_case_flag)
|
||||
{
|
||||
if (ISUPPER (c1))
|
||||
c1 = tolower (c1);
|
||||
if (ISUPPER (c2))
|
||||
c2 = tolower (c2);
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
break;
|
||||
}
|
||||
if (c1 == '\n')
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Find the consecutive changes at the start of the script START.
|
||||
Return the last link before the first gap. */
|
||||
|
||||
struct change *
|
||||
find_change (start)
|
||||
struct change *start;
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
struct change *
|
||||
find_reverse_change (start)
|
||||
struct change *start;
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Divide SCRIPT into pieces by calling HUNKFUN and
|
||||
print each piece with PRINTFUN.
|
||||
Both functions take one arg, an edit script.
|
||||
|
||||
HUNKFUN is called with the tail of the script
|
||||
and returns the last link that belongs together with the start
|
||||
of the tail.
|
||||
|
||||
PRINTFUN takes a subscript which belongs together (with a null
|
||||
link at the end) and prints it. */
|
||||
|
||||
void
|
||||
print_script (script, hunkfun, printfun)
|
||||
struct change *script;
|
||||
struct change * (*hunkfun) PARAMS((struct change *));
|
||||
void (*printfun) PARAMS((struct change *));
|
||||
{
|
||||
struct change *next = script;
|
||||
|
||||
while (next)
|
||||
{
|
||||
struct change *this, *end;
|
||||
|
||||
/* Find a set of changes that belong together. */
|
||||
this = next;
|
||||
end = (*hunkfun) (next);
|
||||
|
||||
/* Disconnect them from the rest of the changes,
|
||||
making them a hunk, and remember the rest for next iteration. */
|
||||
next = end->link;
|
||||
end->link = 0;
|
||||
#ifdef DEBUG
|
||||
debug_script (this);
|
||||
#endif
|
||||
|
||||
/* Print this hunk. */
|
||||
(*printfun) (this);
|
||||
|
||||
/* Reconnect the script so it will all be freed properly. */
|
||||
end->link = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the text of a single line LINE,
|
||||
flagging it with the characters in LINE_FLAG (which say whether
|
||||
the line is inserted, deleted, changed, etc.). */
|
||||
|
||||
void
|
||||
print_1_line (line_flag, line)
|
||||
char const *line_flag;
|
||||
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.
|
||||
Otherwise use a Space (as Unix diff does).
|
||||
Print neither space nor tab if line-flags are empty. */
|
||||
|
||||
if (line_flag && *line_flag)
|
||||
{
|
||||
flag_format = tab_align_flag ? "%s\t" : "%s ";
|
||||
fprintf (out, 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");
|
||||
}
|
||||
|
||||
/* Output a line from TEXT up to LIMIT. Without -t, output verbatim.
|
||||
With -t, expand white space characters to spaces, and if FLAG_FORMAT
|
||||
is nonzero, output it with argument LINE_FLAG after every
|
||||
internal carriage return, so that tab stops continue to line up. */
|
||||
|
||||
void
|
||||
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);
|
||||
else
|
||||
{
|
||||
register FILE *out = outfile;
|
||||
register unsigned char c;
|
||||
register char const *t = text;
|
||||
register unsigned column = 0;
|
||||
|
||||
while (t < limit)
|
||||
switch ((c = *t++))
|
||||
{
|
||||
case '\t':
|
||||
{
|
||||
unsigned spaces = TAB_WIDTH - column % TAB_WIDTH;
|
||||
column += spaces;
|
||||
do
|
||||
putc (' ', out);
|
||||
while (--spaces);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
putc (c, out);
|
||||
if (flag_format && t < limit && *t != '\n')
|
||||
fprintf (out, flag_format, line_flag);
|
||||
column = 0;
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
if (column == 0)
|
||||
continue;
|
||||
column--;
|
||||
putc (c, out);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ISPRINT (c))
|
||||
column++;
|
||||
putc (c, out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
change_letter (inserts, deletes)
|
||||
int inserts, deletes;
|
||||
{
|
||||
if (!inserts)
|
||||
return 'd';
|
||||
else if (!deletes)
|
||||
return 'a';
|
||||
else
|
||||
return 'c';
|
||||
}
|
||||
|
||||
/* Translate an internal line number (an index into diff's table of lines)
|
||||
into an actual line number in the input file.
|
||||
The internal line number is LNUM. FILE points to the data on the file.
|
||||
|
||||
Internal line numbers count from 0 starting after the prefix.
|
||||
Actual line numbers count from 1 within the entire file. */
|
||||
|
||||
int
|
||||
translate_line_number (file, lnum)
|
||||
struct file_data const *file;
|
||||
int lnum;
|
||||
{
|
||||
return lnum + file->prefix_lines + 1;
|
||||
}
|
||||
|
||||
void
|
||||
translate_range (file, a, b, aptr, bptr)
|
||||
struct file_data const *file;
|
||||
int a, b;
|
||||
int *aptr, *bptr;
|
||||
{
|
||||
*aptr = translate_line_number (file, a - 1) + 1;
|
||||
*bptr = translate_line_number (file, b + 1) - 1;
|
||||
}
|
||||
|
||||
/* Print a pair of line numbers with SEPCHAR, translated for file FILE.
|
||||
If the two numbers are identical, print just one number.
|
||||
|
||||
Args A and B are internal line numbers.
|
||||
We print the translated (real) line numbers. */
|
||||
|
||||
void
|
||||
print_number_range (sepchar, file, a, b)
|
||||
int sepchar;
|
||||
struct file_data *file;
|
||||
int a, b;
|
||||
{
|
||||
int trans_a, trans_b;
|
||||
translate_range (file, a, b, &trans_a, &trans_b);
|
||||
|
||||
/* Note: we can have B < A in the case of a range of no lines.
|
||||
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);
|
||||
else
|
||||
fprintf (outfile, "%d", trans_b);
|
||||
}
|
||||
|
||||
/* Look at a hunk of edit script and report the range of lines in each file
|
||||
that it applies to. HUNK is the start of the hunk, which is a chain
|
||||
of `struct change'. The first and last line numbers of file 0 are stored in
|
||||
*FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
|
||||
Note that these are internal line numbers that count from 0.
|
||||
|
||||
If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
|
||||
|
||||
Also set *DELETES nonzero if any lines of file 0 are deleted
|
||||
and set *INSERTS nonzero if any lines of file 1 are inserted.
|
||||
If only ignorable lines are inserted or deleted, both are
|
||||
set to 0. */
|
||||
|
||||
void
|
||||
analyze_hunk (hunk, first0, last0, first1, last1, deletes, inserts)
|
||||
struct change *hunk;
|
||||
int *first0, *last0, *first1, *last1;
|
||||
int *deletes, *inserts;
|
||||
{
|
||||
int l0, l1, show_from, show_to;
|
||||
int i;
|
||||
int trivial = ignore_blank_lines_flag || ignore_regexp_list;
|
||||
struct change *next;
|
||||
|
||||
show_from = show_to = 0;
|
||||
|
||||
*first0 = hunk->line0;
|
||||
*first1 = hunk->line1;
|
||||
|
||||
next = hunk;
|
||||
do
|
||||
{
|
||||
l0 = next->line0 + next->deleted - 1;
|
||||
l1 = next->line1 + next->inserted - 1;
|
||||
show_from += next->deleted;
|
||||
show_to += next->inserted;
|
||||
|
||||
for (i = next->line0; i <= l0 && trivial; i++)
|
||||
if (!ignore_blank_lines_flag || files[0].linbuf[i][0] != '\n')
|
||||
{
|
||||
struct regexp_list *r;
|
||||
char const *line = files[0].linbuf[i];
|
||||
int len = files[0].linbuf[i + 1] - line;
|
||||
|
||||
for (r = ignore_regexp_list; r; r = r->next)
|
||||
if (0 <= re_search (&r->buf, line, len, 0, len, 0))
|
||||
break; /* Found a match. Ignore this line. */
|
||||
/* If we got all the way through the regexp list without
|
||||
finding a match, then it's nontrivial. */
|
||||
if (!r)
|
||||
trivial = 0;
|
||||
}
|
||||
|
||||
for (i = next->line1; i <= l1 && trivial; i++)
|
||||
if (!ignore_blank_lines_flag || files[1].linbuf[i][0] != '\n')
|
||||
{
|
||||
struct regexp_list *r;
|
||||
char const *line = files[1].linbuf[i];
|
||||
int len = files[1].linbuf[i + 1] - line;
|
||||
|
||||
for (r = ignore_regexp_list; r; r = r->next)
|
||||
if (0 <= re_search (&r->buf, line, len, 0, len, 0))
|
||||
break; /* Found a match. Ignore this line. */
|
||||
/* If we got all the way through the regexp list without
|
||||
finding a match, then it's nontrivial. */
|
||||
if (!r)
|
||||
trivial = 0;
|
||||
}
|
||||
}
|
||||
while ((next = next->link) != 0);
|
||||
|
||||
*last0 = l0;
|
||||
*last1 = l1;
|
||||
|
||||
/* If all inserted or deleted lines are ignorable,
|
||||
tell the caller to ignore this hunk. */
|
||||
|
||||
if (trivial)
|
||||
show_from = show_to = 0;
|
||||
|
||||
*deletes = show_from;
|
||||
*inserts = show_to;
|
||||
}
|
||||
|
||||
/* malloc a block of memory, with fatal error message if we can't do it. */
|
||||
|
||||
VOID *
|
||||
xmalloc (size)
|
||||
size_t size;
|
||||
{
|
||||
register VOID *value;
|
||||
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
value = (VOID *) malloc (size);
|
||||
|
||||
if (!value)
|
||||
fatal ("memory exhausted");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* realloc a block of memory, with fatal error message if we can't do it. */
|
||||
|
||||
VOID *
|
||||
xrealloc (old, size)
|
||||
VOID *old;
|
||||
size_t size;
|
||||
{
|
||||
register VOID *value;
|
||||
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
value = (VOID *) realloc (old, size);
|
||||
|
||||
if (!value)
|
||||
fatal ("memory exhausted");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Concatenate three strings, returning a newly malloc'd string. */
|
||||
|
||||
char *
|
||||
concat (s1, s2, s3)
|
||||
char const *s1, *s2, *s3;
|
||||
{
|
||||
size_t len = strlen (s1) + strlen (s2) + strlen (s3);
|
||||
char *new = xmalloc (len + 1);
|
||||
sprintf (new, "%s%s%s", s1, s2, s3);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Yield the newly malloc'd pathname
|
||||
of the file in DIR whose filename is FILE. */
|
||||
|
||||
char *
|
||||
dir_file_pathname (dir, file)
|
||||
char const *dir, *file;
|
||||
{
|
||||
char const *p = filename_lastdirchar (dir);
|
||||
return concat (dir, "/" + (p && !p[1]), file);
|
||||
}
|
||||
|
||||
void
|
||||
debug_script (sp)
|
||||
struct change *sp;
|
||||
{
|
||||
fflush (stdout);
|
||||
for (; sp; sp = sp->link)
|
||||
fprintf (stderr, "%3d %3d delete %d insert %d\n",
|
||||
sp->line0, sp->line1, sp->deleted, sp->inserted);
|
||||
fflush (stderr);
|
||||
}
|
Loading…
Reference in New Issue
Block a user