/* Calculate what line insertion or deletion to do, and do it
-Copyright (C) 1985-1986, 1990, 1993-1994, 2001-2015 Free Software
+Copyright (C) 1985-1986, 1990, 1993-1994, 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
#include "lisp.h"
#include "termchar.h"
#include "dispextern.h"
-#include "keyboard.h"
#include "frame.h"
-#include "window.h"
#include "termhooks.h"
/* All costs measured in characters.
/* 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;
- int frame_lines = FRAME_LINES (frame);
- register struct matrix_elt *p, *p1;
- register int cost, cost1;
+ int i, j;
+ int frame_total_lines = FRAME_TOTAL_LINES (frame);
+ struct matrix_elt *p, *p1;
+ int cost, cost1;
int lines_moved = window_size
+ (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below);
at the i'th line of the lines we are considering,
where I is origin 1 (as it is below). */
int *first_insert_cost
- = &FRAME_INSERT_COST (frame)[frame_lines - 1 - lines_moved];
+ = &FRAME_INSERT_COST (frame)[frame_total_lines - 1 - lines_moved];
int *first_delete_cost
- = &FRAME_DELETE_COST (frame)[frame_lines - 1 - lines_moved];
+ = &FRAME_DELETE_COST (frame)[frame_total_lines - 1 - lines_moved];
int *next_insert_cost
- = &FRAME_INSERTN_COST (frame)[frame_lines - 1 - lines_moved];
+ = &FRAME_INSERTN_COST (frame)[frame_total_lines - 1 - lines_moved];
int *next_delete_cost
- = &FRAME_DELETEN_COST (frame)[frame_lines - 1 - lines_moved];
+ = &FRAME_DELETEN_COST (frame)[frame_total_lines - 1 - lines_moved];
/* Discourage long scrolls on fast lines.
Don't scroll nearly a full frame height unless it saves
at least 1/4 second. */
- int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame)));
+ int extra_cost = baud_rate / (10 * 4 * frame_total_lines);
if (baud_rate <= 0)
extra_cost = 1;
{
struct matrix_elt *p;
int i, j, k;
+ USE_SAFE_ALLOCA;
/* 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
- = alloca (current_matrix->nrows * sizeof *queue_start);
+ struct queue *queue_start;
+ SAFE_NALLOCA (queue_start, 1, current_matrix->nrows);
struct queue *queue = queue_start;
- char *retained_p = alloca (window_size * sizeof *retained_p);
- int *copy_from = alloca (window_size * sizeof *copy_from);
+ 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));
if (terminal_window_p)
set_terminal_window (frame, 0);
+ SAFE_FREE ();
}
\f
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;
- int frame_lines = FRAME_LINES (frame);
- register struct matrix_elt *p, *p1;
- register int cost, cost1, delta;
+ int i, j;
+ int frame_total_lines = FRAME_TOTAL_LINES (frame);
+ struct matrix_elt *p, *p1;
+ int cost, cost1, delta;
/* first_insert_cost[-I] is the cost of doing the first insert-line
at a position I lines above the bottom line in the scroll window. */
int *first_insert_cost
- = &FRAME_INSERT_COST (frame)[frame_lines - 1];
+ = &FRAME_INSERT_COST (frame)[frame_total_lines - 1];
int *first_delete_cost
- = &FRAME_DELETE_COST (frame)[frame_lines - 1];
+ = &FRAME_DELETE_COST (frame)[frame_total_lines - 1];
int *next_insert_cost
- = &FRAME_INSERTN_COST (frame)[frame_lines - 1];
+ = &FRAME_INSERTN_COST (frame)[frame_total_lines - 1];
int *next_delete_cost
- = &FRAME_DELETEN_COST (frame)[frame_lines - 1];
+ = &FRAME_DELETEN_COST (frame)[frame_total_lines - 1];
int scroll_overhead;
/* Discourage long scrolls on fast lines.
Don't scroll nearly a full frame height unless it saves
at least 1/4 second. */
- int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame)));
+ int extra_cost = baud_rate / (10 * 4 * frame_total_lines);
if (baud_rate <= 0)
extra_cost = 1;
{
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 = alloca (window_size * sizeof *queue_start);
+ struct alt_queue *queue_start;
+ SAFE_NALLOCA (queue_start, 1, window_size);
struct alt_queue *queue = queue_start;
/* True if a terminal window has been set with set_terminal_window. */
bool write_follows_p = 1;
/* For each row in the new matrix what row of the old matrix it is. */
- int *copy_from = alloca (window_size * sizeof *copy_from);
+ 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 = alloca (window_size * sizeof *retained_p);
+ char *retained_p = SAFE_ALLOCA (window_size);
memset (retained_p, 0, window_size * sizeof (char));
if (terminal_window_p)
set_terminal_window (frame, 0);
+ SAFE_FREE ();
}
void
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)
{
- struct matrix_elt *matrix
- = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix);
+ USE_SAFE_ALLOCA;
+ struct matrix_elt *matrix;
+ SAFE_NALLOCA (matrix, window_size + 1, window_size + 1);
if (FRAME_SCROLL_REGION_OK (frame))
{
frame->current_matrix, matrix, window_size,
unchanged_at_top);
}
+
+ SAFE_FREE ();
}
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;
{
if (cost[i] > threshold)
{
- h = newhash[i] & 0777;
+ h = newhash[i] & (NLINES - 1);
lines[h].hash = newhash[i];
lines[h].count++;
}
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++;
static void
line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn,
- register int *ov, register int *mf)
+ int *ov, int *mf)
{
- register int i;
- register int frame_lines = FRAME_LINES (frame);
- register int insert_overhead = ov1 * 10;
- register int next_insert_cost = ovn * 10;
+ int i;
+ int frame_total_lines = FRAME_TOTAL_LINES (frame);
+ int insert_overhead = ov1 * 10;
+ int next_insert_cost = ovn * 10;
- for (i = frame_lines-1; i >= 0; i--)
+ for (i = frame_total_lines - 1; i >= 0; i--)
{
mf[i] = next_insert_cost / 10;
next_insert_cost += pfn;
only) and those that must repeatedly insert one line.
The cost to insert N lines at line L is
- [tt.t_ILov + (frame_lines + 1 - L) * tt.t_ILpf] +
- N * [tt.t_ILnov + (frame_lines + 1 - L) * tt.t_ILnpf]
+ [tt.t_ILov + (frame_total_lines + 1 - L) * tt.t_ILpf] +
+ N * [tt.t_ILnov + (frame_total_lines + 1 - L) * tt.t_ILnpf]
ILov represents the basic insert line overhead. ILpf is the padding
required to allow the terminal time to move a line: insertion at line
- L changes (frame_lines + 1 - L) lines.
+ L changes (frame_total_lines + 1 - L) lines.
The first bracketed expression above is the overhead; the second is
the multiply factor. Both are dependent only on the position at
const char *cleanup_string,
int coefficient)
{
+ int frame_total_lines = FRAME_TOTAL_LINES (frame);
FRAME_INSERT_COST (frame) =
- xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int));
+ xnrealloc (FRAME_INSERT_COST (frame), frame_total_lines, sizeof (int));
FRAME_DELETEN_COST (frame) =
- xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int));
+ xnrealloc (FRAME_DELETEN_COST (frame), frame_total_lines, sizeof (int));
FRAME_INSERTN_COST (frame) =
- xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int));
+ xnrealloc (FRAME_INSERTN_COST (frame), frame_total_lines, sizeof (int));
FRAME_DELETE_COST (frame) =
- xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int));
+ xnrealloc (FRAME_DELETE_COST (frame), frame_total_lines, sizeof (int));
ins_del_costs (frame,
ins_line_string, multi_ins_string,