diff options
| author | Paul Eggert | 2015-07-27 23:36:48 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-07-27 23:40:27 -0700 |
| commit | 1216f7332d18248017835b1b01ded6345b51b976 (patch) | |
| tree | 5f877f9ac22b4a789d95a29b8413ad6ced83f366 /src | |
| parent | f5dc3cf21cf6d6f51c096262225fcb96a8a7f126 (diff) | |
| download | emacs-1216f7332d18248017835b1b01ded6345b51b976.tar.gz emacs-1216f7332d18248017835b1b01ded6345b51b976.zip | |
Fix subscript error in calculate_direct_scrolling
Use slightly-longer cost vectors. Without this change,
calculate_direct_scrolling can have a subscript violation when
FRAME_LINES (frame) <= delta.
* src/scroll.c (calculate_scrolling, calculate_direct_scrolling)
(line_ins_del, do_line_insertion_deletion_costs):
Allocate and use slightly-larger cost vectors, ones based on
FRAME_TOTAL_LINES instead of FRAME_LINES.
Diffstat (limited to 'src')
| -rw-r--r-- | src/scroll.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/src/scroll.c b/src/scroll.c index ad7f0f7eced..7f5b73bd773 100644 --- a/src/scroll.c +++ b/src/scroll.c | |||
| @@ -93,10 +93,10 @@ calculate_scrolling (struct frame *frame, | |||
| 93 | int *draw_cost, unsigned *old_hash, unsigned *new_hash, | 93 | int *draw_cost, unsigned *old_hash, unsigned *new_hash, |
| 94 | int free_at_end) | 94 | int free_at_end) |
| 95 | { | 95 | { |
| 96 | register int i, j; | 96 | int i, j; |
| 97 | int frame_lines = FRAME_LINES (frame); | 97 | int frame_total_lines = FRAME_TOTAL_LINES (frame); |
| 98 | register struct matrix_elt *p, *p1; | 98 | struct matrix_elt *p, *p1; |
| 99 | register int cost, cost1; | 99 | int cost, cost1; |
| 100 | 100 | ||
| 101 | int lines_moved = window_size | 101 | int lines_moved = window_size |
| 102 | + (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below); | 102 | + (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below); |
| @@ -104,18 +104,18 @@ calculate_scrolling (struct frame *frame, | |||
| 104 | at the i'th line of the lines we are considering, | 104 | at the i'th line of the lines we are considering, |
| 105 | where I is origin 1 (as it is below). */ | 105 | where I is origin 1 (as it is below). */ |
| 106 | int *first_insert_cost | 106 | int *first_insert_cost |
| 107 | = &FRAME_INSERT_COST (frame)[frame_lines - 1 - lines_moved]; | 107 | = &FRAME_INSERT_COST (frame)[frame_total_lines - 1 - lines_moved]; |
| 108 | int *first_delete_cost | 108 | int *first_delete_cost |
| 109 | = &FRAME_DELETE_COST (frame)[frame_lines - 1 - lines_moved]; | 109 | = &FRAME_DELETE_COST (frame)[frame_total_lines - 1 - lines_moved]; |
| 110 | int *next_insert_cost | 110 | int *next_insert_cost |
| 111 | = &FRAME_INSERTN_COST (frame)[frame_lines - 1 - lines_moved]; | 111 | = &FRAME_INSERTN_COST (frame)[frame_total_lines - 1 - lines_moved]; |
| 112 | int *next_delete_cost | 112 | int *next_delete_cost |
| 113 | = &FRAME_DELETEN_COST (frame)[frame_lines - 1 - lines_moved]; | 113 | = &FRAME_DELETEN_COST (frame)[frame_total_lines - 1 - lines_moved]; |
| 114 | 114 | ||
| 115 | /* Discourage long scrolls on fast lines. | 115 | /* Discourage long scrolls on fast lines. |
| 116 | Don't scroll nearly a full frame height unless it saves | 116 | Don't scroll nearly a full frame height unless it saves |
| 117 | at least 1/4 second. */ | 117 | at least 1/4 second. */ |
| 118 | int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame))); | 118 | int extra_cost = baud_rate / (10 * 4 * frame_total_lines); |
| 119 | 119 | ||
| 120 | if (baud_rate <= 0) | 120 | if (baud_rate <= 0) |
| 121 | extra_cost = 1; | 121 | extra_cost = 1; |
| @@ -433,28 +433,28 @@ calculate_direct_scrolling (struct frame *frame, | |||
| 433 | unsigned *old_hash, unsigned *new_hash, | 433 | unsigned *old_hash, unsigned *new_hash, |
| 434 | int free_at_end) | 434 | int free_at_end) |
| 435 | { | 435 | { |
| 436 | register int i, j; | 436 | int i, j; |
| 437 | int frame_lines = FRAME_LINES (frame); | 437 | int frame_total_lines = FRAME_TOTAL_LINES (frame); |
| 438 | register struct matrix_elt *p, *p1; | 438 | struct matrix_elt *p, *p1; |
| 439 | register int cost, cost1, delta; | 439 | int cost, cost1, delta; |
| 440 | 440 | ||
| 441 | /* first_insert_cost[-I] is the cost of doing the first insert-line | 441 | /* first_insert_cost[-I] is the cost of doing the first insert-line |
| 442 | at a position I lines above the bottom line in the scroll window. */ | 442 | at a position I lines above the bottom line in the scroll window. */ |
| 443 | int *first_insert_cost | 443 | int *first_insert_cost |
| 444 | = &FRAME_INSERT_COST (frame)[frame_lines - 1]; | 444 | = &FRAME_INSERT_COST (frame)[frame_total_lines - 1]; |
| 445 | int *first_delete_cost | 445 | int *first_delete_cost |
| 446 | = &FRAME_DELETE_COST (frame)[frame_lines - 1]; | 446 | = &FRAME_DELETE_COST (frame)[frame_total_lines - 1]; |
| 447 | int *next_insert_cost | 447 | int *next_insert_cost |
| 448 | = &FRAME_INSERTN_COST (frame)[frame_lines - 1]; | 448 | = &FRAME_INSERTN_COST (frame)[frame_total_lines - 1]; |
| 449 | int *next_delete_cost | 449 | int *next_delete_cost |
| 450 | = &FRAME_DELETEN_COST (frame)[frame_lines - 1]; | 450 | = &FRAME_DELETEN_COST (frame)[frame_total_lines - 1]; |
| 451 | 451 | ||
| 452 | int scroll_overhead; | 452 | int scroll_overhead; |
| 453 | 453 | ||
| 454 | /* Discourage long scrolls on fast lines. | 454 | /* Discourage long scrolls on fast lines. |
| 455 | Don't scroll nearly a full frame height unless it saves | 455 | Don't scroll nearly a full frame height unless it saves |
| 456 | at least 1/4 second. */ | 456 | at least 1/4 second. */ |
| 457 | int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame))); | 457 | int extra_cost = baud_rate / (10 * 4 * frame_total_lines); |
| 458 | 458 | ||
| 459 | if (baud_rate <= 0) | 459 | if (baud_rate <= 0) |
| 460 | extra_cost = 1; | 460 | extra_cost = 1; |
| @@ -894,14 +894,14 @@ scrolling_max_lines_saved (int start, int end, | |||
| 894 | 894 | ||
| 895 | static void | 895 | static void |
| 896 | line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn, | 896 | line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn, |
| 897 | register int *ov, register int *mf) | 897 | int *ov, int *mf) |
| 898 | { | 898 | { |
| 899 | register int i; | 899 | int i; |
| 900 | register int frame_lines = FRAME_LINES (frame); | 900 | int frame_total_lines = FRAME_TOTAL_LINES (frame); |
| 901 | register int insert_overhead = ov1 * 10; | 901 | int insert_overhead = ov1 * 10; |
| 902 | register int next_insert_cost = ovn * 10; | 902 | int next_insert_cost = ovn * 10; |
| 903 | 903 | ||
| 904 | for (i = frame_lines-1; i >= 0; i--) | 904 | for (i = frame_total_lines - 1; i >= 0; i--) |
| 905 | { | 905 | { |
| 906 | mf[i] = next_insert_cost / 10; | 906 | mf[i] = next_insert_cost / 10; |
| 907 | next_insert_cost += pfn; | 907 | next_insert_cost += pfn; |
| @@ -946,12 +946,12 @@ ins_del_costs (struct frame *frame, | |||
| 946 | only) and those that must repeatedly insert one line. | 946 | only) and those that must repeatedly insert one line. |
| 947 | 947 | ||
| 948 | The cost to insert N lines at line L is | 948 | The cost to insert N lines at line L is |
| 949 | [tt.t_ILov + (frame_lines + 1 - L) * tt.t_ILpf] + | 949 | [tt.t_ILov + (frame_total_lines + 1 - L) * tt.t_ILpf] + |
| 950 | N * [tt.t_ILnov + (frame_lines + 1 - L) * tt.t_ILnpf] | 950 | N * [tt.t_ILnov + (frame_total_lines + 1 - L) * tt.t_ILnpf] |
| 951 | 951 | ||
| 952 | ILov represents the basic insert line overhead. ILpf is the padding | 952 | ILov represents the basic insert line overhead. ILpf is the padding |
| 953 | required to allow the terminal time to move a line: insertion at line | 953 | required to allow the terminal time to move a line: insertion at line |
| 954 | L changes (frame_lines + 1 - L) lines. | 954 | L changes (frame_total_lines + 1 - L) lines. |
| 955 | 955 | ||
| 956 | The first bracketed expression above is the overhead; the second is | 956 | The first bracketed expression above is the overhead; the second is |
| 957 | the multiply factor. Both are dependent only on the position at | 957 | the multiply factor. Both are dependent only on the position at |
| @@ -976,14 +976,15 @@ do_line_insertion_deletion_costs (struct frame *frame, | |||
| 976 | const char *cleanup_string, | 976 | const char *cleanup_string, |
| 977 | int coefficient) | 977 | int coefficient) |
| 978 | { | 978 | { |
| 979 | int frame_total_lines = FRAME_TOTAL_LINES (frame); | ||
| 979 | FRAME_INSERT_COST (frame) = | 980 | FRAME_INSERT_COST (frame) = |
| 980 | xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int)); | 981 | xnrealloc (FRAME_INSERT_COST (frame), frame_total_lines, sizeof (int)); |
| 981 | FRAME_DELETEN_COST (frame) = | 982 | FRAME_DELETEN_COST (frame) = |
| 982 | xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int)); | 983 | xnrealloc (FRAME_DELETEN_COST (frame), frame_total_lines, sizeof (int)); |
| 983 | FRAME_INSERTN_COST (frame) = | 984 | FRAME_INSERTN_COST (frame) = |
| 984 | xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int)); | 985 | xnrealloc (FRAME_INSERTN_COST (frame), frame_total_lines, sizeof (int)); |
| 985 | FRAME_DELETE_COST (frame) = | 986 | FRAME_DELETE_COST (frame) = |
| 986 | xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int)); | 987 | xnrealloc (FRAME_DELETE_COST (frame), frame_total_lines, sizeof (int)); |
| 987 | 988 | ||
| 988 | ins_del_costs (frame, | 989 | ins_del_costs (frame, |
| 989 | ins_line_string, multi_ins_string, | 990 | ins_line_string, multi_ins_string, |