Merge branch 'jk/bisect-final-output'
[gitweb.git] / xdiff-interface.c
index 9315bc0ede11ba0377e27d711e37b6a0ae555c43..8509f9ea223a1282a367874c3e3a3ef0c351a30f 100644 (file)
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "config.h"
+#include "object-store.h"
 #include "xdiff-interface.h"
 #include "xdiff/xtypes.h"
 #include "xdiff/xdiffi.h"
@@ -8,54 +9,26 @@
 #include "xdiff/xutils.h"
 
 struct xdiff_emit_state {
-       xdiff_emit_consume_fn consume;
+       xdiff_emit_hunk_fn hunk_fn;
+       xdiff_emit_line_fn line_fn;
        void *consume_callback_data;
        struct strbuf remainder;
 };
 
-static int parse_num(char **cp_p, int *num_p)
+static int xdiff_out_hunk(void *priv_,
+                         long old_begin, long old_nr,
+                         long new_begin, long new_nr,
+                         const char *func, long funclen)
 {
-       char *cp = *cp_p;
-       int num = 0;
+       struct xdiff_emit_state *priv = priv_;
 
-       while ('0' <= *cp && *cp <= '9')
-               num = num * 10 + *cp++ - '0';
-       if (!(cp - *cp_p))
-               return -1;
-       *cp_p = cp;
-       *num_p = num;
-       return 0;
-}
+       if (priv->remainder.len)
+               BUG("xdiff emitted hunk in the middle of a line");
 
-int parse_hunk_header(char *line, int len,
-                     int *ob, int *on,
-                     int *nb, int *nn)
-{
-       char *cp;
-       cp = line + 4;
-       if (parse_num(&cp, ob)) {
-       bad_line:
-               return error("malformed diff output: %s", line);
-       }
-       if (*cp == ',') {
-               cp++;
-               if (parse_num(&cp, on))
-                       goto bad_line;
-       }
-       else
-               *on = 1;
-       if (*cp++ != ' ' || *cp++ != '+')
-               goto bad_line;
-       if (parse_num(&cp, nb))
-               goto bad_line;
-       if (*cp == ',') {
-               cp++;
-               if (parse_num(&cp, nn))
-                       goto bad_line;
-       }
-       else
-               *nn = 1;
-       return -!!memcmp(cp, " @@", 3);
+       priv->hunk_fn(priv->consume_callback_data,
+                     old_begin, old_nr, new_begin, new_nr,
+                     func, funclen);
+       return 0;
 }
 
 static void consume_one(void *priv_, char *s, unsigned long size)
@@ -66,7 +39,7 @@ 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->consume_callback_data, s, this_size);
+               priv->line_fn(priv->consume_callback_data, s, this_size);
                size -= this_size;
                s += this_size;
        }
@@ -77,6 +50,9 @@ static int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
        struct xdiff_emit_state *priv = priv_;
        int i;
 
+       if (!priv->line_fn)
+               return 0;
+
        for (i = 0; i < nbuf; i++) {
                if (mb[i].ptr[mb[i].size-1] != '\n') {
                        /* Incomplete line */
@@ -139,8 +115,16 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
        return xdl_diff(&a, &b, xpp, xecfg, xecb);
 }
 
+void discard_hunk_line(void *priv,
+                      long ob, long on, long nb, long nn,
+                      const char *func, long funclen)
+{
+}
+
 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
-                 xdiff_emit_consume_fn fn, void *consume_callback_data,
+                 xdiff_emit_hunk_fn hunk_fn,
+                 xdiff_emit_line_fn line_fn,
+                 void *consume_callback_data,
                  xpparam_t const *xpp, xdemitconf_t const *xecfg)
 {
        int ret;
@@ -148,10 +132,13 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
        xdemitcb_t ecb;
 
        memset(&state, 0, sizeof(state));
-       state.consume = fn;
+       state.hunk_fn = hunk_fn;
+       state.line_fn = line_fn;
        state.consume_callback_data = consume_callback_data;
        memset(&ecb, 0, sizeof(ecb));
-       ecb.outf = xdiff_outf;
+       if (hunk_fn)
+               ecb.out_hunk = xdiff_out_hunk;
+       ecb.out_line = xdiff_outf;
        ecb.priv = &state;
        strbuf_init(&state.remainder, 0);
        ret = xdi_diff(mf1, mf2, xpp, xecfg, &ecb);
@@ -185,7 +172,7 @@ void read_mmblob(mmfile_t *ptr, const struct object_id *oid)
        unsigned long size;
        enum object_type type;
 
-       if (!oidcmp(oid, &null_oid)) {
+       if (oideq(oid, &null_oid)) {
                ptr->ptr = xstrdup("");
                ptr->size = 0;
                return;
@@ -319,6 +306,10 @@ int git_xmerge_config(const char *var, const char *value, void *cb)
                        git_xmerge_style = XDL_MERGE_DIFF3;
                else if (!strcmp(value, "merge"))
                        git_xmerge_style = 0;
+               /*
+                * Please update _git_checkout() in
+                * git-completion.bash when you add new merge config
+                */
                else
                        die("unknown style '%s' given for '%s'",
                            value, var);