/* GNU Emacs routines to deal with syntax tables; also word and list parsing.
- Copyright (C) 1985, 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1985, 87, 93, 94, 95, 1997 Free Software Foundation, Inc.
This file is part of GNU Emacs.
gl_state.current_syntax_table = tmp_table;
gl_state.old_prop = tmp_table;
- if (Fsyntax_table_p (tmp_table) == Qt)
+ if (EQ (Fsyntax_table_p (tmp_table), Qt))
{
gl_state.use_global = 0;
}
the search was not successful). */
static int
-back_comment (from, stop)
- int from, stop;
+back_comment (from, stop, comstyle)
+ int from, stop, comstyle;
{
/* Look back, counting the parity of string-quotes,
and recording the comment-starters seen.
int comstart_parity = 0;
int scanstart = from - 1;
register enum syntaxcode code;
- int c, comstyle = 0;
+ int c;
/* At beginning of range to scan, we're outside of strings;
that determines quote parity to the comment-end. */
/* If this char starts a 2-char comment start sequence,
treat it like a 1-char comment starter. */
- if (from < scanstart && SYNTAX_COMSTART_FIRST (c)
- && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from + 1))
- && comstyle == SYNTAX_COMMENT_STYLE (FETCH_CHAR (from + 1)))
- code = Scomment;
+ if (from < scanstart && SYNTAX_COMSTART_SECOND (c)
+ && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
+ && comstyle == SYNTAX_COMMENT_STYLE (c))
+ {
+ code = Scomment;
+ DEC_POS (from);
+ /* This is apparently the best we can do: */
+ UPDATE_SYNTAX_TABLE_BACKWARD (from);
+ c = FETCH_CHAR (from);
+ }
/* Ignore escaped characters. */
if (char_quoted (from))
Lisp_Object object;
{
if (CHAR_TABLE_P (object)
- && XCHAR_TABLE (object)->purpose == Qsyntax_table)
+ && EQ (XCHAR_TABLE (object)->purpose, Qsyntax_table))
return Qt;
return Qnil;
}
Lisp_Object obj;
{
if (!(CHAR_TABLE_P (obj)
- && XCHAR_TABLE (obj)->purpose == Qsyntax_table))
+ && EQ (XCHAR_TABLE (obj)->purpose, Qsyntax_table)))
wrong_type_argument (Qsyntax_table_p, obj);
}
char_int = XINT (character);
code = SYNTAX (char_int);
if (code == Sopen || code == Sclose)
- return make_number (SYNTAX_MATCH (char_int));
+ return SYNTAX_MATCH (char_int);
return Qnil;
}
p = XSTRING (newentry)->data;
code = (enum syntaxcode) syntax_spec_code[*p++];
if (((int) code & 0377) == 0377)
- error ("invalid syntax description letter: %c", c);
+ error ("invalid syntax description letter: %c", p[-1]);
if (code == Sinherit)
{
- SET_RAW_SYNTAX_ENTRY (syntax_table, c, Qnil);
+ SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), Qnil);
return Qnil;
}
/* Since we can't use a shared object, let's make a new one. */
newentry = Fcons (make_number (val), match);
- SET_RAW_SYNTAX_ENTRY (syntax_table, c, newentry);
+ SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), newentry);
return Qnil;
}
return;
}
- code = (enum syntaxcode) (first & 0377);
+ code = (enum syntaxcode) (XINT (first) & 0377);
start1 = (XINT (first) >> 16) & 1;
start2 = (XINT (first) >> 17) & 1;
end1 = (XINT (first) >> 18) & 1;
{
struct buffer *old = current_buffer;
set_buffer_internal (XBUFFER (Vstandard_output));
- describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil);
+ describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil, (int *) 0, 0);
while (! NILP (XCHAR_TABLE (vector)->parent))
{
vector = XCHAR_TABLE (vector)->parent;
insert_string ("\nThe parent syntax table is:");
- describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil);
+ describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil,
+ (int *) 0, 0);
}
call0 (intern ("help-mode"));
{
register unsigned char *p, *pend;
register unsigned int c;
+ register int ch;
unsigned char fastmap[0400];
+ /* If SYNTAXP is 0, STRING may contain multi-byte form of characters
+ of which codes don't fit in FASTMAP. In that case, we set the
+ first byte of multibyte form (i.e. base leading-code) in FASTMAP
+ and set the actual ranges of characters in CHAR_RANGES. In the
+ form "X-Y" of STRING, both X and Y must belong to the same
+ character set because a range striding across character sets is
+ meaningless. */
+ int *char_ranges
+ = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2);
+ int n_char_ranges = 0;
int negate = 0;
register int i;
+ int multibyte = !NILP (current_buffer->enable_multibyte_characters);
CHECK_STRING (string, 0);
while (p != pend)
{
- c = *p++;
+ c = *p;
+ if (multibyte)
+ {
+ ch = STRING_CHAR (p, pend - p);
+ p += BYTES_BY_CHAR_HEAD (*p);
+ }
+ else
+ {
+ ch = c;
+ p++;
+ }
if (syntaxp)
fastmap[syntax_spec_code[c]] = 1;
else
}
if (p != pend && *p == '-')
{
+ unsigned int ch2;
+
p++;
if (p == pend) break;
- while (c <= *p)
+ if (SINGLE_BYTE_CHAR_P (ch))
+ while (c <= *p)
+ {
+ fastmap[c] = 1;
+ c++;
+ }
+ else
{
- fastmap[c] = 1;
- c++;
+ 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;
}
- p++;
+ p += multibyte ? BYTES_BY_CHAR_HEAD (*p) : 1;
}
else
- fastmap[c] = 1;
+ {
+ fastmap[c] = 1;
+ if (!SINGLE_BYTE_CHAR_P (ch))
+ {
+ char_ranges[n_char_ranges++] = ch;
+ char_ranges[n_char_ranges++] = ch;
+ }
+ }
}
}
- /* If ^ was the first character, complement the fastmap. */
+ /* If ^ was the first character, complement the fastmap. In
+ addition, as all multibyte characters have possibility of
+ matching, set all entries for base leading codes, which is
+ harmless even if SYNTAXP is 1. */
if (negate)
for (i = 0; i < sizeof fastmap; i++)
- fastmap[i] ^= 1;
+ {
+ if (!multibyte || !BASE_LEADING_CODE_P (i))
+ fastmap[i] ^= 1;
+ else
+ fastmap[i] = 1;
+ }
{
int start_point = PT;
SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
if (forwardp)
{
- while (pos < XINT (lim)
- && fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+ if (multibyte)
{
- pos++;
- UPDATE_SYNTAX_TABLE_FORWARD (pos);
+ while (pos < XINT (lim)
+ && fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+ {
+ INC_POS (pos);
+ UPDATE_SYNTAX_TABLE_FORWARD (pos);
+ }
+ }
+ else
+ {
+ while (pos < XINT (lim)
+ && fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
+ {
+ pos++;
+ UPDATE_SYNTAX_TABLE_FORWARD (pos);
+ }
}
}
else
{
- while (pos > XINT (lim)
- && fastmap[(int) SYNTAX (FETCH_CHAR (pos - 1))])
+ if (multibyte)
{
- pos--;
- UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
+ while (pos > XINT (lim))
+ {
+ int savepos = pos;
+ DEC_POS (pos);
+ UPDATE_SYNTAX_TABLE_BACKWARD (pos);
+ if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+ {
+ pos = savepos;
+ break;
+ }
+ }
+ }
+ else
+ {
+ while (pos > XINT (lim))
+ {
+ pos--;
+ UPDATE_SYNTAX_TABLE_BACKWARD (pos);
+ if (!fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
+ {
+ pos++;
+ break;
+ }
+ }
}
}
}
{
if (forwardp)
{
- while (pos < XINT (lim) && fastmap[FETCH_CHAR (pos)])
- pos++;
+ if (multibyte)
+ while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos))])
+ {
+ if (!BASE_LEADING_CODE_P (c))
+ pos++;
+ else if (n_char_ranges)
+ {
+ /* We much check CHAR_RANGES for a multibyte
+ character. */
+ ch = FETCH_MULTIBYTE_CHAR (pos);
+ for (i = 0; i < n_char_ranges; i += 2)
+ if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1]))
+ break;
+ if (!(negate ^ (i < n_char_ranges)))
+ break;
+
+ INC_POS (pos);
+ }
+ else
+ {
+ if (!negate) break;
+ INC_POS (pos);
+ }
+ }
+ else
+ while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)])
+ pos++;
}
else
{
- while (pos > XINT (lim) && fastmap[FETCH_CHAR (pos - 1)])
- pos--;
+ if (multibyte)
+ while (pos > XINT (lim))
+ {
+ int savepos = pos;
+ DEC_POS (pos);
+ if (fastmap[(c = FETCH_BYTE (pos))])
+ {
+ if (!BASE_LEADING_CODE_P (c))
+ ;
+ else if (n_char_ranges)
+ {
+ /* We much check CHAR_RANGES for a multibyte
+ character. */
+ ch = FETCH_MULTIBYTE_CHAR (pos);
+ for (i = 0; i < n_char_ranges; i += 2)
+ if (ch >= char_ranges[i] && ch <= char_ranges[i + 1])
+ break;
+ if (!(negate ^ (i < n_char_ranges)))
+ {
+ pos = savepos;
+ break;
+ }
+ }
+ else
+ if (!negate)
+ {
+ pos = savepos;
+ break;
+ }
+ }
+ else
+ {
+ pos = savepos;
+ break;
+ }
+ }
+ else
+ while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)])
+ pos--;
}
}
+
+ if (multibyte
+ /* INC_POS or DEC_POS might have moved POS over LIM. */
+ && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))
+ pos = XINT (lim);
+
SET_PT (pos);
immediate_quit = 0;
comstyle = SYNTAX_COMMENT_STYLE (c1);
from = temp_pos;
}
+ if (from > stop && SYNTAX_COMSTART_SECOND (c)
+ && (c1 = FETCH_CHAR (temp_pos),
+ SYNTAX_COMSTART_FIRST (c1))
+ && !char_quoted (temp_pos))
+ {
+ /* We must record the comment style encountered so that
+ later, we can match only the proper comment begin
+ sequence of the same style. */
+ code = Scomment;
+ from = temp_pos;
+ }
if (code == Scomment_fence)
{
break;
}
#endif /* 0 */
- found = back_comment (from, stop);
+ found = back_comment (from, stop, comstyle);
if (found != -1) from = found;
#if 0
/* Look back, counting the parity of string-quotes,
break;
}
#endif /* 0 */
- found = back_comment (from, stop);
+ found = back_comment (from, stop, comstyle);
if (found != -1) from = found;
#if 0
/* Look back, counting the parity of string-quotes,
UPDATE_SYNTAX_TABLE_FORWARD (from);
code = SYNTAX (FETCH_CHAR (from));
INC_FROM;
+
if (code == Scomment)
state.comstr_start = prev_from;
-
- else if (code == Scomment_fence
- || (from < end && SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from))
- && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))))
+ else if (code == Scomment_fence)
{
/* Record the comment style we have entered so that only
the comment-end sequence of the same style actually
if (code != Scomment_fence) INC_FROM;
code = Scomment;
}
+ else if (from < end)
+ if (SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from)))
+ if (SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)))
+ /* Duplicate code to avoid a very complex if-expression
+ which causes trouble for the SGI compiler. */
+ {
+ /* Record the comment style we have entered so that only
+ the comment-end sequence of the same style actually
+ terminates the comment section. */
+ state.comstyle = ( code == Scomment_fence
+ ? ST_COMMENT_STYLE
+ : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)));
+ state.comstr_start = prev_from;
+ if (code != Scomment_fence) INC_FROM;
+ code = Scomment;
+ }
if (SYNTAX_PREFIX (FETCH_CHAR (prev_from)))
continue;
Qchar_table_extra_slots = intern ("char-table-extra-slots");
/* Create objects which can be shared among syntax tables. */
- Vsyntax_code_object = Fmake_vector (13, Qnil);
+ Vsyntax_code_object = Fmake_vector (make_number (13), Qnil);
for (i = 0; i < XVECTOR (Vsyntax_code_object)->size; i++)
XVECTOR (Vsyntax_code_object)->contents[i]
= Fcons (make_number (i), Qnil);