From d2b368135803170fc2d1f65237b7ef22676f9ecb Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 29 Aug 2013 11:03:18 +0400 Subject: [PATCH] Hook scanning and indentation functions to find_newline. This helps to avoid duplicated code and renders more respect to newline cache. * lisp.h (scan_newline): Prefer ptrdiff_t to EMACS_INT. * cmds.c (Fforward_line): * indent.c (scan_for_column, Fcurrent_indentation, indented_beyond_p): Use find_newline and avoid unnecessary point movements. * search.c (scan_newline): Implement on top of find_newline. --- src/ChangeLog | 10 ++++++ src/cmds.c | 18 ++++------- src/indent.c | 38 ++++++++--------------- src/lisp.h | 4 +-- src/search.c | 86 ++++++--------------------------------------------- 5 files changed, 40 insertions(+), 116 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 9e62a8e08a4..2105391755b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2013-08-29 Dmitry Antipov + + Hook scanning and indentation functions to find_newline. This helps + to avoid duplicated code and renders more respect to newline cache. + * lisp.h (scan_newline): Prefer ptrdiff_t to EMACS_INT. + * cmds.c (Fforward_line): + * indent.c (scan_for_column, Fcurrent_indentation, indented_beyond_p): + Use find_newline and avoid unnecessary point movements. + * search.c (scan_newline): Implement on top of find_newline. + 2013-08-28 Stefan Monnier * eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically diff --git a/src/cmds.c b/src/cmds.c index ce91877f85e..ee3be79a0ab 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -121,9 +121,7 @@ With positive N, a non-empty line at the end counts as one line successfully moved (for the return value). */) (Lisp_Object n) { - ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - ptrdiff_t pos, pos_byte; - EMACS_INT count, shortage; + ptrdiff_t opoint = PT, pos, pos_byte, shortage, count; if (NILP (n)) count = 1; @@ -134,16 +132,12 @@ successfully moved (for the return value). */) } if (count <= 0) - shortage = scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, 1); + pos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, + &shortage, &pos_byte, 1); else - shortage = scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, 1); - - /* Since scan_newline does TEMP_SET_PT_BOTH, - and we want to set PT "for real", - go back to the old point and then come back here. */ - pos = PT; - pos_byte = PT_BYTE; - TEMP_SET_PT_BOTH (opoint, opoint_byte); + pos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, + &shortage, &pos_byte, 1); + SET_PT_BOTH (pos, pos_byte); if (shortage > 0 diff --git a/src/indent.c b/src/indent.c index 6aaf86579d7..891b42788ed 100644 --- a/src/indent.c +++ b/src/indent.c @@ -510,15 +510,10 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) register ptrdiff_t col = 0, prev_col = 0; EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; ptrdiff_t end = endpos ? *endpos : PT; - ptrdiff_t scan, scan_byte; - ptrdiff_t next_boundary; - { - ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); - scan = PT, scan_byte = PT_BYTE; - SET_PT_BOTH (opoint, opoint_byte); + ptrdiff_t scan, scan_byte, next_boundary; + + scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); next_boundary = scan; - } window = Fget_buffer_window (Fcurrent_buffer (), Qnil); w = ! NILP (window) ? XWINDOW (window) : NULL; @@ -835,14 +830,10 @@ This is the horizontal position of the character following any initial whitespace. */) (void) { - Lisp_Object val; - ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - - scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); + ptrdiff_t posbyte; - XSETFASTINT (val, position_indentation (PT_BYTE)); - SET_PT_BOTH (opoint, opoint_byte); - return val; + find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &posbyte, 1); + return make_number (position_indentation (posbyte)); } static ptrdiff_t @@ -935,16 +926,13 @@ position_indentation (ptrdiff_t pos_byte) bool indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) { - ptrdiff_t val; - ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - - SET_PT_BOTH (pos, pos_byte); - while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n') - scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0); - - val = position_indentation (PT_BYTE); - SET_PT_BOTH (opoint, opoint_byte); - return val >= column; + while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n') + { + DEC_BOTH (pos, pos_byte); + pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE, + -1, NULL, &pos_byte, 0); + } + return position_indentation (pos_byte) >= column; } DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, diff --git a/src/lisp.h b/src/lisp.h index 3dab0d6ddfd..f3a78f48a17 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3834,8 +3834,8 @@ 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, ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); -extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, - EMACS_INT, bool); +extern ptrdiff_t scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, + ptrdiff_t, bool); extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, diff --git a/src/search.c b/src/search.c index 761c12a364a..99e8d2501fe 100644 --- a/src/search.c +++ b/src/search.c @@ -859,88 +859,20 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, If ALLOW_QUIT, set immediate_quit. That's good to do except in special cases. */ -EMACS_INT +ptrdiff_t scan_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t limit, ptrdiff_t limit_byte, - EMACS_INT count, bool allow_quit) + ptrdiff_t count, bool allow_quit) { - int direction = ((count > 0) ? 1 : -1); - - unsigned char *cursor; - unsigned char *base; - - ptrdiff_t ceiling; - unsigned char *ceiling_addr; - - bool old_immediate_quit = immediate_quit; - - if (allow_quit) - immediate_quit++; + ptrdiff_t charpos, bytepos, shortage; - if (count > 0) - { - while (start_byte < limit_byte) - { - ceiling = BUFFER_CEILING_OF (start_byte); - ceiling = min (limit_byte - 1, ceiling); - ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; - base = (cursor = BYTE_POS_ADDR (start_byte)); - - do - { - unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); - if (! nl) - break; - if (--count == 0) - { - immediate_quit = old_immediate_quit; - start_byte += nl - base + 1; - start = BYTE_TO_CHAR (start_byte); - TEMP_SET_PT_BOTH (start, start_byte); - return 0; - } - cursor = nl + 1; - } - while (cursor < ceiling_addr); - - start_byte += ceiling_addr - base; - } - } + charpos = find_newline (start, start_byte, limit, limit_byte, + count, &shortage, &bytepos, allow_quit); + if (shortage) + TEMP_SET_PT_BOTH (limit, limit_byte); else - { - while (start_byte > limit_byte) - { - ceiling = BUFFER_FLOOR_OF (start_byte - 1); - ceiling = max (limit_byte, ceiling); - ceiling_addr = BYTE_POS_ADDR (ceiling); - base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); - while (1) - { - unsigned char *nl = memrchr (ceiling_addr, '\n', - cursor - ceiling_addr); - if (! nl) - break; - - if (++count == 0) - { - immediate_quit = old_immediate_quit; - /* Return the position AFTER the match we found. */ - start_byte += nl - base + 1; - start = BYTE_TO_CHAR (start_byte); - TEMP_SET_PT_BOTH (start, start_byte); - return 0; - } - - cursor = nl; - } - start_byte += ceiling_addr - base; - } - } - - TEMP_SET_PT_BOTH (limit, limit_byte); - immediate_quit = old_immediate_quit; - - return count * direction; + TEMP_SET_PT_BOTH (charpos, bytepos); + return shortage; } /* Like find_newline, but doesn't allow QUITting and doesn't return -- 2.39.2