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