xref: /netbsd-src/external/gpl2/xcvs/dist/diff/diff.h (revision a7c918477dd5f12c1da816ba05caf44eab2d06d6)
1*a7c91847Schristos /* Shared definitions for GNU DIFF
2*a7c91847Schristos    Copyright (C) 1988, 89, 91, 92, 93, 97, 1998 Free Software Foundation, Inc.
3*a7c91847Schristos 
4*a7c91847Schristos This file is part of GNU DIFF.
5*a7c91847Schristos 
6*a7c91847Schristos GNU DIFF is free software; you can redistribute it and/or modify
7*a7c91847Schristos it under the terms of the GNU General Public License as published by
8*a7c91847Schristos the Free Software Foundation; either version 2, or (at your option)
9*a7c91847Schristos any later version.
10*a7c91847Schristos 
11*a7c91847Schristos GNU DIFF is distributed in the hope that it will be useful,
12*a7c91847Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a7c91847Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a7c91847Schristos GNU General Public License for more details.
15*a7c91847Schristos 
16*a7c91847Schristos */
17*a7c91847Schristos 
18*a7c91847Schristos #include "system.h"
19*a7c91847Schristos #include <stdio.h>
20*a7c91847Schristos #include <setjmp.h>
21*a7c91847Schristos #include "regex.h"
22*a7c91847Schristos #include "diffrun.h"
23*a7c91847Schristos 
24*a7c91847Schristos #define TAB_WIDTH 8
25*a7c91847Schristos 
26*a7c91847Schristos /* Variables for command line options */
27*a7c91847Schristos 
28*a7c91847Schristos #ifndef GDIFF_MAIN
29*a7c91847Schristos #define EXTERN extern
30*a7c91847Schristos #else
31*a7c91847Schristos #define EXTERN
32*a7c91847Schristos #endif
33*a7c91847Schristos 
34*a7c91847Schristos /* The callbacks to use for output.  */
35*a7c91847Schristos EXTERN const struct diff_callbacks *callbacks;
36*a7c91847Schristos 
37*a7c91847Schristos enum output_style {
38*a7c91847Schristos   /* Default output style.  */
39*a7c91847Schristos   OUTPUT_NORMAL,
40*a7c91847Schristos   /* Output the differences with lines of context before and after (-c).  */
41*a7c91847Schristos   OUTPUT_CONTEXT,
42*a7c91847Schristos   /* Output the differences in a unified context diff format (-u). */
43*a7c91847Schristos   OUTPUT_UNIFIED,
44*a7c91847Schristos   /* Output the differences as commands suitable for `ed' (-e).  */
45*a7c91847Schristos   OUTPUT_ED,
46*a7c91847Schristos   /* Output the diff as a forward ed script (-f).  */
47*a7c91847Schristos   OUTPUT_FORWARD_ED,
48*a7c91847Schristos   /* Like -f, but output a count of changed lines in each "command" (-n). */
49*a7c91847Schristos   OUTPUT_RCS,
50*a7c91847Schristos   /* Output merged #ifdef'd file (-D).  */
51*a7c91847Schristos   OUTPUT_IFDEF,
52*a7c91847Schristos   /* Output sdiff style (-y).  */
53*a7c91847Schristos   OUTPUT_SDIFF
54*a7c91847Schristos };
55*a7c91847Schristos 
56*a7c91847Schristos /* True for output styles that are robust,
57*a7c91847Schristos    i.e. can handle a file that ends in a non-newline.  */
58*a7c91847Schristos #define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
59*a7c91847Schristos 
60*a7c91847Schristos EXTERN enum output_style output_style;
61*a7c91847Schristos 
62*a7c91847Schristos /* Nonzero if output cannot be generated for identical files.  */
63*a7c91847Schristos EXTERN int no_diff_means_no_output;
64*a7c91847Schristos 
65*a7c91847Schristos /* Number of lines of context to show in each set of diffs.
66*a7c91847Schristos    This is zero when context is not to be shown.  */
67*a7c91847Schristos EXTERN int      context;
68*a7c91847Schristos 
69*a7c91847Schristos /* Consider all files as text files (-a).
70*a7c91847Schristos    Don't interpret codes over 0177 as implying a "binary file".  */
71*a7c91847Schristos EXTERN int	always_text_flag;
72*a7c91847Schristos 
73*a7c91847Schristos /* Number of lines to keep in identical prefix and suffix.  */
74*a7c91847Schristos EXTERN int      horizon_lines;
75*a7c91847Schristos 
76*a7c91847Schristos /* Ignore changes in horizontal white space (-b).  */
77*a7c91847Schristos EXTERN int      ignore_space_change_flag;
78*a7c91847Schristos 
79*a7c91847Schristos /* Ignore all horizontal white space (-w).  */
80*a7c91847Schristos EXTERN int      ignore_all_space_flag;
81*a7c91847Schristos 
82*a7c91847Schristos /* Ignore changes that affect only blank lines (-B).  */
83*a7c91847Schristos EXTERN int      ignore_blank_lines_flag;
84*a7c91847Schristos 
85*a7c91847Schristos /* 1 if lines may match even if their contents do not match exactly.
86*a7c91847Schristos    This depends on various options.  */
87*a7c91847Schristos EXTERN int      ignore_some_line_changes;
88*a7c91847Schristos 
89*a7c91847Schristos /* 1 if files may match even if their contents are not byte-for-byte identical.
90*a7c91847Schristos    This depends on various options.  */
91*a7c91847Schristos EXTERN int      ignore_some_changes;
92*a7c91847Schristos 
93*a7c91847Schristos /* Ignore differences in case of letters (-i).  */
94*a7c91847Schristos EXTERN int      ignore_case_flag;
95*a7c91847Schristos 
96*a7c91847Schristos /* File labels for `-c' output headers (-L).  */
97*a7c91847Schristos EXTERN char *file_label[2];
98*a7c91847Schristos 
99*a7c91847Schristos struct regexp_list
100*a7c91847Schristos {
101*a7c91847Schristos   struct re_pattern_buffer buf;
102*a7c91847Schristos   struct regexp_list *next;
103*a7c91847Schristos };
104*a7c91847Schristos 
105*a7c91847Schristos /* Regexp to identify function-header lines (-F).  */
106*a7c91847Schristos EXTERN struct regexp_list *function_regexp_list;
107*a7c91847Schristos 
108*a7c91847Schristos /* Ignore changes that affect only lines matching this regexp (-I).  */
109*a7c91847Schristos EXTERN struct regexp_list *ignore_regexp_list;
110*a7c91847Schristos 
111*a7c91847Schristos /* Say only whether files differ, not how (-q).  */
112*a7c91847Schristos EXTERN int 	no_details_flag;
113*a7c91847Schristos 
114*a7c91847Schristos /* Report files compared that match (-s).
115*a7c91847Schristos    Normally nothing is output when that happens.  */
116*a7c91847Schristos EXTERN int      print_file_same_flag;
117*a7c91847Schristos 
118*a7c91847Schristos /* Output the differences with exactly 8 columns added to each line
119*a7c91847Schristos    so that any tabs in the text line up properly (-T).  */
120*a7c91847Schristos EXTERN int	tab_align_flag;
121*a7c91847Schristos 
122*a7c91847Schristos /* Expand tabs in the output so the text lines up properly
123*a7c91847Schristos    despite the characters added to the front of each line (-t).  */
124*a7c91847Schristos EXTERN int	tab_expand_flag;
125*a7c91847Schristos 
126*a7c91847Schristos /* In directory comparison, specify file to start with (-S).
127*a7c91847Schristos    All file names less than this name are ignored.  */
128*a7c91847Schristos EXTERN char	*dir_start_file;
129*a7c91847Schristos 
130*a7c91847Schristos /* If a file is new (appears in only one dir)
131*a7c91847Schristos    include its entire contents (-N).
132*a7c91847Schristos    Then `patch' would create the file with appropriate contents.  */
133*a7c91847Schristos EXTERN int	entire_new_file_flag;
134*a7c91847Schristos 
135*a7c91847Schristos /* If a file is new (appears in only the second dir)
136*a7c91847Schristos    include its entire contents (-P).
137*a7c91847Schristos    Then `patch' would create the file with appropriate contents.  */
138*a7c91847Schristos EXTERN int	unidirectional_new_file_flag;
139*a7c91847Schristos 
140*a7c91847Schristos /* Pipe each file's output through pr (-l).  */
141*a7c91847Schristos EXTERN int	paginate_flag;
142*a7c91847Schristos 
143*a7c91847Schristos enum line_class {
144*a7c91847Schristos   /* Lines taken from just the first file.  */
145*a7c91847Schristos   OLD,
146*a7c91847Schristos   /* Lines taken from just the second file.  */
147*a7c91847Schristos   NEW,
148*a7c91847Schristos   /* Lines common to both files.  */
149*a7c91847Schristos   UNCHANGED,
150*a7c91847Schristos   /* A hunk containing both old and new lines (line groups only).  */
151*a7c91847Schristos   CHANGED
152*a7c91847Schristos };
153*a7c91847Schristos 
154*a7c91847Schristos /* Line group formats for old, new, unchanged, and changed groups.  */
155*a7c91847Schristos EXTERN char *group_format[CHANGED + 1];
156*a7c91847Schristos 
157*a7c91847Schristos /* Line formats for old, new, and unchanged lines.  */
158*a7c91847Schristos EXTERN char *line_format[UNCHANGED + 1];
159*a7c91847Schristos 
160*a7c91847Schristos /* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
161*a7c91847Schristos EXTERN int sdiff_help_sdiff;
162*a7c91847Schristos 
163*a7c91847Schristos /* Tell OUTPUT_SDIFF to show only the left version of common lines. */
164*a7c91847Schristos EXTERN int sdiff_left_only;
165*a7c91847Schristos 
166*a7c91847Schristos /* Tell OUTPUT_SDIFF to not show common lines. */
167*a7c91847Schristos EXTERN int sdiff_skip_common_lines;
168*a7c91847Schristos 
169*a7c91847Schristos /* The half line width and column 2 offset for OUTPUT_SDIFF.  */
170*a7c91847Schristos EXTERN unsigned sdiff_half_width;
171*a7c91847Schristos EXTERN unsigned sdiff_column2_offset;
172*a7c91847Schristos 
173*a7c91847Schristos /* String containing all the command options diff received,
174*a7c91847Schristos    with spaces between and at the beginning but none at the end.
175*a7c91847Schristos    If there were no options given, this string is empty.  */
176*a7c91847Schristos EXTERN char *	switch_string;
177*a7c91847Schristos 
178*a7c91847Schristos /* Nonzero means use heuristics for better speed.  */
179*a7c91847Schristos EXTERN int	heuristic;
180*a7c91847Schristos 
181*a7c91847Schristos /* Name of program the user invoked (for error messages).  */
182*a7c91847Schristos EXTERN char *diff_program_name;
183*a7c91847Schristos 
184*a7c91847Schristos /* Jump buffer for nonlocal exits. */
185*a7c91847Schristos EXTERN jmp_buf diff_abort_buf;
186*a7c91847Schristos #define DIFF_ABORT(retval) longjmp(diff_abort_buf, retval)
187*a7c91847Schristos 
188*a7c91847Schristos /* The result of comparison is an "edit script": a chain of `struct change'.
189*a7c91847Schristos    Each `struct change' represents one place where some lines are deleted
190*a7c91847Schristos    and some are inserted.
191*a7c91847Schristos 
192*a7c91847Schristos    LINE0 and LINE1 are the first affected lines in the two files (origin 0).
193*a7c91847Schristos    DELETED is the number of lines deleted here from file 0.
194*a7c91847Schristos    INSERTED is the number of lines inserted here in file 1.
195*a7c91847Schristos 
196*a7c91847Schristos    If DELETED is 0 then LINE0 is the number of the line before
197*a7c91847Schristos    which the insertion was done; vice versa for INSERTED and LINE1.  */
198*a7c91847Schristos 
199*a7c91847Schristos struct change
200*a7c91847Schristos {
201*a7c91847Schristos   struct change *link;		/* Previous or next edit command  */
202*a7c91847Schristos   int inserted;			/* # lines of file 1 changed here.  */
203*a7c91847Schristos   int deleted;			/* # lines of file 0 changed here.  */
204*a7c91847Schristos   int line0;			/* Line number of 1st deleted line.  */
205*a7c91847Schristos   int line1;			/* Line number of 1st inserted line.  */
206*a7c91847Schristos   char ignore;			/* Flag used in context.c */
207*a7c91847Schristos };
208*a7c91847Schristos 
209*a7c91847Schristos /* Structures that describe the input files.  */
210*a7c91847Schristos 
211*a7c91847Schristos /* Data on one input file being compared.  */
212*a7c91847Schristos 
213*a7c91847Schristos struct file_data {
214*a7c91847Schristos     int             desc;	/* File descriptor  */
215*a7c91847Schristos     char const      *name;	/* File name  */
216*a7c91847Schristos     struct stat     stat;	/* File status from fstat()  */
217*a7c91847Schristos     int             dir_p;	/* nonzero if file is a directory  */
218*a7c91847Schristos 
219*a7c91847Schristos     /* Buffer in which text of file is read.  */
220*a7c91847Schristos     char *	    buffer;
221*a7c91847Schristos     /* Allocated size of buffer.  */
222*a7c91847Schristos     size_t	    bufsize;
223*a7c91847Schristos     /* Number of valid characters now in the buffer. */
224*a7c91847Schristos     size_t	    buffered_chars;
225*a7c91847Schristos 
226*a7c91847Schristos     /* Array of pointers to lines in the file.  */
227*a7c91847Schristos     char const **linbuf;
228*a7c91847Schristos 
229*a7c91847Schristos     /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
230*a7c91847Schristos        linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
231*a7c91847Schristos        linebuf[linbuf_base ... valid_lines - 1] contain valid data.
232*a7c91847Schristos        linebuf[linbuf_base ... alloc_lines - 1] are allocated.  */
233*a7c91847Schristos     int linbuf_base, buffered_lines, valid_lines, alloc_lines;
234*a7c91847Schristos 
235*a7c91847Schristos     /* Pointer to end of prefix of this file to ignore when hashing. */
236*a7c91847Schristos     char const *prefix_end;
237*a7c91847Schristos 
238*a7c91847Schristos     /* Count of lines in the prefix.
239*a7c91847Schristos        There are this many lines in the file before linbuf[0].  */
240*a7c91847Schristos     int prefix_lines;
241*a7c91847Schristos 
242*a7c91847Schristos     /* Pointer to start of suffix of this file to ignore when hashing. */
243*a7c91847Schristos     char const *suffix_begin;
244*a7c91847Schristos 
245*a7c91847Schristos     /* Vector, indexed by line number, containing an equivalence code for
246*a7c91847Schristos        each line.  It is this vector that is actually compared with that
247*a7c91847Schristos        of another file to generate differences. */
248*a7c91847Schristos     int		   *equivs;
249*a7c91847Schristos 
250*a7c91847Schristos     /* Vector, like the previous one except that
251*a7c91847Schristos        the elements for discarded lines have been squeezed out.  */
252*a7c91847Schristos     int		   *undiscarded;
253*a7c91847Schristos 
254*a7c91847Schristos     /* Vector mapping virtual line numbers (not counting discarded lines)
255*a7c91847Schristos        to real ones (counting those lines).  Both are origin-0.  */
256*a7c91847Schristos     int		   *realindexes;
257*a7c91847Schristos 
258*a7c91847Schristos     /* Total number of nondiscarded lines. */
259*a7c91847Schristos     int		    nondiscarded_lines;
260*a7c91847Schristos 
261*a7c91847Schristos     /* Vector, indexed by real origin-0 line number,
262*a7c91847Schristos        containing 1 for a line that is an insertion or a deletion.
263*a7c91847Schristos        The results of comparison are stored here.  */
264*a7c91847Schristos     char	   *changed_flag;
265*a7c91847Schristos 
266*a7c91847Schristos     /* 1 if file ends in a line with no final newline. */
267*a7c91847Schristos     int		    missing_newline;
268*a7c91847Schristos 
269*a7c91847Schristos     /* 1 more than the maximum equivalence value used for this or its
270*a7c91847Schristos        sibling file. */
271*a7c91847Schristos     int equiv_max;
272*a7c91847Schristos };
273*a7c91847Schristos 
274*a7c91847Schristos /* Describe the two files currently being compared.  */
275*a7c91847Schristos 
276*a7c91847Schristos EXTERN struct file_data files[2];
277*a7c91847Schristos 
278*a7c91847Schristos /* Stdio stream to output diffs to.  */
279*a7c91847Schristos 
280*a7c91847Schristos EXTERN FILE *outfile;
281*a7c91847Schristos 
282*a7c91847Schristos /* Declare various functions.  */
283*a7c91847Schristos 
284*a7c91847Schristos /* analyze.c */
285*a7c91847Schristos int diff_2_files PARAMS((struct file_data[], int));
286*a7c91847Schristos 
287*a7c91847Schristos /* context.c */
288*a7c91847Schristos void print_context_header PARAMS((struct file_data[], int));
289*a7c91847Schristos void print_context_script PARAMS((struct change *, int));
290*a7c91847Schristos 
291*a7c91847Schristos /* diff.c */
292*a7c91847Schristos int excluded_filename PARAMS((char const *));
293*a7c91847Schristos 
294*a7c91847Schristos /* dir.c */
295*a7c91847Schristos int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int));
296*a7c91847Schristos 
297*a7c91847Schristos /* ed.c */
298*a7c91847Schristos void print_ed_script PARAMS((struct change *));
299*a7c91847Schristos void pr_forward_ed_script PARAMS((struct change *));
300*a7c91847Schristos 
301*a7c91847Schristos /* ifdef.c */
302*a7c91847Schristos void print_ifdef_script PARAMS((struct change *));
303*a7c91847Schristos 
304*a7c91847Schristos /* io.c */
305*a7c91847Schristos int read_files PARAMS((struct file_data[], int));
306*a7c91847Schristos int sip PARAMS((struct file_data *, int));
307*a7c91847Schristos void slurp PARAMS((struct file_data *));
308*a7c91847Schristos 
309*a7c91847Schristos /* normal.c */
310*a7c91847Schristos void print_normal_script PARAMS((struct change *));
311*a7c91847Schristos 
312*a7c91847Schristos /* rcs.c */
313*a7c91847Schristos void print_rcs_script PARAMS((struct change *));
314*a7c91847Schristos 
315*a7c91847Schristos /* side.c */
316*a7c91847Schristos void print_sdiff_script PARAMS((struct change *));
317*a7c91847Schristos 
318*a7c91847Schristos /* util.c */
319*a7c91847Schristos VOID *xmalloc PARAMS((size_t));
320*a7c91847Schristos VOID *xrealloc PARAMS((VOID *, size_t));
321*a7c91847Schristos char *concat PARAMS((char const *, char const *, char const *));
322*a7c91847Schristos char *dir_file_pathname PARAMS((char const *, char const *));
323*a7c91847Schristos int change_letter PARAMS((int, int));
324*a7c91847Schristos int line_cmp PARAMS((char const *, char const *));
325*a7c91847Schristos int translate_line_number PARAMS((struct file_data const *, int));
326*a7c91847Schristos struct change *find_change PARAMS((struct change *));
327*a7c91847Schristos struct change *find_reverse_change PARAMS((struct change *));
328*a7c91847Schristos void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *));
329*a7c91847Schristos void begin_output PARAMS((void));
330*a7c91847Schristos void debug_script PARAMS((struct change *));
331*a7c91847Schristos void diff_error PARAMS((char const *, char const *, char const *));
332*a7c91847Schristos void fatal PARAMS((char const *));
333*a7c91847Schristos void finish_output PARAMS((void));
334*a7c91847Schristos void write_output PARAMS((char const *, size_t));
335*a7c91847Schristos void printf_output PARAMS((char const *, ...))
336*a7c91847Schristos #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
337*a7c91847Schristos      __attribute__ ((__format__ (__printf__, 1, 2)))
338*a7c91847Schristos #endif
339*a7c91847Schristos      ;
340*a7c91847Schristos void flush_output PARAMS((void));
341*a7c91847Schristos void message PARAMS((char const *, char const *, char const *));
342*a7c91847Schristos void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
343*a7c91847Schristos void output_1_line PARAMS((char const *, char const *, char const *, char const *));
344*a7c91847Schristos void perror_with_name PARAMS((char const *));
345*a7c91847Schristos void pfatal_with_name PARAMS((char const *));
346*a7c91847Schristos void print_1_line PARAMS((char const *, char const * const *));
347*a7c91847Schristos void print_message_queue PARAMS((void));
348*a7c91847Schristos void print_number_range PARAMS((int, struct file_data *, int, int));
349*a7c91847Schristos void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *))));
350*a7c91847Schristos void setup_output PARAMS((char const *, char const *, int));
351*a7c91847Schristos void translate_range PARAMS((struct file_data const *, int, int, int *, int *));
352*a7c91847Schristos 
353*a7c91847Schristos /* version.c */
354*a7c91847Schristos extern char const diff_version_string[];
355