static int xdl_hunk_match(recfile_t *rf, long irec, patch_t *pch, int mode) { long i, j, fsize, psize, ptop; char const *fline, *pline; for (i = irec, j = pch->hkrec + 1, ptop = pch->hkrec + 1 + pch->hklen; i < rf->nrec && j < ptop; i++, j++) { for (; j < ptop; j++) { if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) return 0; if (*pline == ' ' || *pline == mode) break; } if (j == ptop) break; if (!(fline = xdl_recfile_get(rf, i, &fsize))) return 0; if (fsize != --psize || memcmp(fline, pline + 1, fsize)) return 0; } for (; j < ptop; j++) if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)) || *pline == ' ' || *pline == mode) return 0; return 1; }
static int xdl_load_hunk(patch_t *pch, long hkrec) { long size, i, nb; char const *line; for (;; hkrec++) { pch->hkrec = hkrec; if (!(line = xdl_recfile_get(&pch->rf, pch->hkrec, &size))) return 0; if (*line == '@') break; } if (xdl_load_hunk_info(line, size, &pch->hi) < 0) { return -1; } pch->hi.cmn = pch->hi.radd = pch->hi.rdel = pch->hi.pctx = pch->hi.sctx = 0; for (i = pch->hkrec + 1, nb = 0; (line = xdl_recfile_get(&pch->rf, i, &size)) != NULL; i++) { if (*line == '@' || *line == '\n') break; if (*line == ' ') { nb++; pch->hi.cmn++; } else if (*line == '+') { if (pch->hi.radd + pch->hi.rdel == 0) pch->hi.pctx = nb; nb = 0; pch->hi.radd++; } else if (*line == '-') { if (pch->hi.radd + pch->hi.rdel == 0) pch->hi.pctx = nb; nb = 0; pch->hi.rdel++; } else { return -1; } } pch->hi.sctx = nb; if (pch->hi.cmn + pch->hi.radd != pch->hi.c2 || pch->hi.cmn + pch->hi.rdel != pch->hi.c1) { return -1; } pch->hklen = i - pch->hkrec - 1; return 1; }
static int xdl_emit_rfile_line(recfile_t *rf, long line, xdemitcb_t *ecb) { mmbuffer_t mb; if (!(mb.ptr = (char *) xdl_recfile_get(rf, line, &mb.size)) || ecb->outf(ecb->priv, &mb, 1) < 0) { return -1; } return 0; }
static int xdl_reject_hunk(recfile_t *rf, patch_t *pch, int mode, xdemitcb_t *rjecb, patchstats_t *ps) { long i, size, s1, s2, c1, c2; char const *line, *pre; mmbuffer_t mb; if (mode == '-') { s1 = pch->hi.s1; s2 = pch->hi.s2; c1 = pch->hi.c1; c2 = pch->hi.c2; } else { s1 = pch->hi.s2; s2 = pch->hi.s1; c1 = pch->hi.c2; c2 = pch->hi.c1; } s1 += ps->adds - ps->dels; if (xdl_emit_hunk_hdr(s1 + 1, c1, s2 + 1, c2, rjecb) < 0) { return -1; } for (i = pch->hkrec + 1; (line = xdl_recfile_get(&pch->rf, i, &size)) != NULL; i++) { if (*line == '@' || *line == '\n') break; if (mode == '-' || *line == ' ') { mb.ptr = (char *) line; mb.size = size; if (rjecb->outf(rjecb->priv, &mb, 1) < 0) { return -1; } } else { pre = *line == '+' ? "-": "+"; if (xdl_emit_diffrec(line + 1, size - 1, pre, strlen(pre), rjecb) < 0) { return -1; } } } return 0; }
static int xdl_apply_hunk(recfile_t *rf, long hkpos, patch_t *pch, int mode, long *ibase, xdemitcb_t *ecb) { long j, psize, ptop; char const *pline; mmbuffer_t mb; /* * The hunk starting position (hkpos) can be negative, up to the number * of prefix context lines. Since this function only emit the core of * the hunk (the remaining lines are flushed by xdl_flush_section() calls) * we need to normalize it by adding the number of prefix context lines. * The normalized value of the starting position is then greater/equal * to zero. */ hkpos += pch->hi.pctx; if (xdl_flush_section(rf, *ibase, hkpos - 1, ecb) < 0) { return -1; } *ibase = hkpos; for (j = pch->hkrec + 1 + pch->hi.pctx, ptop = pch->hkrec + 1 + pch->hklen - pch->hi.sctx; j < ptop; j++) { if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) { return -1; } if (*pline == ' ') { if (xdl_emit_rfile_line(rf, *ibase, ecb) < 0) { return -1; } (*ibase)++; } else if (*pline != mode) { mb.ptr = (char *) pline + 1; mb.size = psize - 1; if (ecb->outf(ecb->priv, &mb, 1) < 0) { return -1; } pch->ps.adds++; } else { (*ibase)++; pch->ps.dels++; } } return 0; }
static int xdl_flush_section(recfile_t *rf, long start, long top, xdemitcb_t *ecb) { long i; mmbuffer_t mb; for (i = start; i <= top; i++) { if (!(mb.ptr = (char *) xdl_recfile_get(rf, i, &mb.size))) { return -1; } if (ecb->outf(ecb->priv, &mb, 1) < 0) { return -1; } } return 0; }
static int xdl_apply_hunk(recfile_t *rf, long hkpos, patch_t *pch, int mode, long *ibase, xdemitcb_t *ecb, patchstats_t *ps) { long i, size; char const *line; mmbuffer_t mb; if (xdl_flush_section(rf, *ibase, hkpos - 1, ecb) < 0) { return -1; } *ibase = hkpos; for (i = pch->hkrec + 1; (line = xdl_recfile_get(&pch->rf, i, &size)) != NULL; i++) { if (*line == '@' || *line == '\n') break; if (*line == ' ' || *line != mode) { mb.ptr = (char *) line + 1; mb.size = size - 1; if (ecb->outf(ecb->priv, &mb, 1) < 0) { return -1; } } if (*line == ' ' || *line == mode) (*ibase)++; if (*line == mode) ps->dels++; else if (*line != ' ') ps->adds++; } return 0; }
static int xdl_hunk_match(recfile_t *rf, long irec, patch_t *pch, int mode, int fuzz) { long i, j, z, fsize, psize = 0, ptop, pfuzz, sfuzz, misses; char const *fline, *pline = NULL; /* * Limit fuzz to not be greater than the prefix and suffix context. */ pfuzz = fuzz < pch->hi.pctx ? fuzz: pch->hi.pctx; sfuzz = fuzz < pch->hi.sctx ? fuzz: pch->hi.sctx; /* * First loop through the prefix fuzz area. In this loop we simply * note mismatching lines. We allow missing lines here, that is, * some prefix context lines are missing. */ for (z = pfuzz, misses = 0, i = irec, j = pch->hkrec + 1, ptop = pch->hkrec + 1 + pch->hklen - sfuzz; z > 0 && i < rf->nrec && j < ptop; i++, j++, z--) { if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) return 0; if (!(fline = xdl_recfile_get(rf, i, &fsize)) || !xdl_line_match(pch, fline, fsize, pline + 1, psize - 1)) misses++; } if (misses > fuzz) return 0; /* * Strict match loop. */ for (; i < rf->nrec && j < ptop; i++, j++) { for (; j < ptop; j++) { if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) return 0; if (*pline == ' ' || *pline == mode) break; } if (j == ptop) break; if (!(fline = xdl_recfile_get(rf, i, &fsize)) || !xdl_line_match(pch, fline, fsize, pline + 1, psize - 1)) return 0; } for (; j < ptop; j++) if (!(pline = xdl_recfile_get(&pch->rf, j, &psize)) || *pline == ' ' || *pline == mode) return 0; /* * Finally loop through the suffix fuzz area. In this loop we simply * note mismatching lines. We allow missing lines here, that is, * some suffix context lines are missing. */ for (z = sfuzz; z > 0 && i < rf->nrec; i++, j++, z--) { if (!(pline = xdl_recfile_get(&pch->rf, j, &psize))) return 0; if (!(fline = xdl_recfile_get(rf, i, &fsize)) || !xdl_line_match(pch, fline, fsize, pline + 1, psize - 1)) misses++; } return misses <= fuzz; }