On Sunday 18 April 2010 16:13:01 Andreas Gruenbacher wrote: > 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?
The patch was getting word wrapped, sorry -- here is the correct version. 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