xref: /netbsd-src/external/gpl2/diffutils/dist/src/diff.h (revision 75f6d617e282811cb173c2ccfbf5df0dd71f7045)
1*75f6d617Schristos /*	$NetBSD: diff.h,v 1.1.1.1 2016/01/13 03:15:30 christos Exp $	*/
2*75f6d617Schristos 
3*75f6d617Schristos /* Shared definitions for GNU DIFF
4*75f6d617Schristos 
5*75f6d617Schristos    Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001,
6*75f6d617Schristos    2002 Free Software Foundation, Inc.
7*75f6d617Schristos 
8*75f6d617Schristos    This file is part of GNU DIFF.
9*75f6d617Schristos 
10*75f6d617Schristos    GNU DIFF is free software; you can redistribute it and/or modify
11*75f6d617Schristos    it under the terms of the GNU General Public License as published by
12*75f6d617Schristos    the Free Software Foundation; either version 2, or (at your option)
13*75f6d617Schristos    any later version.
14*75f6d617Schristos 
15*75f6d617Schristos    GNU DIFF is distributed in the hope that it will be useful,
16*75f6d617Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
17*75f6d617Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*75f6d617Schristos    GNU General Public License for more details.
19*75f6d617Schristos 
20*75f6d617Schristos    You should have received a copy of the GNU General Public License
21*75f6d617Schristos    along with this program; see the file COPYING.
22*75f6d617Schristos    If not, write to the Free Software Foundation,
23*75f6d617Schristos    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24*75f6d617Schristos 
25*75f6d617Schristos #include "system.h"
26*75f6d617Schristos #include <stdio.h>
27*75f6d617Schristos 
28*75f6d617Schristos #define TAB_WIDTH 8
29*75f6d617Schristos 
30*75f6d617Schristos /* What kind of changes a hunk contains.  */
31*75f6d617Schristos enum changes
32*75f6d617Schristos {
33*75f6d617Schristos   /* No changes: lines common to both files.  */
34*75f6d617Schristos   UNCHANGED,
35*75f6d617Schristos 
36*75f6d617Schristos   /* Deletes only: lines taken from just the first file.  */
37*75f6d617Schristos   OLD,
38*75f6d617Schristos 
39*75f6d617Schristos   /* Inserts only: lines taken from just the second file.  */
40*75f6d617Schristos   NEW,
41*75f6d617Schristos 
42*75f6d617Schristos   /* Both deletes and inserts: a hunk containing both old and new lines.  */
43*75f6d617Schristos   CHANGED
44*75f6d617Schristos };
45*75f6d617Schristos 
46*75f6d617Schristos /* Variables for command line options */
47*75f6d617Schristos 
48*75f6d617Schristos #ifndef GDIFF_MAIN
49*75f6d617Schristos # define XTERN extern
50*75f6d617Schristos #else
51*75f6d617Schristos # define XTERN
52*75f6d617Schristos #endif
53*75f6d617Schristos 
54*75f6d617Schristos enum output_style
55*75f6d617Schristos {
56*75f6d617Schristos   /* No output style specified.  */
57*75f6d617Schristos   OUTPUT_UNSPECIFIED,
58*75f6d617Schristos 
59*75f6d617Schristos   /* Default output style.  */
60*75f6d617Schristos   OUTPUT_NORMAL,
61*75f6d617Schristos 
62*75f6d617Schristos   /* Output the differences with lines of context before and after (-c).  */
63*75f6d617Schristos   OUTPUT_CONTEXT,
64*75f6d617Schristos 
65*75f6d617Schristos   /* Output the differences in a unified context diff format (-u).  */
66*75f6d617Schristos   OUTPUT_UNIFIED,
67*75f6d617Schristos 
68*75f6d617Schristos   /* Output the differences as commands suitable for `ed' (-e).  */
69*75f6d617Schristos   OUTPUT_ED,
70*75f6d617Schristos 
71*75f6d617Schristos   /* Output the diff as a forward ed script (-f).  */
72*75f6d617Schristos   OUTPUT_FORWARD_ED,
73*75f6d617Schristos 
74*75f6d617Schristos   /* Like -f, but output a count of changed lines in each "command" (-n).  */
75*75f6d617Schristos   OUTPUT_RCS,
76*75f6d617Schristos 
77*75f6d617Schristos   /* Output merged #ifdef'd file (-D).  */
78*75f6d617Schristos   OUTPUT_IFDEF,
79*75f6d617Schristos 
80*75f6d617Schristos   /* Output sdiff style (-y).  */
81*75f6d617Schristos   OUTPUT_SDIFF
82*75f6d617Schristos };
83*75f6d617Schristos 
84*75f6d617Schristos /* True for output styles that are robust,
85*75f6d617Schristos    i.e. can handle a file that ends in a non-newline.  */
86*75f6d617Schristos #define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
87*75f6d617Schristos 
88*75f6d617Schristos XTERN enum output_style output_style;
89*75f6d617Schristos 
90*75f6d617Schristos /* Nonzero if output cannot be generated for identical files.  */
91*75f6d617Schristos XTERN bool no_diff_means_no_output;
92*75f6d617Schristos 
93*75f6d617Schristos /* Number of lines of context to show in each set of diffs.
94*75f6d617Schristos    This is zero when context is not to be shown.  */
95*75f6d617Schristos XTERN lin context;
96*75f6d617Schristos 
97*75f6d617Schristos /* Consider all files as text files (-a).
98*75f6d617Schristos    Don't interpret codes over 0177 as implying a "binary file".  */
99*75f6d617Schristos XTERN bool text;
100*75f6d617Schristos 
101*75f6d617Schristos /* Number of lines to keep in identical prefix and suffix.  */
102*75f6d617Schristos XTERN lin horizon_lines;
103*75f6d617Schristos 
104*75f6d617Schristos /* The significance of white space during comparisons.  */
105*75f6d617Schristos XTERN enum
106*75f6d617Schristos {
107*75f6d617Schristos   /* All white space is significant (the default).  */
108*75f6d617Schristos   IGNORE_NO_WHITE_SPACE,
109*75f6d617Schristos 
110*75f6d617Schristos   /* Ignore changes due to tab expansion (-E).  */
111*75f6d617Schristos   IGNORE_TAB_EXPANSION,
112*75f6d617Schristos 
113*75f6d617Schristos   /* Ignore changes in horizontal white space (-b).  */
114*75f6d617Schristos   IGNORE_SPACE_CHANGE,
115*75f6d617Schristos 
116*75f6d617Schristos   /* Ignore all horizontal white space (-w).  */
117*75f6d617Schristos   IGNORE_ALL_SPACE
118*75f6d617Schristos } ignore_white_space;
119*75f6d617Schristos 
120*75f6d617Schristos /* Ignore changes that affect only blank lines (-B).  */
121*75f6d617Schristos XTERN bool ignore_blank_lines;
122*75f6d617Schristos 
123*75f6d617Schristos /* Files can be compared byte-by-byte, as if they were binary.
124*75f6d617Schristos    This depends on various options.  */
125*75f6d617Schristos XTERN bool files_can_be_treated_as_binary;
126*75f6d617Schristos 
127*75f6d617Schristos /* Ignore differences in case of letters (-i).  */
128*75f6d617Schristos XTERN bool ignore_case;
129*75f6d617Schristos 
130*75f6d617Schristos /* Ignore differences in case of letters in file names.  */
131*75f6d617Schristos XTERN bool ignore_file_name_case;
132*75f6d617Schristos 
133*75f6d617Schristos /* File labels for `-c' output headers (--label).  */
134*75f6d617Schristos XTERN char *file_label[2];
135*75f6d617Schristos 
136*75f6d617Schristos /* Regexp to identify function-header lines (-F).  */
137*75f6d617Schristos XTERN struct re_pattern_buffer function_regexp;
138*75f6d617Schristos 
139*75f6d617Schristos /* Ignore changes that affect only lines matching this regexp (-I).  */
140*75f6d617Schristos XTERN struct re_pattern_buffer ignore_regexp;
141*75f6d617Schristos 
142*75f6d617Schristos /* Say only whether files differ, not how (-q).  */
143*75f6d617Schristos XTERN bool brief;
144*75f6d617Schristos 
145*75f6d617Schristos /* Expand tabs in the output so the text lines up properly
146*75f6d617Schristos    despite the characters added to the front of each line (-t).  */
147*75f6d617Schristos XTERN bool expand_tabs;
148*75f6d617Schristos 
149*75f6d617Schristos /* Use a tab in the output, rather than a space, before the text of an
150*75f6d617Schristos    input line, so as to keep the proper alignment in the input line
151*75f6d617Schristos    without changing the characters in it (-T).  */
152*75f6d617Schristos XTERN bool initial_tab;
153*75f6d617Schristos 
154*75f6d617Schristos /* Remove trailing carriage returns from input.  */
155*75f6d617Schristos XTERN bool strip_trailing_cr;
156*75f6d617Schristos 
157*75f6d617Schristos /* In directory comparison, specify file to start with (-S).
158*75f6d617Schristos    This is used for resuming an aborted comparison.
159*75f6d617Schristos    All file names less than this name are ignored.  */
160*75f6d617Schristos XTERN char const *starting_file;
161*75f6d617Schristos 
162*75f6d617Schristos /* Pipe each file's output through pr (-l).  */
163*75f6d617Schristos XTERN bool paginate;
164*75f6d617Schristos 
165*75f6d617Schristos /* Line group formats for unchanged, old, new, and changed groups.  */
166*75f6d617Schristos XTERN char const *group_format[CHANGED + 1];
167*75f6d617Schristos 
168*75f6d617Schristos /* Line formats for unchanged, old, and new lines.  */
169*75f6d617Schristos XTERN char const *line_format[NEW + 1];
170*75f6d617Schristos 
171*75f6d617Schristos /* If using OUTPUT_SDIFF print extra information to help the sdiff filter.  */
172*75f6d617Schristos XTERN bool sdiff_merge_assist;
173*75f6d617Schristos 
174*75f6d617Schristos /* Tell OUTPUT_SDIFF to show only the left version of common lines.  */
175*75f6d617Schristos XTERN bool left_column;
176*75f6d617Schristos 
177*75f6d617Schristos /* Tell OUTPUT_SDIFF to not show common lines.  */
178*75f6d617Schristos XTERN bool suppress_common_lines;
179*75f6d617Schristos 
180*75f6d617Schristos /* The half line width and column 2 offset for OUTPUT_SDIFF.  */
181*75f6d617Schristos XTERN unsigned int sdiff_half_width;
182*75f6d617Schristos XTERN unsigned int sdiff_column2_offset;
183*75f6d617Schristos 
184*75f6d617Schristos /* String containing all the command options diff received,
185*75f6d617Schristos    with spaces between and at the beginning but none at the end.
186*75f6d617Schristos    If there were no options given, this string is empty.  */
187*75f6d617Schristos XTERN char *switch_string;
188*75f6d617Schristos 
189*75f6d617Schristos /* Use heuristics for better speed with large files with a small
190*75f6d617Schristos    density of changes.  */
191*75f6d617Schristos XTERN bool speed_large_files;
192*75f6d617Schristos 
193*75f6d617Schristos /* Patterns that match file names to be excluded.  */
194*75f6d617Schristos XTERN struct exclude *excluded;
195*75f6d617Schristos 
196*75f6d617Schristos /* Don't discard lines.  This makes things slower (sometimes much
197*75f6d617Schristos    slower) but will find a guaranteed minimal set of changes.  */
198*75f6d617Schristos XTERN bool minimal;
199*75f6d617Schristos 
200*75f6d617Schristos /* Name of program the user invoked (for error messages).  */
201*75f6d617Schristos XTERN char *program_name;
202*75f6d617Schristos 
203*75f6d617Schristos /* The strftime format to use for time strings.  */
204*75f6d617Schristos XTERN char const *time_format;
205*75f6d617Schristos 
206*75f6d617Schristos /* The result of comparison is an "edit script": a chain of `struct change'.
207*75f6d617Schristos    Each `struct change' represents one place where some lines are deleted
208*75f6d617Schristos    and some are inserted.
209*75f6d617Schristos 
210*75f6d617Schristos    LINE0 and LINE1 are the first affected lines in the two files (origin 0).
211*75f6d617Schristos    DELETED is the number of lines deleted here from file 0.
212*75f6d617Schristos    INSERTED is the number of lines inserted here in file 1.
213*75f6d617Schristos 
214*75f6d617Schristos    If DELETED is 0 then LINE0 is the number of the line before
215*75f6d617Schristos    which the insertion was done; vice versa for INSERTED and LINE1.  */
216*75f6d617Schristos 
217*75f6d617Schristos struct change
218*75f6d617Schristos {
219*75f6d617Schristos   struct change *link;		/* Previous or next edit command  */
220*75f6d617Schristos   lin inserted;			/* # lines of file 1 changed here.  */
221*75f6d617Schristos   lin deleted;			/* # lines of file 0 changed here.  */
222*75f6d617Schristos   lin line0;			/* Line number of 1st deleted line.  */
223*75f6d617Schristos   lin line1;			/* Line number of 1st inserted line.  */
224*75f6d617Schristos   bool ignore;			/* Flag used in context.c.  */
225*75f6d617Schristos };
226*75f6d617Schristos 
227*75f6d617Schristos /* Structures that describe the input files.  */
228*75f6d617Schristos 
229*75f6d617Schristos /* Data on one input file being compared.  */
230*75f6d617Schristos 
231*75f6d617Schristos struct file_data {
232*75f6d617Schristos     int             desc;	/* File descriptor  */
233*75f6d617Schristos     char const      *name;	/* File name  */
234*75f6d617Schristos     struct stat     stat;	/* File status */
235*75f6d617Schristos 
236*75f6d617Schristos     /* Buffer in which text of file is read.  */
237*75f6d617Schristos     word *buffer;
238*75f6d617Schristos 
239*75f6d617Schristos     /* Allocated size of buffer, in bytes.  Always a multiple of
240*75f6d617Schristos        sizeof *buffer.  */
241*75f6d617Schristos     size_t bufsize;
242*75f6d617Schristos 
243*75f6d617Schristos     /* Number of valid bytes now in the buffer.  */
244*75f6d617Schristos     size_t buffered;
245*75f6d617Schristos 
246*75f6d617Schristos     /* Array of pointers to lines in the file.  */
247*75f6d617Schristos     char const **linbuf;
248*75f6d617Schristos 
249*75f6d617Schristos     /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
250*75f6d617Schristos        linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
251*75f6d617Schristos        linebuf[linbuf_base ... valid_lines - 1] contain valid data.
252*75f6d617Schristos        linebuf[linbuf_base ... alloc_lines - 1] are allocated.  */
253*75f6d617Schristos     lin linbuf_base, buffered_lines, valid_lines, alloc_lines;
254*75f6d617Schristos 
255*75f6d617Schristos     /* Pointer to end of prefix of this file to ignore when hashing.  */
256*75f6d617Schristos     char const *prefix_end;
257*75f6d617Schristos 
258*75f6d617Schristos     /* Count of lines in the prefix.
259*75f6d617Schristos        There are this many lines in the file before linbuf[0].  */
260*75f6d617Schristos     lin prefix_lines;
261*75f6d617Schristos 
262*75f6d617Schristos     /* Pointer to start of suffix of this file to ignore when hashing.  */
263*75f6d617Schristos     char const *suffix_begin;
264*75f6d617Schristos 
265*75f6d617Schristos     /* Vector, indexed by line number, containing an equivalence code for
266*75f6d617Schristos        each line.  It is this vector that is actually compared with that
267*75f6d617Schristos        of another file to generate differences.  */
268*75f6d617Schristos     lin *equivs;
269*75f6d617Schristos 
270*75f6d617Schristos     /* Vector, like the previous one except that
271*75f6d617Schristos        the elements for discarded lines have been squeezed out.  */
272*75f6d617Schristos     lin *undiscarded;
273*75f6d617Schristos 
274*75f6d617Schristos     /* Vector mapping virtual line numbers (not counting discarded lines)
275*75f6d617Schristos        to real ones (counting those lines).  Both are origin-0.  */
276*75f6d617Schristos     lin *realindexes;
277*75f6d617Schristos 
278*75f6d617Schristos     /* Total number of nondiscarded lines.  */
279*75f6d617Schristos     lin nondiscarded_lines;
280*75f6d617Schristos 
281*75f6d617Schristos     /* Vector, indexed by real origin-0 line number,
282*75f6d617Schristos        containing TRUE for a line that is an insertion or a deletion.
283*75f6d617Schristos        The results of comparison are stored here.  */
284*75f6d617Schristos     bool *changed;
285*75f6d617Schristos 
286*75f6d617Schristos     /* 1 if file ends in a line with no final newline.  */
287*75f6d617Schristos     bool missing_newline;
288*75f6d617Schristos 
289*75f6d617Schristos     /* 1 if at end of file.  */
290*75f6d617Schristos     bool eof;
291*75f6d617Schristos 
292*75f6d617Schristos     /* 1 more than the maximum equivalence value used for this or its
293*75f6d617Schristos        sibling file.  */
294*75f6d617Schristos     lin equiv_max;
295*75f6d617Schristos };
296*75f6d617Schristos 
297*75f6d617Schristos /* The file buffer, considered as an array of bytes rather than
298*75f6d617Schristos    as an array of words.  */
299*75f6d617Schristos #define FILE_BUFFER(f) ((char *) (f)->buffer)
300*75f6d617Schristos 
301*75f6d617Schristos /* Data on two input files being compared.  */
302*75f6d617Schristos 
303*75f6d617Schristos struct comparison
304*75f6d617Schristos   {
305*75f6d617Schristos     struct file_data file[2];
306*75f6d617Schristos     struct comparison const *parent;  /* parent, if a recursive comparison */
307*75f6d617Schristos   };
308*75f6d617Schristos 
309*75f6d617Schristos /* Describe the two files currently being compared.  */
310*75f6d617Schristos 
311*75f6d617Schristos XTERN struct file_data files[2];
312*75f6d617Schristos 
313*75f6d617Schristos /* Stdio stream to output diffs to.  */
314*75f6d617Schristos 
315*75f6d617Schristos XTERN FILE *outfile;
316*75f6d617Schristos 
317*75f6d617Schristos /* Declare various functions.  */
318*75f6d617Schristos 
319*75f6d617Schristos /* analyze.c */
320*75f6d617Schristos int diff_2_files (struct comparison *);
321*75f6d617Schristos 
322*75f6d617Schristos /* context.c */
323*75f6d617Schristos void print_context_header (struct file_data[], bool);
324*75f6d617Schristos void print_context_script (struct change *, bool);
325*75f6d617Schristos 
326*75f6d617Schristos /* dir.c */
327*75f6d617Schristos int diff_dirs (struct comparison const *, int (*) (struct comparison const *, char const *, char const *));
328*75f6d617Schristos 
329*75f6d617Schristos /* ed.c */
330*75f6d617Schristos void print_ed_script (struct change *);
331*75f6d617Schristos void pr_forward_ed_script (struct change *);
332*75f6d617Schristos 
333*75f6d617Schristos /* ifdef.c */
334*75f6d617Schristos void print_ifdef_script (struct change *);
335*75f6d617Schristos 
336*75f6d617Schristos /* io.c */
337*75f6d617Schristos void file_block_read (struct file_data *, size_t);
338*75f6d617Schristos bool read_files (struct file_data[], bool);
339*75f6d617Schristos 
340*75f6d617Schristos /* normal.c */
341*75f6d617Schristos void print_normal_script (struct change *);
342*75f6d617Schristos 
343*75f6d617Schristos /* rcs.c */
344*75f6d617Schristos void print_rcs_script (struct change *);
345*75f6d617Schristos 
346*75f6d617Schristos /* side.c */
347*75f6d617Schristos void print_sdiff_script (struct change *);
348*75f6d617Schristos 
349*75f6d617Schristos /* util.c */
350*75f6d617Schristos extern char const change_letter[4];
351*75f6d617Schristos extern char const pr_program[];
352*75f6d617Schristos char *concat (char const *, char const *, char const *);
353*75f6d617Schristos char *dir_file_pathname (char const *, char const *);
354*75f6d617Schristos bool lines_differ (char const *, char const *);
355*75f6d617Schristos lin translate_line_number (struct file_data const *, lin);
356*75f6d617Schristos struct change *find_change (struct change *);
357*75f6d617Schristos struct change *find_reverse_change (struct change *);
358*75f6d617Schristos void *zalloc (size_t);
359*75f6d617Schristos enum changes analyze_hunk (struct change *, lin *, lin *, lin *, lin *);
360*75f6d617Schristos void begin_output (void);
361*75f6d617Schristos void debug_script (struct change *);
362*75f6d617Schristos void fatal (char const *) __attribute__((noreturn));
363*75f6d617Schristos void finish_output (void);
364*75f6d617Schristos void message (char const *, char const *, char const *);
365*75f6d617Schristos void message5 (char const *, char const *, char const *, char const *, char const *);
366*75f6d617Schristos void output_1_line (char const *, char const *, char const *, char const *);
367*75f6d617Schristos void perror_with_name (char const *);
368*75f6d617Schristos void pfatal_with_name (char const *) __attribute__((noreturn));
369*75f6d617Schristos void print_1_line (char const *, char const * const *);
370*75f6d617Schristos void print_message_queue (void);
371*75f6d617Schristos void print_number_range (char, struct file_data *, lin, lin);
372*75f6d617Schristos void print_script (struct change *, struct change * (*) (struct change *), void (*) (struct change *));
373*75f6d617Schristos void setup_output (char const *, char const *, bool);
374*75f6d617Schristos void translate_range (struct file_data const *, lin, lin, long *, long *);
375*75f6d617Schristos 
376*75f6d617Schristos /* version.c */
377*75f6d617Schristos extern char const version_string[];
378