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-29 Dmitry Antipov <dmantipov@yandex.ru>
+
+ 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 <monnier@iro.umontreal.ca>
* eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically
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;
}
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
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;
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
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;
}
\f
DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2,
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,
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