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