diff --git a/Makefile b/Makefile index 145099adaae0a8..7030370c6f497b 100644 --- a/Makefile +++ b/Makefile @@ -208,7 +208,7 @@ LIB_OBJS = \ quote.o read-cache.o refs.o run-command.o \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ tag.o tree.o usage.o config.o environment.o ctype.o copy.o \ - fetch-clone.o revision.o pager.o tree-walk.o \ + fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \ $(DIFF_OBJS) GITLIBS = $(LIB_FILE) $(XDIFF_LIB) diff --git a/combine-diff.c b/combine-diff.c index 11f5143eeceb62..e17afd109633da 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -4,7 +4,7 @@ #include "diff.h" #include "diffcore.h" #include "quote.h" -#include "xdiff/xdiff.h" +#include "xdiff-interface.h" static int uninteresting(struct diff_filepair *p) { @@ -195,8 +195,8 @@ static void append_lost(struct sline *sline, int n, const char *line, int len) } struct combine_diff_state { - char *remainder; - unsigned long remainder_size; + struct xdiff_emit_state xm; + unsigned int lno, ob, on, nb, nn; unsigned long nmask; int num_parent; @@ -205,10 +205,9 @@ struct combine_diff_state { struct sline *lost_bucket; }; -static void consume_line(struct combine_diff_state *state, - char *line, - unsigned long len) +static void consume_line(void *state_, char *line, unsigned long len) { + struct combine_diff_state *state = state_; if (5 < len && !memcmp("@@ -", line, 4)) { if (parse_hunk_header(line, len, &state->ob, &state->on, @@ -249,41 +248,6 @@ static void consume_line(struct combine_diff_state *state, } } -static int combine_diff_outf(void *priv_, mmbuffer_t *mb, int nbuf) -{ - struct combine_diff_state *priv = priv_; - int i; - for (i = 0; i < nbuf; i++) { - if (mb[i].ptr[mb[i].size-1] != '\n') { - /* Incomplete line */ - priv->remainder = realloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - priv->remainder_size += mb[i].size; - continue; - } - - /* we have a complete line */ - if (!priv->remainder) { - consume_line(priv, mb[i].ptr, mb[i].size); - continue; - } - priv->remainder = realloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - consume_line(priv, priv->remainder, - priv->remainder_size + mb[i].size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; - } - return 0; -} - static void combine_diff(const unsigned char *parent, mmfile_t *result_file, struct sline *sline, int cnt, int n, int num_parent) { @@ -304,9 +268,10 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, xpp.flags = XDF_NEED_MINIMAL; xecfg.ctxlen = 0; xecfg.flags = 0; - ecb.outf = combine_diff_outf; + ecb.outf = xdiff_outf; ecb.priv = &state; memset(&state, 0, sizeof(state)); + state.xm.consume = consume_line; state.nmask = nmask; state.sline = sline; state.lno = 1; @@ -314,9 +279,6 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, state.n = n; xdl_diff(&parent_file, result_file, &xpp, &xecfg, &ecb); - if (state.remainder && state.remainder_size) - consume_line(&state, state.remainder, state.remainder_size); - free(state.remainder); free(parent_file.ptr); /* Assign line numbers for this parent. diff --git a/xdiff-interface.c b/xdiff-interface.c new file mode 100644 index 00000000000000..0a66ded9533009 --- /dev/null +++ b/xdiff-interface.c @@ -0,0 +1,58 @@ +#include "cache.h" +#include "xdiff-interface.h" + +static void consume_one(void *priv_, char *s, unsigned long size) +{ + struct xdiff_emit_state *priv = priv_; + char *ep; + while (size) { + unsigned long this_size; + ep = memchr(s, '\n', size); + this_size = (ep == NULL) ? size : (ep - s + 1); + priv->consume(priv, s, this_size); + size -= this_size; + s += this_size; + } +} + +int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) +{ + struct xdiff_emit_state *priv = priv_; + int i; + + for (i = 0; i < nbuf; i++) { + if (mb[i].ptr[mb[i].size-1] != '\n') { + /* Incomplete line */ + priv->remainder = realloc(priv->remainder, + priv->remainder_size + + mb[i].size); + memcpy(priv->remainder + priv->remainder_size, + mb[i].ptr, mb[i].size); + priv->remainder_size += mb[i].size; + continue; + } + + /* we have a complete line */ + if (!priv->remainder) { + consume_one(priv, mb[i].ptr, mb[i].size); + continue; + } + priv->remainder = realloc(priv->remainder, + priv->remainder_size + + mb[i].size); + memcpy(priv->remainder + priv->remainder_size, + mb[i].ptr, mb[i].size); + consume_one(priv, priv->remainder, + priv->remainder_size + mb[i].size); + free(priv->remainder); + priv->remainder = NULL; + priv->remainder_size = 0; + } + if (priv->remainder) { + consume_one(priv, priv->remainder, priv->remainder_size); + free(priv->remainder); + priv->remainder = NULL; + priv->remainder_size = 0; + } + return 0; +} diff --git a/xdiff-interface.h b/xdiff-interface.h new file mode 100644 index 00000000000000..e2f0d661236504 --- /dev/null +++ b/xdiff-interface.h @@ -0,0 +1,18 @@ +#ifndef XDIFF_INTERFACE_H +#define XDIFF_INTERFACE_H + +#include "xdiff/xdiff.h" + +struct xdiff_emit_state; + +typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long); + +struct xdiff_emit_state { + xdiff_emit_consume_fn consume; + char *remainder; + unsigned long remainder_size; +}; + +int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf); + +#endif