/* GNU Emacs routines to deal with syntax tables; also word and list parsing.
- Copyright (C) 1985, 87, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1985, 87, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
This file is part of GNU Emacs.
invalidate = 0;
if (NULL_INTERVAL_P (i))
return;
- gl_state.b_property = i->position - 1;
- gl_state.e_property = INTERVAL_LAST_POS (i);
+ /* interval_of () updates only ->position of the return value,
+ update the parents manually to speed up update_interval. */
+ while (!NULL_PARENT (i))
+ {
+ if (AM_RIGHT_CHILD (i))
+ i->parent->position = i->position
+ - LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */
+ - TOTAL_LENGTH (i->parent)
+ + LEFT_TOTAL_LENGTH (i->parent);
+ else
+ i->parent->position = i->position - LEFT_TOTAL_LENGTH (i)
+ + TOTAL_LENGTH (i);
+ i = i->parent;
+ }
+ i = gl_state.forward_i;
+ gl_state.b_property = i->position - 1 - gl_state.offset;
+ gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;
goto update;
}
oldi = i = count > 0 ? gl_state.forward_i : gl_state.backward_i;
invalidate = 0;
gl_state.right_ok = 1; /* Invalidate the other end. */
gl_state.forward_i = i;
- gl_state.e_property = INTERVAL_LAST_POS (i);
+ gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;
}
}
else if (charpos >= INTERVAL_LAST_POS (i)) /* Move right. */
invalidate = 0;
gl_state.left_ok = 1; /* Invalidate the other end. */
gl_state.backward_i = i;
- gl_state.b_property = i->position - 1;
+ gl_state.b_property = i->position - 1 - gl_state.offset;
}
}
else if (count > 0 ? gl_state.right_ok : gl_state.left_ok)
{
gl_state.backward_i = i;
gl_state.left_ok = 1; /* Invalidate the other end. */
- gl_state.b_property = i->position - 1;
+ gl_state.b_property = i->position - 1 - gl_state.offset;
}
else
{
gl_state.forward_i = i;
gl_state.right_ok = 1; /* Invalidate the other end. */
- gl_state.e_property = INTERVAL_LAST_POS (i);
+ gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;
}
}
{
if (count > 0)
{
- gl_state.e_property = i->position;
+ gl_state.e_property = i->position - gl_state.offset;
gl_state.forward_i = i;
}
else
{
- gl_state.b_property = i->position + LENGTH (i) - 1;
+ gl_state.b_property = i->position + LENGTH (i) - 1 - gl_state.offset;
gl_state.backward_i = i;
}
}
inc_bytepos (bytepos)
int bytepos;
{
+ if (NILP (current_buffer->enable_multibyte_characters))
+ return bytepos + 1;
+
INC_POS (bytepos);
return bytepos;
}
dec_bytepos (bytepos)
int bytepos;
{
+ if (NILP (current_buffer->enable_multibyte_characters))
+ return bytepos - 1;
+
DEC_POS (bytepos);
return bytepos;
}
int comment_end = from;
int comment_end_byte = from_byte;
int comstart_pos = 0;
- int comstart_parity = 0;
int comstart_byte;
+ /* Value that PARITY had, when we reached the position
+ in COMSTART_POS. */
+ int comstart_parity = 0;
int scanstart = from - 1;
+ /* Place where the containing defun starts,
+ or 0 if we didn't come across it yet. */
+ int defun_start = 0;
+ int defun_start_byte = 0;
register enum syntaxcode code;
int c;
&& comstyle == SYNTAX_COMMENT_STYLE (FETCH_CHAR (temp_byte)))))
code = Scomment;
- /* Ignore escaped characters. */
- if (char_quoted (from, from_byte))
+ /* Ignore escaped characters, except comment-enders. */
+ if (code != Sendcomment && char_quoted (from, from_byte))
continue;
/* Track parity of quotes. */
&& (from == stop
|| (temp_byte = dec_bytepos (from_byte),
FETCH_CHAR (temp_byte) == '\n')))
- break;
+ {
+ defun_start = from;
+ defun_start_byte = from_byte;
+ break;
+ }
}
if (comstart_pos == 0)
to the one in question; this records where we
last passed a comment starter. */
struct lisp_parse_state state;
+ /* If we did not already find the defun start, find it now. */
+ if (defun_start == 0)
+ {
+ defun_start = find_defun_start (comment_end, comment_end_byte);
+ defun_start_byte = find_start_value_byte;
+ }
scan_sexps_forward (&state,
- find_defun_start (comment_end, comment_end_byte),
- find_start_value_byte,
+ defun_start, defun_start_byte,
comment_end - 1, -10000, 0, Qnil, 0);
if (state.incomment)
{
If that many words cannot be found before the end of the buffer, return 0.
COUNT negative means scan backward and stop at word beginning. */
+int
scan_words (from, count)
register int from, count;
{
int *char_ranges;
int n_char_ranges = 0;
int negate = 0;
- register int i;
+ register int i, i_byte;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
+ int string_multibyte = STRING_MULTIBYTE (string);
CHECK_STRING (string, 0);
char_ranges = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2);
if (XINT (lim) < BEGV)
XSETFASTINT (lim, BEGV);
- p = XSTRING (string)->data;
- pend = p + XSTRING (string)->size;
bzero (fastmap, sizeof fastmap);
- if (p != pend && *p == '^')
+ i = 0, i_byte = 0;
+
+ if (i < XSTRING (string)->size
+ && XSTRING (string)->data[0] == '^')
{
- negate = 1; p++;
+ negate = 1; i++, i_byte++;
}
/* Find the characters specified and set their elements of fastmap.
If syntaxp, each character counts as itself.
Otherwise, handle backslashes and ranges specially. */
- while (p != pend)
+ while (i < XSTRING (string)->size)
{
- c = *p;
- if (multibyte)
+ int c_leading_code;
+
+ if (string_multibyte)
{
- ch = STRING_CHAR (p, pend - p);
- p += BYTES_BY_CHAR_HEAD (*p);
+ c_leading_code = XSTRING (string)->data[i_byte];
+ FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
}
else
- {
- ch = c;
- p++;
- }
+ c = c_leading_code = XSTRING (string)->data[i++];
+
+ /* Convert multibyteness between what the string has
+ and what the buffer has. */
+ if (multibyte)
+ c = unibyte_char_to_multibyte (c);
+ else
+ c &= 0377;
+
if (syntaxp)
- fastmap[syntax_spec_code[c]] = 1;
+ fastmap[syntax_spec_code[c & 0377]] = 1;
else
{
if (c == '\\')
{
- if (p == pend) break;
- c = *p++;
+ if (i == XSTRING (string)->size)
+ break;
+
+ if (string_multibyte)
+ FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
+ else
+ c = XSTRING (string)->data[i++];
}
- if (p != pend && *p == '-')
+ if (i < XSTRING (string)->size && XSTRING (string)->data[i] == '-')
{
- unsigned int ch2;
+ unsigned int c2;
+
+ /* Skip over the dash. */
+ i++, i_byte++;
+
+ if (i == XSTRING (string)->size)
+ break;
+
+ /* Get the end of the range. */
+ if (string_multibyte)
+ FETCH_STRING_CHAR_ADVANCE (c2, string, i, i_byte);
+ else
+ c2 = XSTRING (string)->data[i++];
- p++;
- if (p == pend) break;
- if (SINGLE_BYTE_CHAR_P (ch))
- while (c <= *p)
+ if (SINGLE_BYTE_CHAR_P (c))
+ while (c <= c2)
{
fastmap[c] = 1;
c++;
}
else
{
- fastmap[c] = 1; /* C is the base leading-code. */
- ch2 = STRING_CHAR (p, pend - p);
- if (ch <= ch2)
- char_ranges[n_char_ranges++] = ch,
- char_ranges[n_char_ranges++] = ch2;
+ fastmap[c_leading_code] = 1;
+ if (c <= c2)
+ {
+ char_ranges[n_char_ranges++] = c;
+ char_ranges[n_char_ranges++] = c2;
+ }
}
- p += multibyte ? BYTES_BY_CHAR_HEAD (*p) : 1;
}
else
{
- fastmap[c] = 1;
- if (!SINGLE_BYTE_CHAR_P (ch))
+ fastmap[c_leading_code] = 1;
+ if (!SINGLE_BYTE_CHAR_P (c))
{
- char_ranges[n_char_ranges++] = ch;
- char_ranges[n_char_ranges++] = ch;
+ char_ranges[n_char_ranges++] = c;
+ char_ranges[n_char_ranges++] = c;
}
}
}
{
if (multibyte)
{
- while (pos < XINT (lim)
- && fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))])
- {
- INC_BOTH (pos, pos_byte);
- UPDATE_SYNTAX_TABLE_FORWARD (pos);
- }
+ if (pos < XINT (lim))
+ while (fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))])
+ {
+ /* Since we already checked for multibyteness,
+ avoid using INC_BOTH which checks again. */
+ INC_POS (pos_byte);
+ pos++;
+ if (pos >= XINT (lim))
+ break;
+ UPDATE_SYNTAX_TABLE_FORWARD (pos);
+ }
}
else
{
while (pos > XINT (lim))
{
int savepos = pos_byte;
- DEC_BOTH (pos, pos_byte);
+ /* Since we already checked for multibyteness,
+ avoid using DEC_BOTH which checks again. */
+ pos--;
+ DEC_POS (pos_byte);
UPDATE_SYNTAX_TABLE_BACKWARD (pos);
if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))])
{
}
else
{
- while (pos > XINT (lim))
- {
- pos--;
- UPDATE_SYNTAX_TABLE_BACKWARD (pos);
- if (!fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
- {
- pos++;
+ if (pos > XINT (lim))
+ while (fastmap[(int) SYNTAX (FETCH_BYTE (pos - 1))])
+ {
+ pos--;
+ if (pos <= XINT (lim))
break;
- }
- }
+ UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
+ }
}
}
}
{
if (from == stop)
{
- if (! NILP (current_buffer->enable_multibyte_characters))
- SET_PT_BOTH (from, from_byte);
- else
- SET_PT_BOTH (from_byte, from_byte);
+ SET_PT_BOTH (from, from_byte);
immediate_quit = 0;
return Qnil;
}
{
immediate_quit = 0;
DEC_BOTH (from, from_byte);
- if (! NILP (current_buffer->enable_multibyte_characters))
- SET_PT_BOTH (from, from_byte);
- else
- SET_PT_BOTH (from_byte, from_byte);
+ SET_PT_BOTH (from, from_byte);
return Qnil;
}
/* We're at the start of a comment. */
if (from == stop)
{
immediate_quit = 0;
- if (! NILP (current_buffer->enable_multibyte_characters))
- SET_PT_BOTH (from, from_byte);
- else
- SET_PT_BOTH (from_byte, from_byte);
+ SET_PT_BOTH (from, from_byte);
return Qnil;
}
UPDATE_SYNTAX_TABLE_FORWARD (from);
comstyle = 0;
if (code == Sendcomment)
comstyle = SYNTAX_COMMENT_STYLE (c);
- temp_pos = from_byte;
- DEC_POS (temp_pos);
+ temp_pos = dec_bytepos (from_byte);
if (from > stop && SYNTAX_COMEND_SECOND (c)
&& (c1 = FETCH_CHAR (temp_pos),
SYNTAX_COMEND_FIRST (c1))
leave:
immediate_quit = 0;
INC_BOTH (from, from_byte);
- if (! NILP (current_buffer->enable_multibyte_characters))
- SET_PT_BOTH (from, from_byte);
- else
- SET_PT_BOTH (from_byte, from_byte);
+ SET_PT_BOTH (from, from_byte);
return Qnil;
}
}
count1++;
}
- if (! NILP (current_buffer->enable_multibyte_characters))
- SET_PT_BOTH (from, from_byte);
- else
- SET_PT_BOTH (from_byte, from_byte);
+ SET_PT_BOTH (from, from_byte);
immediate_quit = 0;
return Qt;
}
case Sstring:
case Sstring_fence:
- temp_pos = from_byte;
- DEC_POS (temp_pos);
+ temp_pos = dec_bytepos (from_byte);
stringterm = FETCH_CHAR (temp_pos);
while (1)
{
{
DEC_BOTH (from, from_byte);
UPDATE_SYNTAX_TABLE_BACKWARD (from);
- if (quoted = char_quoted (from, from_byte))
- {
- DEC_BOTH (from, from_byte);
- UPDATE_SYNTAX_TABLE_BACKWARD (from);
- }
c = FETCH_CHAR (from_byte);
code = SYNTAX (c);
if (depth == min_depth)
if (code == Sendcomment)
comstyle = SYNTAX_COMMENT_STYLE (c);
temp_pos = from_byte;
- DEC_POS (temp_pos);
+ if (! NILP (current_buffer->enable_multibyte_characters))
+ DEC_POS (temp_pos);
+ else
+ temp_pos--;
if (from > stop && SYNTAX_COMEND_SECOND (c)
&& (c1 = FETCH_CHAR (temp_pos), SYNTAX_COMEND_FIRST (c1))
- && !char_quoted (from - 1, temp_pos)
&& parse_sexp_ignore_comments)
{
/* we must record the comment style encountered so that
DEC_BOTH (from, from_byte);
}
- if (SYNTAX_PREFIX (c))
+ /* Quoting turns anything except a comment-ender
+ into a word character. */
+ if (code != Sendcomment && char_quoted (from, from_byte))
+ code = Sword;
+ else if (SYNTAX_PREFIX (c))
continue;
- switch (SWITCH_ENUM_CAST (quoted ? Sword : code))
+ switch (SWITCH_ENUM_CAST (code))
{
case Sword:
case Ssymbol:
+ case Sescape:
+ case Scharquote:
if (depth || !sexpflag) break;
/* This word counts as a sexp; count object finished
after passing it. */
while (from > stop)
{
temp_pos = from_byte;
- DEC_POS (temp_pos);
+ if (! NILP (current_buffer->enable_multibyte_characters))
+ DEC_POS (temp_pos);
+ else
+ temp_pos--;
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
+ c1 = FETCH_CHAR (temp_pos);
+ temp_code = SYNTAX (c1);
+ /* Don't allow comment-end to be quoted. */
+ if (temp_code == Sendcomment)
+ goto done2;
quoted = char_quoted (from - 1, temp_pos);
if (quoted)
{
DEC_BOTH (from, from_byte);
- DEC_POS (temp_pos);
+ temp_pos = dec_bytepos (temp_pos);
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
}
c1 = FETCH_CHAR (temp_pos);
case Smath:
if (!sexpflag)
break;
- temp_pos = from_byte;
- DEC_POS (temp_pos);
+ temp_pos = dec_bytepos (from_byte);
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
if (from != stop && c == FETCH_CHAR (temp_pos))
DEC_BOTH (from, from_byte);
{
if (from == stop) goto lose;
temp_pos = from_byte;
- DEC_POS (temp_pos);
+ if (! NILP (current_buffer->enable_multibyte_characters))
+ DEC_POS (temp_pos);
+ else
+ temp_pos--;
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
if (!char_quoted (from - 1, temp_pos)
&& stringterm == FETCH_CHAR (temp_pos))
DEC_BOTH (pos, pos_byte);
- while (pos + 1 > beg && !char_quoted (pos, pos_byte)
+ while (!char_quoted (pos, pos_byte)
/* Previous statement updates syntax table. */
&& ((c = FETCH_CHAR (pos_byte), SYNTAX (c) == Squote)
|| SYNTAX_PREFIX (c)))
{
- DEC_BOTH (pos, pos_byte);
+ opoint = pos;
+ opoint_byte = pos_byte;
+
+ if (pos + 1 > beg)
+ DEC_BOTH (pos, pos_byte);
}
SET_PT_BOTH (opoint, opoint_byte);
Lisp_Object tem;
int prev_from; /* Keep one character before FROM. */
int prev_from_byte;
+ int prev_from_syntax;
int boundary_stop = commentstop == -1;
int nofence;
#define INC_FROM \
do { prev_from = from; \
prev_from_byte = from_byte; \
- from++; \
- INC_POS (from_byte); \
+ prev_from_syntax \
+ = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); \
+ INC_BOTH (from, from_byte); \
+ UPDATE_SYNTAX_TABLE_FORWARD (from); \
} while (0)
immediate_quit = 1;
QUIT;
- SETUP_SYNTAX_TABLE (from, 1);
-
if (NILP (oldstate))
{
depth = 0;
}
if (start_quoted) goto startquoted;
+
+ SETUP_SYNTAX_TABLE (prev_from, 1);
+ prev_from_syntax = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte));
+ UPDATE_SYNTAX_TABLE_FORWARD (from);
+
while (from < end)
{
- UPDATE_SYNTAX_TABLE_FORWARD (from);
- code = SYNTAX (FETCH_CHAR (from_byte));
INC_FROM;
+ code = prev_from_syntax & 0xff;
if (code == Scomment)
state.comstr_start = prev_from;
? ST_COMMENT_STYLE
: SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte)));
state.comstr_start = prev_from;
- if (code != Scomment_fence) INC_FROM;
+ if (code != Scomment_fence)
+ INC_FROM;
code = Scomment;
}
else if (from < end)
- if (SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from_byte)))
+ if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax))
if (SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte)))
- /* Duplicate code to avoid a very complex if-expression
+ /* Duplicate code to avoid a complex if-expression
which causes trouble for the SGI compiler. */
{
/* Record the comment style we have entered so that only
? ST_COMMENT_STYLE
: SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte)));
state.comstr_start = prev_from;
- if (code != Scomment_fence) INC_FROM;
+ if (code != Scomment_fence)
+ INC_FROM;
code = Scomment;
}
- if (SYNTAX_PREFIX (FETCH_CHAR (prev_from_byte)))
+ if (SYNTAX_FLAGS_PREFIX (prev_from_syntax))
continue;
switch (SWITCH_ENUM_CAST (code))
{
symstarted:
while (from < end)
{
- UPDATE_SYNTAX_TABLE_FORWARD (from);
switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from_byte))))
{
case Scharquote:
{
/* Enter the loop in the middle so that we find
a 2-char comment ender if we start in the middle of it. */
- prev = FETCH_CHAR (prev_from_byte);
goto startincomment_1;
}
/* At beginning of buffer, enter the loop the ordinary way. */
while (1)
{
if (from == end) goto done;
- UPDATE_SYNTAX_TABLE_FORWARD (from);
prev = FETCH_CHAR (from_byte);
if (SYNTAX (prev) == Sendcomment
&& SYNTAX_COMMENT_STYLE (prev) == state.comstyle)
break;
INC_FROM;
startincomment_1:
- if (from < end && SYNTAX_COMEND_FIRST (prev)
+ if (from < end && SYNTAX_FLAGS_COMEND_FIRST (prev_from_syntax)
&& SYNTAX_COMEND_SECOND (FETCH_CHAR (from_byte))
- && SYNTAX_COMMENT_STYLE (prev) == state.comstyle)
+ && (SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax)
+ == state.comstyle))
/* Only terminate the comment section if the end-comment
sequence of the same style as the start sequence has
been encountered. */
if (from >= end) goto done;
c = FETCH_CHAR (from_byte);
if (nofence && c == state.instring) break;
- UPDATE_SYNTAX_TABLE_FORWARD (from);
switch (SWITCH_ENUM_CAST (SYNTAX (c)))
{
case Sstring_fence:
Qnil)))))))));
}
\f
+void
init_syntax_once ()
{
register int i, c;
}
}
+void
syms_of_syntax ()
{
Qsyntax_table_p = intern ("syntax-table-p");