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