joachim99@52: /* Shared definitions for GNU DIFF joachim99@52: joachim99@68: Modified for KDiff3 by Joachim Eibl 2003, 2004, 2005. joachim99@53: The original file was part of GNU DIFF. joachim99@52: joachim99@52: Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001, joachim99@52: 2002 Free Software Foundation, Inc. joachim99@52: joachim99@52: GNU DIFF is free software; you can redistribute it and/or modify joachim99@52: it under the terms of the GNU General Public License as published by joachim99@52: the Free Software Foundation; either version 2, or (at your option) joachim99@52: any later version. joachim99@52: joachim99@52: GNU DIFF is distributed in the hope that it will be useful, joachim99@52: but WITHOUT ANY WARRANTY; without even the implied warranty of joachim99@52: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the joachim99@52: GNU General Public License for more details. joachim99@52: joachim99@52: You should have received a copy of the GNU General Public License joachim99@52: along with this program; see the file COPYING. joachim99@52: If not, write to the Free Software Foundation, joachim99@69: 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. */ joachim99@52: joachim99@53: #ifndef GNUDIFF_DIFF_H joachim99@53: #define GNUDIFF_DIFF_H joachim99@53: joachim99@52: #include "gnudiff_system.h" joachim99@52: joachim99@52: #include joachim99@68: #include joachim99@52: joachim99@52: #define TAB_WIDTH 8 joachim99@52: joachim99@53: class GnuDiff joachim99@52: { joachim99@53: public: joachim99@52: /* What kind of changes a hunk contains. */ joachim99@52: enum changes joachim99@52: { joachim99@52: /* No changes: lines common to both files. */ joachim99@52: UNCHANGED, joachim99@52: joachim99@52: /* Deletes only: lines taken from just the first file. */ joachim99@52: OLD, joachim99@52: joachim99@52: /* Inserts only: lines taken from just the second file. */ joachim99@52: NEW, joachim99@52: joachim99@52: /* Both deletes and inserts: a hunk containing both old and new lines. */ joachim99@52: CHANGED joachim99@52: }; joachim99@52: joachim99@52: /* Variables for command line options */ joachim99@52: joachim99@52: /* Nonzero if output cannot be generated for identical files. */ joachim99@53: bool no_diff_means_no_output; joachim99@52: joachim99@52: /* Number of lines of context to show in each set of diffs. joachim99@52: This is zero when context is not to be shown. */ joachim99@53: lin context; joachim99@52: joachim99@52: /* Consider all files as text files (-a). joachim99@52: Don't interpret codes over 0177 as implying a "binary file". */ joachim99@53: bool text; joachim99@52: joachim99@52: /* The significance of white space during comparisons. */ joachim99@53: enum joachim99@52: { joachim99@52: /* All white space is significant (the default). */ joachim99@52: IGNORE_NO_WHITE_SPACE, joachim99@52: joachim99@52: /* Ignore changes due to tab expansion (-E). */ joachim99@52: IGNORE_TAB_EXPANSION, joachim99@52: joachim99@52: /* Ignore changes in horizontal white space (-b). */ joachim99@52: IGNORE_SPACE_CHANGE, joachim99@52: joachim99@52: /* Ignore all horizontal white space (-w). */ joachim99@52: IGNORE_ALL_SPACE joachim99@52: } ignore_white_space; joachim99@52: joachim99@52: /* Ignore changes that affect only blank lines (-B). */ joachim99@53: bool ignore_blank_lines; joachim99@52: joachim99@52: /* Ignore changes that affect only numbers. (J. Eibl) */ joachim99@53: bool bIgnoreNumbers; joachim99@53: bool bIgnoreWhiteSpace; joachim99@52: joachim99@52: /* Files can be compared byte-by-byte, as if they were binary. joachim99@52: This depends on various options. */ joachim99@53: bool files_can_be_treated_as_binary; joachim99@52: joachim99@52: /* Ignore differences in case of letters (-i). */ joachim99@53: bool ignore_case; joachim99@52: joachim99@52: /* Ignore differences in case of letters in file names. */ joachim99@53: bool ignore_file_name_case; joachim99@52: joachim99@52: /* Regexp to identify function-header lines (-F). */ joachim99@53: //struct re_pattern_buffer function_regexp; joachim99@52: joachim99@52: /* Ignore changes that affect only lines matching this regexp (-I). */ joachim99@53: //struct re_pattern_buffer ignore_regexp; joachim99@52: joachim99@52: /* Say only whether files differ, not how (-q). */ joachim99@53: bool brief; joachim99@52: joachim99@52: /* Expand tabs in the output so the text lines up properly joachim99@52: despite the characters added to the front of each line (-t). */ joachim99@53: bool expand_tabs; joachim99@52: joachim99@52: /* Use a tab in the output, rather than a space, before the text of an joachim99@52: input line, so as to keep the proper alignment in the input line joachim99@52: without changing the characters in it (-T). */ joachim99@53: bool initial_tab; joachim99@52: joachim99@52: /* In directory comparison, specify file to start with (-S). joachim99@52: This is used for resuming an aborted comparison. joachim99@52: All file names less than this name are ignored. */ joachim99@68: const QChar *starting_file; joachim99@52: joachim99@52: /* Pipe each file's output through pr (-l). */ joachim99@53: bool paginate; joachim99@52: joachim99@52: /* Line group formats for unchanged, old, new, and changed groups. */ joachim99@68: const QChar *group_format[CHANGED + 1]; joachim99@52: joachim99@52: /* Line formats for unchanged, old, and new lines. */ joachim99@68: const QChar *line_format[NEW + 1]; joachim99@52: joachim99@52: /* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */ joachim99@53: bool sdiff_merge_assist; joachim99@52: joachim99@52: /* Tell OUTPUT_SDIFF to show only the left version of common lines. */ joachim99@53: bool left_column; joachim99@52: joachim99@52: /* Tell OUTPUT_SDIFF to not show common lines. */ joachim99@53: bool suppress_common_lines; joachim99@52: joachim99@52: /* The half line width and column 2 offset for OUTPUT_SDIFF. */ joachim99@53: unsigned int sdiff_half_width; joachim99@53: unsigned int sdiff_column2_offset; joachim99@52: joachim99@52: /* Use heuristics for better speed with large files with a small joachim99@52: density of changes. */ joachim99@53: bool speed_large_files; joachim99@52: joachim99@52: /* Patterns that match file names to be excluded. */ joachim99@53: struct exclude *excluded; joachim99@52: joachim99@52: /* Don't discard lines. This makes things slower (sometimes much joachim99@52: slower) but will find a guaranteed minimal set of changes. */ joachim99@53: bool minimal; joachim99@52: joachim99@52: joachim99@52: /* The result of comparison is an "edit script": a chain of `struct change'. joachim99@52: Each `struct change' represents one place where some lines are deleted joachim99@52: and some are inserted. joachim99@52: joachim99@52: LINE0 and LINE1 are the first affected lines in the two files (origin 0). joachim99@52: DELETED is the number of lines deleted here from file 0. joachim99@52: INSERTED is the number of lines inserted here in file 1. joachim99@52: joachim99@52: If DELETED is 0 then LINE0 is the number of the line before joachim99@52: which the insertion was done; vice versa for INSERTED and LINE1. */ joachim99@52: joachim99@52: struct change joachim99@52: { joachim99@52: struct change *link; /* Previous or next edit command */ joachim99@52: lin inserted; /* # lines of file 1 changed here. */ joachim99@52: lin deleted; /* # lines of file 0 changed here. */ joachim99@52: lin line0; /* Line number of 1st deleted line. */ joachim99@52: lin line1; /* Line number of 1st inserted line. */ joachim99@52: bool ignore; /* Flag used in context.c. */ joachim99@52: }; joachim99@52: joachim99@52: /* Structures that describe the input files. */ joachim99@52: joachim99@52: /* Data on one input file being compared. */ joachim99@52: joachim99@52: struct file_data { joachim99@52: /* Buffer in which text of file is read. */ joachim99@69: const QChar* buffer; joachim99@52: joachim99@68: /* Allocated size of buffer, in QChars. Always a multiple of joachim99@52: sizeof *buffer. */ joachim99@52: size_t bufsize; joachim99@52: joachim99@52: /* Number of valid bytes now in the buffer. */ joachim99@52: size_t buffered; joachim99@52: joachim99@52: /* Array of pointers to lines in the file. */ joachim99@68: const QChar **linbuf; joachim99@52: joachim99@52: /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines. joachim99@52: linebuf[linbuf_base ... buffered_lines - 1] are possibly differing. joachim99@52: linebuf[linbuf_base ... valid_lines - 1] contain valid data. joachim99@52: linebuf[linbuf_base ... alloc_lines - 1] are allocated. */ joachim99@52: lin linbuf_base, buffered_lines, valid_lines, alloc_lines; joachim99@52: joachim99@52: /* Pointer to end of prefix of this file to ignore when hashing. */ joachim99@68: const QChar *prefix_end; joachim99@52: joachim99@52: /* Count of lines in the prefix. joachim99@52: There are this many lines in the file before linbuf[0]. */ joachim99@52: lin prefix_lines; joachim99@52: joachim99@52: /* Pointer to start of suffix of this file to ignore when hashing. */ joachim99@68: const QChar *suffix_begin; joachim99@52: joachim99@52: /* Vector, indexed by line number, containing an equivalence code for joachim99@52: each line. It is this vector that is actually compared with that joachim99@52: of another file to generate differences. */ joachim99@52: lin *equivs; joachim99@52: joachim99@52: /* Vector, like the previous one except that joachim99@52: the elements for discarded lines have been squeezed out. */ joachim99@52: lin *undiscarded; joachim99@52: joachim99@52: /* Vector mapping virtual line numbers (not counting discarded lines) joachim99@52: to real ones (counting those lines). Both are origin-0. */ joachim99@52: lin *realindexes; joachim99@52: joachim99@52: /* Total number of nondiscarded lines. */ joachim99@52: lin nondiscarded_lines; joachim99@52: joachim99@52: /* Vector, indexed by real origin-0 line number, joachim99@52: containing TRUE for a line that is an insertion or a deletion. joachim99@52: The results of comparison are stored here. */ joachim99@52: bool *changed; joachim99@52: joachim99@52: /* 1 if at end of file. */ joachim99@52: bool eof; joachim99@52: joachim99@52: /* 1 more than the maximum equivalence value used for this or its joachim99@52: sibling file. */ joachim99@52: lin equiv_max; joachim99@52: }; joachim99@52: joachim99@52: /* Data on two input files being compared. */ joachim99@52: joachim99@52: struct comparison joachim99@52: { joachim99@52: struct file_data file[2]; joachim99@52: struct comparison const *parent; /* parent, if a recursive comparison */ joachim99@52: }; joachim99@52: joachim99@52: /* Describe the two files currently being compared. */ joachim99@52: joachim99@53: struct file_data files[2]; joachim99@52: joachim99@52: /* Stdio stream to output diffs to. */ joachim99@52: joachim99@53: FILE *outfile; joachim99@52: joachim99@52: /* Declare various functions. */ joachim99@52: joachim99@52: /* analyze.c */ joachim99@52: struct change* diff_2_files (struct comparison *); joachim99@52: joachim99@52: /* context.c */ joachim99@52: void print_context_header (struct file_data[], bool); joachim99@52: void print_context_script (struct change *, bool); joachim99@52: joachim99@52: /* dir.c */ joachim99@68: int diff_dirs (struct comparison const *, int (*) (struct comparison const *, const QChar *, const QChar *)); joachim99@52: joachim99@52: /* ed.c */ joachim99@52: void print_ed_script (struct change *); joachim99@52: void pr_forward_ed_script (struct change *); joachim99@52: joachim99@52: /* ifdef.c */ joachim99@52: void print_ifdef_script (struct change *); joachim99@52: joachim99@52: /* io.c */ joachim99@52: void file_block_read (struct file_data *, size_t); joachim99@52: bool read_files (struct file_data[], bool); joachim99@52: joachim99@52: /* normal.c */ joachim99@52: void print_normal_script (struct change *); joachim99@52: joachim99@52: /* rcs.c */ joachim99@52: void print_rcs_script (struct change *); joachim99@52: joachim99@52: /* side.c */ joachim99@52: void print_sdiff_script (struct change *); joachim99@52: joachim99@52: /* util.c */ joachim99@68: QChar *concat (const QChar *, const QChar *, const QChar *); joachim99@69: bool lines_differ ( const QChar *, size_t, const QChar *, size_t ); joachim99@52: lin translate_line_number (struct file_data const *, lin); joachim99@52: struct change *find_change (struct change *); joachim99@52: struct change *find_reverse_change (struct change *); joachim99@52: void *zalloc (size_t); joachim99@52: enum changes analyze_hunk (struct change *, lin *, lin *, lin *, lin *); joachim99@52: void begin_output (void); joachim99@52: void debug_script (struct change *); joachim99@52: void finish_output (void); joachim99@68: void message (const QChar *, const QChar *, const QChar *); joachim99@68: void message5 (const QChar *, const QChar *, const QChar *, const QChar *, const QChar *); joachim99@68: void output_1_line (const QChar *, const QChar *, const QChar *, const QChar *); joachim99@68: void perror_with_name (const QChar *); joachim99@68: void setup_output (const QChar *, const QChar *, bool); joachim99@52: void translate_range (struct file_data const *, lin, lin, long *, long *); joachim99@52: joachim99@52: /* version.c */ joachim99@68: //extern const QChar version_string[]; joachim99@53: joachim99@53: private: joachim99@53: // gnudiff_analyze.cpp joachim99@53: lin diag (lin xoff, lin xlim, lin yoff, lin ylim, bool find_minimal, struct partition *part); joachim99@53: void compareseq (lin xoff, lin xlim, lin yoff, lin ylim, bool find_minimal); joachim99@53: void discard_confusing_lines (struct file_data filevec[]); joachim99@53: void shift_boundaries (struct file_data filevec[]); joachim99@53: struct change * add_change (lin line0, lin line1, lin deleted, lin inserted, struct change *old); joachim99@53: struct change * build_reverse_script (struct file_data const filevec[]); joachim99@53: struct change* build_script (struct file_data const filevec[]); joachim99@69: joachim99@53: // gnudiff_io.cpp joachim99@53: void find_and_hash_each_line (struct file_data *current); joachim99@53: void find_identical_ends (struct file_data filevec[]); joachim99@53: joachim99@53: // gnudiff_xmalloc.cpp joachim99@53: void *xmalloc (size_t n); joachim99@53: void *xrealloc(void *p, size_t n); joachim99@53: void xalloc_die (void); joachim99@69: joachim99@68: inline bool isWhite( QChar c ) joachim99@53: { joachim99@53: return c==' ' || c=='\t' || c=='\r'; joachim99@53: } joachim99@53: }; // class GnuDiff joachim99@53: joachim99@53: # define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items))) joachim99@53: # define XREALLOC(Ptr, Type, N_items) \ joachim99@53: ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items))) joachim99@53: joachim99@53: /* Declare and alloc memory for VAR of type TYPE. */ joachim99@53: # define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) joachim99@53: joachim99@53: /* Free VAR only if non NULL. */ joachim99@53: # define XFREE(Var) \ joachim99@53: do { \ joachim99@53: if (Var) \ joachim99@53: free (Var); \ joachim99@53: } while (0) joachim99@53: joachim99@53: /* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ joachim99@53: # define CCLONE(Src, Num) \ joachim99@53: (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num))) joachim99@53: joachim99@53: /* Return a malloc'ed copy of SRC. */ joachim99@53: # define CLONE(Src) CCLONE (Src, 1) joachim99@53: joachim99@53: #endif