aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diffseq.h
diff options
context:
space:
mode:
authorPaul Eggert2020-08-24 16:18:48 -0700
committerPaul Eggert2020-08-24 16:19:28 -0700
commitd494f9e81a6d11dcf6c22333cd950989b2051dff (patch)
tree5d5da817d3bbddc60963cb3588be044c4670fe70 /lib/diffseq.h
parente0345b4e86154f42f47a9f7bbbf458a72bf5c06d (diff)
downloademacs-d494f9e81a6d11dcf6c22333cd950989b2051dff.tar.gz
emacs-d494f9e81a6d11dcf6c22333cd950989b2051dff.zip
Update from Gnulib
This incorporates: * lib/diffseq.h, m4/inttypes.m4: Copy from Gnulib. * m4/gnulib-comp.m4: Regenerate.
Diffstat (limited to 'lib/diffseq.h')
-rw-r--r--lib/diffseq.h128
1 files changed, 84 insertions, 44 deletions
diff --git a/lib/diffseq.h b/lib/diffseq.h
index c89363ac9ee..26e10bdd043 100644
--- a/lib/diffseq.h
+++ b/lib/diffseq.h
@@ -51,10 +51,14 @@
51 EXTRA_CONTEXT_FIELDS Declarations of fields for 'struct context'. 51 EXTRA_CONTEXT_FIELDS Declarations of fields for 'struct context'.
52 NOTE_DELETE(ctxt, xoff) Record the removal of the object xvec[xoff]. 52 NOTE_DELETE(ctxt, xoff) Record the removal of the object xvec[xoff].
53 NOTE_INSERT(ctxt, yoff) Record the insertion of the object yvec[yoff]. 53 NOTE_INSERT(ctxt, yoff) Record the insertion of the object yvec[yoff].
54 NOTE_ORDERED (Optional) A boolean expression saying that
55 NOTE_DELETE and NOTE_INSERT calls must be
56 issued in offset order.
54 EARLY_ABORT(ctxt) (Optional) A boolean expression that triggers an 57 EARLY_ABORT(ctxt) (Optional) A boolean expression that triggers an
55 early abort of the computation. 58 early abort of the computation.
56 USE_HEURISTIC (Optional) Define if you want to support the 59 USE_HEURISTIC (Optional) Define if you want to support the
57 heuristic for large vectors. 60 heuristic for large vectors.
61
58 It is also possible to use this file with abstract arrays. In this case, 62 It is also possible to use this file with abstract arrays. In this case,
59 xvec and yvec are not represented in memory. They only exist conceptually. 63 xvec and yvec are not represented in memory. They only exist conceptually.
60 In this case, the list of defines above is amended as follows: 64 In this case, the list of defines above is amended as follows:
@@ -63,6 +67,7 @@
63 XVECREF_YVECREF_EQUAL(ctxt, xoff, yoff) 67 XVECREF_YVECREF_EQUAL(ctxt, xoff, yoff)
64 A three-argument macro: References xvec[xoff] and 68 A three-argument macro: References xvec[xoff] and
65 yvec[yoff] and tests these elements for equality. 69 yvec[yoff] and tests these elements for equality.
70
66 Before including this file, you also need to include: 71 Before including this file, you also need to include:
67 #include <limits.h> 72 #include <limits.h>
68 #include <stdbool.h> 73 #include <stdbool.h>
@@ -78,6 +83,10 @@
78# define EARLY_ABORT(ctxt) false 83# define EARLY_ABORT(ctxt) false
79#endif 84#endif
80 85
86#ifndef NOTE_ORDERED
87# define NOTE_ORDERED false
88#endif
89
81/* Use this to suppress gcc's "...may be used before initialized" warnings. 90/* Use this to suppress gcc's "...may be used before initialized" warnings.
82 Beware: The Code argument must not contain commas. */ 91 Beware: The Code argument must not contain commas. */
83#ifndef IF_LINT 92#ifndef IF_LINT
@@ -88,15 +97,6 @@
88# endif 97# endif
89#endif 98#endif
90 99
91/* As above, but when Code must contain one comma. */
92#ifndef IF_LINT2
93# if defined GCC_LINT || defined lint
94# define IF_LINT2(Code1, Code2) Code1, Code2
95# else
96# define IF_LINT2(Code1, Code2) /* empty */
97# endif
98#endif
99
100/* 100/*
101 * Context of comparison operation. 101 * Context of comparison operation.
102 */ 102 */
@@ -468,49 +468,89 @@ compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
468 #define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y) 468 #define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y)
469#endif 469#endif
470 470
471 /* Slide down the bottom initial diagonal. */ 471 while (true)
472 while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
473 { 472 {
474 xoff++; 473 /* Slide down the bottom initial diagonal. */
475 yoff++; 474 while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
476 } 475 {
476 xoff++;
477 yoff++;
478 }
477 479
478 /* Slide up the top initial diagonal. */ 480 /* Slide up the top initial diagonal. */
479 while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1)) 481 while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
480 { 482 {
481 xlim--; 483 xlim--;
482 ylim--; 484 ylim--;
483 } 485 }
484 486
485 /* Handle simple cases. */ 487 /* Handle simple cases. */
486 if (xoff == xlim) 488 if (xoff == xlim)
487 while (yoff < ylim) 489 {
488 { 490 while (yoff < ylim)
489 NOTE_INSERT (ctxt, yoff); 491 {
490 if (EARLY_ABORT (ctxt)) 492 NOTE_INSERT (ctxt, yoff);
491 return true; 493 if (EARLY_ABORT (ctxt))
492 yoff++; 494 return true;
493 } 495 yoff++;
494 else if (yoff == ylim) 496 }
495 while (xoff < xlim) 497 break;
496 { 498 }
497 NOTE_DELETE (ctxt, xoff); 499 if (yoff == ylim)
498 if (EARLY_ABORT (ctxt)) 500 {
499 return true; 501 while (xoff < xlim)
500 xoff++; 502 {
501 } 503 NOTE_DELETE (ctxt, xoff);
502 else 504 if (EARLY_ABORT (ctxt))
503 { 505 return true;
504 struct partition part IF_LINT2 (= { .xmid = 0, .ymid = 0 }); 506 xoff++;
507 }
508 break;
509 }
510
511 struct partition part;
505 512
506 /* Find a point of correspondence in the middle of the vectors. */ 513 /* Find a point of correspondence in the middle of the vectors. */
507 diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt); 514 diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
508 515
509 /* Use the partitions to split this problem into subproblems. */ 516 /* Use the partitions to split this problem into subproblems. */
510 if (compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt)) 517 OFFSET xoff1, xlim1, yoff1, ylim1, xoff2, xlim2, yoff2, ylim2;
511 return true; 518 bool find_minimal1, find_minimal2;
512 if (compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt)) 519 if (!NOTE_ORDERED
513 return true; 520 && ((xlim + ylim) - (part.xmid + part.ymid)
521 < (part.xmid + part.ymid) - (xoff + yoff)))
522 {
523 /* The second problem is smaller and the caller doesn't
524 care about order, so do the second problem first to
525 lessen recursion. */
526 xoff1 = part.xmid; xlim1 = xlim;
527 yoff1 = part.ymid; ylim1 = ylim;
528 find_minimal1 = part.hi_minimal;
529
530 xoff2 = xoff; xlim2 = part.xmid;
531 yoff2 = yoff; ylim2 = part.ymid;
532 find_minimal2 = part.lo_minimal;
533 }
534 else
535 {
536 xoff1 = xoff; xlim1 = part.xmid;
537 yoff1 = yoff; ylim1 = part.ymid;
538 find_minimal1 = part.lo_minimal;
539
540 xoff2 = part.xmid; xlim2 = xlim;
541 yoff2 = part.ymid; ylim2 = ylim;
542 find_minimal2 = part.hi_minimal;
543 }
544
545 /* Recurse to do one subproblem. */
546 bool early = compareseq (xoff1, xlim1, yoff1, ylim1, find_minimal1, ctxt);
547 if (early)
548 return early;
549
550 /* Iterate to do the other subproblem. */
551 xoff = xoff2; xlim = xlim2;
552 yoff = yoff2; ylim = ylim2;
553 find_minimal = find_minimal2;
514 } 554 }
515 555
516 return false; 556 return false;