# HG changeset patch # User Bram Moolenaar # Date 1630436405 -7200 # Node ID d5142d87f898a7b81cd9c13e94740007d43b7667 # Parent a1f90f486bf7668c3acfe294ac7b1133ba3695a7 patch 8.2.3390: included xdiff code is outdated Commit: https://github.com/vim/vim/commit/ba02e4720f863fdb456e7023520f0a354eec0dcf Author: Christian Brabandt Date: Tue Aug 31 20:46:39 2021 +0200 patch 8.2.3390: included xdiff code is outdated Problem: Included xdiff code is outdated. Solution: Sync with xdiff in git 2.33. (Christian Brabandt, closes https://github.com/vim/vim/issues/8431) diff --git a/src/diff.c b/src/diff.c --- a/src/diff.c +++ b/src/diff.c @@ -1095,7 +1095,7 @@ diff_file_internal(diffio_T *diffio) emit_cfg.ctxlen = 0; // don't need any diff_context here emit_cb.priv = &diffio->dio_diff; - emit_cb.outf = xdiff_out; + emit_cb.out_line = xdiff_out; if (xdl_diff(&diffio->dio_orig.din_mmfile, &diffio->dio_new.din_mmfile, ¶m, &emit_cfg, &emit_cb) < 0) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3390, +/**/ 3389, /**/ 3388, diff --git a/src/xdiff/README.txt b/src/xdiff/README.txt --- a/src/xdiff/README.txt +++ b/src/xdiff/README.txt @@ -1,6 +1,6 @@ The files in this directory come from the xdiff implementation in git. You can find it here: https://github.com/git/git/tree/master/xdiff -The files were last updated 2018 September 10. +The files were last updated August 31, 2021 from git release v.2.33.0 This is originally based on libxdiff, which can be found here: http://www.xmailserver.org/xdiff-lib.html diff --git a/src/xdiff/xdiff.h b/src/xdiff/xdiff.h --- a/src/xdiff/xdiff.h +++ b/src/xdiff/xdiff.h @@ -25,9 +25,9 @@ #ifdef __cplusplus extern "C" { -#endif // #ifdef __cplusplus +#endif /* #ifdef __cplusplus */ -// xpparm_t.flags +/* xpparm_t.flags */ #define XDF_NEED_MINIMAL (1 << 0) #define XDF_IGNORE_WHITESPACE (1 << 1) @@ -48,22 +48,23 @@ extern "C" { #define XDF_INDENT_HEURISTIC (1 << 23) -// xdemitconf_t.flags +/* xdemitconf_t.flags */ #define XDL_EMIT_FUNCNAMES (1 << 0) +#define XDL_EMIT_NO_HUNK_HDR (1 << 1) #define XDL_EMIT_FUNCCONTEXT (1 << 2) -// merge simplification levels +/* merge simplification levels */ #define XDL_MERGE_MINIMAL 0 #define XDL_MERGE_EAGER 1 #define XDL_MERGE_ZEALOUS 2 #define XDL_MERGE_ZEALOUS_ALNUM 3 -// merge favor modes +/* merge favor modes */ #define XDL_MERGE_FAVOR_OURS 1 #define XDL_MERGE_FAVOR_THEIRS 2 #define XDL_MERGE_FAVOR_UNION 3 -// merge output styles +/* merge output styles */ #define XDL_MERGE_DIFF3 1 typedef struct s_mmfile { @@ -79,14 +80,24 @@ typedef struct s_mmbuffer { typedef struct s_xpparam { unsigned long flags; - // See Documentation/diff-options.txt. + /* -I */ + #if 0 // unused by Vim + regex_t **ignore_regex; + size_t ignore_regex_nr; +#endif + + /* See Documentation/diff-options.txt. */ char **anchors; size_t anchors_nr; } xpparam_t; typedef struct s_xdemitcb { void *priv; - int (*outf)(void *, mmbuffer_t *, int); + int (*out_hunk)(void *, + long old_begin, long old_nr, + long new_begin, long new_nr, + const char *func, long funclen); + int (*out_line)(void *, mmbuffer_t *, int); } xdemitcb_t; typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv); @@ -130,9 +141,9 @@ typedef struct s_xmparam { int level; int favor; int style; - const char *ancestor; // label for orig - const char *file1; // label for mf1 - const char *file2; // label for mf2 + const char *ancestor; /* label for orig */ + const char *file1; /* label for mf1 */ + const char *file2; /* label for mf2 */ } xmparam_t; #define DEFAULT_CONFLICT_MARKER_SIZE 7 @@ -142,6 +153,6 @@ int xdl_merge(mmfile_t *orig, mmfile_t * #ifdef __cplusplus } -#endif // #ifdef __cplusplus +#endif /* #ifdef __cplusplus */ -#endif // #if !defined(XDIFF_H) +#endif /* #if !defined(XDIFF_H) */ diff --git a/src/xdiff/xdiffi.c b/src/xdiff/xdiffi.c --- a/src/xdiff/xdiffi.c +++ b/src/xdiff/xdiffi.c @@ -38,9 +38,9 @@ typedef struct s_xdpsplit { * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both * the forward diagonal starting from (off1, off2) and the backward diagonal * starting from (lim1, lim2). If the K values on the same diagonal crosses - * returns the furthest point of reach. We might end up having to expensive - * cases using this algorithm is full, so a little bit of heuristic is needed - * to cut the search and to return a suboptimal point. + * returns the furthest point of reach. We might encounter expensive edge cases + * using this algorithm, so a little bit of heuristic is needed to cut the + * search and to return a suboptimal point. */ static long xdl_split(unsigned long const *ha1, long off1, long lim1, unsigned long const *ha2, long off2, long lim2, @@ -63,11 +63,13 @@ static long xdl_split(unsigned long cons int got_snake = 0; /* - * We need to extent the diagonal "domain" by one. If the next + * We need to extend the diagonal "domain" by one. If the next * values exits the box boundaries we need to change it in the - * opposite direction because (max - min) must be a power of two. + * opposite direction because (max - min) must be a power of + * two. + * * Also we initialize the external K value to -1 so that we can - * avoid extra conditions check inside the core loop. + * avoid extra conditions in the check inside the core loop. */ if (fmin > dmin) kvdf[--fmin - 1] = -1; @@ -98,11 +100,13 @@ static long xdl_split(unsigned long cons } /* - * We need to extent the diagonal "domain" by one. If the next + * We need to extend the diagonal "domain" by one. If the next * values exits the box boundaries we need to change it in the - * opposite direction because (max - min) must be a power of two. + * opposite direction because (max - min) must be a power of + * two. + * * Also we initialize the external K value to -1 so that we can - * avoid extra conditions check inside the core loop. + * avoid extra conditions in the check inside the core loop. */ if (bmin > dmin) kvdb[--bmin - 1] = XDL_LINE_MAX; @@ -138,7 +142,7 @@ static long xdl_split(unsigned long cons /* * If the edit cost is above the heuristic trigger and if * we got a good snake, we sample current diagonals to see - * if some of the, have reached an "interesting" path. Our + * if some of them have reached an "interesting" path. Our * measure is a function of the distance from the diagonal * corner (i1 + i2) penalized with the distance from the * mid diagonal itself. If this value is above the current @@ -196,8 +200,9 @@ static long xdl_split(unsigned long cons } /* - * Enough is enough. We spent too much time here and now we collect - * the furthest reaching path using the (i1 + i2) measure. + * Enough is enough. We spent too much time here and now we + * collect the furthest reaching path using the (i1 + i2) + * measure. */ if (ec >= xenv->mxcost) { long fbest, fbest1, bbest, bbest1; @@ -244,9 +249,9 @@ static long xdl_split(unsigned long cons /* - * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling - * the box splitting function. Note that the real job (marking changed lines) - * is done in the two boundary reaching checks. + * Rule: "Divide et Impera" (divide & conquer). Recursively split the box in + * sub-boxes by calling the box splitting function. Note that the real job + * (marking changed lines) is done in the two boundary reaching checks. */ int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1, diffdata_t *dd2, long off2, long lim2, @@ -323,7 +328,9 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t } /* - * Allocate and setup K vectors to be used by the differential algorithm. + * Allocate and setup K vectors to be used by the differential + * algorithm. + * * One is to store the forward path and one to store the backward path. */ ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3; @@ -418,13 +425,13 @@ static int xget_indent(xrecord_t *rec) ret += 1; else if (c == '\t') ret += 8 - ret % 8; - // ignore other whitespace characters + /* ignore other whitespace characters */ if (ret >= MAX_INDENT) return MAX_INDENT; } - // The line contains only whitespace. + /* The line contains only whitespace. */ return -1; } @@ -435,7 +442,7 @@ static int xget_indent(xrecord_t *rec) */ #define MAX_BLANKS 20 -// Characteristics measured about a hypothetical split position. +/* Characteristics measured about a hypothetical split position. */ struct split_measurement { /* * Is the split at the end of the file (aside from any blank lines)? @@ -443,8 +450,8 @@ struct split_measurement { int end_of_file; /* - * How much is the line immediately following the split indented (or -1 if - * the line is blank): + * How much is the line immediately following the split indented (or -1 + * if the line is blank): */ int indent; @@ -454,8 +461,8 @@ struct split_measurement { int pre_blank; /* - * How much is the nearest non-blank line above the split indented (or -1 - * if there is no such line)? + * How much is the nearest non-blank line above the split indented (or + * -1 if there is no such line)? */ int pre_indent; @@ -472,10 +479,10 @@ struct split_measurement { }; struct split_score { - // The effective indent of this split (smaller is preferred). + /* The effective indent of this split (smaller is preferred). */ int effective_indent; - // Penalty for this split (smaller is preferred). + /* Penalty for this split (smaller is preferred). */ int penalty; }; @@ -534,16 +541,16 @@ static void measure_split(const xdfile_t * integer math. */ -// Penalty if there are no non-blank lines before the split +/* Penalty if there are no non-blank lines before the split */ #define START_OF_FILE_PENALTY 1 -// Penalty if there are no non-blank lines after the split +/* Penalty if there are no non-blank lines after the split */ #define END_OF_FILE_PENALTY 21 -// Multiplier for the number of blank lines around the split +/* Multiplier for the number of blank lines around the split */ #define TOTAL_BLANK_WEIGHT (-30) -// Multiplier for the number of blank lines after the split +/* Multiplier for the number of blank lines after the split */ #define POST_BLANK_WEIGHT 6 /* @@ -581,13 +588,13 @@ static void measure_split(const xdfile_t /* * Compute a badness score for the hypothetical split whose measurements are - * stored in m. The weight factors were determined empirically using the tools and - * corpus described in + * stored in m. The weight factors were determined empirically using the tools + * and corpus described in * * https://github.com/mhagger/diff-slider-tools * - * Also see that project if you want to improve the weights based on, for example, - * a larger or more diverse corpus. + * Also see that project if you want to improve the weights based on, for + * example, a larger or more diverse corpus. */ static void score_add_split(const struct split_measurement *m, struct split_score *s) { @@ -610,7 +617,7 @@ static void score_add_split(const struct post_blank = (m->indent == -1) ? 1 + m->post_blank : 0; total_blank = m->pre_blank + post_blank; - // Penalties based on nearby blank lines: + /* Penalties based on nearby blank lines: */ s->penalty += TOTAL_BLANK_WEIGHT * total_blank; s->penalty += POST_BLANK_WEIGHT * post_blank; @@ -621,13 +628,13 @@ static void score_add_split(const struct any_blanks = (total_blank != 0); - // Note that the effective indent is -1 at the end of the file: + /* Note that the effective indent is -1 at the end of the file: */ s->effective_indent += indent; if (indent == -1) { - // No additional adjustments needed. + /* No additional adjustments needed. */ } else if (m->pre_indent == -1) { - // No additional adjustments needed. + /* No additional adjustments needed. */ } else if (indent > m->pre_indent) { /* * The line is indented more than its predecessor. @@ -669,7 +676,7 @@ static void score_add_split(const struct static int score_cmp(struct split_score *s1, struct split_score *s2) { - // -1 if s1.effective_indent < s2->effective_indent, etc. + /* -1 if s1.effective_indent < s2->effective_indent, etc. */ int cmp_indents = ((s1->effective_indent > s2->effective_indent) - (s1->effective_indent < s2->effective_indent)); @@ -809,13 +816,16 @@ int xdl_change_compact(xdfile_t *xdf, xd group_init(xdfo, &go); while (1) { - // If the group is empty in the to-be-compacted file, skip it: + /* + * If the group is empty in the to-be-compacted file, skip it: + */ if (g.end == g.start) goto next; /* * Now shift the change up and then down as far as possible in - * each direction. If it bumps into any other changes, merge them. + * each direction. If it bumps into any other changes, merge + * them. */ do { groupsize = g.end - g.start; @@ -828,7 +838,7 @@ int xdl_change_compact(xdfile_t *xdf, xd */ end_matching_other = -1; - // Shift the group backward as much as possible: + /* Shift the group backward as much as possible: */ while (!group_slide_up(xdf, &g, flags)) if (group_previous(xdfo, &go)) xdl_bug("group sync broken sliding up"); @@ -842,7 +852,7 @@ int xdl_change_compact(xdfile_t *xdf, xd if (go.end > go.start) end_matching_other = g.end; - // Now shift the group forward as far as possible: + /* Now shift the group forward as far as possible: */ while (1) { if (group_slide_down(xdf, &g, flags)) break; @@ -858,17 +868,17 @@ int xdl_change_compact(xdfile_t *xdf, xd * If the group can be shifted, then we can possibly use this * freedom to produce a more intuitive diff. * - * The group is currently shifted as far down as possible, so the - * heuristics below only have to handle upwards shifts. + * The group is currently shifted as far down as possible, so + * the heuristics below only have to handle upwards shifts. */ if (g.end == earliest_end) { - // no shifting was possible + /* no shifting was possible */ } else if (end_matching_other != -1) { /* - * Move the possibly merged group of changes back to line - * up with the last group of changes from the other file - * that it can align with. + * Move the possibly merged group of changes back to + * line up with the last group of changes from the + * other file that it can align with. */ while (go.end == go.start) { if (group_slide_up(xdf, &g, flags)) @@ -879,14 +889,15 @@ int xdl_change_compact(xdfile_t *xdf, xd } else if (flags & XDF_INDENT_HEURISTIC) { /* * Indent heuristic: a group of pure add/delete lines - * implies two splits, one between the end of the "before" - * context and the start of the group, and another between - * the end of the group and the beginning of the "after" - * context. Some splits are aesthetically better and some - * are worse. We compute a badness "score" for each split, - * and add the scores for the two splits to define a - * "score" for each position that the group can be shifted - * to. Then we pick the shift with the lowest score. + * implies two splits, one between the end of the + * "before" context and the start of the group, and + * another between the end of the group and the + * beginning of the "after" context. Some splits are + * aesthetically better and some are worse. We compute + * a badness "score" for each split, and add the scores + * for the two splits to define a "score" for each + * position that the group can be shifted to. Then we + * pick the shift with the lowest score. */ long shift, best_shift = -1; struct split_score best_score; @@ -921,7 +932,7 @@ int xdl_change_compact(xdfile_t *xdf, xd } next: - // Move past the just-processed group: + /* Move past the just-processed group: */ if (group_next(xdf, &g)) break; if (group_next(xdfo, &go)) @@ -987,7 +998,7 @@ static int xdl_call_hunk_func(xdfenv_t * return 0; } -static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags) +static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags) { xdchange_t *xch; @@ -1008,6 +1019,48 @@ static void xdl_mark_ignorable(xdchange_ } } +#if 0 // unused by Vim +static int record_matches_regex(xrecord_t *rec, xpparam_t const *xpp) { + regmatch_t regmatch; + int i; + + for (i = 0; i < xpp->ignore_regex_nr; i++) + if (!regexec_buf(xpp->ignore_regex[i], rec->ptr, rec->size, 1, + ®match, 0)) + return 1; + + return 0; +} + +static void xdl_mark_ignorable_regex(xdchange_t *xscr, const xdfenv_t *xe, + xpparam_t const *xpp) +{ + xdchange_t *xch; + + for (xch = xscr; xch; xch = xch->next) { + xrecord_t **rec; + int ignore = 1; + long i; + + /* + * Do not override --ignore-blank-lines. + */ + if (xch->ignore) + continue; + + rec = &xe->xdf1.recs[xch->i1]; + for (i = 0; i < xch->chg1 && ignore; i++) + ignore = record_matches_regex(rec[i], xpp); + + rec = &xe->xdf2.recs[xch->i2]; + for (i = 0; i < xch->chg2 && ignore; i++) + ignore = record_matches_regex(rec[i], xpp); + + xch->ignore = ignore; + } +} +#endif + int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb) { xdchange_t *xscr; @@ -1027,7 +1080,12 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf } if (xscr) { if (xpp->flags & XDF_IGNORE_BLANK_LINES) - xdl_mark_ignorable(xscr, &xe, xpp->flags); + xdl_mark_ignorable_lines(xscr, &xe, xpp->flags); + +#if 0 + if (xpp->ignore_regex) + xdl_mark_ignorable_regex(xscr, &xe, xpp); +#endif if (ef(&xe, xscr, ecb, xecfg) < 0) { diff --git a/src/xdiff/xdiffi.h b/src/xdiff/xdiffi.h --- a/src/xdiff/xdiffi.h +++ b/src/xdiff/xdiffi.h @@ -61,4 +61,4 @@ int xdl_do_patience_diff(mmfile_t *mf1, int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdfenv_t *env); -#endif // #if !defined(XDIFFI_H) +#endif /* #if !defined(XDIFFI_H) */ diff --git a/src/xdiff/xemit.c b/src/xdiff/xemit.c --- a/src/xdiff/xemit.c +++ b/src/xdiff/xemit.c @@ -31,7 +31,7 @@ static long xdl_get_rec(xdfile_t *xdf, l static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) { - long size, psize = (long)strlen(pre); + long size, psize = strlen(pre); char const *rec; size = xdl_get_rec(xdf, ri, &rec); @@ -54,9 +54,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xs xdchange_t *xch, *xchp, *lxch; long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen; long max_ignorable = xecfg->ctxlen; - unsigned long ignored = 0; // number of ignored blank lines + unsigned long ignored = 0; /* number of ignored blank lines */ - // remove ignorable changes that are too far before other changes + /* remove ignorable changes that are too far before other changes */ for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) { xch = xchp->next; @@ -99,9 +99,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xs static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED) { if (len > 0 && - (isalpha((unsigned char)*rec) || // identifier? - *rec == '_' || // also identifier? - *rec == '$')) { // identifiers from VMS and other esoterico + (isalpha((unsigned char)*rec) || /* identifier? */ + *rec == '_' || /* also identifier? */ + *rec == '$')) { /* identifiers from VMS and other esoterico */ if (len > sz) len = sz; while (0 < len && isspace((unsigned char)rec[len - 1])) @@ -197,7 +197,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) { long fs1, i1 = xch->i1; - // Appended chunk? + /* Appended chunk? */ if (i1 >= xe->xdf1.nrec) { long i2 = xch->i2; @@ -225,8 +225,23 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange if (fs1 < 0) fs1 = 0; if (fs1 < s1) { - s2 -= s1 - fs1; + s2 = XDL_MAX(s2 - (s1 - fs1), 0); s1 = fs1; + + /* + * Did we extend context upwards into an + * ignored change? + */ + while (xchp != xch && + xchp->i1 + xchp->chg1 <= s1 && + xchp->i2 + xchp->chg2 <= s2) + xchp = xchp->next; + + /* If so, show it after all. */ + if (xchp != xch) { + xch = xchp; + goto pre_context_calculation; + } } } @@ -249,7 +264,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange if (fe1 < 0) fe1 = xe->xdf1.nrec; if (fe1 > e1) { - e2 += fe1 - e1; + e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec); e1 = fe1; } @@ -281,7 +296,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange funclineprev = s1 - 1; } #endif - if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, + if (!(xecfg->flags & XDL_EMIT_NO_HUNK_HDR) && + xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, func_line.buf, func_line.len, ecb) < 0) return -1; diff --git a/src/xdiff/xemit.h b/src/xdiff/xemit.h --- a/src/xdiff/xemit.h +++ b/src/xdiff/xemit.h @@ -33,4 +33,4 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange -#endif // #if !defined(XEMIT_H) +#endif /* #if !defined(XEMIT_H) */ diff --git a/src/xdiff/xhistogram.c b/src/xdiff/xhistogram.c --- a/src/xdiff/xhistogram.c +++ b/src/xdiff/xhistogram.c @@ -42,8 +42,6 @@ */ #include "xinclude.h" -#include "xtypes.h" -#include "xdiff.h" #define MAX_PTR INT_MAX #define MAX_CNT INT_MAX @@ -55,8 +53,8 @@ struct histindex { struct record { unsigned int ptr, cnt; struct record *next; - } **records, // an occurrence - **line_map; // map of line to record chain + } **records, /* an occurrence */ + **line_map; /* map of line to record chain */ chastore_t rcha; unsigned int *next_ptrs; unsigned int table_bits, @@ -128,7 +126,7 @@ static int scanA(struct histindex *index */ NEXT_PTR(index, ptr) = rec->ptr; rec->ptr = ptr; - // cap rec->cnt at MAX_CNT + /* cap rec->cnt at MAX_CNT */ rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1); LINE_MAP(index, ptr) = rec; goto continue_scan; @@ -154,7 +152,7 @@ static int scanA(struct histindex *index LINE_MAP(index, ptr) = rec; continue_scan: - ; // no op + ; /* no op */ } return 0; @@ -237,6 +235,8 @@ static int fall_back_to_classic_diff(xpp int line1, int count1, int line2, int count2) { xpparam_t xpparam; + + memset(&xpparam, 0, sizeof(xpparam)); xpparam.flags = xpp->flags & ~XDF_DIFF_ALGORITHM_MASK; return xdl_fall_back_diff(env, &xpparam, @@ -266,7 +266,7 @@ static int find_lcs(xpparam_t const *xpp index.records = NULL; index.line_map = NULL; - // in case of early xdl_cha_free() + /* in case of early xdl_cha_free() */ index.rcha.head = NULL; index.table_bits = xdl_hashbits(count1); @@ -288,7 +288,7 @@ static int find_lcs(xpparam_t const *xpp goto cleanup; memset(index.next_ptrs, 0, sz); - // lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() + /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */ if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0) goto cleanup; diff --git a/src/xdiff/xinclude.h b/src/xdiff/xinclude.h --- a/src/xdiff/xinclude.h +++ b/src/xdiff/xinclude.h @@ -20,6 +20,8 @@ * */ +// The following includes come from Vim: + // defines HAVE_ATTRIBUTE_UNUSED #ifdef HAVE_CONFIG_H # ifdef VMS @@ -44,6 +46,7 @@ #if !defined(XINCLUDE_H) #define XINCLUDE_H +// This effectively re-verts b46054b3746271d23feab0 from git #include #include #include @@ -52,7 +55,10 @@ #endif #include #include - +// This include comes from git, so uncomment it +#if 0 +#include "git-compat-util.h" +#endif #include "xmacros.h" #include "xdiff.h" #include "xtypes.h" @@ -62,4 +68,4 @@ #include "xemit.h" -#endif // #if !defined(XINCLUDE_H) +#endif /* #if !defined(XINCLUDE_H) */ diff --git a/src/xdiff/xmacros.h b/src/xdiff/xmacros.h --- a/src/xdiff/xmacros.h +++ b/src/xdiff/xmacros.h @@ -51,4 +51,4 @@ do { \ } while (0) -#endif // #if !defined(XMACROS_H) +#endif /* #if !defined(XMACROS_H) */ diff --git a/src/xdiff/xpatience.c b/src/xdiff/xpatience.c --- a/src/xdiff/xpatience.c +++ b/src/xdiff/xpatience.c @@ -20,8 +20,6 @@ * */ #include "xinclude.h" -#include "xtypes.h" -#include "xdiff.h" /* * The basic idea of patience diff is to find lines that are unique in @@ -69,7 +67,7 @@ struct hashmap { */ unsigned anchor : 1; } *entries, *first, *last; - // were common records found? + /* were common records found? */ unsigned long has_matches; mmfile_t *file1, *file2; xdfenv_t *env; @@ -78,21 +76,21 @@ struct hashmap { static int is_anchor(xpparam_t const *xpp, const char *line) { - size_t i; - for (i = 0; i < xpp->anchors_nr; i++) { + int i; + for (i = 0; i < (int)xpp->anchors_nr; i++) { if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i]))) return 1; } return 0; } -// The argument "pass" is 1 for the first file, 2 for the second. +/* The argument "pass" is 1 for the first file, 2 for the second. */ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map, int pass) { xrecord_t **records = pass == 1 ? map->env->xdf1.recs : map->env->xdf2.recs; - xrecord_t *record = records[line - 1], *other; + xrecord_t *record = records[line - 1]; /* * After xdl_prepare_env() (or more precisely, due to * xdl_classify_record()), the "ha" member of the records (AKA lines) @@ -106,11 +104,7 @@ static void insert_record(xpparam_t cons int index = (int)((record->ha << 1) % map->alloc); while (map->entries[index].line1) { - other = map->env->xdf1.recs[map->entries[index].line1 - 1]; - if (map->entries[index].hash != record->ha || - !xdl_recmatch(record->ptr, record->size, - other->ptr, other->size, - map->xpp->flags)) { + if (map->entries[index].hash != record->ha) { if (++index >= map->alloc) index = 0; continue; @@ -155,7 +149,7 @@ static int fill_hashmap(mmfile_t *file1, result->xpp = xpp; result->env = env; - // We know exactly how large we want the hash map + /* We know exactly how large we want the hash map */ result->alloc = count1 * 2; result->entries = (struct entry *) xdl_malloc(result->alloc * sizeof(struct entry)); @@ -163,11 +157,11 @@ static int fill_hashmap(mmfile_t *file1, return -1; memset(result->entries, 0, result->alloc * sizeof(struct entry)); - // First, fill with entries from the first file + /* First, fill with entries from the first file */ while (count1--) insert_record(xpp, line1++, result, 1); - // Then search for matches in the second file + /* Then search for matches in the second file */ while (count2--) insert_record(xpp, line2++, result, 2); @@ -185,13 +179,13 @@ static int binary_search(struct entry ** while (left + 1 < right) { int middle = left + (right - left) / 2; - // by construction, no two entries can be equal + /* by construction, no two entries can be equal */ if (sequence[middle]->line2 > entry->line2) right = middle; else left = middle; } - // return the index in "sequence", _not_ the sequence length + /* return the index in "sequence", _not_ the sequence length */ return left; } @@ -206,9 +200,10 @@ static int binary_search(struct entry ** */ static struct entry *find_longest_common_sequence(struct hashmap *map) { - struct entry **sequence = (struct entry **)xdl_malloc(map->nr * sizeof(struct entry *)); + struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *)); int longest = 0, i; struct entry *entry; + /* * If not -1, this entry in sequence must never be overridden. * Therefore, overriding entries before this has no effect, so @@ -237,13 +232,13 @@ static struct entry *find_longest_common } } - // No common unique lines were found + /* No common unique lines were found */ if (!longest) { xdl_free(sequence); return NULL; } - // Iterate starting at the last element, adjusting the "next" members + /* Iterate starting at the last element, adjusting the "next" members */ entry = sequence[longest - 1]; entry->next = NULL; while (entry->previous) { @@ -258,8 +253,7 @@ static int match(struct hashmap *map, in { xrecord_t *record1 = map->env->xdf1.recs[line1 - 1]; xrecord_t *record2 = map->env->xdf2.recs[line2 - 1]; - return xdl_recmatch(record1->ptr, record1->size, - record2->ptr, record2->size, map->xpp->flags); + return record1->ha == record2->ha; } static int patience_diff(mmfile_t *file1, mmfile_t *file2, @@ -273,7 +267,7 @@ static int walk_common_sequence(struct h int next1, next2; for (;;) { - // Try to grow the line ranges of common lines + /* Try to grow the line ranges of common lines */ if (first) { next1 = first->line1; next2 = first->line2; @@ -292,11 +286,8 @@ static int walk_common_sequence(struct h line2++; } - // Recurse + /* Recurse */ if (next1 > line1 || next2 > line2) { - struct hashmap submap; - - memset(&submap, 0, sizeof(submap)); if (patience_diff(map->file1, map->file2, map->xpp, map->env, line1, next1 - line1, @@ -323,6 +314,8 @@ static int fall_back_to_classic_diff(str int line1, int count1, int line2, int count2) { xpparam_t xpp; + + memset(&xpp, 0, sizeof(xpp)); xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK; return xdl_fall_back_diff(map->env, &xpp, @@ -343,7 +336,7 @@ static int patience_diff(mmfile_t *file1 struct entry *first; int result = 0; - // trivial case: one side is empty + /* trivial case: one side is empty */ if (!count1) { while(count2--) env->xdf2.rchg[line2++ - 1] = 1; @@ -359,7 +352,7 @@ static int patience_diff(mmfile_t *file1 line1, count1, line2, count2)) return -1; - // are there any matching lines at all? + /* are there any matching lines at all? */ if (!map.has_matches) { while(count1--) env->xdf1.rchg[line1++ - 1] = 1; @@ -387,7 +380,7 @@ int xdl_do_patience_diff(mmfile_t *file1 if (xdl_prepare_env(file1, file2, xpp, env) < 0) return -1; - // environment is cleaned up in xdl_diff() + /* environment is cleaned up in xdl_diff() */ return patience_diff(file1, file2, xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec); } diff --git a/src/xdiff/xprepare.h b/src/xdiff/xprepare.h --- a/src/xdiff/xprepare.h +++ b/src/xdiff/xprepare.h @@ -31,4 +31,4 @@ void xdl_free_env(xdfenv_t *xe); -#endif // #if !defined(XPREPARE_H) +#endif /* #if !defined(XPREPARE_H) */ diff --git a/src/xdiff/xtypes.h b/src/xdiff/xtypes.h --- a/src/xdiff/xtypes.h +++ b/src/xdiff/xtypes.h @@ -64,4 +64,4 @@ typedef struct s_xdfenv { -#endif // #if !defined(XTYPES_H) +#endif /* #if !defined(XTYPES_H) */ diff --git a/src/xdiff/xutils.c b/src/xdiff/xutils.c --- a/src/xdiff/xutils.c +++ b/src/xdiff/xutils.c @@ -20,13 +20,9 @@ * */ -#include -#include #include "xinclude.h" - - long xdl_bogosqrt(long n) { long i; @@ -51,10 +47,10 @@ int xdl_emit_diffrec(char const *rec, lo mb[1].size = size; if (size > 0 && rec[size - 1] != '\n') { mb[2].ptr = (char *) "\n\\ No newline at end of file\n"; - mb[2].size = (long)strlen(mb[2].ptr); + mb[2].size = strlen(mb[2].ptr); i++; } - if (ecb->outf(ecb->priv, mb, i) < 0) { + if (ecb->out_line(ecb->priv, mb, i) < 0) { return -1; } @@ -168,7 +164,7 @@ static int ends_with_optional_cr(const c s--; if (s == i) return 1; - // do not ignore CR at the end of an incomplete line + /* do not ignore CR at the end of an incomplete line */ if (complete && s == i + 1 && l[i] == '\r') return 1; return 0; @@ -208,7 +204,7 @@ int xdl_recmatch(const char *l1, long s1 } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { while (i1 < s1 && i2 < s2) { if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) { - // Skip matching spaces and try again + /* Skip matching spaces and try again */ while (i1 < s1 && XDL_ISSPACE(l1[i1])) i1++; while (i2 < s2 && XDL_ISSPACE(l2[i2])) @@ -224,7 +220,7 @@ int xdl_recmatch(const char *l1, long s1 i2++; } } else if (flags & XDF_IGNORE_CR_AT_EOL) { - // Find the first difference and see how the line ends + /* Find the first difference and see how the line ends */ while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) { i1++; i2++; @@ -261,7 +257,7 @@ static unsigned long xdl_hash_record_wit for (; ptr < top && *ptr != '\n'; ptr++) { if (cr_at_eol_only) { - // do not ignore CR at the end of an incomplete line + /* do not ignore CR at the end of an incomplete line */ if (*ptr == '\r' && (ptr + 1 < top && ptr[1] == '\n')) continue; @@ -274,7 +270,7 @@ static unsigned long xdl_hash_record_wit ptr++; at_eol = (top <= ptr + 1 || ptr[1] == '\n'); if (flags & XDF_IGNORE_WHITESPACE) - ; // already handled + ; /* already handled */ else if (flags & XDF_IGNORE_WHITESPACE_CHANGE && !at_eol) { ha += (ha << 5); @@ -344,8 +340,9 @@ int xdl_num_out(char *out, long val) { return str - out; } -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, - const char *func, long funclen, xdemitcb_t *ecb) { +static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { int nb = 0; mmbuffer_t mb; char buf[128]; @@ -387,9 +384,21 @@ int xdl_emit_hunk_hdr(long s1, long c1, mb.ptr = buf; mb.size = nb; - if (ecb->outf(ecb->priv, &mb, 1) < 0) + if (ecb->out_line(ecb->priv, &mb, 1) < 0) return -1; + return 0; +} +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { + if (!ecb->out_hunk) + return xdl_format_hunk_hdr(s1, c1, s2, c2, func, funclen, ecb); + if (ecb->out_hunk(ecb->priv, + c1 ? s1 : s1 - 1, c1, + c2 ? s2 : s2 - 1, c2, + func, funclen) < 0) + return -1; return 0; } diff --git a/src/xdiff/xutils.h b/src/xdiff/xutils.h --- a/src/xdiff/xutils.h +++ b/src/xdiff/xutils.h @@ -44,4 +44,4 @@ int xdl_fall_back_diff(xdfenv_t *diff_en -#endif // #if !defined(XUTILS_H) +#endif /* #if !defined(XUTILS_H) */