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