From 467d348c19b2ce82753bb9b5a873f6d129eb04e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:20:55 +0200 Subject: [PATCH 1/7] xdiff: add hunk_func() Add a way to register a callback function that is gets passed the start line and line count of each hunk of a diff. Only standard types are used. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- xdiff/xdiff.h | 5 +++++ xdiff/xdiffi.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 09215afe6e..33c010b1f1 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -86,6 +86,10 @@ typedef struct s_xdemitcb { typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv); +typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a, + long start_b, long count_b, + void *cb_data); + typedef struct s_xdemitconf { long ctxlen; long interhunkctxlen; @@ -93,6 +97,7 @@ typedef struct s_xdemitconf { find_func_t find_func; void *find_func_priv; void (*emit_func)(); + xdl_emit_hunk_consume_func_t hunk_func; } xdemitconf_t; typedef struct s_bdiffparam { diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index bc889e8789..4d671f4371 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -538,6 +538,20 @@ void xdl_free_script(xdchange_t *xscr) { } } +static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, + xdemitconf_t const *xecfg) +{ + xdchange_t *xch, *xche; + + for (xch = xscr; xch; xch = xche->next) { + xche = xdl_get_hunk(xch, xecfg); + if (xecfg->hunk_func(xch->i1, xche->i1 + xche->chg1 - xch->i1, + xch->i2, xche->i2 + xche->chg2 - xch->i2, + ecb->priv) < 0) + return -1; + } + return 0; +} int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb) { @@ -546,6 +560,9 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, emit_func_t ef = xecfg->emit_func ? (emit_func_t)xecfg->emit_func : xdl_emit_diff; + if (xecfg->hunk_func) + ef = xdl_call_hunk_func; + if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) { return -1; From 0af596c6ffba19bff4362ac532be35abd67d2630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:21:56 +0200 Subject: [PATCH 2/7] blame: use hunk_func(), part 1 Use blame_chunk_cb() directly as hunk_func() callback, without detour through xdi_diff_hunks(). Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/blame.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index 324d476abf..9ae5cf3a56 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -759,12 +759,14 @@ struct blame_chunk_cb_data { long tlno; }; -static void blame_chunk_cb(void *data, long same, long p_next, long t_next) +static int blame_chunk_cb(long start_a, long count_a, + long start_b, long count_b, void *data) { struct blame_chunk_cb_data *d = data; - blame_chunk(d->sb, d->tlno, d->plno, same, d->target, d->parent); - d->plno = p_next; - d->tlno = t_next; + blame_chunk(d->sb, d->tlno, d->plno, start_b, d->target, d->parent); + d->plno = start_a + count_a; + d->tlno = start_b + count_b; + return 0; } /* @@ -781,6 +783,8 @@ static int pass_blame_to_parent(struct scoreboard *sb, struct blame_chunk_cb_data d; xpparam_t xpp; xdemitconf_t xecfg; + xdemitcb_t ecb; + memset(&d, 0, sizeof(d)); d.sb = sb; d.target = target; d.parent = parent; last_in_target = find_last_in_target(sb, target); @@ -795,7 +799,10 @@ static int pass_blame_to_parent(struct scoreboard *sb, xpp.flags = xdl_opts; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 0; - xdi_diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, &xpp, &xecfg); + xecfg.hunk_func = blame_chunk_cb; + memset(&ecb, 0, sizeof(ecb)); + ecb.priv = &d; + xdi_diff(&file_p, &file_o, &xpp, &xecfg, &ecb); /* The rest (i.e. anything after tlno) are the same as the parent */ blame_chunk(sb, d.tlno, d.plno, last_in_target, target, parent); From 5d23ec7664ed41afd92d9d8d7ce5e75f87564f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:22:47 +0200 Subject: [PATCH 3/7] blame: use hunk_func(), part 2 Use handle_split_cb() directly as hunk_func() callback, without going through xdi_diff_hunks(). Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/blame.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index 9ae5cf3a56..c83fc7cd61 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -906,12 +906,15 @@ struct handle_split_cb_data { long tlno; }; -static void handle_split_cb(void *data, long same, long p_next, long t_next) +static int handle_split_cb(long start_a, long count_a, + long start_b, long count_b, void *data) { struct handle_split_cb_data *d = data; - handle_split(d->sb, d->ent, d->tlno, d->plno, same, d->parent, d->split); - d->plno = p_next; - d->tlno = t_next; + handle_split(d->sb, d->ent, d->tlno, d->plno, start_b, d->parent, + d->split); + d->plno = start_a + count_a; + d->tlno = start_b + count_b; + return 0; } /* @@ -931,6 +934,8 @@ static void find_copy_in_blob(struct scoreboard *sb, struct handle_split_cb_data d; xpparam_t xpp; xdemitconf_t xecfg; + xdemitcb_t ecb; + memset(&d, 0, sizeof(d)); d.sb = sb; d.ent = ent; d.parent = parent; d.split = split; /* @@ -954,8 +959,11 @@ static void find_copy_in_blob(struct scoreboard *sb, xpp.flags = xdl_opts; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 1; + xecfg.hunk_func = handle_split_cb; + memset(&ecb, 0, sizeof(ecb)); + ecb.priv = &d; memset(split, 0, sizeof(struct blame_entry [3])); - xdi_diff_hunks(file_p, &file_o, handle_split_cb, &d, &xpp, &xecfg); + xdi_diff(file_p, &file_o, &xpp, &xecfg, &ecb); /* remainder, if any, all match the preimage */ handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split); } From 4b4132fd89b248896d527dffd1ddfb7bbf375a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:23:39 +0200 Subject: [PATCH 4/7] blame: factor out helper for calling xdi_diff() Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin/blame.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index c83fc7cd61..778d661bef 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -88,6 +88,20 @@ struct origin { char path[FLEX_ARRAY]; }; +static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen, + xdl_emit_hunk_consume_func_t hunk_func, void *cb_data) +{ + xpparam_t xpp = {0}; + xdemitconf_t xecfg = {0}; + xdemitcb_t ecb = {0}; + + xpp.flags = xdl_opts; + xecfg.ctxlen = ctxlen; + xecfg.hunk_func = hunk_func; + ecb.priv = cb_data; + return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb); +} + /* * Prepare diff_filespec and convert it using diff textconv API * if the textconv driver exists. @@ -781,9 +795,6 @@ static int pass_blame_to_parent(struct scoreboard *sb, int last_in_target; mmfile_t file_p, file_o; struct blame_chunk_cb_data d; - xpparam_t xpp; - xdemitconf_t xecfg; - xdemitcb_t ecb; memset(&d, 0, sizeof(d)); d.sb = sb; d.target = target; d.parent = parent; @@ -795,14 +806,7 @@ static int pass_blame_to_parent(struct scoreboard *sb, fill_origin_blob(&sb->revs->diffopt, target, &file_o); num_get_patch++; - memset(&xpp, 0, sizeof(xpp)); - xpp.flags = xdl_opts; - memset(&xecfg, 0, sizeof(xecfg)); - xecfg.ctxlen = 0; - xecfg.hunk_func = blame_chunk_cb; - memset(&ecb, 0, sizeof(ecb)); - ecb.priv = &d; - xdi_diff(&file_p, &file_o, &xpp, &xecfg, &ecb); + diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d); /* The rest (i.e. anything after tlno) are the same as the parent */ blame_chunk(sb, d.tlno, d.plno, last_in_target, target, parent); @@ -932,9 +936,6 @@ static void find_copy_in_blob(struct scoreboard *sb, int cnt; mmfile_t file_o; struct handle_split_cb_data d; - xpparam_t xpp; - xdemitconf_t xecfg; - xdemitcb_t ecb; memset(&d, 0, sizeof(d)); d.sb = sb; d.ent = ent; d.parent = parent; d.split = split; @@ -955,15 +956,8 @@ static void find_copy_in_blob(struct scoreboard *sb, * file_o is a part of final image we are annotating. * file_p partially may match that image. */ - memset(&xpp, 0, sizeof(xpp)); - xpp.flags = xdl_opts; - memset(&xecfg, 0, sizeof(xecfg)); - xecfg.ctxlen = 1; - xecfg.hunk_func = handle_split_cb; - memset(&ecb, 0, sizeof(ecb)); - ecb.priv = &d; memset(split, 0, sizeof(struct blame_entry [3])); - xdi_diff(file_p, &file_o, &xpp, &xecfg, &ecb); + diff_hunks(file_p, &file_o, 1, handle_split_cb, &d); /* remainder, if any, all match the preimage */ handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split); } From 3319e606336c13ba6475d83e700ca53537cedfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:24:34 +0200 Subject: [PATCH 5/7] xdiff: remove emit_func() and xdi_diff_hunks() The functions are unused now, remove them. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- xdiff-interface.c | 44 -------------------------------------------- xdiff-interface.h | 4 ---- xdiff/xdiff.h | 1 - xdiff/xdiffi.c | 6 +----- 4 files changed, 1 insertion(+), 54 deletions(-) diff --git a/xdiff-interface.c b/xdiff-interface.c index 0e2c169227..ecfa05f616 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -156,50 +156,6 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, return ret; } -struct xdiff_emit_hunk_state { - xdiff_emit_hunk_consume_fn consume; - void *consume_callback_data; -}; - -static int process_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, - xdemitconf_t const *xecfg) -{ - long s1, s2, same, p_next, t_next; - xdchange_t *xch, *xche; - struct xdiff_emit_hunk_state *state = ecb->priv; - xdiff_emit_hunk_consume_fn fn = state->consume; - void *consume_callback_data = state->consume_callback_data; - - for (xch = xscr; xch; xch = xche->next) { - xche = xdl_get_hunk(xch, xecfg); - - s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0); - s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0); - same = s2 + XDL_MAX(xch->i1 - s1, 0); - p_next = xche->i1 + xche->chg1; - t_next = xche->i2 + xche->chg2; - - fn(consume_callback_data, same, p_next, t_next); - } - return 0; -} - -int xdi_diff_hunks(mmfile_t *mf1, mmfile_t *mf2, - xdiff_emit_hunk_consume_fn fn, void *consume_callback_data, - xpparam_t const *xpp, xdemitconf_t *xecfg) -{ - struct xdiff_emit_hunk_state state; - xdemitcb_t ecb; - - memset(&state, 0, sizeof(state)); - memset(&ecb, 0, sizeof(ecb)); - state.consume = fn; - state.consume_callback_data = consume_callback_data; - xecfg->emit_func = (void (*)())process_diff; - ecb.priv = &state; - return xdi_diff(mf1, mf2, xpp, xecfg, &ecb); -} - int read_mmfile(mmfile_t *ptr, const char *filename) { struct stat st; diff --git a/xdiff-interface.h b/xdiff-interface.h index 49d1116fc3..eff7762ee1 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -4,15 +4,11 @@ #include "xdiff/xdiff.h" typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long); -typedef void (*xdiff_emit_hunk_consume_fn)(void *, long, long, long); int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb); int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, xdiff_emit_consume_fn fn, void *consume_callback_data, xpparam_t const *xpp, xdemitconf_t const *xecfg); -int xdi_diff_hunks(mmfile_t *mf1, mmfile_t *mf2, - xdiff_emit_hunk_consume_fn fn, void *consume_callback_data, - xpparam_t const *xpp, xdemitconf_t *xecfg); int parse_hunk_header(char *line, int len, int *ob, int *on, int *nb, int *nn); diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 33c010b1f1..219a3bbca6 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -96,7 +96,6 @@ typedef struct s_xdemitconf { unsigned long flags; find_func_t find_func; void *find_func_priv; - void (*emit_func)(); xdl_emit_hunk_consume_func_t hunk_func; } xdemitconf_t; diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 4d671f4371..1b7012a119 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -557,11 +557,7 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb) { xdchange_t *xscr; xdfenv_t xe; - emit_func_t ef = xecfg->emit_func ? - (emit_func_t)xecfg->emit_func : xdl_emit_diff; - - if (xecfg->hunk_func) - ef = xdl_call_hunk_func; + emit_func_t ef = xecfg->hunk_func ? xdl_call_hunk_func : xdl_emit_diff; if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) { From be89977543c7798411f336236a506bf07b0a3d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 9 May 2012 22:43:30 +0200 Subject: [PATCH 6/7] xdiff: remove unused functions The functions xdl_cha_first(), xdl_cha_next() and xdl_atol() are not used by us. While removing them increases the difference to the upstream version of libxdiff, it only adds a bit to the more than 600 differing lines in xutils.c (mmfile_t management was simplified significantly when the library was imported initially). Besides, if upstream modifies these functions in the future, we won't need to think about importing those changes, so in that sense it makes tracking modifications easier. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- xdiff/xutils.c | 43 ------------------------------------------- xdiff/xutils.h | 3 --- 2 files changed, 46 deletions(-) diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 1b3b471ac8..ae6ce0d95c 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -122,35 +122,6 @@ void *xdl_cha_alloc(chastore_t *cha) { return data; } - -void *xdl_cha_first(chastore_t *cha) { - chanode_t *sncur; - - if (!(cha->sncur = sncur = cha->head)) - return NULL; - - cha->scurr = 0; - - return (char *) sncur + sizeof(chanode_t) + cha->scurr; -} - - -void *xdl_cha_next(chastore_t *cha) { - chanode_t *sncur; - - if (!(sncur = cha->sncur)) - return NULL; - cha->scurr += cha->isize; - if (cha->scurr == sncur->icurr) { - if (!(sncur = cha->sncur = sncur->next)) - return NULL; - cha->scurr = 0; - } - - return (char *) sncur + sizeof(chanode_t) + cha->scurr; -} - - long xdl_guess_lines(mmfile_t *mf, long sample) { long nl = 0, size, tsize = 0; char const *data, *cur, *top; @@ -430,20 +401,6 @@ int xdl_num_out(char *out, long val) { return str - out; } - -long xdl_atol(char const *str, char const **next) { - long val, base; - char const *top; - - for (top = str; XDL_ISDIGIT(*top); top++); - if (next) - *next = top; - for (val = 0, base = 1, top--; top >= str; top--, base *= 10) - val += base * (long)(*top - '0'); - return val; -} - - int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, const char *func, long funclen, xdemitcb_t *ecb) { int nb = 0; diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 714719a89c..ad1428ed69 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -31,14 +31,11 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, int xdl_cha_init(chastore_t *cha, long isize, long icount); void xdl_cha_free(chastore_t *cha); void *xdl_cha_alloc(chastore_t *cha); -void *xdl_cha_first(chastore_t *cha); -void *xdl_cha_next(chastore_t *cha); long xdl_guess_lines(mmfile_t *mf, long sample); int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags); unsigned long xdl_hash_record(char const **data, char const *top, long flags); unsigned int xdl_hashbits(unsigned int size); int xdl_num_out(char *out, long val); -long xdl_atol(char const *str, char const **next); int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, const char *func, long funclen, xdemitcb_t *ecb); int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp, From 85c20c304f991b33b59fbf00182a66f5cf6d2960 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Sun, 13 May 2012 22:41:16 +0100 Subject: [PATCH 7/7] builtin/blame.c: Fix a "Using plain integer as NULL pointer" warning Plain gcc may not but sparse catches and complains about this sort of stuff. Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- builtin/blame.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/blame.c b/builtin/blame.c index 778d661bef..24d3dd5292 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -93,7 +93,7 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen, { xpparam_t xpp = {0}; xdemitconf_t xecfg = {0}; - xdemitcb_t ecb = {0}; + xdemitcb_t ecb = {NULL}; xpp.flags = xdl_opts; xecfg.ctxlen = ctxlen;