From: Dmitry Antipov Date: Wed, 20 Feb 2013 05:18:20 +0000 (+0400) Subject: * search.c (find_newline): Return byte position in bytepos. X-Git-Tag: emacs-24.3.90~173^2~6^2~89 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2a14a4f13cdb22f5b6b0840081d977c8d38a91e6;p=emacs.git * search.c (find_newline): Return byte position in bytepos. Adjust comment. (find_next_newline_no_quit, find_before_next_newline): Add bytepos argument. * lisp.h (find_newline, find_next_newline_no_quit) (find_before_next_newline): Adjust prototypes. * bidi.c (bidi_find_paragraph_start): * editfns.c (Fconstrain_to_field, Fline_end_position): * indent.c (compute_motion, vmotion): * xdisp.c (back_to_previous_line_start, forward_to_next_line_start): (get_visually_first_element, move_it_vertically_backward): Adjust users and avoid calls to CHAR_TO_BYTE where appropriate. --- diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el index 734975f7f11..8ab2abec67e 100644 --- a/lisp/emacs-lisp/cl-loaddefs.el +++ b/lisp/emacs-lisp/cl-loaddefs.el @@ -267,7 +267,7 @@ including `cl-block' and `cl-eval-when'. ;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when ;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp ;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*) -;;;;;; "cl-macs" "cl-macs.el" "3b4d4e869f81f0b07ab3aa08f5478c2e") +;;;;;; "cl-macs" "cl-macs.el" "8a90c81a400a2846e7b4c3da07626d94") ;;; Generated autoloads from cl-macs.el (autoload 'cl--compiler-macro-list* "cl-macs" "\ diff --git a/src/ChangeLog b/src/ChangeLog index ff059cf1a3c..7396ccb3759 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2013-02-20 Dmitry Antipov + + * search.c (find_newline): Return byte position in bytepos. + Adjust comment. + (find_next_newline_no_quit, find_before_next_newline): Add + bytepos argument. + * lisp.h (find_newline, find_next_newline_no_quit) + (find_before_next_newline): Adjust prototypes. + * bidi.c (bidi_find_paragraph_start): + * editfns.c (Fconstrain_to_field, Fline_end_position): + * indent.c (compute_motion, vmotion): + * xdisp.c (back_to_previous_line_start, forward_to_next_line_start): + (get_visually_first_element, move_it_vertically_backward): + Adjust users and avoid calls to CHAR_TO_BYTE where appropriate. + 2013-02-19 Eli Zaretskii * w32proc.c (new_child): Avoid leaking handles if the subprocess diff --git a/src/bidi.c b/src/bidi.c index db2e48a2ca7..364d7e500ba 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -1104,14 +1104,11 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) while (pos_byte > BEGV_BYTE && n++ < MAX_PARAGRAPH_SEARCH && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0) - { - /* FIXME: What if the paragraph beginning is covered by a - display string? And what if a display string covering some - of the text over which we scan back includes - paragraph_start_re? */ - pos = find_next_newline_no_quit (pos - 1, -1); - pos_byte = CHAR_TO_BYTE (pos); - } + /* FIXME: What if the paragraph beginning is covered by a + display string? And what if a display string covering some + of the text over which we scan back includes + paragraph_start_re? */ + pos = find_next_newline_no_quit (pos - 1, -1, &pos_byte); if (n >= MAX_PARAGRAPH_SEARCH) pos_byte = BEGV_BYTE; return pos_byte; diff --git a/src/editfns.c b/src/editfns.c index bee0bcc158d..831c8359fab 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -736,7 +736,7 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */) FIELD_BOUND are on the same line by seeing whether there's an intervening newline or not. */ || (find_newline (XFASTINT (new_pos), XFASTINT (field_bound), - fwd ? -1 : 1, &shortage, 1), + fwd ? -1 : 1, &shortage, NULL, 1), shortage != 0))) /* Constrain NEW_POS to FIELD_BOUND. */ new_pos = field_bound; @@ -821,7 +821,8 @@ This function does not move point. */) CHECK_NUMBER (n); clipped_n = clip_to_bounds (PTRDIFF_MIN + 1, XINT (n), PTRDIFF_MAX); - end_pos = find_before_next_newline (orig, 0, clipped_n - (clipped_n <= 0)); + end_pos = find_before_next_newline (orig, 0, clipped_n - (clipped_n <= 0), + NULL); /* Return END_POS constrained to the current input field. */ return Fconstrain_to_field (make_number (end_pos), make_number (orig), diff --git a/src/indent.c b/src/indent.c index ce1639eae1e..9bf75bc6d95 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1328,8 +1328,7 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos, TO (we need to go back below). */ if (pos <= to) { - pos = find_before_next_newline (pos, to, 1); - pos_byte = CHAR_TO_BYTE (pos); + pos = find_before_next_newline (pos, to, 1, &pos_byte); hpos = width; /* If we just skipped next_boundary, loop around in the main while @@ -1583,10 +1582,9 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos, /* Skip any number of invisible lines all at once */ do { - pos = find_before_next_newline (pos, to, 1); + pos = find_before_next_newline (pos, to, 1, &pos_byte); if (pos < to) - pos++; - pos_byte = CHAR_TO_BYTE (pos); + INC_BOTH (pos, pos_byte); } while (pos < to && indented_beyond_p (pos, pos_byte, @@ -1622,10 +1620,7 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos, everything from a ^M to the end of the line is invisible. Stop *before* the real newline. */ if (pos < to) - { - pos = find_before_next_newline (pos, to, 1); - pos_byte = CHAR_TO_BYTE (pos); - } + pos = find_before_next_newline (pos, to, 1, &pos_byte); /* If we just skipped next_boundary, loop around in the main while and handle it. */ @@ -1845,21 +1840,20 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w) while ((vpos > vtarget || first) && from > BEGV) { + ptrdiff_t bytepos; Lisp_Object propval; - prevline = find_next_newline_no_quit (from - 1, -1); + prevline = find_next_newline_no_quit (from - 1, -1, &bytepos); while (prevline > BEGV && ((selective > 0 - && indented_beyond_p (prevline, - CHAR_TO_BYTE (prevline), - selective)) + && indented_beyond_p (prevline, bytepos, selective)) /* Watch out for newlines with `invisible' property. When moving upward, check the newline before. */ || (propval = Fget_char_property (make_number (prevline - 1), Qinvisible, text_prop_object), TEXT_PROP_MEANS_INVISIBLE (propval)))) - prevline = find_next_newline_no_quit (prevline - 1, -1); + prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos); pos = *compute_motion (prevline, 0, lmargin, 0, @@ -1897,21 +1891,20 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w) from_byte = CHAR_TO_BYTE (from); if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n') { + ptrdiff_t bytepos; Lisp_Object propval; - prevline = find_next_newline_no_quit (from, -1); + prevline = find_next_newline_no_quit (from, -1, &bytepos); while (prevline > BEGV && ((selective > 0 - && indented_beyond_p (prevline, - CHAR_TO_BYTE (prevline), - selective)) + && indented_beyond_p (prevline, bytepos, selective)) /* Watch out for newlines with `invisible' property. When moving downward, check the newline after. */ || (propval = Fget_char_property (make_number (prevline), Qinvisible, text_prop_object), TEXT_PROP_MEANS_INVISIBLE (propval)))) - prevline = find_next_newline_no_quit (prevline - 1, -1); + prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos); pos = *compute_motion (prevline, 0, lmargin, 0, diff --git a/src/lisp.h b/src/lisp.h index 79fc9616d67..e0a8b237e72 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3343,12 +3343,13 @@ extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, Lisp_Object); extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, - ptrdiff_t *, bool); + ptrdiff_t *, ptrdiff_t *, bool); extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT, bool); extern ptrdiff_t find_next_newline (ptrdiff_t, int); -extern ptrdiff_t find_next_newline_no_quit (ptrdiff_t, ptrdiff_t); -extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t); +extern ptrdiff_t find_next_newline_no_quit (ptrdiff_t, ptrdiff_t, ptrdiff_t *); +extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, + ptrdiff_t, ptrdiff_t *); extern void syms_of_search (void); extern void clear_regexp_cache (void); diff --git a/src/search.c b/src/search.c index d4508004bf6..1c0f57487f9 100644 --- a/src/search.c +++ b/src/search.c @@ -638,15 +638,18 @@ newline_cache_on_off (struct buffer *buf) If we don't find COUNT instances before reaching END, set *SHORTAGE to the number of newlines left unfound, and return END. + If BYTEPOS is not NULL, set *BYTEPOS to the byte position corresponding + to the returned character position. + If ALLOW_QUIT, set immediate_quit. That's good to do except when inside redisplay. */ ptrdiff_t -find_newline (ptrdiff_t start, ptrdiff_t end, - ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) +find_newline (ptrdiff_t start, ptrdiff_t end, ptrdiff_t count, + ptrdiff_t *shortage, ptrdiff_t *bytepos, bool allow_quit) { struct region_cache *newline_cache; - ptrdiff_t end_byte = -1; + ptrdiff_t start_byte = -1, end_byte = -1; int direction; if (count > 0) @@ -680,9 +683,7 @@ find_newline (ptrdiff_t start, ptrdiff_t end, the position of the last character before the next such obstacle --- the last character the dumb search loop should examine. */ - ptrdiff_t ceiling_byte = end_byte - 1; - ptrdiff_t start_byte; - ptrdiff_t tem; + ptrdiff_t tem, ceiling_byte = end_byte - 1; /* If we're looking for a newline, consult the newline cache to see where we can avoid some scanning. */ @@ -745,21 +746,22 @@ find_newline (ptrdiff_t start, ptrdiff_t end, if (--count == 0) { immediate_quit = 0; + if (bytepos) + *bytepos = nl + 1 - base + start_byte; return BYTE_TO_CHAR (nl + 1 - base + start_byte); } cursor = nl + 1; } - start = BYTE_TO_CHAR (ceiling_addr - base + start_byte); + start_byte += ceiling_addr - base; + start = BYTE_TO_CHAR (start_byte); } } else while (start > end) { /* The last character to check before the next obstacle. */ - ptrdiff_t ceiling_byte = end_byte; - ptrdiff_t start_byte; - ptrdiff_t tem; + ptrdiff_t tem, ceiling_byte = end_byte; /* Consult the newline cache, if appropriate. */ if (newline_cache) @@ -816,18 +818,26 @@ find_newline (ptrdiff_t start, ptrdiff_t end, if (++count >= 0) { immediate_quit = 0; + if (bytepos) + *bytepos = nl - base + start_byte; return BYTE_TO_CHAR (nl - base + start_byte); } cursor = nl - 1; } - start = BYTE_TO_CHAR (ceiling_addr - 1 - base + start_byte); + start_byte += ceiling_addr - 1 - base; + start = BYTE_TO_CHAR (start_byte); } } immediate_quit = 0; - if (shortage != 0) + if (shortage) *shortage = count * direction; + if (bytepos) + { + *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; + eassert (*bytepos == CHAR_TO_BYTE (start)); + } return start; } @@ -932,9 +942,9 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, } ptrdiff_t -find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) +find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt, ptrdiff_t *bytepos) { - return find_newline (from, 0, cnt, (ptrdiff_t *) 0, 0); + return find_newline (from, 0, cnt, NULL, bytepos, 0); } /* Like find_next_newline, but returns position before the newline, @@ -942,14 +952,19 @@ find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) find_next_newline (...)-1, because you might hit TO. */ ptrdiff_t -find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) +find_before_next_newline (ptrdiff_t from, ptrdiff_t to, + ptrdiff_t cnt, ptrdiff_t *bytepos) { ptrdiff_t shortage; - ptrdiff_t pos = find_newline (from, to, cnt, &shortage, 1); + ptrdiff_t pos = find_newline (from, to, cnt, &shortage, bytepos, 1); if (shortage == 0) - pos--; - + { + if (bytepos) + DEC_BOTH (pos, *bytepos); + else + pos--; + } return pos; } diff --git a/src/xdisp.c b/src/xdisp.c index f32b88f3027..6b86fd076a5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -5905,8 +5905,9 @@ pop_it (struct it *it) static void back_to_previous_line_start (struct it *it) { - IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1); - IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); + IT_CHARPOS (*it) + = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, + -1, &IT_BYTEPOS (*it)); } @@ -5977,8 +5978,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p, short-cut. */ if (!newline_found_p) { - ptrdiff_t start = IT_CHARPOS (*it); - ptrdiff_t limit = find_next_newline_no_quit (start, 1); + ptrdiff_t bytepos, start = IT_CHARPOS (*it); + ptrdiff_t limit = find_next_newline_no_quit (start, 1, &bytepos); Lisp_Object pos; eassert (!STRINGP (it->string)); @@ -5996,7 +5997,7 @@ forward_to_next_line_start (struct it *it, int *skipped_p, if (!it->bidi_p) { IT_CHARPOS (*it) = limit; - IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); + IT_BYTEPOS (*it) = bytepos; } else { @@ -7432,11 +7433,9 @@ get_visually_first_element (struct it *it) if (string_p) it->bidi_it.charpos = it->bidi_it.bytepos = 0; else - { - it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it), - -1); - it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos); - } + it->bidi_it.charpos + = find_next_newline_no_quit (IT_CHARPOS (*it), -1, + &it->bidi_it.bytepos); bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); do { @@ -9071,7 +9070,7 @@ move_it_vertically_backward (struct it *it, int dy) && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n') { ptrdiff_t nl_pos = - find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1); + find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1, NULL); move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS); }