Hello, here is a change to diffseq whcih I need in GNU patch: patch has a historic feature called "plan B" for when only little memory is available; it then doesn't load the entire patch and file to be patched into memory. To support this, the file and patch are accessed through functions rather than directly as arrays. (This feature is probably relatively worthless these days except for weird corner cases, but I would still like to keep it exactly for such corner cases.)
Is this change acceptable? Thanks, Andreas * diffseq (EQUAL_IDX): When this macro is defined instead of EQUAL, do not assume that the x and y vectors are directly accessible as xvec and yvec. Use EQUAL_IDX() instead of EQUAL() to compare vector elements. Signed-off-by: Andreas Gruenbacher <agr...@suse.de> --- lib/diffseq.h | 28 ++++++++++++++++++++-------- 1 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/diffseq.h b/lib/diffseq.h index d9c871b..02df835 100644 --- a/lib/diffseq.h +++ b/lib/diffseq.h @@ -41,8 +41,9 @@ /* Before including this file, you need to define: ELEMENT The element type of the vectors being compared. - EQUAL A two-argument macro that tests two elements for - equality. + EQUAL(x, y) or EQUAL_IDX(ctxt, xoff, yoff) + Test two ELEMENTs for equality, or test the + elements at offsets xoff and yoff for equality. OFFSET A signed integer type sufficient to hold the difference between two indices. Usually something like ssize_t. @@ -87,14 +88,20 @@ # endif #endif +#ifdef EQUAL +# define EQUAL_IDX(ctxt, xoff, yoff) EQUAL(xv[xoff], yv[yoff]) +#endif + /* * Context of comparison operation. */ struct context { +#ifdef EQUAL /* Vectors being compared. */ ELEMENT const *xvec; ELEMENT const *yvec; +#endif /* Extra fields. */ EXTRA_CONTEXT_FIELDS @@ -170,8 +177,10 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, { OFFSET *const fd = ctxt->fdiag; /* Give the compiler a chance. */ OFFSET *const bd = ctxt->bdiag; /* Additional help for the compiler. */ +#ifdef EQUAL ELEMENT const *const xv = ctxt->xvec; /* Still more help for the compiler. */ ELEMENT const *const yv = ctxt->yvec; /* And more and more . . . */ +#endif const OFFSET dmin = xoff - ylim; /* Minimum valid diagonal. */ const OFFSET dmax = xlim - yoff; /* Maximum valid diagonal. */ const OFFSET fmid = xoff - yoff; /* Center diagonal of top-down search. */ @@ -210,7 +219,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, OFFSET x0 = tlo < thi ? thi : tlo + 1; for (x = x0, y = x0 - d; - x < xlim && y < ylim && EQUAL (xv[x], yv[y]); + x < xlim && y < ylim && EQUAL_IDX (ctxt, x, y); x++, y++) continue; if (x - x0 > SNAKE_LIMIT) @@ -243,7 +252,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, OFFSET x0 = tlo < thi ? tlo : thi - 1; for (x = x0, y = x0 - d; - xoff < x && yoff < y && EQUAL (xv[x - 1], yv[y - 1]); + xoff < x && yoff < y && EQUAL_IDX (ctxt, x - 1, y - 1); x--, y--) continue; if (x0 - x > SNAKE_LIMIT) @@ -292,7 +301,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, that it end with a significant snake. */ int k; - for (k = 1; EQUAL (xv[x - k], yv[y - k]); k++) + for (k = 1; EQUAL_IDX (ctxt, x - k, y - k); k++) if (k == SNAKE_LIMIT) { best = v; @@ -331,7 +340,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, that it end with a significant snake. */ int k; - for (k = 0; EQUAL (xv[x + k], yv[y + k]); k++) + for (k = 0; EQUAL_IDX (ctxt, x + k, y + k); k++) if (k == SNAKE_LIMIT - 1) { best = v; @@ -438,18 +447,20 @@ static bool compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal, struct context *ctxt) { +#ifdef EQUAL ELEMENT const *xv = ctxt->xvec; /* Help the compiler. */ ELEMENT const *yv = ctxt->yvec; +#endif /* Slide down the bottom initial diagonal. */ - while (xoff < xlim && yoff < ylim && EQUAL (xv[xoff], yv[yoff])) + while (xoff < xlim && yoff < ylim && EQUAL_IDX (ctxt, xoff, yoff)) { xoff++; yoff++; } /* Slide up the top initial diagonal. */ - while (xoff < xlim && yoff < ylim && EQUAL (xv[xlim - 1], yv[ylim - 1])) + while (xoff < xlim && yoff < ylim && EQUAL_IDX (ctxt, xlim - 1, ylim - 1)) { xlim--; ylim--; @@ -491,6 +502,7 @@ compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, #undef ELEMENT #undef EQUAL +#undef EQUAL_IDX #undef OFFSET #undef EXTRA_CONTEXT_FIELDS #undef NOTE_DELETE -- 1.7.1.rc1.12.ga601