xref: /openbsd-src/gnu/usr.bin/cvs/diff/diff.h (revision b2346922a76a50a89e33beab4ebbc0950de8a8df)
12286d8edStholo /* Shared definitions for GNU DIFF
2*b2346922Stholo    Copyright (C) 1988, 89, 91, 92, 93, 97, 1998 Free Software Foundation, Inc.
32286d8edStholo 
42286d8edStholo This file is part of GNU DIFF.
52286d8edStholo 
62286d8edStholo GNU DIFF is free software; you can redistribute it and/or modify
72286d8edStholo it under the terms of the GNU General Public License as published by
82286d8edStholo the Free Software Foundation; either version 2, or (at your option)
92286d8edStholo any later version.
102286d8edStholo 
112286d8edStholo GNU DIFF is distributed in the hope that it will be useful,
122286d8edStholo but WITHOUT ANY WARRANTY; without even the implied warranty of
132286d8edStholo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142286d8edStholo GNU General Public License for more details.
152286d8edStholo 
162286d8edStholo You should have received a copy of the GNU General Public License
172286d8edStholo along with GNU DIFF; see the file COPYING.  If not, write to
182286d8edStholo the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
192286d8edStholo 
202286d8edStholo #include "system.h"
212286d8edStholo #include <stdio.h>
222286d8edStholo #include <setjmp.h>
232286d8edStholo #include "regex.h"
24*b2346922Stholo #include "diffrun.h"
252286d8edStholo 
262286d8edStholo #define TAB_WIDTH 8
272286d8edStholo 
282286d8edStholo /* Variables for command line options */
292286d8edStholo 
302286d8edStholo #ifndef GDIFF_MAIN
312286d8edStholo #define EXTERN extern
322286d8edStholo #else
332286d8edStholo #define EXTERN
342286d8edStholo #endif
352286d8edStholo 
36*b2346922Stholo /* The callbacks to use for output.  */
37*b2346922Stholo EXTERN const struct diff_callbacks *callbacks;
38*b2346922Stholo 
392286d8edStholo enum output_style {
402286d8edStholo   /* Default output style.  */
412286d8edStholo   OUTPUT_NORMAL,
422286d8edStholo   /* Output the differences with lines of context before and after (-c).  */
432286d8edStholo   OUTPUT_CONTEXT,
442286d8edStholo   /* Output the differences in a unified context diff format (-u). */
452286d8edStholo   OUTPUT_UNIFIED,
462286d8edStholo   /* Output the differences as commands suitable for `ed' (-e).  */
472286d8edStholo   OUTPUT_ED,
482286d8edStholo   /* Output the diff as a forward ed script (-f).  */
492286d8edStholo   OUTPUT_FORWARD_ED,
502286d8edStholo   /* Like -f, but output a count of changed lines in each "command" (-n). */
512286d8edStholo   OUTPUT_RCS,
522286d8edStholo   /* Output merged #ifdef'd file (-D).  */
532286d8edStholo   OUTPUT_IFDEF,
542286d8edStholo   /* Output sdiff style (-y).  */
552286d8edStholo   OUTPUT_SDIFF
562286d8edStholo };
572286d8edStholo 
582286d8edStholo /* True for output styles that are robust,
592286d8edStholo    i.e. can handle a file that ends in a non-newline.  */
602286d8edStholo #define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
612286d8edStholo 
622286d8edStholo EXTERN enum output_style output_style;
632286d8edStholo 
642286d8edStholo /* Nonzero if output cannot be generated for identical files.  */
652286d8edStholo EXTERN int no_diff_means_no_output;
662286d8edStholo 
672286d8edStholo /* Number of lines of context to show in each set of diffs.
682286d8edStholo    This is zero when context is not to be shown.  */
692286d8edStholo EXTERN int      context;
702286d8edStholo 
712286d8edStholo /* Consider all files as text files (-a).
722286d8edStholo    Don't interpret codes over 0177 as implying a "binary file".  */
732286d8edStholo EXTERN int	always_text_flag;
742286d8edStholo 
752286d8edStholo /* Number of lines to keep in identical prefix and suffix.  */
762286d8edStholo EXTERN int      horizon_lines;
772286d8edStholo 
782286d8edStholo /* Ignore changes in horizontal white space (-b).  */
792286d8edStholo EXTERN int      ignore_space_change_flag;
802286d8edStholo 
812286d8edStholo /* Ignore all horizontal white space (-w).  */
822286d8edStholo EXTERN int      ignore_all_space_flag;
832286d8edStholo 
842286d8edStholo /* Ignore changes that affect only blank lines (-B).  */
852286d8edStholo EXTERN int      ignore_blank_lines_flag;
862286d8edStholo 
872286d8edStholo /* 1 if lines may match even if their contents do not match exactly.
882286d8edStholo    This depends on various options.  */
892286d8edStholo EXTERN int      ignore_some_line_changes;
902286d8edStholo 
912286d8edStholo /* 1 if files may match even if their contents are not byte-for-byte identical.
922286d8edStholo    This depends on various options.  */
932286d8edStholo EXTERN int      ignore_some_changes;
942286d8edStholo 
952286d8edStholo /* Ignore differences in case of letters (-i).  */
962286d8edStholo EXTERN int      ignore_case_flag;
972286d8edStholo 
982286d8edStholo /* File labels for `-c' output headers (-L).  */
992286d8edStholo EXTERN char *file_label[2];
1002286d8edStholo 
1012286d8edStholo struct regexp_list
1022286d8edStholo {
1032286d8edStholo   struct re_pattern_buffer buf;
1042286d8edStholo   struct regexp_list *next;
1052286d8edStholo };
1062286d8edStholo 
1072286d8edStholo /* Regexp to identify function-header lines (-F).  */
1082286d8edStholo EXTERN struct regexp_list *function_regexp_list;
1092286d8edStholo 
1102286d8edStholo /* Ignore changes that affect only lines matching this regexp (-I).  */
1112286d8edStholo EXTERN struct regexp_list *ignore_regexp_list;
1122286d8edStholo 
1132286d8edStholo /* Say only whether files differ, not how (-q).  */
1142286d8edStholo EXTERN int 	no_details_flag;
1152286d8edStholo 
1162286d8edStholo /* Report files compared that match (-s).
1172286d8edStholo    Normally nothing is output when that happens.  */
1182286d8edStholo EXTERN int      print_file_same_flag;
1192286d8edStholo 
1202286d8edStholo /* Output the differences with exactly 8 columns added to each line
1212286d8edStholo    so that any tabs in the text line up properly (-T).  */
1222286d8edStholo EXTERN int	tab_align_flag;
1232286d8edStholo 
1242286d8edStholo /* Expand tabs in the output so the text lines up properly
1252286d8edStholo    despite the characters added to the front of each line (-t).  */
1262286d8edStholo EXTERN int	tab_expand_flag;
1272286d8edStholo 
1282286d8edStholo /* In directory comparison, specify file to start with (-S).
1292286d8edStholo    All file names less than this name are ignored.  */
1302286d8edStholo EXTERN char	*dir_start_file;
1312286d8edStholo 
1322286d8edStholo /* If a file is new (appears in only one dir)
1332286d8edStholo    include its entire contents (-N).
1342286d8edStholo    Then `patch' would create the file with appropriate contents.  */
1352286d8edStholo EXTERN int	entire_new_file_flag;
1362286d8edStholo 
1372286d8edStholo /* If a file is new (appears in only the second dir)
1382286d8edStholo    include its entire contents (-P).
1392286d8edStholo    Then `patch' would create the file with appropriate contents.  */
1402286d8edStholo EXTERN int	unidirectional_new_file_flag;
1412286d8edStholo 
1422286d8edStholo /* Pipe each file's output through pr (-l).  */
1432286d8edStholo EXTERN int	paginate_flag;
1442286d8edStholo 
1452286d8edStholo enum line_class {
1462286d8edStholo   /* Lines taken from just the first file.  */
1472286d8edStholo   OLD,
1482286d8edStholo   /* Lines taken from just the second file.  */
1492286d8edStholo   NEW,
1502286d8edStholo   /* Lines common to both files.  */
1512286d8edStholo   UNCHANGED,
1522286d8edStholo   /* A hunk containing both old and new lines (line groups only).  */
1532286d8edStholo   CHANGED
1542286d8edStholo };
1552286d8edStholo 
1562286d8edStholo /* Line group formats for old, new, unchanged, and changed groups.  */
1572286d8edStholo EXTERN char *group_format[CHANGED + 1];
1582286d8edStholo 
1592286d8edStholo /* Line formats for old, new, and unchanged lines.  */
1602286d8edStholo EXTERN char *line_format[UNCHANGED + 1];
1612286d8edStholo 
1622286d8edStholo /* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
1632286d8edStholo EXTERN int sdiff_help_sdiff;
1642286d8edStholo 
1652286d8edStholo /* Tell OUTPUT_SDIFF to show only the left version of common lines. */
1662286d8edStholo EXTERN int sdiff_left_only;
1672286d8edStholo 
1682286d8edStholo /* Tell OUTPUT_SDIFF to not show common lines. */
1692286d8edStholo EXTERN int sdiff_skip_common_lines;
1702286d8edStholo 
1712286d8edStholo /* The half line width and column 2 offset for OUTPUT_SDIFF.  */
1722286d8edStholo EXTERN unsigned sdiff_half_width;
1732286d8edStholo EXTERN unsigned sdiff_column2_offset;
1742286d8edStholo 
1752286d8edStholo /* String containing all the command options diff received,
1762286d8edStholo    with spaces between and at the beginning but none at the end.
1772286d8edStholo    If there were no options given, this string is empty.  */
1782286d8edStholo EXTERN char *	switch_string;
1792286d8edStholo 
1802286d8edStholo /* Nonzero means use heuristics for better speed.  */
1812286d8edStholo EXTERN int	heuristic;
1822286d8edStholo 
1832286d8edStholo /* Name of program the user invoked (for error messages).  */
1842286d8edStholo EXTERN char *diff_program_name;
1852286d8edStholo 
1862286d8edStholo /* Jump buffer for nonlocal exits. */
1872286d8edStholo EXTERN jmp_buf diff_abort_buf;
1882286d8edStholo #define DIFF_ABORT(retval) longjmp(diff_abort_buf, retval)
1892286d8edStholo 
1902286d8edStholo /* The result of comparison is an "edit script": a chain of `struct change'.
1912286d8edStholo    Each `struct change' represents one place where some lines are deleted
1922286d8edStholo    and some are inserted.
1932286d8edStholo 
1942286d8edStholo    LINE0 and LINE1 are the first affected lines in the two files (origin 0).
1952286d8edStholo    DELETED is the number of lines deleted here from file 0.
1962286d8edStholo    INSERTED is the number of lines inserted here in file 1.
1972286d8edStholo 
1982286d8edStholo    If DELETED is 0 then LINE0 is the number of the line before
1992286d8edStholo    which the insertion was done; vice versa for INSERTED and LINE1.  */
2002286d8edStholo 
2012286d8edStholo struct change
2022286d8edStholo {
2032286d8edStholo   struct change *link;		/* Previous or next edit command  */
2042286d8edStholo   int inserted;			/* # lines of file 1 changed here.  */
2052286d8edStholo   int deleted;			/* # lines of file 0 changed here.  */
2062286d8edStholo   int line0;			/* Line number of 1st deleted line.  */
2072286d8edStholo   int line1;			/* Line number of 1st inserted line.  */
2082286d8edStholo   char ignore;			/* Flag used in context.c */
2092286d8edStholo };
2102286d8edStholo 
2112286d8edStholo /* Structures that describe the input files.  */
2122286d8edStholo 
2132286d8edStholo /* Data on one input file being compared.  */
2142286d8edStholo 
2152286d8edStholo struct file_data {
2162286d8edStholo     int             desc;	/* File descriptor  */
2172286d8edStholo     char const      *name;	/* File name  */
2182286d8edStholo     struct stat     stat;	/* File status from fstat()  */
2192286d8edStholo     int             dir_p;	/* nonzero if file is a directory  */
2202286d8edStholo 
2212286d8edStholo     /* Buffer in which text of file is read.  */
2222286d8edStholo     char *	    buffer;
2232286d8edStholo     /* Allocated size of buffer.  */
2242286d8edStholo     size_t	    bufsize;
2252286d8edStholo     /* Number of valid characters now in the buffer. */
2262286d8edStholo     size_t	    buffered_chars;
2272286d8edStholo 
2282286d8edStholo     /* Array of pointers to lines in the file.  */
2292286d8edStholo     char const **linbuf;
2302286d8edStholo 
2312286d8edStholo     /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
2322286d8edStholo        linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
2332286d8edStholo        linebuf[linbuf_base ... valid_lines - 1] contain valid data.
2342286d8edStholo        linebuf[linbuf_base ... alloc_lines - 1] are allocated.  */
2352286d8edStholo     int linbuf_base, buffered_lines, valid_lines, alloc_lines;
2362286d8edStholo 
2372286d8edStholo     /* Pointer to end of prefix of this file to ignore when hashing. */
2382286d8edStholo     char const *prefix_end;
2392286d8edStholo 
2402286d8edStholo     /* Count of lines in the prefix.
2412286d8edStholo        There are this many lines in the file before linbuf[0].  */
2422286d8edStholo     int prefix_lines;
2432286d8edStholo 
2442286d8edStholo     /* Pointer to start of suffix of this file to ignore when hashing. */
2452286d8edStholo     char const *suffix_begin;
2462286d8edStholo 
2472286d8edStholo     /* Vector, indexed by line number, containing an equivalence code for
2482286d8edStholo        each line.  It is this vector that is actually compared with that
2492286d8edStholo        of another file to generate differences. */
2502286d8edStholo     int		   *equivs;
2512286d8edStholo 
2522286d8edStholo     /* Vector, like the previous one except that
2532286d8edStholo        the elements for discarded lines have been squeezed out.  */
2542286d8edStholo     int		   *undiscarded;
2552286d8edStholo 
2562286d8edStholo     /* Vector mapping virtual line numbers (not counting discarded lines)
2572286d8edStholo        to real ones (counting those lines).  Both are origin-0.  */
2582286d8edStholo     int		   *realindexes;
2592286d8edStholo 
2602286d8edStholo     /* Total number of nondiscarded lines. */
2612286d8edStholo     int		    nondiscarded_lines;
2622286d8edStholo 
2632286d8edStholo     /* Vector, indexed by real origin-0 line number,
2642286d8edStholo        containing 1 for a line that is an insertion or a deletion.
2652286d8edStholo        The results of comparison are stored here.  */
2662286d8edStholo     char	   *changed_flag;
2672286d8edStholo 
2682286d8edStholo     /* 1 if file ends in a line with no final newline. */
2692286d8edStholo     int		    missing_newline;
2702286d8edStholo 
2712286d8edStholo     /* 1 more than the maximum equivalence value used for this or its
2722286d8edStholo        sibling file. */
2732286d8edStholo     int equiv_max;
2742286d8edStholo };
2752286d8edStholo 
2762286d8edStholo /* Describe the two files currently being compared.  */
2772286d8edStholo 
2782286d8edStholo EXTERN struct file_data files[2];
2792286d8edStholo 
2802286d8edStholo /* Stdio stream to output diffs to.  */
2812286d8edStholo 
2822286d8edStholo EXTERN FILE *outfile;
2832286d8edStholo 
2842286d8edStholo /* Declare various functions.  */
2852286d8edStholo 
2862286d8edStholo /* analyze.c */
2872286d8edStholo int diff_2_files PARAMS((struct file_data[], int));
2882286d8edStholo 
2892286d8edStholo /* context.c */
2902286d8edStholo void print_context_header PARAMS((struct file_data[], int));
2912286d8edStholo void print_context_script PARAMS((struct change *, int));
2922286d8edStholo 
2932286d8edStholo /* diff.c */
2942286d8edStholo int excluded_filename PARAMS((char const *));
2952286d8edStholo 
2962286d8edStholo /* dir.c */
2972286d8edStholo int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int));
2982286d8edStholo 
2992286d8edStholo /* ed.c */
3002286d8edStholo void print_ed_script PARAMS((struct change *));
3012286d8edStholo void pr_forward_ed_script PARAMS((struct change *));
3022286d8edStholo 
3032286d8edStholo /* ifdef.c */
3042286d8edStholo void print_ifdef_script PARAMS((struct change *));
3052286d8edStholo 
3062286d8edStholo /* io.c */
3072286d8edStholo int read_files PARAMS((struct file_data[], int));
3082286d8edStholo int sip PARAMS((struct file_data *, int));
3092286d8edStholo void slurp PARAMS((struct file_data *));
3102286d8edStholo 
3112286d8edStholo /* normal.c */
3122286d8edStholo void print_normal_script PARAMS((struct change *));
3132286d8edStholo 
3142286d8edStholo /* rcs.c */
3152286d8edStholo void print_rcs_script PARAMS((struct change *));
3162286d8edStholo 
3172286d8edStholo /* side.c */
3182286d8edStholo void print_sdiff_script PARAMS((struct change *));
3192286d8edStholo 
3202286d8edStholo /* util.c */
3212286d8edStholo VOID *xmalloc PARAMS((size_t));
3222286d8edStholo VOID *xrealloc PARAMS((VOID *, size_t));
3232286d8edStholo char *concat PARAMS((char const *, char const *, char const *));
3242286d8edStholo char *dir_file_pathname PARAMS((char const *, char const *));
3252286d8edStholo int change_letter PARAMS((int, int));
3262286d8edStholo int line_cmp PARAMS((char const *, char const *));
3272286d8edStholo int translate_line_number PARAMS((struct file_data const *, int));
3282286d8edStholo struct change *find_change PARAMS((struct change *));
3292286d8edStholo struct change *find_reverse_change PARAMS((struct change *));
3302286d8edStholo void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *));
3312286d8edStholo void begin_output PARAMS((void));
3322286d8edStholo void debug_script PARAMS((struct change *));
3332286d8edStholo void diff_error PARAMS((char const *, char const *, char const *));
3342286d8edStholo void fatal PARAMS((char const *));
3352286d8edStholo void finish_output PARAMS((void));
336*b2346922Stholo void write_output PARAMS((char const *, size_t));
337*b2346922Stholo void printf_output PARAMS((char const *, ...))
338*b2346922Stholo #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
339*b2346922Stholo      __attribute__ ((__format__ (__printf__, 1, 2)))
340*b2346922Stholo #endif
341*b2346922Stholo      ;
342*b2346922Stholo void flush_output PARAMS((void));
3432286d8edStholo void message PARAMS((char const *, char const *, char const *));
3442286d8edStholo void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
3452286d8edStholo void output_1_line PARAMS((char const *, char const *, char const *, char const *));
3462286d8edStholo void perror_with_name PARAMS((char const *));
3472286d8edStholo void pfatal_with_name PARAMS((char const *));
3482286d8edStholo void print_1_line PARAMS((char const *, char const * const *));
3492286d8edStholo void print_message_queue PARAMS((void));
3502286d8edStholo void print_number_range PARAMS((int, struct file_data *, int, int));
3512286d8edStholo void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *))));
3522286d8edStholo void setup_output PARAMS((char const *, char const *, int));
3532286d8edStholo void translate_range PARAMS((struct file_data const *, int, int, int *, int *));
3542286d8edStholo 
3552286d8edStholo /* version.c */
3562286d8edStholo extern char const diff_version_string[];
357