int xdl_patch(mmfile_t *mf, mmfile_t *mfp, int mode, xdemitcb_t *ecb, xdemitcb_t *rjecb) { int hkres; long hkpos, ibase; recfile_t rff; patch_t pch; patchstats_t ps; if (xdl_init_recfile(mf, &rff) < 0) { return -1; } if (xdl_init_patch(mfp, &pch) < 0) { xdl_free_recfile(&rff); return -1; } ps.adds = ps.dels = 0; ibase = 0; if ((hkres = xdl_first_hunk(&pch)) > 0) { do { if (xdl_find_hunk(&rff, ibase, &pch, mode, &hkpos)) { if (xdl_apply_hunk(&rff, hkpos, &pch, mode, &ibase, ecb, &ps) < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } } else { if (xdl_reject_hunk(&rff, &pch, mode, rjecb, &ps) < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } } } while ((hkres = xdl_next_hunk(&pch)) > 0); } if (hkres < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } if (xdl_flush_section(&rff, ibase, rff.nrec - 1, ecb) < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } xdl_free_patch(&pch); xdl_free_recfile(&rff); 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; }
int xdl_patch(mmfile_t *mf, mmfile_t *mfp, int mode, xdemitcb_t *ecb, xdemitcb_t *rjecb) { /* int hkres, exact; */ int hkres; /* long hkpos, ibase; */ long ibase; recfile_t rff; patch_t pch; if (xdl_init_recfile(mf, 0, &rff) < 0) { return -1; } if (xdl_init_patch(mfp, mode & ~XDL_PATCH_MODEMASK, &pch) < 0) { xdl_free_recfile(&rff); return -1; } mode &= XDL_PATCH_MODEMASK; ibase = 0; if ((hkres = xdl_first_hunk(&pch)) > 0) { do { if (xdl_process_hunk(&rff, &pch, &ibase, mode, ecb, rjecb) < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } } while ((hkres = xdl_next_hunk(&pch)) > 0); } if (hkres < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } if (xdl_flush_section(&rff, ibase, rff.nrec - 1, ecb) < 0) { xdl_free_patch(&pch); xdl_free_recfile(&rff); return -1; } xdl_free_patch(&pch); xdl_free_recfile(&rff); return pch.fuzzies; }
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; }