summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--combine-diff.c52
-rw-r--r--xdiff-interface.c58
-rw-r--r--xdiff-interface.h18
4 files changed, 84 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index 145099adaa..7030370c6f 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 11f5143eec..e17afd1096 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 0000000000..0a66ded953
--- /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 0000000000..e2f0d66123
--- /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