Show More
@@ -32,17 +32,6 b' extern "C" {' | |||||
32 | /* xpparm_t.flags */ |
|
32 | /* xpparm_t.flags */ | |
33 | #define XDF_NEED_MINIMAL (1 << 0) |
|
33 | #define XDF_NEED_MINIMAL (1 << 0) | |
34 |
|
34 | |||
35 | #define XDF_IGNORE_WHITESPACE (1 << 1) |
|
|||
36 | #define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2) |
|
|||
37 | #define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3) |
|
|||
38 | #define XDF_IGNORE_CR_AT_EOL (1 << 4) |
|
|||
39 | #define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \ |
|
|||
40 | XDF_IGNORE_WHITESPACE_CHANGE | \ |
|
|||
41 | XDF_IGNORE_WHITESPACE_AT_EOL | \ |
|
|||
42 | XDF_IGNORE_CR_AT_EOL) |
|
|||
43 |
|
||||
44 | #define XDF_IGNORE_BLANK_LINES (1 << 7) |
|
|||
45 |
|
||||
46 | #define XDF_INDENT_HEURISTIC (1 << 23) |
|
35 | #define XDF_INDENT_HEURISTIC (1 << 23) | |
47 |
|
36 | |||
48 | /* xdemitconf_t.flags */ |
|
37 | /* xdemitconf_t.flags */ |
@@ -1041,27 +1041,6 b' static int xdl_call_hunk_func(xdfenv_t *' | |||||
1041 | return 0; |
|
1041 | return 0; | |
1042 | } |
|
1042 | } | |
1043 |
|
1043 | |||
1044 | static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags) |
|
|||
1045 | { |
|
|||
1046 | xdchange_t *xch; |
|
|||
1047 |
|
||||
1048 | for (xch = xscr; xch; xch = xch->next) { |
|
|||
1049 | int ignore = 1; |
|
|||
1050 | xrecord_t **rec; |
|
|||
1051 | long i; |
|
|||
1052 |
|
||||
1053 | rec = &xe->xdf1.recs[xch->i1]; |
|
|||
1054 | for (i = 0; i < xch->chg1 && ignore; i++) |
|
|||
1055 | ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags); |
|
|||
1056 |
|
||||
1057 | rec = &xe->xdf2.recs[xch->i2]; |
|
|||
1058 | for (i = 0; i < xch->chg2 && ignore; i++) |
|
|||
1059 | ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags); |
|
|||
1060 |
|
||||
1061 | xch->ignore = ignore; |
|
|||
1062 | } |
|
|||
1063 | } |
|
|||
1064 |
|
||||
1065 | int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, |
|
1044 | int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, | |
1066 | xdemitconf_t const *xecfg, xdemitcb_t *ecb) { |
|
1045 | xdemitconf_t const *xecfg, xdemitcb_t *ecb) { | |
1067 | xdchange_t *xscr; |
|
1046 | xdchange_t *xscr; | |
@@ -1080,8 +1059,6 b' int xdl_diff(mmfile_t *mf1, mmfile_t *mf' | |||||
1080 | return -1; |
|
1059 | return -1; | |
1081 | } |
|
1060 | } | |
1082 |
|
1061 | |||
1083 | if (xpp->flags & XDF_IGNORE_BLANK_LINES) |
|
|||
1084 | xdl_mark_ignorable(xscr, &xe, xpp->flags); |
|
|||
1085 | if (ef(&xe, xscr, ecb, xecfg) < 0) { |
|
1062 | if (ef(&xe, xscr, ecb, xecfg) < 0) { | |
1086 | xdl_free_script(xscr); |
|
1063 | xdl_free_script(xscr); | |
1087 | xdl_free_env(&xe); |
|
1064 | xdl_free_env(&xe); |
@@ -143,168 +143,17 b' long xdl_guess_lines(mmfile_t *mf, long ' | |||||
143 | return nl + 1; |
|
143 | return nl + 1; | |
144 | } |
|
144 | } | |
145 |
|
145 | |||
146 | int xdl_blankline(const char *line, long size, long flags) |
|
|||
147 | { |
|
|||
148 | long i; |
|
|||
149 |
|
||||
150 | if (!(flags & XDF_WHITESPACE_FLAGS)) |
|
|||
151 | return (size <= 1); |
|
|||
152 |
|
||||
153 | for (i = 0; i < size && XDL_ISSPACE(line[i]); i++) |
|
|||
154 | ; |
|
|||
155 |
|
||||
156 | return (i == size); |
|
|||
157 | } |
|
|||
158 |
|
||||
159 | /* |
|
|||
160 | * Have we eaten everything on the line, except for an optional |
|
|||
161 | * CR at the very end? |
|
|||
162 | */ |
|
|||
163 | static int ends_with_optional_cr(const char *l, long s, long i) |
|
|||
164 | { |
|
|||
165 | int complete = s && l[s-1] == '\n'; |
|
|||
166 |
|
||||
167 | if (complete) |
|
|||
168 | s--; |
|
|||
169 | if (s == i) |
|
|||
170 | return 1; |
|
|||
171 | /* do not ignore CR at the end of an incomplete line */ |
|
|||
172 | if (complete && s == i + 1 && l[i] == '\r') |
|
|||
173 | return 1; |
|
|||
174 | return 0; |
|
|||
175 | } |
|
|||
176 |
|
||||
177 | int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) |
|
146 | int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) | |
178 | { |
|
147 | { | |
179 | int i1, i2; |
|
|||
180 |
|
||||
181 | if (s1 == s2 && !memcmp(l1, l2, s1)) |
|
148 | if (s1 == s2 && !memcmp(l1, l2, s1)) | |
182 | return 1; |
|
149 | return 1; | |
183 | if (!(flags & XDF_WHITESPACE_FLAGS)) |
|
150 | return 0; | |
184 | return 0; |
|
|||
185 |
|
||||
186 | i1 = 0; |
|
|||
187 | i2 = 0; |
|
|||
188 |
|
||||
189 | /* |
|
|||
190 | * -w matches everything that matches with -b, and -b in turn |
|
|||
191 | * matches everything that matches with --ignore-space-at-eol, |
|
|||
192 | * which in turn matches everything that matches with --ignore-cr-at-eol. |
|
|||
193 | * |
|
|||
194 | * Each flavor of ignoring needs different logic to skip whitespaces |
|
|||
195 | * while we have both sides to compare. |
|
|||
196 | */ |
|
|||
197 | if (flags & XDF_IGNORE_WHITESPACE) { |
|
|||
198 | goto skip_ws; |
|
|||
199 | while (i1 < s1 && i2 < s2) { |
|
|||
200 | if (l1[i1++] != l2[i2++]) |
|
|||
201 | return 0; |
|
|||
202 | skip_ws: |
|
|||
203 | while (i1 < s1 && XDL_ISSPACE(l1[i1])) |
|
|||
204 | i1++; |
|
|||
205 | while (i2 < s2 && XDL_ISSPACE(l2[i2])) |
|
|||
206 | i2++; |
|
|||
207 | } |
|
|||
208 | } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { |
|
|||
209 | while (i1 < s1 && i2 < s2) { |
|
|||
210 | if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) { |
|
|||
211 | /* Skip matching spaces and try again */ |
|
|||
212 | while (i1 < s1 && XDL_ISSPACE(l1[i1])) |
|
|||
213 | i1++; |
|
|||
214 | while (i2 < s2 && XDL_ISSPACE(l2[i2])) |
|
|||
215 | i2++; |
|
|||
216 | continue; |
|
|||
217 | } |
|
|||
218 | if (l1[i1++] != l2[i2++]) |
|
|||
219 | return 0; |
|
|||
220 | } |
|
|||
221 | } else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) { |
|
|||
222 | while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) { |
|
|||
223 | i1++; |
|
|||
224 | i2++; |
|
|||
225 | } |
|
|||
226 | } else if (flags & XDF_IGNORE_CR_AT_EOL) { |
|
|||
227 | /* Find the first difference and see how the line ends */ |
|
|||
228 | while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) { |
|
|||
229 | i1++; |
|
|||
230 | i2++; |
|
|||
231 | } |
|
|||
232 | return (ends_with_optional_cr(l1, s1, i1) && |
|
|||
233 | ends_with_optional_cr(l2, s2, i2)); |
|
|||
234 | } |
|
|||
235 |
|
||||
236 | /* |
|
|||
237 | * After running out of one side, the remaining side must have |
|
|||
238 | * nothing but whitespace for the lines to match. Note that |
|
|||
239 | * ignore-whitespace-at-eol case may break out of the loop |
|
|||
240 | * while there still are characters remaining on both lines. |
|
|||
241 | */ |
|
|||
242 | if (i1 < s1) { |
|
|||
243 | while (i1 < s1 && XDL_ISSPACE(l1[i1])) |
|
|||
244 | i1++; |
|
|||
245 | if (s1 != i1) |
|
|||
246 | return 0; |
|
|||
247 | } |
|
|||
248 | if (i2 < s2) { |
|
|||
249 | while (i2 < s2 && XDL_ISSPACE(l2[i2])) |
|
|||
250 | i2++; |
|
|||
251 | return (s2 == i2); |
|
|||
252 | } |
|
|||
253 | return 1; |
|
|||
254 | } |
|
|||
255 |
|
||||
256 | static unsigned long xdl_hash_record_with_whitespace(char const **data, |
|
|||
257 | char const *top, long flags) { |
|
|||
258 | unsigned long ha = 5381; |
|
|||
259 | char const *ptr = *data; |
|
|||
260 | int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL; |
|
|||
261 |
|
||||
262 | for (; ptr < top && *ptr != '\n'; ptr++) { |
|
|||
263 | if (cr_at_eol_only) { |
|
|||
264 | /* do not ignore CR at the end of an incomplete line */ |
|
|||
265 | if (*ptr == '\r' && |
|
|||
266 | (ptr + 1 < top && ptr[1] == '\n')) |
|
|||
267 | continue; |
|
|||
268 | } |
|
|||
269 | else if (XDL_ISSPACE(*ptr)) { |
|
|||
270 | const char *ptr2 = ptr; |
|
|||
271 | int at_eol; |
|
|||
272 | while (ptr + 1 < top && XDL_ISSPACE(ptr[1]) |
|
|||
273 | && ptr[1] != '\n') |
|
|||
274 | ptr++; |
|
|||
275 | at_eol = (top <= ptr + 1 || ptr[1] == '\n'); |
|
|||
276 | if (flags & XDF_IGNORE_WHITESPACE) |
|
|||
277 | ; /* already handled */ |
|
|||
278 | else if (flags & XDF_IGNORE_WHITESPACE_CHANGE |
|
|||
279 | && !at_eol) { |
|
|||
280 | ha += (ha << 5); |
|
|||
281 | ha ^= (unsigned long) ' '; |
|
|||
282 | } |
|
|||
283 | else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL |
|
|||
284 | && !at_eol) { |
|
|||
285 | while (ptr2 != ptr + 1) { |
|
|||
286 | ha += (ha << 5); |
|
|||
287 | ha ^= (unsigned long) *ptr2; |
|
|||
288 | ptr2++; |
|
|||
289 | } |
|
|||
290 | } |
|
|||
291 | continue; |
|
|||
292 | } |
|
|||
293 | ha += (ha << 5); |
|
|||
294 | ha ^= (unsigned long) *ptr; |
|
|||
295 | } |
|
|||
296 | *data = ptr < top ? ptr + 1: ptr; |
|
|||
297 |
|
||||
298 | return ha; |
|
|||
299 | } |
|
151 | } | |
300 |
|
152 | |||
301 | unsigned long xdl_hash_record(char const **data, char const *top, long flags) { |
|
153 | unsigned long xdl_hash_record(char const **data, char const *top, long flags) { | |
302 | unsigned long ha = 5381; |
|
154 | unsigned long ha = 5381; | |
303 | char const *ptr = *data; |
|
155 | char const *ptr = *data; | |
304 |
|
156 | |||
305 | if (flags & XDF_WHITESPACE_FLAGS) |
|
|||
306 | return xdl_hash_record_with_whitespace(data, top, flags); |
|
|||
307 |
|
||||
308 | for (; ptr < top && *ptr != '\n'; ptr++) { |
|
157 | for (; ptr < top && *ptr != '\n'; ptr++) { | |
309 | ha += (ha << 5); |
|
158 | ha += (ha << 5); | |
310 | ha ^= (unsigned long) *ptr; |
|
159 | ha ^= (unsigned long) *ptr; |
@@ -32,7 +32,6 b' int xdl_cha_init(chastore_t *cha, long i' | |||||
32 | void xdl_cha_free(chastore_t *cha); |
|
32 | void xdl_cha_free(chastore_t *cha); | |
33 | void *xdl_cha_alloc(chastore_t *cha); |
|
33 | void *xdl_cha_alloc(chastore_t *cha); | |
34 | long xdl_guess_lines(mmfile_t *mf, long sample); |
|
34 | long xdl_guess_lines(mmfile_t *mf, long sample); | |
35 | int xdl_blankline(const char *line, long size, long flags); |
|
|||
36 | int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags); |
|
35 | int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags); | |
37 | unsigned long xdl_hash_record(char const **data, char const *top, long flags); |
|
36 | unsigned long xdl_hash_record(char const **data, char const *top, long flags); | |
38 | unsigned int xdl_hashbits(unsigned int size); |
|
37 | unsigned int xdl_hashbits(unsigned int size); |
General Comments 0
You need to be logged in to leave comments.
Login now