builtin-merge: avoid run_command_v_opt() for recursive and subtree
[gitweb.git] / xdiff-interface.c
index bba236428adb0b34421b9f1b5a3a1728911ee406..944ad9887f5c94ca0e63f9a6c901447634f871ce 100644 (file)
@@ -1,5 +1,12 @@
 #include "cache.h"
 #include "xdiff-interface.h"
+#include "strbuf.h"
+
+struct xdiff_emit_state {
+       xdiff_emit_consume_fn consume;
+       void *consume_callback_data;
+       struct strbuf remainder;
+};
 
 static int parse_num(char **cp_p, int *num_p)
 {
@@ -55,13 +62,13 @@ static void consume_one(void *priv_, char *s, unsigned long size)
                unsigned long this_size;
                ep = memchr(s, '\n', size);
                this_size = (ep == NULL) ? size : (ep - s + 1);
-               priv->consume(priv, s, this_size);
+               priv->consume(priv->consume_callback_data, s, this_size);
                size -= this_size;
                s += this_size;
        }
 }
 
-int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
+static int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
 {
        struct xdiff_emit_state *priv = priv_;
        int i;
@@ -69,36 +76,22 @@ int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
        for (i = 0; i < nbuf; i++) {
                if (mb[i].ptr[mb[i].size-1] != '\n') {
                        /* Incomplete line */
-                       priv->remainder = xrealloc(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;
+                       strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size);
                        continue;
                }
 
                /* we have a complete line */
-               if (!priv->remainder) {
+               if (!priv->remainder.len) {
                        consume_one(priv, mb[i].ptr, mb[i].size);
                        continue;
                }
-               priv->remainder = xrealloc(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;
+               strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size);
+               consume_one(priv, priv->remainder.buf, priv->remainder.len);
+               strbuf_reset(&priv->remainder);
        }
-       if (priv->remainder) {
-               consume_one(priv, priv->remainder, priv->remainder_size);
-               free(priv->remainder);
-               priv->remainder = NULL;
-               priv->remainder_size = 0;
+       if (priv->remainder.len) {
+               consume_one(priv, priv->remainder.buf, priv->remainder.len);
+               strbuf_reset(&priv->remainder);
        }
        return 0;
 }
@@ -141,6 +134,25 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
        return xdl_diff(&a, &b, xpp, xecfg, xecb);
 }
 
+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, xdemitcb_t *xecb)
+{
+       int ret;
+       struct xdiff_emit_state state;
+
+       memset(&state, 0, sizeof(state));
+       state.consume = fn;
+       state.consume_callback_data = consume_callback_data;
+       xecb->outf = xdiff_outf;
+       xecb->priv = &state;
+       strbuf_init(&state.remainder, 0);
+       ret = xdi_diff(mf1, mf2, xpp, xecfg, xecb);
+       strbuf_release(&state.remainder);
+       return ret;
+}
+
 int read_mmfile(mmfile_t *ptr, const char *filename)
 {
        struct stat st;
@@ -152,8 +164,8 @@ int read_mmfile(mmfile_t *ptr, const char *filename)
        if ((f = fopen(filename, "rb")) == NULL)
                return error("Could not open %s", filename);
        sz = xsize_t(st.st_size);
-       ptr->ptr = xmalloc(sz);
-       if (fread(ptr->ptr, sz, 1, f) != 1)
+       ptr->ptr = xmalloc(sz ? sz : 1);
+       if (sz && fread(ptr->ptr, sz, 1, f) != 1)
                return error("Could not read %s", filename);
        fclose(f);
        ptr->size = sz;