3 #include "CompareOptions.h"
\r
5 #include "../Externals/xdiff/xinclude.h"
\r
8 unsigned long make_xdl_flags(const DiffutilsOptions& options)
\r
10 unsigned long xdl_flags = 0;
\r
11 switch (options.m_diffAlgorithm)
\r
13 case DIFF_ALGORITHM_MINIMAL:
\r
14 xdl_flags |= XDF_NEED_MINIMAL;
\r
16 case DIFF_ALGORITHM_PATIENCE:
\r
17 xdl_flags |= XDF_PATIENCE_DIFF;
\r
19 case DIFF_ALGORITHM_HISTOGRAM:
\r
20 xdl_flags |= XDF_HISTOGRAM_DIFF;
\r
22 case DIFF_ALGORITHM_NONE:
\r
23 xdl_flags |= XDF_NONE_DIFF;
\r
28 if (options.m_bIgnoreCase)
\r
29 xdl_flags |= XDF_IGNORE_CASE;
\r
30 if (options.m_bIgnoreNumbers)
\r
31 xdl_flags |= XDF_IGNORE_NUMBERS;
\r
32 if (options.m_bIgnoreBlankLines)
\r
33 xdl_flags |= XDF_IGNORE_BLANK_LINES;
\r
34 if (options.m_bIgnoreEOLDifference)
\r
35 xdl_flags |= XDF_IGNORE_CR_AT_EOL;
\r
36 switch (options.m_ignoreWhitespace)
\r
38 case WHITESPACE_IGNORE_CHANGE:
\r
39 xdl_flags |= XDF_IGNORE_WHITESPACE_CHANGE;
\r
41 case WHITESPACE_IGNORE_ALL:
\r
42 xdl_flags |= XDF_IGNORE_WHITESPACE;
\r
47 if (options.m_bIndentHeuristic)
\r
48 xdl_flags |= XDF_INDENT_HEURISTIC;
\r
52 static int hunk_func(long start_a, long count_a, long start_b, long count_b, void *cb_data)
\r
57 struct change* diff_2_buffers_xdiff(const char* ptr1, size_t size1, const char* ptr2, size_t size2, unsigned xdl_flags)
\r
59 change *script = nullptr;
\r
62 xpparam_t xpp = { 0 };
\r
63 xdemitconf_t xecfg = { 0 };
\r
64 xdemitcb_t ecb = { 0 };
\r
65 mmfile_t mmfile1 = { const_cast<char*>(ptr1), static_cast<long>(size1) };
\r
66 mmfile_t mmfile2 = { const_cast<char*>(ptr2), static_cast<long>(size2) };
\r
68 xpp.flags = xdl_flags;
\r
69 xecfg.hunk_func = hunk_func;
\r
71 if (xdl_diff_modified(&mmfile1, &mmfile2, &xpp, &xecfg, &ecb, &xe, &xscr) == 0)
\r
73 change *prev = nullptr;
\r
74 for (xdchange_t* xcur = xscr; xcur; xcur = xcur->next)
\r
76 change* e = static_cast<change*>(malloc(sizeof(change)));
\r
81 e->line0 = xcur->i1;
\r
82 e->line1 = xcur->i2;
\r
83 e->deleted = xcur->chg1;
\r
84 e->inserted = xcur->chg2;
\r
87 e->trivial = static_cast<char>(xcur->ignore);
\r
95 xdl_free_script(xscr);
\r
105 struct change * diff_2_files_xdiff (struct file_data filevec[], int* bin_status, int bMoved_blocks_flag, int* bin_file, unsigned xdl_flags)
\r
107 change *script = nullptr;
\r
109 if (read_files(filevec, no_details_flag & ~ignore_some_changes, bin_file))
\r
113 // copy from analyze.c
\r
114 // We can now safely assume to have a pair of Binary files.
\r
116 // Are both files Open and Regular (no Pipes, Directories, Devices (e.g. NUL))
\r
117 if (filevec[0].desc < 0 || filevec[1].desc < 0 ||
\r
118 !(S_ISREG (filevec[0].stat.st_mode)) || !(S_ISREG (filevec[1].stat.st_mode)) )
\r
121 // Files with different lengths must be different.
\r
122 if (filevec[0].stat.st_size != filevec[1].stat.st_size)
\r
125 // Identical descriptor implies identical files
\r
126 if (filevec[0].desc == filevec[1].desc)
\r
128 // Scan both files, a buffer at a time, looking for a difference.
\r
131 // Same-sized buffers for both files were allocated in read_files().
\r
132 size_t buffer_size = filevec[0].bufsize;
\r
136 // Read a buffer's worth from both files.
\r
137 for (i = 0; i < 2; i++)
\r
138 while (filevec[i].buffered_chars < buffer_size)
\r
140 cio::ssize_t r = cio::read (filevec[i].desc,
\r
141 filevec[i].buffer + filevec[i].buffered_chars,
\r
142 buffer_size - filevec[i].buffered_chars);
\r
146 pfatal_with_name (filevec[i].name);
\r
147 filevec[i].buffered_chars += r;
\r
150 // If the buffers have different number of chars, the files differ.
\r
151 if (filevec[0].buffered_chars != filevec[1].buffered_chars)
\r
157 // If we reach end-of-file, the files are the same.
\r
158 if (filevec[0].buffered_chars==0) // therefore: filevec[1].buffered_chars==0
\r
164 // If buffers have different contents, the files are different.
\r
165 if (memcmp (filevec[0].buffer,
\r
167 filevec[0].buffered_chars) != 0)
\r
173 // Files appear identical so far...
\r
174 // Prepare to loop again for the next pair of buffers.
\r
175 filevec[0].buffered_chars = filevec[1].buffered_chars = 0;
\r
178 if (bin_status != NULL)
\r
179 *bin_status = (changes != 0 ? -1 : 1);
\r
183 script = diff_2_buffers_xdiff(
\r
184 filevec[0].prefix_end,
\r
185 filevec[0].suffix_begin - filevec[0].prefix_end,
\r
186 filevec[1].prefix_end,
\r
187 filevec[1].suffix_begin - filevec[1].prefix_end,
\r
189 if (bMoved_blocks_flag)
\r
190 moved_block_analysis(&script, filevec);
\r