/* Routines to compute the current syntactic context, for font-lock mode.
Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
Copyright (C) 1995 Sun Microsystems, Inc.
+ Copyright (C) 2001 MORIOKA Tomohiko
This file is part of XEmacs.
context_none,
context_string,
context_comment,
- context_block_comment
+ context_block_comment,
+ context_generic_comment,
+ context_generic_string
};
enum block_comment_context
context_cache.style = comment_style_none;
context_cache.scontext = '\000';
context_cache.depth = 0;
+ /* #### shouldn't this be checking the character's syntax instead of
+ explicitly testing for backslash characters? */
context_cache.backslash_p = ((pt > 1) &&
(BUF_FETCH_CHAR (buf, pt - 1) == '\\'));
/* Note that the BOL context cache may not be at the beginning
/* OK, fine. */
return;
#if 0
- /* This appears to cause huge slowdowns in files like
- emacsfns.h, which have no top-level forms.
+ /* This appears to cause huge slowdowns in files which have no
+ top-level forms.
In any case, it's not really necessary that we know for
sure the top-level form we're in; if we're in a form
}
}
-#define SYNTAX_START_STYLE(table, c1, c2) \
- (SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
- comment_style_a : \
- SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
- comment_style_b : \
- comment_style_none)
-
-#define SYNTAX_END_STYLE(table, c1, c2) \
- (SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
+/* GCC 2.95.4 seems to need the casts */
+#define SYNTAX_START_STYLE(c1, c2) \
+ ((enum comment_style) \
+ (SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
comment_style_a : \
- SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
+ SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
comment_style_b : \
- comment_style_none)
-
-#define SINGLE_SYNTAX_STYLE(table, c) \
- (SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_A) ? \
- comment_style_a : \
- SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_B) ? \
- comment_style_b : \
- comment_style_none)
+ comment_style_none))
+
+#define SYNTAX_END_STYLE(c1, c2) \
+ ((enum comment_style) \
+ (SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
+ comment_style_a : \
+ SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
+ comment_style_b : \
+ comment_style_none))
+
+#define SINGLE_SYNTAX_STYLE(c) \
+ ((enum comment_style) \
+ (SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_A) ? \
+ comment_style_a : \
+ SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_B) ? \
+ comment_style_b : \
+ comment_style_none))
/* Set up context_cache for position PT in BUF. */
find_context (struct buffer *buf, Bufpos pt)
{
/* This function can GC */
+#ifndef emacs
+#ifdef UTF2000
+ Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->syntax_table);
+#else
Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
Lisp_Object syntaxtab = buf->syntax_table;
+#endif
Emchar prev_c, c;
+ int prev_syncode, syncode;
Bufpos target = pt;
setup_context_cache (buf, pt);
pt = context_cache.cur_point;
+ SCS_STATISTICS_SET_FUNCTION (scs_find_context);
+ SETUP_SYNTAX_CACHE (pt - 1, 1);
if (pt > BUF_BEGV (buf))
- c = BUF_FETCH_CHAR (buf, pt - 1);
+ {
+ c = BUF_FETCH_CHAR (buf, pt - 1);
+ syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c);
+ }
else
- c = '\n'; /* to get bol_context_cache at point-min */
+ {
+ c = '\n'; /* to get bol_context_cache at point-min */
+ syncode = Swhitespace;
+ }
for (; pt < target; pt++, context_cache.cur_point = pt)
{
}
}
+ UPDATE_SYNTAX_CACHE_FORWARD (pt);
prev_c = c;
+ prev_syncode = syncode;
c = BUF_FETCH_CHAR (buf, pt);
+ syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c);
if (prev_c == '\n')
bol_context_cache = context_cache;
continue;
}
- switch (SYNTAX (mirrortab, c))
+ switch (SYNTAX_FROM_CACHE (mirrortab, c))
{
case Sescape:
context_cache.backslash_p = 1;
{
context_cache.context = context_comment;
context_cache.ccontext = ccontext_none;
- context_cache.style = SINGLE_SYNTAX_STYLE (mirrortab, c);
- if (context_cache.style == comment_style_none) abort ();
+ context_cache.style = SINGLE_SYNTAX_STYLE (syncode);
+ if (context_cache.style == comment_style_none) ABORT ();
}
break;
case Sendcomment:
- if (context_cache.style != SINGLE_SYNTAX_STYLE (mirrortab, c))
+ if (context_cache.style != SINGLE_SYNTAX_STYLE (syncode))
;
else if (context_cache.context == context_comment)
{
}
else if (context_cache.context == context_none)
{
- Lisp_Object stringtermobj = syntax_match (syntaxtab, c);
+ Lisp_Object stringtermobj =
+ syntax_match (syntax_cache.current_syntax_table, c);
Emchar stringterm;
if (CHARP (stringtermobj))
}
break;
}
+
+ case Scomment_fence:
+ {
+ if (context_cache.context == context_generic_comment)
+ {
+ context_cache.context = context_none;
+ }
+ else if (context_cache.context == context_none)
+ {
+ context_cache.context = context_generic_comment;
+ context_cache.ccontext = ccontext_none;
+ }
+ break;
+ }
+
+ case Sstring_fence:
+ {
+ if (context_cache.context == context_generic_string)
+ {
+ context_cache.context = context_none;
+ }
+ else if (context_cache.context == context_none)
+ {
+ context_cache.context = context_generic_string;
+ context_cache.ccontext = ccontext_none;
+ }
+ break;
+ }
+
default:
;
}
Now we've got to hack multi-char sequences that start
and end block comments.
*/
- if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+ if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
SYNTAX_SECOND_CHAR_START) &&
context_cache.context == context_none &&
context_cache.ccontext == ccontext_start1 &&
- SYNTAX_START_P (mirrortab, prev_c, c) /* the two chars match */
+ SYNTAX_CODES_START_P (prev_syncode, syncode) /* the two chars match */
)
{
context_cache.ccontext = ccontext_start2;
- context_cache.style = SYNTAX_START_STYLE (mirrortab, prev_c, c);
- if (context_cache.style == comment_style_none) abort ();
+ context_cache.style = SYNTAX_START_STYLE (prev_syncode, syncode);
+ if (context_cache.style == comment_style_none) ABORT ();
}
- else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+ else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
SYNTAX_FIRST_CHAR_START) &&
context_cache.context == context_none &&
(context_cache.ccontext == ccontext_none ||
context_cache.ccontext = ccontext_start1;
context_cache.style = comment_style_none; /* should be this already*/
}
- else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+ else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
SYNTAX_SECOND_CHAR_END) &&
context_cache.context == context_block_comment &&
context_cache.ccontext == ccontext_end1 &&
- SYNTAX_END_P (mirrortab, prev_c, c) &&
+ SYNTAX_CODES_END_P (prev_syncode, syncode) &&
/* the two chars match */
context_cache.style ==
- SYNTAX_END_STYLE (mirrortab, prev_c, c)
+ SYNTAX_END_STYLE (prev_syncode, syncode)
)
{
context_cache.context = context_none;
context_cache.ccontext = ccontext_none;
context_cache.style = comment_style_none;
}
- else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+ else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
SYNTAX_FIRST_CHAR_END) &&
context_cache.context == context_block_comment &&
+#if 0
+ /* #### pre-Matt code had: */
(context_cache.style ==
- SYNTAX_END_STYLE (mirrortab, c,
- BUF_FETCH_CHAR (buf, pt+1))) &&
+ SYNTAX_END_STYLE (c, BUF_FETCH_CHAR (buf, pt+1))) &&
+ /* why do these differ here?! */
+#endif
+ context_cache.style == SINGLE_SYNTAX_STYLE (syncode) &&
(context_cache.ccontext == ccontext_start2 ||
context_cache.ccontext == ccontext_end1))
- /* #### is it right to check for end1 here?? */
+ /* check end1, to detect a repetition of the first char of a
+ comment-end sequence. ie, '/xxx foo xxx/' or '/xxx foo x/',
+ where 'x' = '*' -- mct */
{
- if (context_cache.style == comment_style_none) abort ();
+ if (context_cache.style == comment_style_none) ABORT ();
context_cache.ccontext = ccontext_end1;
}
else if (context_cache.ccontext == ccontext_start1)
{
- if (context_cache.context != context_none) abort ();
+ if (context_cache.context != context_none) ABORT ();
context_cache.ccontext = ccontext_none;
}
else if (context_cache.ccontext == ccontext_end1)
{
- if (context_cache.context != context_block_comment) abort ();
+ if (context_cache.context != context_block_comment) ABORT ();
context_cache.context = context_none;
context_cache.ccontext = ccontext_start2;
}
context_cache.context == context_none)
{
context_cache.context = context_block_comment;
- if (context_cache.style == comment_style_none) abort ();
+ if (context_cache.style == comment_style_none) ABORT ();
}
else if (context_cache.ccontext == ccontext_none &&
context_cache.context == context_block_comment)
{
switch (context)
{
- case context_none: return Qnil;
- case context_string: return Qstring;
- case context_comment: return Qcomment;
- case context_block_comment: return Qblock_comment;
- default: abort (); return Qnil; /* suppress compiler warning */
+ case context_none: return Qnil;
+ case context_string: return Qstring;
+ case context_comment: return Qcomment;
+ case context_block_comment: return Qblock_comment;
+ case context_generic_comment: return Qblock_comment;
+ case context_generic_string: return Qstring;
+ default: ABORT (); return Qnil; /* suppress compiler warning */
}
}
if (this_context == context_block_comment &&
context_cache.ccontext == ccontext_start2)
estart -= 2;
- else if (this_context == context_comment)
+ else if (this_context == context_comment
+ || this_context == context_generic_comment
+ )
estart -= 1;
edepth = context_cache.depth;
a part of the comment.
*/
if ((this_context == context_block_comment ||
- this_context == context_comment)
+ this_context == context_comment
+ || this_context == context_generic_comment
+ )
&& pt < e)
eend++;