Update release notes to 2.7
[gitweb.git] / xdiff / xemit.c
index 2e669c3e2570332ee50a72e06a77ad4a356ecfd6..4266ada23f3c37c1989c7fa4283b423d16c0891b 100644 (file)
@@ -56,16 +56,51 @@ static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *
 /*
  * Starting at the passed change atom, find the latest change atom to be included
  * inside the differential hunk according to the specified configuration.
+ * Also advance xscr if the first changes must be discarded.
  */
-xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) {
-       xdchange_t *xch, *xchp;
+xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
+{
+       xdchange_t *xch, *xchp, *lxch;
        long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
+       long max_ignorable = xecfg->ctxlen;
+       unsigned long ignored = 0; /* number of ignored blank lines */
+
+       /* remove ignorable changes that are too far before other changes */
+       for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
+               xch = xchp->next;
+
+               if (xch == NULL ||
+                   xch->i1 - (xchp->i1 + xchp->chg1) >= max_ignorable)
+                       *xscr = xch;
+       }
+
+       if (*xscr == NULL)
+               return NULL;
+
+       lxch = *xscr;
 
-       for (xchp = xscr, xch = xscr->next; xch; xchp = xch, xch = xch->next)
-               if (xch->i1 - (xchp->i1 + xchp->chg1) > max_common)
+       for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
+               long distance = xch->i1 - (xchp->i1 + xchp->chg1);
+               if (distance > max_common)
                        break;
 
-       return xchp;
+               if (distance < max_ignorable && (!xch->ignore || lxch == xchp)) {
+                       lxch = xch;
+                       ignored = 0;
+               } else if (distance < max_ignorable && xch->ignore) {
+                       ignored += xch->chg2;
+               } else if (lxch != xchp &&
+                          xch->i1 + ignored - (lxch->i1 + lxch->chg1) > max_common) {
+                       break;
+               } else if (!xch->ignore) {
+                       lxch = xch;
+                       ignored = 0;
+               } else {
+                       ignored += xch->chg2;
+               }
+       }
+
+       return lxch;
 }
 
 
@@ -73,7 +108,7 @@ static long def_ff(const char *rec, long len, char *buf, long sz, void *priv)
 {
        if (len > 0 &&
                        (isalpha((unsigned char)*rec) || /* identifier? */
-                        *rec == '_' || /* also identifier? */
+                        *rec == '_' || /* also identifier? */
                         *rec == '$')) { /* identifiers from VMS and other esoterico */
                if (len > sz)
                        len = sz;
@@ -87,7 +122,7 @@ static long def_ff(const char *rec, long len, char *buf, long sz, void *priv)
 
 static int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                            xdemitconf_t const *xecfg) {
-       xdfile_t *xdf = &xe->xdf1;
+       xdfile_t *xdf = &xe->xdf2;
        const char *rchg = xdf->rchg;
        long ix;
 
@@ -139,7 +174,9 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                return xdl_emit_common(xe, xscr, ecb, xecfg);
 
        for (xch = xscr; xch; xch = xche->next) {
-               xche = xdl_get_hunk(xch, xecfg);
+               xche = xdl_get_hunk(&xch, xecfg);
+               if (!xch)
+                       break;
 
                s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
                s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
@@ -204,8 +241,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                /*
                 * Emit pre-context.
                 */
-               for (; s1 < xch->i1; s1++)
-                       if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+               for (; s2 < xch->i2; s2++)
+                       if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
                                return -1;
 
                for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
@@ -213,7 +250,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                         * Merge previous with current change atom.
                         */
                        for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
-                               if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+                               if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
                                        return -1;
 
                        /*
@@ -239,8 +276,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                /*
                 * Emit post-context.
                 */
-               for (s1 = xche->i1 + xche->chg1; s1 < e1; s1++)
-                       if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+               for (s2 = xche->i2 + xche->chg2; s2 < e2; s2++)
+                       if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
                                return -1;
        }