execv_dashed_external: wait for child on signal death
[gitweb.git] / xdiff-interface.c
index 0e2c169227ad29b5bf546c6c1b97e1a1d8ed7409..060038c2d6b92512e6625d0f5d94ed5439cd249c 100644 (file)
@@ -100,9 +100,9 @@ static int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
 
 /*
  * Trim down common substring at the end of the buffers,
- * but leave at least ctx lines at the end.
+ * but end on a complete line.
  */
-static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx)
+static void trim_common_tail(mmfile_t *a, mmfile_t *b)
 {
        const int blk = 1024;
        long trimmed = 0, recovered = 0;
@@ -110,9 +110,6 @@ static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx)
        char *bp = b->ptr + b->size;
        long smaller = (a->size < b->size) ? a->size : b->size;
 
-       if (ctx)
-               return;
-
        while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) {
                trimmed += blk;
                ap -= blk;
@@ -131,7 +128,11 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
        mmfile_t a = *mf1;
        mmfile_t b = *mf2;
 
-       trim_common_tail(&a, &b, xecfg->ctxlen);
+       if (mf1->size > MAX_XDIFF_SIZE || mf2->size > MAX_XDIFF_SIZE)
+               return -1;
+
+       if (!xecfg->ctxlen && !(xecfg->flags & XDL_EMIT_FUNCCONTEXT))
+               trim_common_tail(&a, &b);
 
        return xdl_diff(&a, &b, xpp, xecfg, xecb);
 }
@@ -156,50 +157,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;
@@ -221,20 +178,20 @@ int read_mmfile(mmfile_t *ptr, const char *filename)
        return 0;
 }
 
-void read_mmblob(mmfile_t *ptr, const unsigned char *sha1)
+void read_mmblob(mmfile_t *ptr, const struct object_id *oid)
 {
        unsigned long size;
        enum object_type type;
 
-       if (!hashcmp(sha1, null_sha1)) {
+       if (!oidcmp(oid, &null_oid)) {
                ptr->ptr = xstrdup("");
                ptr->size = 0;
                return;
        }
 
-       ptr->ptr = read_sha1_file(sha1, &type, &size);
+       ptr->ptr = read_sha1_file(oid->hash, &type, &size);
        if (!ptr->ptr || type != OBJ_BLOB)
-               die("unable to read blob object %s", sha1_to_hex(sha1));
+               die("unable to read blob object %s", oid_to_hex(oid));
        ptr->size = size;
 }
 
@@ -257,11 +214,10 @@ struct ff_regs {
 static long ff_regexp(const char *line, long len,
                char *buffer, long buffer_size, void *priv)
 {
-       char *line_buffer;
        struct ff_regs *regs = priv;
        regmatch_t pmatch[2];
        int i;
-       int result = -1;
+       int result;
 
        /* Exclude terminating newline (and cr) from matching */
        if (len > 0 && line[len-1] == '\n') {
@@ -271,18 +227,16 @@ static long ff_regexp(const char *line, long len,
                        len--;
        }
 
-       line_buffer = xstrndup(line, len); /* make NUL terminated */
-
        for (i = 0; i < regs->nr; i++) {
                struct ff_reg *reg = regs->array + i;
-               if (!regexec(&reg->re, line_buffer, 2, pmatch, 0)) {
+               if (!regexec_buf(&reg->re, line, len, 2, pmatch, 0)) {
                        if (reg->negate)
-                               goto fail;
+                               return -1;
                        break;
                }
        }
        if (regs->nr <= i)
-               goto fail;
+               return -1;
        i = pmatch[1].rm_so >= 0 ? 1 : 0;
        line += pmatch[i].rm_so;
        result = pmatch[i].rm_eo - pmatch[i].rm_so;
@@ -291,8 +245,6 @@ static long ff_regexp(const char *line, long len,
        while (result > 0 && (isspace(line[result - 1])))
                result--;
        memcpy(buffer, line, result);
- fail:
-       free(line_buffer);
        return result;
 }
 
@@ -306,7 +258,7 @@ void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value, int cflags)
        for (i = 0, regs->nr = 1; value[i]; i++)
                if (value[i] == '\n')
                        regs->nr++;
-       regs->array = xmalloc(regs->nr * sizeof(struct ff_reg));
+       ALLOC_ARRAY(regs->array, regs->nr);
        for (i = 0; i < regs->nr; i++) {
                struct ff_reg *reg = regs->array + i;
                const char *ep = strchr(value, '\n'), *expression;