patch 8.2.3390: included xdiff code is outdated

Problem:    Included xdiff code is outdated.
Solution:   Sync with xdiff in git 2.33. (Christian Brabandt, closes #8431)
diff --git a/src/xdiff/xemit.c b/src/xdiff/xemit.c
index f1a4513..a0078f9 100644
--- a/src/xdiff/xemit.c
+++ b/src/xdiff/xemit.c
@@ -31,7 +31,7 @@
 
 
 static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
-	long size, psize = (long)strlen(pre);
+	long size, psize = strlen(pre);
 	char const *rec;
 
 	size = xdl_get_rec(xdf, ri, &rec);
@@ -54,9 +54,9 @@
 	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
+	unsigned long ignored = 0; /* number of ignored blank lines */
 
-	// remove ignorable changes that are too far before other changes
+	/* remove ignorable changes that are too far before other changes */
 	for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
 		xch = xchp->next;
 
@@ -99,9 +99,9 @@
 static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
 {
 	if (len > 0 &&
-			(isalpha((unsigned char)*rec) || // identifier?
-			 *rec == '_' || // also identifier?
-			 *rec == '$')) { // identifiers from VMS and other esoterico
+			(isalpha((unsigned char)*rec) || /* identifier? */
+			 *rec == '_' || /* also identifier? */
+			 *rec == '$')) { /* identifiers from VMS and other esoterico */
 		if (len > sz)
 			len = sz;
 		while (0 < len && isspace((unsigned char)rec[len - 1]))
@@ -197,7 +197,7 @@
 		if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
 			long fs1, i1 = xch->i1;
 
-			// Appended chunk?
+			/* Appended chunk? */
 			if (i1 >= xe->xdf1.nrec) {
 				long i2 = xch->i2;
 
@@ -225,8 +225,23 @@
 			if (fs1 < 0)
 				fs1 = 0;
 			if (fs1 < s1) {
-				s2 -= s1 - fs1;
+				s2 = XDL_MAX(s2 - (s1 - fs1), 0);
 				s1 = fs1;
+
+				/*
+				 * Did we extend context upwards into an
+				 * ignored change?
+				 */
+				while (xchp != xch &&
+				       xchp->i1 + xchp->chg1 <= s1 &&
+				       xchp->i2 + xchp->chg2 <= s2)
+					xchp = xchp->next;
+
+				/* If so, show it after all. */
+				if (xchp != xch) {
+					xch = xchp;
+					goto pre_context_calculation;
+				}
 			}
 		}
 
@@ -249,7 +264,7 @@
 			if (fe1 < 0)
 				fe1 = xe->xdf1.nrec;
 			if (fe1 > e1) {
-				e2 += fe1 - e1;
+				e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec);
 				e1 = fe1;
 			}
 
@@ -281,7 +296,8 @@
 			funclineprev = s1 - 1;
 		}
 #endif
-		if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
+		if (!(xecfg->flags & XDL_EMIT_NO_HUNK_HDR) &&
+		    xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
 				      func_line.buf, func_line.len, ecb) < 0)
 			return -1;