mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-18 10:16:51 +00:00
Avoid character to byte conversions in motion subroutines.
* indent.h (compute_motion, vmotion): Add byte position argument. * indent.c (compute_motion): Use it and avoid CHAR_TO_BYTE. Add eassert. (Fcompute_motion): Break long line. Adjust call to compute_motion. Use list5 for return value. (vmotion): Use byte position argument and avoid call to CHAR_TO_BYTE. Adjust comments, style and calls to compute_motion. (Fvertical_motion): Adjust call to vmotion. * window.c (Fdelete_other_windows_internal): Record window start byte position and adjust call to vmotion. (window_scroll_line_based): Likewise with call to compute_motion. Use SET_PT_BOTH. (Frecenter): Adjust calls to vmotion.
This commit is contained in:
parent
3de717bdb4
commit
c54aa1668e
@ -1,3 +1,20 @@
|
||||
2013-03-07 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
Avoid character to byte conversions in motion subroutines.
|
||||
* indent.h (compute_motion, vmotion): Add byte position argument.
|
||||
* indent.c (compute_motion): Use it and avoid CHAR_TO_BYTE.
|
||||
Add eassert.
|
||||
(Fcompute_motion): Break long line. Adjust call to compute_motion.
|
||||
Use list5 for return value.
|
||||
(vmotion): Use byte position argument and avoid call to CHAR_TO_BYTE.
|
||||
Adjust comments, style and calls to compute_motion.
|
||||
(Fvertical_motion): Adjust call to vmotion.
|
||||
* window.c (Fdelete_other_windows_internal): Record window start
|
||||
byte position and adjust call to vmotion.
|
||||
(window_scroll_line_based): Likewise with call to compute_motion.
|
||||
Use SET_PT_BOTH.
|
||||
(Frecenter): Adjust calls to vmotion.
|
||||
|
||||
2013-03-07 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* lisp.h (list2i, list3i): New functions.
|
||||
|
75
src/indent.c
75
src/indent.c
@ -1102,8 +1102,8 @@ static struct position val_compute_motion;
|
||||
the scroll bars if they are turned on. */
|
||||
|
||||
struct position *
|
||||
compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos,
|
||||
bool did_motion, ptrdiff_t to,
|
||||
compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
|
||||
EMACS_INT fromhpos, bool did_motion, ptrdiff_t to,
|
||||
EMACS_INT tovpos, EMACS_INT tohpos, EMACS_INT width,
|
||||
ptrdiff_t hscroll, int tab_offset, struct window *win)
|
||||
{
|
||||
@ -1186,8 +1186,11 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos,
|
||||
immediate_quit = 1;
|
||||
QUIT;
|
||||
|
||||
/* It's just impossible to be too paranoid here. */
|
||||
eassert (from == BYTE_TO_CHAR (frombyte) && frombyte == CHAR_TO_BYTE (from));
|
||||
|
||||
pos = prev_pos = from;
|
||||
pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
|
||||
pos_byte = prev_pos_byte = frombyte;
|
||||
contin_hpos = 0;
|
||||
prev_tab_offset = tab_offset;
|
||||
memset (&cmp_it, 0, sizeof cmp_it);
|
||||
@ -1724,7 +1727,8 @@ of a certain window, pass the window's starting location as FROM
|
||||
and the window's upper-left coordinates as FROMPOS.
|
||||
Pass the buffer's (point-max) as TO, to limit the scan to the end of the
|
||||
visible section of the buffer, and pass LINE and COL as TOPOS. */)
|
||||
(Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos, Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
|
||||
(Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos,
|
||||
Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
|
||||
{
|
||||
struct window *w;
|
||||
Lisp_Object bufpos, hpos, vpos, prevhpos;
|
||||
@ -1767,7 +1771,8 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
|
||||
if (XINT (to) < BEGV || XINT (to) > ZV)
|
||||
args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
|
||||
|
||||
pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
|
||||
pos = compute_motion (XINT (from), CHAR_TO_BYTE (XINT (from)),
|
||||
XINT (XCDR (frompos)),
|
||||
XINT (XCAR (frompos)), 0,
|
||||
XINT (to),
|
||||
(NILP (topos)
|
||||
@ -1789,28 +1794,23 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
|
||||
XSETINT (vpos, pos->vpos);
|
||||
XSETINT (prevhpos, pos->prevhpos);
|
||||
|
||||
return Fcons (bufpos,
|
||||
Fcons (hpos,
|
||||
Fcons (vpos,
|
||||
Fcons (prevhpos,
|
||||
Fcons (pos->contin ? Qt : Qnil, Qnil)))));
|
||||
|
||||
return list5 (bufpos, hpos, vpos, prevhpos, pos->contin ? Qt : Qnil);
|
||||
}
|
||||
|
||||
/* Fvertical_motion and vmotion */
|
||||
|
||||
/* Fvertical_motion and vmotion. */
|
||||
|
||||
static struct position val_vmotion;
|
||||
|
||||
struct position *
|
||||
vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
|
||||
vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
|
||||
register EMACS_INT vtarget, struct window *w)
|
||||
{
|
||||
ptrdiff_t hscroll = w->hscroll;
|
||||
struct position pos;
|
||||
/* vpos is cumulative vertical position, changed as from is changed */
|
||||
/* VPOS is cumulative vertical position, changed as from is changed. */
|
||||
register EMACS_INT vpos = 0;
|
||||
ptrdiff_t prevline;
|
||||
register ptrdiff_t first;
|
||||
ptrdiff_t from_byte;
|
||||
ptrdiff_t lmargin = hscroll > 0 ? 1 - hscroll : 0;
|
||||
ptrdiff_t selective
|
||||
= (INTEGERP (BVAR (current_buffer, selective_display))
|
||||
@ -1854,29 +1854,24 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
|
||||
text_prop_object),
|
||||
TEXT_PROP_MEANS_INVISIBLE (propval))))
|
||||
prevline = find_newline_no_quit (prevline - 1, -1, &bytepos);
|
||||
pos = *compute_motion (prevline, 0,
|
||||
lmargin,
|
||||
0,
|
||||
from,
|
||||
pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from,
|
||||
/* Don't care for VPOS... */
|
||||
1 << (BITS_PER_SHORT - 1),
|
||||
/* ... nor HPOS. */
|
||||
1 << (BITS_PER_SHORT - 1),
|
||||
-1, hscroll,
|
||||
0,
|
||||
w);
|
||||
-1, hscroll, 0, w);
|
||||
vpos -= pos.vpos;
|
||||
first = 0;
|
||||
from = prevline;
|
||||
from_byte = bytepos;
|
||||
}
|
||||
|
||||
/* If we made exactly the desired vertical distance,
|
||||
or if we hit beginning of buffer,
|
||||
return point found */
|
||||
/* If we made exactly the desired vertical distance, or
|
||||
if we hit beginning of buffer, return point found. */
|
||||
if (vpos >= vtarget)
|
||||
{
|
||||
val_vmotion.bufpos = from;
|
||||
val_vmotion.bytepos = CHAR_TO_BYTE (from);
|
||||
val_vmotion.bytepos = from_byte;
|
||||
val_vmotion.vpos = vpos;
|
||||
val_vmotion.hpos = lmargin;
|
||||
val_vmotion.contin = 0;
|
||||
@ -1884,11 +1879,12 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
|
||||
return &val_vmotion;
|
||||
}
|
||||
|
||||
/* Otherwise find the correct spot by moving down */
|
||||
/* Otherwise find the correct spot by moving down. */
|
||||
}
|
||||
/* Moving downward is simple, but must calculate from beg of line
|
||||
to determine hpos of starting point */
|
||||
from_byte = CHAR_TO_BYTE (from);
|
||||
|
||||
/* Moving downward is simple, but must calculate from
|
||||
beg of line to determine hpos of starting point. */
|
||||
|
||||
if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
|
||||
{
|
||||
ptrdiff_t bytepos;
|
||||
@ -1905,17 +1901,12 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
|
||||
text_prop_object),
|
||||
TEXT_PROP_MEANS_INVISIBLE (propval))))
|
||||
prevline = find_newline_no_quit (prevline - 1, -1, &bytepos);
|
||||
pos = *compute_motion (prevline, 0,
|
||||
lmargin,
|
||||
0,
|
||||
from,
|
||||
pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from,
|
||||
/* Don't care for VPOS... */
|
||||
1 << (BITS_PER_SHORT - 1),
|
||||
/* ... nor HPOS. */
|
||||
1 << (BITS_PER_SHORT - 1),
|
||||
-1, hscroll,
|
||||
0,
|
||||
w);
|
||||
-1, hscroll, 0, w);
|
||||
did_motion = 1;
|
||||
}
|
||||
else
|
||||
@ -1924,11 +1915,9 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
|
||||
pos.vpos = 0;
|
||||
did_motion = 0;
|
||||
}
|
||||
return compute_motion (from, vpos, pos.hpos, did_motion,
|
||||
return compute_motion (from, from_byte, vpos, pos.hpos, did_motion,
|
||||
ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
|
||||
-1, hscroll,
|
||||
0,
|
||||
w);
|
||||
-1, hscroll, 0, w);
|
||||
}
|
||||
|
||||
DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
|
||||
@ -1995,7 +1984,7 @@ whether or not it is currently displayed in some window. */)
|
||||
if (noninteractive)
|
||||
{
|
||||
struct position pos;
|
||||
pos = *vmotion (PT, XINT (lines), w);
|
||||
pos = *vmotion (PT, PT_BYTE, XINT (lines), w);
|
||||
SET_PT_BOTH (pos.bufpos, pos.bytepos);
|
||||
}
|
||||
else
|
||||
|
12
src/indent.h
12
src/indent.h
@ -26,14 +26,14 @@ struct position
|
||||
int contin;
|
||||
};
|
||||
|
||||
struct position *compute_motion (ptrdiff_t from, EMACS_INT fromvpos,
|
||||
EMACS_INT fromhpos, bool did_motion,
|
||||
ptrdiff_t to, EMACS_INT tovpos,
|
||||
EMACS_INT tohpos,
|
||||
struct position *compute_motion (ptrdiff_t from, ptrdiff_t frombyte,
|
||||
EMACS_INT fromvpos, EMACS_INT fromhpos,
|
||||
bool did_motion, ptrdiff_t to,
|
||||
EMACS_INT tovpos, EMACS_INT tohpos,
|
||||
EMACS_INT width, ptrdiff_t hscroll,
|
||||
int tab_offset, struct window *);
|
||||
struct position *vmotion (ptrdiff_t from, EMACS_INT vtarget,
|
||||
struct window *);
|
||||
struct position *vmotion (ptrdiff_t from, ptrdiff_t from_byte,
|
||||
EMACS_INT vtarget, struct window *);
|
||||
ptrdiff_t skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p,
|
||||
ptrdiff_t to, Lisp_Object window);
|
||||
|
||||
|
23
src/window.c
23
src/window.c
@ -2743,7 +2743,7 @@ window-start value is reasonable when this function is called. */)
|
||||
struct window *w, *r, *s;
|
||||
struct frame *f;
|
||||
Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
|
||||
ptrdiff_t startpos IF_LINT (= 0);
|
||||
ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
|
||||
int top IF_LINT (= 0), new_top, resize_failed;
|
||||
|
||||
w = decode_valid_window (window);
|
||||
@ -2782,6 +2782,7 @@ window-start value is reasonable when this function is called. */)
|
||||
if (!NILP (w->buffer))
|
||||
{
|
||||
startpos = marker_position (w->start);
|
||||
startbyte = marker_byte_position (w->start);
|
||||
top = WINDOW_TOP_EDGE_LINE (w)
|
||||
- FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
|
||||
/* Make sure WINDOW is the frame's selected window. */
|
||||
@ -2951,7 +2952,7 @@ window-start value is reasonable when this function is called. */)
|
||||
Fset_buffer (w->buffer);
|
||||
/* This computation used to temporarily move point, but that
|
||||
can have unwanted side effects due to text properties. */
|
||||
pos = *vmotion (startpos, -top, w);
|
||||
pos = *vmotion (startpos, startbyte, -top, w);
|
||||
|
||||
set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
|
||||
w->window_end_valid = 0;
|
||||
@ -4748,7 +4749,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
|
||||
register Lisp_Object tem;
|
||||
int lose;
|
||||
Lisp_Object bolp;
|
||||
ptrdiff_t startpos;
|
||||
ptrdiff_t startpos = marker_position (w->start);
|
||||
ptrdiff_t startbyte = marker_byte_position (w->start);
|
||||
Lisp_Object original_pos = Qnil;
|
||||
|
||||
/* If scrolling screen-fulls, compute the number of lines to
|
||||
@ -4756,8 +4758,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
|
||||
if (whole)
|
||||
n *= max (1, ht - next_screen_context_lines);
|
||||
|
||||
startpos = marker_position (w->start);
|
||||
|
||||
if (!NILP (Vscroll_preserve_screen_position))
|
||||
{
|
||||
if (window_scroll_preserve_vpos <= 0
|
||||
@ -4765,10 +4765,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
|
||||
|| NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
|
||||
{
|
||||
struct position posit
|
||||
= *compute_motion (startpos, 0, 0, 0,
|
||||
PT, ht, 0,
|
||||
-1, w->hscroll,
|
||||
0, w);
|
||||
= *compute_motion (startpos, startbyte, 0, 0, 0,
|
||||
PT, ht, 0, -1, w->hscroll, 0, w);
|
||||
window_scroll_preserve_vpos = posit.vpos;
|
||||
window_scroll_preserve_hpos = posit.hpos + w->hscroll;
|
||||
}
|
||||
@ -4784,9 +4782,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
|
||||
{
|
||||
Fvertical_motion (make_number (- (ht / 2)), window);
|
||||
startpos = PT;
|
||||
startbyte = PT_BYTE;
|
||||
}
|
||||
|
||||
SET_PT (startpos);
|
||||
SET_PT_BOTH (startpos, startbyte);
|
||||
lose = n < 0 && PT == BEGV;
|
||||
Fvertical_motion (make_number (n), window);
|
||||
pos = PT;
|
||||
@ -5321,7 +5320,7 @@ and redisplay normally--don't erase and redraw the frame. */)
|
||||
|
||||
iarg = max (iarg, this_scroll_margin);
|
||||
|
||||
pos = *vmotion (PT, -iarg, w);
|
||||
pos = *vmotion (PT, PT_BYTE, -iarg, w);
|
||||
charpos = pos.bufpos;
|
||||
bytepos = pos.bytepos;
|
||||
}
|
||||
@ -5340,7 +5339,7 @@ and redisplay normally--don't erase and redraw the frame. */)
|
||||
iarg = clip_to_bounds (this_scroll_margin, iarg,
|
||||
ht - this_scroll_margin - 1);
|
||||
|
||||
pos = *vmotion (PT, - iarg, w);
|
||||
pos = *vmotion (PT, PT_BYTE, - iarg, w);
|
||||
charpos = pos.bufpos;
|
||||
bytepos = pos.bytepos;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user