/* GNU Emacs routines to deal with syntax tables; also word and list parsing.
- Copyright (C) 1985, 1987, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU Emacs.
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include "config.h"
+#include <config.h>
#include <ctype.h>
#include "lisp.h"
#include "commands.h"
return find_start_value;
/* Back up to start of line. */
- tem = scan_buffer ('\n', pos, -1, &shortage);
+ tem = scan_buffer ('\n', pos, BEGV, -1, &shortage, 1);
while (tem > BEGV)
{
if (SYNTAX (FETCH_CHAR (tem)) == Sopen)
break;
/* Move to beg of previous line. */
- tem = scan_buffer ('\n', tem, -2, &shortage);
+ tem = scan_buffer ('\n', tem, BEGV, -2, &shortage, 1);
}
/* Record what we found, for the next try. */
(obj)
Lisp_Object obj;
{
- if (XTYPE (obj) == Lisp_Vector && XVECTOR (obj)->size == 0400)
+ if (VECTORP (obj) && XVECTOR (obj)->size == 0400)
return Qt;
return Qnil;
}
Lisp_Object table;
{
Lisp_Object size, val;
- XFASTINT (size) = 0400;
- XFASTINT (val) = 0;
+ XSETFASTINT (size, 0400);
+ XSETFASTINT (val, 0);
val = Fmake_vector (size, val);
if (!NILP (table))
table = check_syntax_table (table);
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377,
(char) Scomment, 0377, (char) Sendcomment, 0377,
- 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* @, A, ... */
+ (char) Sinherit, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* @, A ... */
0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,
0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol,
/* Indexed by syntax code, give the letter that describes it. */
-char syntax_code_spec[13] =
+char syntax_code_spec[14] =
{
- ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
+ ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>', '@'
};
\f
DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
Lisp_Object ch;
{
CHECK_NUMBER (ch, 0);
- return make_number (syntax_code_spec[(int) SYNTAX (0xFF & XINT (ch))]);
+ return make_number (syntax_code_spec[(int) SYNTAX (XINT (ch))]);
+}
+
+DEFUN ("matching-paren", Fmatching_paren, Smatching_paren, 1, 1, 0,
+ "Return the matching parenthesis of CHAR, or nil if none.")
+ (ch)
+ Lisp_Object ch;
+{
+ int code;
+ CHECK_NUMBER (ch, 0);
+ code = SYNTAX (XINT (ch));
+ if (code == Sopen || code == Sclose)
+ return make_number (SYNTAX_MATCH (XINT (ch)));
+ return Qnil;
}
/* This comment supplies the doc string for modify-syntax-entry,
( open-parenthesis. ) close-parenthesis.\n\
\" string quote. \\ escape.\n\
$ paired delimiter. ' expression quote or prefix operator.\n\
- < comment starter. > comment ender.\n\
- / character-quote.\n\
+ < comment starter. > comment ender.\n\
+ / character-quote. @ inherit from `standard-syntax-table'.\n\
+\n\
Only single-character comment start and end sequences are represented thus.\n\
Two-character sequences are represented as described below.\n\
The second character of S is the matching parenthesis,\n\
\n\
There can be up to two orthogonal comment sequences. This is to support\n\
language modes such as C++. By default, all comment sequences are of style\n\
-a, but you can set the comment sequence style to b (on the second character of a\n\
-comment-start, or the first character of a comment-end sequence) by using\n\
+a, but you can set the comment sequence style to b (on the second character\n\
+of a comment-start, or the first character of a comment-end sequence) using\n\
this flag:\n\
b means C is part of comment sequence b.\n\
\n\
{
register unsigned char *p, match;
register enum syntaxcode code;
- Lisp_Object val;
+ int val;
CHECK_NUMBER (c, 0);
CHECK_STRING (newentry, 1);
if (match) p++;
if (match == ' ') match = 0;
- XFASTINT (val) = (match << 8) + (int) code;
+ val = (match << 8) + (int) code;
while (*p)
switch (*p++)
{
case '1':
- XFASTINT (val) |= 1 << 16;
+ val |= 1 << 16;
break;
case '2':
- XFASTINT (val) |= 1 << 17;
+ val |= 1 << 17;
break;
case '3':
- XFASTINT (val) |= 1 << 18;
+ val |= 1 << 18;
break;
case '4':
- XFASTINT (val) |= 1 << 19;
+ val |= 1 << 19;
break;
case 'p':
- XFASTINT (val) |= 1 << 20;
+ val |= 1 << 20;
break;
case 'b':
- XFASTINT (val) |= 1 << 21;
+ val |= 1 << 21;
break;
}
- XVECTOR (syntax_table)->contents[0xFF & XINT (c)] = val;
+ XSETFASTINT (XVECTOR (syntax_table)->contents[0xFF & XINT (c)], val);
return Qnil;
}
Findent_to (make_number (16), make_number (1));
- if (XTYPE (value) != Lisp_Int)
+ if (!INTEGERP (value))
{
insert_string ("invalid");
return;
insert_string ("\twhich means: ");
-#ifdef SWITCH_ENUM_BUG
- switch ((int) code)
-#else
- switch (code)
-#endif
+ switch (SWITCH_ENUM_CAST (code))
{
case Swhitespace:
insert_string ("whitespace"); break;
insert_string ("comment"); break;
case Sendcomment:
insert_string ("endcomment"); break;
+ case Sinherit:
+ insert_string ("inherit"); break;
default:
insert_string ("invalid");
return;
struct buffer *old = current_buffer;
set_buffer_internal (XBUFFER (Vstandard_output));
describe_vector (vector, Qnil, describe_syntax, 0, Qnil);
+ call0 (intern ("help-mode"));
set_buffer_internal (old);
return Qnil;
}
while (count1 > 0)
{
stop = ZV;
- while (from < stop)
+ do
{
+ if (from == stop)
+ {
+ SET_PT (from);
+ immediate_quit = 0;
+ return Qnil;
+ }
c = FETCH_CHAR (from);
code = SYNTAX (c);
from++;
if (from < stop && SYNTAX_COMSTART_FIRST (c)
&& SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)))
{
- /* we have encountered a comment start sequence and we
- are ignoring all text inside comments. we must record
+ /* We have encountered a comment start sequence and we
+ are ignoring all text inside comments. We must record
the comment style this sequence begins so that later,
only a comment end of the same style actually ends
- the comment section */
+ the comment section. */
code = Scomment;
comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from));
from++;
}
-
- if (code == Scomment)
- {
- while (1)
- {
- if (from == stop)
- {
- immediate_quit = 0;
- SET_PT (from);
- return Qnil;
- }
- c = FETCH_CHAR (from);
- if (SYNTAX (c) == Sendcomment
- && SYNTAX_COMMENT_STYLE (c) == comstyle)
- /* we have encountered a comment end of the same style
- as the comment sequence which began this comment
- section */
- break;
- from++;
- if (from < stop && SYNTAX_COMEND_FIRST (c)
- && SYNTAX_COMEND_SECOND (FETCH_CHAR (from))
- && SYNTAX_COMMENT_STYLE (c) == comstyle)
- /* we have encountered a comment end of the same style
- as the comment sequence which began this comment
- section */
- { from++; break; }
- }
- /* We have skipped one comment. */
- break;
- }
- else if (code != Swhitespace && code != Sendcomment)
+ }
+ while (code == Swhitespace || code == Sendcomment);
+ if (code != Scomment)
+ {
+ immediate_quit = 0;
+ SET_PT (from - 1);
+ return Qnil;
+ }
+ /* We're at the start of a comment. */
+ while (1)
+ {
+ if (from == stop)
{
immediate_quit = 0;
- SET_PT (from - 1);
+ SET_PT (from);
return Qnil;
}
+ c = FETCH_CHAR (from);
+ from++;
+ if (SYNTAX (c) == Sendcomment
+ && SYNTAX_COMMENT_STYLE (c) == comstyle)
+ /* we have encountered a comment end of the same style
+ as the comment sequence which began this comment
+ section */
+ break;
+ if (from < stop && SYNTAX_COMEND_FIRST (c)
+ && SYNTAX_COMEND_SECOND (FETCH_CHAR (from))
+ && SYNTAX_COMMENT_STYLE (c) == comstyle)
+ /* we have encountered a comment end of the same style
+ as the comment sequence which began this comment
+ section */
+ { from++; break; }
}
-
- /* End of comment reached */
+ /* We have skipped one comment. */
count1--;
}
c = FETCH_CHAR (from);
code = SYNTAX (c);
comstyle = 0;
+ if (code == Sendcomment)
+ comstyle = SYNTAX_COMMENT_STYLE (c);
if (from > stop && SYNTAX_COMEND_SECOND (c)
&& SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1))
&& !char_quoted (from - 1))
{
- /* we must record the comment style encountered so that
+ /* We must record the comment style encountered so that
later, we can match only the proper comment begin
- sequence of the same style */
+ sequence of the same style. */
code = Sendcomment;
comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from - 1));
from--;
int comment_end = from;
int comstart_pos = 0;
int comstart_parity = 0;
+ int scanstart = from - 1;
/* At beginning of range to scan, we're outside of strings;
that determines quote parity to the comment-end. */
{
code = Sendcomment;
from--;
+ c = FETCH_CHAR (from);
}
- else if (from > stop && SYNTAX_COMSTART_SECOND (c)
- && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
- && comstyle == SYNTAX_COMMENT_STYLE (c))
- {
- code = Scomment;
- from--;
- }
+ /* 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;
/* Ignore escaped characters. */
if (char_quoted (from))
from = comment_end;
}
}
+ /* We have skipped one comment. */
+ break;
}
else if ((code != Swhitespace && code != Scomment) || quoted)
{
if (SYNTAX_PREFIX (c))
continue;
-#ifdef SWITCH_ENUM_BUG
- switch ((int) code)
-#else
- switch (code)
-#endif
+ switch (SWITCH_ENUM_CAST (code))
{
case Sescape:
case Scharquote:
/* This word counts as a sexp; return at end of it. */
while (from < stop)
{
-#ifdef SWITCH_ENUM_BUG
- switch ((int) SYNTAX (FETCH_CHAR (from)))
-#else
- switch (SYNTAX (FETCH_CHAR (from)))
-#endif
+ switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from))))
{
case Scharquote:
case Sescape:
if (!parse_sexp_ignore_comments) break;
while (1)
{
- if (from == stop) goto done;
+ if (from == stop)
+ {
+ if (depth == 0)
+ goto done;
+ goto lose;
+ }
c = FETCH_CHAR (from);
if (SYNTAX (c) == Sendcomment
&& SYNTAX_COMMENT_STYLE (c) == comstyle)
{
if (from >= stop) goto lose;
if (FETCH_CHAR (from) == stringterm) break;
-#ifdef SWITCH_ENUM_BUG
- switch ((int) SYNTAX (FETCH_CHAR (from)))
-#else
- switch (SYNTAX (FETCH_CHAR (from)))
-#endif
+ switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from))))
{
case Scharquote:
case Sescape:
from--;
c = FETCH_CHAR (from);
code = SYNTAX (c);
+ comstyle = 0;
+ if (code == Sendcomment)
+ comstyle = SYNTAX_COMMENT_STYLE (c);
if (from > stop && SYNTAX_COMEND_SECOND (c)
&& SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1))
&& !char_quoted (from - 1)
if (SYNTAX_PREFIX (c))
continue;
-#ifdef SWITCH_ENUM_BUG
- switch ((int) (quoted ? Sword : code))
-#else
- switch (quoted ? Sword : code)
-#endif
+ switch (SWITCH_ENUM_CAST (quoted ? Sword : code))
{
case Sword:
case Ssymbol:
if (SYNTAX (c = FETCH_CHAR (from)) == Scomment
&& SYNTAX_COMMENT_STYLE (c) == comstyle)
break;
- if (from == stop) goto done;
+ if (from == stop)
+ {
+ if (depth == 0)
+ goto done2;
+ goto lose;
+ }
from--;
if (SYNTAX_COMSTART_SECOND (c)
&& SYNTAX_COMSTART_FIRST (FETCH_CHAR (from))
int comment_end = from;
int comstart_pos = 0;
int comstart_parity = 0;
+ int scanstart = from - 1;
/* At beginning of range to scan, we're outside of strings;
that determines quote parity to the comment-end. */
{
code = Sendcomment;
from--;
+ c = FETCH_CHAR (from);
}
- else if (from > stop && SYNTAX_COMSTART_SECOND (c)
- && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
- && comstyle == SYNTAX_COMMENT_STYLE (c))
- {
- code = Scomment;
- from--;
- }
+ /* 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;
/* Ignore escaped characters. */
if (char_quoted (from))
immediate_quit = 0;
- XFASTINT (val) = from;
+ XSETFASTINT (val, from);
return val;
lose:
style a. if it is non-nil, we are in comment style b */
oldstate = Fcdr (oldstate);
oldstate = Fcdr (oldstate);
- oldstate = Fcdr (oldstate);
tem = Fcar (oldstate);
state.comstyle = !NILP (tem);
}
if (SYNTAX_PREFIX (FETCH_CHAR (from - 1)))
continue;
-#ifdef SWITCH_ENUM_BUG
- switch ((int) code)
-#else
- switch (code)
-#endif
+ switch (SWITCH_ENUM_CAST (code))
{
case Sescape:
case Scharquote:
symstarted:
while (from < end)
{
-#ifdef SWITCH_ENUM_BUG
- switch ((int) SYNTAX (FETCH_CHAR (from)))
-#else
- switch (SYNTAX (FETCH_CHAR (from)))
-#endif
+ switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from))))
{
case Scharquote:
case Sescape:
curlevel->prev = curlevel->last;
break;
+ startincomment:
+ if (commentstop)
+ goto done;
+ if (from != BEGV)
+ {
+ /* 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 (from - 1);
+ goto startincomment_1;
+ }
+ /* At beginning of buffer, enter the loop the ordinary way. */
+
case Scomment:
state.incomment = 1;
- startincomment:
if (commentstop)
goto done;
while (1)
encountered. */
break;
from++;
+ startincomment_1:
if (from < end && SYNTAX_COMEND_FIRST (prev)
&& SYNTAX_COMEND_SECOND (FETCH_CHAR (from))
&& SYNTAX_COMMENT_STYLE (prev) == state.comstyle)
{
if (from >= end) goto done;
if (FETCH_CHAR (from) == state.instring) break;
-#ifdef SWITCH_ENUM_BUG
- switch ((int) SYNTAX (FETCH_CHAR (from)))
-#else
- switch (SYNTAX (FETCH_CHAR (from)))
-#endif
+ switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from))))
{
case Scharquote:
case Sescape:
If fifth arg STATE is omitted or nil,\n\
parsing assumes that FROM is the beginning of a function.\n\
Value is a list of eight elements describing final state of parsing:\n\
- 1. depth in parens.\n\
- 2. character address of start of innermost containing list; nil if none.\n\
- 3. character address of start of last complete sexp terminated.\n\
- 4. non-nil if inside a string.\n\
+ 0. depth in parens.\n\
+ 1. character address of start of innermost containing list; nil if none.\n\
+ 2. character address of start of last complete sexp terminated.\n\
+ 3. non-nil if inside a string.\n\
(it is the character that will terminate the string.)\n\
- 5. t if inside a comment.\n\
- 6. t if following a quote character.\n\
- 7. the minimum paren-depth encountered during this scan.\n\
- 8. t if in a comment of style `b'.\n\
+ 4. t if inside a comment.\n\
+ 5. t if following a quote character.\n\
+ 6. the minimum paren-depth encountered during this scan.\n\
+ 7. t if in a comment of style `b'.\n\
If third arg TARGETDEPTH is non-nil, parsing stops if the depth\n\
in parentheses becomes equal to TARGETDEPTH.\n\
Fourth arg STOPBEFORE non-nil means stop when come to\n\
any character that starts a sexp.\n\
-Fifth arg STATE is a seven-list like what this function returns.\n\
+Fifth arg STATE is an eight-list like what this function returns.\n\
It is used to initialize the state of the parse. Its second and third
elements are ignored.
Sixth args COMMENTSTOP non-nil means stop at the start of a comment.")
v = XVECTOR (Vstandard_syntax_table);
for (i = 'a'; i <= 'z'; i++)
- XFASTINT (v->contents[i]) = (int) Sword;
+ XSETFASTINT (v->contents[i], (int) Sword);
for (i = 'A'; i <= 'Z'; i++)
- XFASTINT (v->contents[i]) = (int) Sword;
+ XSETFASTINT (v->contents[i], (int) Sword);
for (i = '0'; i <= '9'; i++)
- XFASTINT (v->contents[i]) = (int) Sword;
- XFASTINT (v->contents['$']) = (int) Sword;
- XFASTINT (v->contents['%']) = (int) Sword;
-
- XFASTINT (v->contents['(']) = (int) Sopen + (')' << 8);
- XFASTINT (v->contents[')']) = (int) Sclose + ('(' << 8);
- XFASTINT (v->contents['[']) = (int) Sopen + (']' << 8);
- XFASTINT (v->contents[']']) = (int) Sclose + ('[' << 8);
- XFASTINT (v->contents['{']) = (int) Sopen + ('}' << 8);
- XFASTINT (v->contents['}']) = (int) Sclose + ('{' << 8);
- XFASTINT (v->contents['"']) = (int) Sstring;
- XFASTINT (v->contents['\\']) = (int) Sescape;
+ XSETFASTINT (v->contents[i], (int) Sword);
+ XSETFASTINT (v->contents['$'], (int) Sword);
+ XSETFASTINT (v->contents['%'], (int) Sword);
+
+ XSETFASTINT (v->contents['('], (int) Sopen + (')' << 8));
+ XSETFASTINT (v->contents[')'], (int) Sclose + ('(' << 8));
+ XSETFASTINT (v->contents['['], (int) Sopen + (']' << 8));
+ XSETFASTINT (v->contents[']'], (int) Sclose + ('[' << 8));
+ XSETFASTINT (v->contents['{'], (int) Sopen + ('}' << 8));
+ XSETFASTINT (v->contents['}'], (int) Sclose + ('{' << 8));
+ XSETFASTINT (v->contents['"'], (int) Sstring);
+ XSETFASTINT (v->contents['\\'], (int) Sescape);
for (i = 0; i < 10; i++)
- XFASTINT (v->contents["_-+*/&|<>="[i]]) = (int) Ssymbol;
+ XSETFASTINT (v->contents["_-+*/&|<>="[i]], (int) Ssymbol);
for (i = 0; i < 12; i++)
- XFASTINT (v->contents[".,;:?!#@~^'`"[i]]) = (int) Spunct;
+ XSETFASTINT (v->contents[".,;:?!#@~^'`"[i]], (int) Spunct);
}
syms_of_syntax ()
defsubr (&Scopy_syntax_table);
defsubr (&Sset_syntax_table);
defsubr (&Schar_syntax);
+ defsubr (&Smatching_paren);
defsubr (&Smodify_syntax_entry);
defsubr (&Sdescribe_syntax);