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