]> code.delx.au - gnu-emacs/blobdiff - src/scroll.c
Merge from emacs-24
[gnu-emacs] / src / scroll.c
index 77ea1007ade9cf38e1eb45d227218bfc94bbeb6a..7cb683c4577c059c1a8a6cf3fe03c21db73ad117 100644 (file)
@@ -1,7 +1,7 @@
 /* Calculate what line insertion or deletion to do, and do it
 
-Copyright (C) 1985-1986, 1990, 1993-1994, 2001-2012
-  Free Software Foundation, Inc.
+Copyright (C) 1985-1986, 1990, 1993-1994, 2001-2014 Free Software
+Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -21,7 +21,7 @@ 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 "termchar.h"
 #include "dispextern.h"
@@ -86,15 +86,15 @@ static void do_scrolling (struct frame *,
    new contents appears.  */
 
 static void
-calculate_scrolling (FRAME_PTR frame,
+calculate_scrolling (struct frame *frame,
                     /* matrix is of size window_size + 1 on each side.  */
                     struct matrix_elt *matrix,
                     int window_size, int lines_below,
-                    int *draw_cost, int *old_hash, int *new_hash,
+                    int *draw_cost, unsigned *old_hash, unsigned *new_hash,
                     int free_at_end)
 {
   register int i, j;
-  EMACS_INT frame_lines = FRAME_LINES (frame);
+  int frame_lines = FRAME_LINES (frame);
   register struct matrix_elt *p, *p1;
   register int cost, cost1;
 
@@ -195,13 +195,13 @@ calculate_scrolling (FRAME_PTR frame,
          {
            cost = p1->writecost + first_insert_cost[i];
            if ((int) p1->insertcount > i)
-             abort ();
+             emacs_abort ();
            cost1 = p1->insertcost + next_insert_cost[i - p1->insertcount];
          }
        p->insertcost = min (cost, cost1) + draw_cost[i] + extra_cost;
        p->insertcount = (cost < cost1) ? 1 : p1->insertcount + 1;
        if ((int) p->insertcount > i)
-         abort ();
+         emacs_abort ();
 
        /* Calculate the cost if we do a delete line after
           outputting this line.
@@ -245,32 +245,33 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
 {
   struct matrix_elt *p;
   int i, j, k;
+  USE_SAFE_ALLOCA;
 
-  /* Set to 1 if we have set a terminal window with
-     set_terminal_window.  It's unsigned to work around GCC bug 48228.  */
-  unsigned int terminal_window_p = 0;
+  /* True if we have set a terminal window with set_terminal_window.  */
+  bool terminal_window_p = 0;
 
   /* A queue for line insertions to be done.  */
   struct queue { int count, pos; };
-  struct queue *queue_start
-    = (struct queue *) alloca (current_matrix->nrows * sizeof (struct queue));
+  struct queue *queue_start;
+  SAFE_NALLOCA (queue_start, 1, current_matrix->nrows);
   struct queue *queue = queue_start;
 
-  char *retained_p = (char *) alloca (window_size * sizeof (char));
-  int *copy_from = (int *) alloca (window_size * sizeof (int));
+  char *retained_p = SAFE_ALLOCA (window_size);
+  int *copy_from;
+  SAFE_NALLOCA (copy_from, 1, window_size);
 
   /* Zero means line is empty.  */
   memset (retained_p, 0, window_size * sizeof (char));
   for (k = 0; k < window_size; ++k)
     copy_from[k] = -1;
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 # define CHECK_BOUNDS                                                  \
   do                                                                   \
     {                                                                  \
       int ck;                                                          \
       for (ck = 0; ck < window_size; ++ck)                             \
-       xassert (copy_from[ck] == -1                                    \
+       eassert (copy_from[ck] == -1                                    \
                 || (copy_from[ck] >= 0 && copy_from[ck] < window_size)); \
     }                                                                  \
   while (0);
@@ -317,12 +318,12 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
        {
          /* Best thing done here is no insert or delete, i.e. a write.  */
          --i, --j;
-         xassert (i >= 0 && i < window_size);
-         xassert (j >= 0 && j < window_size);
+         eassert (i >= 0 && i < window_size);
+         eassert (j >= 0 && j < window_size);
          copy_from[i] = j;
          retained_p[j] = 1;
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
          CHECK_BOUNDS;
 #endif
        }
@@ -368,17 +369,18 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
     }
 
   for (k = 0; k < window_size; ++k)
-    xassert (copy_from[k] >= 0 && copy_from[k] < window_size);
+    eassert (copy_from[k] >= 0 && copy_from[k] < window_size);
 
   /* Perform the row swizzling.  */
   mirrored_line_dance (current_matrix, unchanged_at_top, window_size,
                       copy_from, retained_p);
 
-  /* Some sanity checks if GLYPH_DEBUG != 0.  */
+  /* Some sanity checks if GLYPH_DEBUG is defined.  */
   CHECK_MATRIX (current_matrix);
 
   if (terminal_window_p)
     set_terminal_window (frame, 0);
+  SAFE_FREE ();
 }
 
 \f
@@ -423,16 +425,16 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
    is the equivalent of draw_cost for the old line contents */
 
 static void
-calculate_direct_scrolling (FRAME_PTR frame,
+calculate_direct_scrolling (struct frame *frame,
                            /* matrix is of size window_size + 1 on each side.  */
                            struct matrix_elt *matrix,
                            int window_size, int lines_below,
                            int *draw_cost, int *old_draw_cost,
-                           int *old_hash, int *new_hash,
+                           unsigned *old_hash, unsigned *new_hash,
                            int free_at_end)
 {
   register int i, j;
-  EMACS_INT frame_lines = FRAME_LINES (frame);
+  int frame_lines = FRAME_LINES (frame);
   register struct matrix_elt *p, *p1;
   register int cost, cost1, delta;
 
@@ -650,32 +652,32 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
 {
   struct matrix_elt *p;
   int i, j;
+  USE_SAFE_ALLOCA;
 
   /* A queue of deletions and insertions to be performed.  */
   struct alt_queue { int count, pos, window; };
-  struct alt_queue *queue_start = (struct alt_queue *)
-    alloca (window_size * sizeof *queue_start);
+  struct alt_queue *queue_start;
+  SAFE_NALLOCA (queue_start, 1, window_size);
   struct alt_queue *queue = queue_start;
 
-  /* Set to 1 if a terminal window has been set with
-     set_terminal_window: */
-  int terminal_window_p = 0;
+  /* True if a terminal window has been set with set_terminal_window.  */
+  bool terminal_window_p = 0;
 
-  /* A nonzero value of write_follows indicates that a write has been
-     selected, allowing either an insert or a delete to be selected
-     next.  When write_follows is zero, a delete cannot be selected
+  /* If true, a write has been selected, allowing either an insert or a
+     delete to be selected next.  If false, a delete cannot be selected
      unless j < i, and an insert cannot be selected unless i < j.
      This corresponds to a similar restriction (with the ordering
      reversed) in calculate_direct_scrolling, which is intended to
      ensure that lines marked as inserted will be blank. */
-  int write_follows_p = 1;
+  bool write_follows_p = 1;
 
   /* For each row in the new matrix what row of the old matrix it is.  */
-  int *copy_from = (int *) alloca (window_size * sizeof (int));
+  int *copy_from;
+  SAFE_NALLOCA (copy_from, 1, window_size);
 
   /* Non-zero for each row in the new matrix that is retained from the
      old matrix.  Lines not retained are empty.  */
-  char *retained_p = (char *) alloca (window_size * sizeof (char));
+  char *retained_p = SAFE_ALLOCA (window_size);
 
   memset (retained_p, 0, window_size * sizeof (char));
 
@@ -728,7 +730,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
             place they belong.  */
          int n_to_write = p->writecount;
          write_follows_p = 1;
-         xassert (n_to_write > 0);
+         eassert (n_to_write > 0);
 
          if (i > j)
            {
@@ -791,18 +793,19 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
 
   if (terminal_window_p)
     set_terminal_window (frame, 0);
+  SAFE_FREE ();
 }
 
 
 \f
 void
-scrolling_1 (FRAME_PTR frame, int window_size, int unchanged_at_top,
+scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
             int unchanged_at_bottom, int *draw_cost, int *old_draw_cost,
-            int *old_hash, int *new_hash, int free_at_end)
+            unsigned *old_hash, unsigned *new_hash, int free_at_end)
 {
+  USE_SAFE_ALLOCA;
   struct matrix_elt *matrix;
-  matrix = ((struct matrix_elt *)
-           alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix));
+  SAFE_NALLOCA (matrix, window_size + 1, window_size + 1);
 
   if (FRAME_SCROLL_REGION_OK (frame))
     {
@@ -822,6 +825,8 @@ scrolling_1 (FRAME_PTR frame, int window_size, int unchanged_at_top,
                     frame->current_matrix, matrix, window_size,
                    unchanged_at_top);
     }
+
+  SAFE_FREE ();
 }
 
 
@@ -834,12 +839,14 @@ scrolling_1 (FRAME_PTR frame, int window_size, int unchanged_at_top,
 
 int
 scrolling_max_lines_saved (int start, int end,
-                           int *oldhash, int *newhash,
+                           unsigned *oldhash, unsigned *newhash,
                            int *cost)
 {
-  struct { int hash; int count; } lines[01000];
-  register int i, h;
-  register int matchcount = 0;
+  enum { LOG2_NLINES = 9 };
+  enum { NLINES = 1 << LOG2_NLINES };
+  struct { unsigned hash; int count; } lines[NLINES];
+  int i, h;
+  int matchcount = 0;
   int avg_length = 0;
   int threshold;
 
@@ -860,7 +867,7 @@ scrolling_max_lines_saved (int start, int end,
     {
       if (cost[i] > threshold)
        {
-         h = newhash[i] & 0777;
+         h = newhash[i] & (NLINES - 1);
          lines[h].hash = newhash[i];
          lines[h].count++;
        }
@@ -870,7 +877,7 @@ scrolling_max_lines_saved (int start, int end,
      matches between old lines and new.  */
   for (i = start; i < end; i++)
     {
-      h = oldhash[i] & 0777;
+      h = oldhash[i] & (NLINES - 1);
       if (oldhash[i] == lines[h].hash)
        {
          matchcount++;
@@ -886,11 +893,11 @@ scrolling_max_lines_saved (int start, int end,
    overhead and multiply factor values */
 
 static void
-line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn,
+line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn,
               register int *ov, register int *mf)
 {
-  register EMACS_INT i;
-  register EMACS_INT frame_lines = FRAME_LINES (frame);
+  register int i;
+  register int frame_lines = FRAME_LINES (frame);
   register int insert_overhead = ov1 * 10;
   register int next_insert_cost = ovn * 10;
 
@@ -904,7 +911,7 @@ line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn,
 }
 
 static void
-ins_del_costs (FRAME_PTR frame,
+ins_del_costs (struct frame *frame,
               const char *one_line_string, const char *multi_string,
               const char *setup_string, const char *cleanup_string,
               int *costvec, int *ncostvec,
@@ -960,7 +967,7 @@ ins_del_costs (FRAME_PTR frame,
  */
 
 void
-do_line_insertion_deletion_costs (FRAME_PTR frame,
+do_line_insertion_deletion_costs (struct frame *frame,
                                  const char *ins_line_string,
                                  const char *multi_ins_string,
                                  const char *del_line_string,