]> code.delx.au - gnu-emacs/blobdiff - src/region-cache.c
Ibuffer change marks
[gnu-emacs] / src / region-cache.c
index ed7a07a67097470173ea703f239e7e974391e47a..45849568bff7f6409794f434787a558d9b2ba480 100644 (file)
@@ -1,14 +1,14 @@
 /* Caching facts about regions of the buffer, for optimization.
 
-Copyright (C) 1985-1989, 1993, 1995, 2001-2011
-  Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993, 1995, 2001-2016 Free Software Foundation,
+Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,7 +21,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "buffer.h"
@@ -131,15 +130,13 @@ static void revalidate_region_cache (struct buffer *buf, struct region_cache *c)
 struct region_cache *
 new_region_cache (void)
 {
-  struct region_cache *c
-    = (struct region_cache *) xmalloc (sizeof (struct region_cache));
+  struct region_cache *c = xmalloc (sizeof *c);
 
   c->gap_start = 0;
   c->gap_len = NEW_CACHE_GAP;
   c->cache_len = 0;
-  c->boundaries =
-    (struct boundary *) xmalloc ((c->gap_len + c->cache_len)
-                                 * sizeof (*c->boundaries));
+  c->boundaries = xmalloc ((c->gap_len + c->cache_len)
+                          * sizeof (*c->boundaries));
 
   c->beg_unchanged = 0;
   c->end_unchanged = 0;
@@ -192,10 +189,9 @@ find_cache_boundary (struct region_cache *c, ptrdiff_t pos)
     }
 
   /* Some testing.  */
-  if (BOUNDARY_POS (c, low) > pos
-      || (low + 1 < c->cache_len
-          && BOUNDARY_POS (c, low + 1) <= pos))
-      abort ();
+  eassert (!(BOUNDARY_POS (c, low) > pos
+            || (low + 1 < c->cache_len
+                && BOUNDARY_POS (c, low + 1) <= pos)));
 
   return low;
 }
@@ -216,14 +212,9 @@ move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size)
   ptrdiff_t buffer_beg = c->buffer_beg;
   ptrdiff_t buffer_end = c->buffer_end;
 
-  if (pos < 0
-      || pos > c->cache_len)
-    abort ();
-
   /* We mustn't ever try to put the gap before the dummy start
      boundary.  That must always be start-relative.  */
-  if (pos == 0)
-    abort ();
+  eassert (0 < pos && pos <= c->cache_len);
 
   /* Need we move the gap right?  */
   while (gap_start < pos)
@@ -246,16 +237,16 @@ move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size)
      when the portion after the gap is smallest.  */
   if (gap_len < min_size)
     {
-      ptrdiff_t i;
+      ptrdiff_t i, nboundaries = c->cache_len;
 
       c->boundaries =
-       xpalloc (c->boundaries, &c->cache_len, min_size, -1,
+       xpalloc (c->boundaries, &nboundaries, min_size - gap_len, -1,
                 sizeof *c->boundaries);
 
       /* Some systems don't provide a version of the copy routine that
          can be trusted to shift memory upward into an overlapping
          region.  memmove isn't widely available.  */
-      min_size -= gap_len;
+      min_size = nboundaries - c->cache_len - gap_len;
       for (i = c->cache_len - 1; i >= gap_start; i--)
         {
           c->boundaries[i + min_size].pos   = c->boundaries[i + gap_len].pos;
@@ -290,26 +281,19 @@ static void
 insert_cache_boundary (struct region_cache *c, ptrdiff_t i, ptrdiff_t pos,
                       int value)
 {
-  /* i must be a valid cache index.  */
-  if (i < 0 || i > c->cache_len)
-    abort ();
-
-  /* We must never want to insert something before the dummy first
-     boundary.  */
-  if (i == 0)
-    abort ();
+  /* I must be a valid cache index, and we must never want
+     to insert something before the dummy first boundary.  */
+  eassert (0 < i && i <= c->cache_len);
 
   /* We must only be inserting things in order.  */
-  if (! (BOUNDARY_POS (c, i - 1) < pos
-         && (i == c->cache_len
-             || pos < BOUNDARY_POS (c, i))))
-    abort ();
+  eassert ((BOUNDARY_POS (c, i - 1) < pos
+           && (i == c->cache_len
+               || pos < BOUNDARY_POS (c, i))));
 
   /* The value must be different from the ones around it.  However, we
      temporarily create boundaries that establish the same value as
      the subsequent boundary, so we're not going to flag that case.  */
-  if (BOUNDARY_VALUE (c, i - 1) == value)
-    abort ();
+  eassert (BOUNDARY_VALUE (c, i - 1) != value);
 
   move_cache_gap (c, i, 1);
 
@@ -330,18 +314,13 @@ delete_cache_boundaries (struct region_cache *c,
   ptrdiff_t len = end - start;
 
   /* Gotta be in range.  */
-  if (start < 0
-      || end > c->cache_len)
-    abort ();
+  eassert (0 <= start && end <= c->cache_len);
 
   /* Gotta be in order.  */
-  if (start > end)
-    abort ();
+  eassert (start <= end);
 
   /* Can't delete the dummy entry.  */
-  if (start == 0
-      && end >= 1)
-    abort ();
+  eassert (!(start == 0 && end >= 1));
 
   /* Minimize gap motion.  If we're deleting nothing, do nothing.  */
   if (len == 0)
@@ -380,11 +359,8 @@ static void
 set_cache_region (struct region_cache *c,
                  ptrdiff_t start, ptrdiff_t end, int value)
 {
-  if (start > end)
-    abort ();
-  if (start < c->buffer_beg
-      || end   > c->buffer_end)
-    abort ();
+  eassert (start <= end);
+  eassert (c->buffer_beg <= start && end <= c->buffer_end);
 
   /* Eliminate this case; then we can assume that start and end-1 are
      both the locations of real characters in the buffer.  */
@@ -697,9 +673,10 @@ know_region_cache (struct buffer *buf, struct region_cache *c,
 \f
 /* Interface: using the cache.  */
 
-/* Return true if the text immediately after POS in BUF is known, for
-   the purposes of CACHE.  If NEXT is non-zero, set *NEXT to the nearest
-   position after POS where the knownness changes.  */
+/* Return the value for the text immediately after POS in BUF if the value
+   is known, for the purposes of CACHE, and return zero otherwise.
+   If NEXT is non-zero, set *NEXT to the nearest
+   position after POS where the knowledge changes.  */
 int
 region_cache_forward (struct buffer *buf, struct region_cache *c,
                      ptrdiff_t pos, ptrdiff_t *next)
@@ -734,11 +711,13 @@ region_cache_forward (struct buffer *buf, struct region_cache *c,
   }
 }
 
-/* Return true if the text immediately before POS in BUF is known, for
-   the purposes of CACHE.  If NEXT is non-zero, set *NEXT to the nearest
-   position before POS where the knownness changes.  */
-int region_cache_backward (struct buffer *buf, struct region_cache *c,
-                          ptrdiff_t pos, ptrdiff_t *next)
+/* Return the value for the text immediately before POS in BUF if the
+   value is known, for the purposes of CACHE, and return zero
+   otherwise.  If NEXT is non-zero, set *NEXT to the nearest
+   position before POS where the knowledge changes.  */
+int
+region_cache_backward (struct buffer *buf, struct region_cache *c,
+                      ptrdiff_t pos, ptrdiff_t *next)
 {
   revalidate_region_cache (buf, c);
 
@@ -772,7 +751,8 @@ int region_cache_backward (struct buffer *buf, struct region_cache *c,
   }
 }
 
-\f
+#ifdef ENABLE_CHECKING
+
 /* Debugging: pretty-print a cache to the standard error output.  */
 
 void pp_cache (struct region_cache *) EXTERNALLY_VISIBLE;
@@ -803,3 +783,5 @@ pp_cache (struct region_cache *c)
       fprintf (stderr, "%"pD"d : %d\n", pos, BOUNDARY_VALUE (c, i));
     }
 }
+
+#endif /* ENABLE_CHECKING */