mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-28 16:21:07 -08:00
Syntax cleanup, mostly replacing macros with functions.
This removes the need for the syntax_temp hack. * search.c: Include syntax.h after buffer.h, since syntax.h uses BVAR. * syntax.c (SYNTAX_INLINE): New macro. (SYNTAX_FLAGS_COMSTART_FIRST, SYNTAX_FLAGS_COMSTART_SECOND) (SYNTAX_FLAGS_COMEND_FIRST, SYNTAX_FLAGS_COMEND_SECOND) (SYNTAX_FLAGS_PREFIX, SYNTAX_FLAGS_COMMENT_STYLEB) (SYNTAX_FLAGS_COMMENT_STYLEC, SYNTAX_FLAGS_COMMENT_STYLEC2) (SYNTAX_FLAGS_COMMENT_NESTED, SYNTAX_FLAGS_COMMENT_STYLE) (SYNTAX_COMEND_FIRST): Now functions, not macros. (ST_COMMENT_STYLE, ST_STRING_STYLE, INTERVALS_AT_ONCE): Now constants, not macros. (syntax_temp) [!__GNUC__]: Remove. (SYNTAX_PREFIX): Remove; all uses replaced by syntax_prefix_flag_p. (syntax_prefix_flag_p): Move implementation of SYNTAX_PREFIX here. (SET_RAW_SYNTAX_ENTRY, SET_RAW_SYNTAX_ENTRY_RANGE, SYNTAX_MATCH) (SETUP_SYNTAX_TABLE, SETUP_SYNTAX_TABLE_FOR_OBJECT): Move here from syntax.h; now functions, not macros. Except for the last function, these are static since only syntax.c uses them. (syntax_multibyte): Rename from SYNTAX_WITH_MULTIBYTE_CHECK. All uses changed. Now a function, not a macro; use this fact to simplify the code. (scan_lists, scan_sexps_forward): Remove workarounds for ancient compiler bugs; no longer relevant. * syntax.h: Use INLINE_HEADER_BEGIN, INLINE_HEADER_END. (SYNTAX_INLINE): New macro. (struct gl_state_s, gl_state): Move earlier, so that it's in scope for the new functions. Use bool for boolean member. (SYNTAX_ENTRY, SYNTAX, SYNTAX_WITH_FLAGS, SYNTAX_MATCH) (SYNTAX_TABLE_BYTE_TO_CHAR, UPDATE_SYNTAX_TABLE_FORWARD) (UPDATE_SYNTAX_TABLE_BACKWARD, UPDATE_SYNTAX_TABLE) (SETUP_BUFFER_SYNTAX_TABLE): Now extern inline functions, not macros. (CURRENT_SYNTAX_TABLE, SYNTAX_ENTRY_INT): Remove; all uses replaced by implementation. (syntax_temp) [!__GNUC__]: Remove decl. (SETUP_SYNTAX_TABLE_FOR_OBJECT): New decl.
This commit is contained in:
parent
500dd7a35d
commit
45b683a16c
4 changed files with 357 additions and 293 deletions
|
|
@ -1,3 +1,43 @@
|
|||
2013-07-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Syntax cleanup, mostly replacing macros with functions.
|
||||
` This removes the need for the syntax_temp hack.
|
||||
* search.c: Include syntax.h after buffer.h, since syntax.h uses BVAR.
|
||||
* syntax.c (SYNTAX_INLINE): New macro.
|
||||
(SYNTAX_FLAGS_COMSTART_FIRST, SYNTAX_FLAGS_COMSTART_SECOND)
|
||||
(SYNTAX_FLAGS_COMEND_FIRST, SYNTAX_FLAGS_COMEND_SECOND)
|
||||
(SYNTAX_FLAGS_PREFIX, SYNTAX_FLAGS_COMMENT_STYLEB)
|
||||
(SYNTAX_FLAGS_COMMENT_STYLEC, SYNTAX_FLAGS_COMMENT_STYLEC2)
|
||||
(SYNTAX_FLAGS_COMMENT_NESTED, SYNTAX_FLAGS_COMMENT_STYLE)
|
||||
(SYNTAX_COMEND_FIRST): Now functions, not macros.
|
||||
(ST_COMMENT_STYLE, ST_STRING_STYLE, INTERVALS_AT_ONCE):
|
||||
Now constants, not macros.
|
||||
(syntax_temp) [!__GNUC__]: Remove.
|
||||
(SYNTAX_PREFIX): Remove; all uses replaced by syntax_prefix_flag_p.
|
||||
(syntax_prefix_flag_p): Move implementation of SYNTAX_PREFIX here.
|
||||
(SET_RAW_SYNTAX_ENTRY, SET_RAW_SYNTAX_ENTRY_RANGE, SYNTAX_MATCH)
|
||||
(SETUP_SYNTAX_TABLE, SETUP_SYNTAX_TABLE_FOR_OBJECT):
|
||||
Move here from syntax.h; now functions, not macros. Except for the
|
||||
last function, these are static since only syntax.c uses them.
|
||||
(syntax_multibyte): Rename from SYNTAX_WITH_MULTIBYTE_CHECK.
|
||||
All uses changed. Now a function, not a macro; use this fact
|
||||
to simplify the code.
|
||||
(scan_lists, scan_sexps_forward): Remove workarounds for ancient
|
||||
compiler bugs; no longer relevant.
|
||||
* syntax.h: Use INLINE_HEADER_BEGIN, INLINE_HEADER_END.
|
||||
(SYNTAX_INLINE): New macro.
|
||||
(struct gl_state_s, gl_state): Move earlier, so that it's in scope
|
||||
for the new functions. Use bool for boolean member.
|
||||
(SYNTAX_ENTRY, SYNTAX, SYNTAX_WITH_FLAGS, SYNTAX_MATCH)
|
||||
(SYNTAX_TABLE_BYTE_TO_CHAR, UPDATE_SYNTAX_TABLE_FORWARD)
|
||||
(UPDATE_SYNTAX_TABLE_BACKWARD, UPDATE_SYNTAX_TABLE)
|
||||
(SETUP_BUFFER_SYNTAX_TABLE):
|
||||
Now extern inline functions, not macros.
|
||||
(CURRENT_SYNTAX_TABLE, SYNTAX_ENTRY_INT):
|
||||
Remove; all uses replaced by implementation.
|
||||
(syntax_temp) [!__GNUC__]: Remove decl.
|
||||
(SETUP_SYNTAX_TABLE_FOR_OBJECT): New decl.
|
||||
|
||||
2013-07-10 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* emacs.c (main): Fix syntax error.
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include <config.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "syntax.h"
|
||||
#include "category.h"
|
||||
#include "character.h"
|
||||
#include "buffer.h"
|
||||
#include "syntax.h"
|
||||
#include "charset.h"
|
||||
#include "region-cache.h"
|
||||
#include "commands.h"
|
||||
|
|
|
|||
272
src/syntax.c
272
src/syntax.c
|
|
@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#define SYNTAX_INLINE EXTERN_INLINE
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lisp.h"
|
||||
|
|
@ -58,54 +60,86 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
For style c (like the nested flag), the flag can be placed on any of
|
||||
the chars. */
|
||||
|
||||
/* These macros extract specific flags from an integer
|
||||
/* These functions extract specific flags from an integer
|
||||
that holds the syntax code and the flags. */
|
||||
|
||||
#define SYNTAX_FLAGS_COMSTART_FIRST(flags) (((flags) >> 16) & 1)
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMSTART_FIRST (int flags)
|
||||
{
|
||||
return (flags >> 16) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMSTART_SECOND (int flags)
|
||||
{
|
||||
return (flags >> 17) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMEND_FIRST (int flags)
|
||||
{
|
||||
return (flags >> 18) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMEND_SECOND (int flags)
|
||||
{
|
||||
return (flags >> 19) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_PREFIX (int flags)
|
||||
{
|
||||
return (flags >> 20) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMMENT_STYLEB (int flags)
|
||||
{
|
||||
return (flags >> 21) & 1;
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMMENT_STYLEC (int flags)
|
||||
{
|
||||
return (flags >> 23) & 1;
|
||||
}
|
||||
static int
|
||||
SYNTAX_FLAGS_COMMENT_STYLEC2 (int flags)
|
||||
{
|
||||
return (flags >> 22) & 2; /* SYNTAX_FLAGS_COMMENT_STYLEC (flags) * 2 */
|
||||
}
|
||||
static bool
|
||||
SYNTAX_FLAGS_COMMENT_NESTED (int flags)
|
||||
{
|
||||
return (flags >> 22) & 1;
|
||||
}
|
||||
|
||||
#define SYNTAX_FLAGS_COMSTART_SECOND(flags) (((flags) >> 17) & 1)
|
||||
|
||||
#define SYNTAX_FLAGS_COMEND_FIRST(flags) (((flags) >> 18) & 1)
|
||||
|
||||
#define SYNTAX_FLAGS_COMEND_SECOND(flags) (((flags) >> 19) & 1)
|
||||
|
||||
#define SYNTAX_FLAGS_PREFIX(flags) (((flags) >> 20) & 1)
|
||||
|
||||
#define SYNTAX_FLAGS_COMMENT_STYLEB(flags) (((flags) >> 21) & 1)
|
||||
#define SYNTAX_FLAGS_COMMENT_STYLEC(flags) (((flags) >> 23) & 1)
|
||||
#define SYNTAX_FLAGS_COMMENT_STYLEC2(flags) (((flags) >> 22) & 2) /* C * 2 */
|
||||
/* FLAGS should be the flags of the main char of the comment marker, e.g.
|
||||
the second for comstart and the first for comend. */
|
||||
#define SYNTAX_FLAGS_COMMENT_STYLE(flags, other_flags) \
|
||||
(SYNTAX_FLAGS_COMMENT_STYLEB (flags) \
|
||||
| SYNTAX_FLAGS_COMMENT_STYLEC2 (flags) \
|
||||
| SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags))
|
||||
static int
|
||||
SYNTAX_FLAGS_COMMENT_STYLE (int flags, int other_flags)
|
||||
{
|
||||
return (SYNTAX_FLAGS_COMMENT_STYLEB (flags)
|
||||
| SYNTAX_FLAGS_COMMENT_STYLEC2 (flags)
|
||||
| SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags));
|
||||
}
|
||||
|
||||
#define SYNTAX_FLAGS_COMMENT_NESTED(flags) (((flags) >> 22) & 1)
|
||||
/* Extract a particular flag for a given character. */
|
||||
|
||||
/* These macros extract a particular flag for a given character. */
|
||||
|
||||
#define SYNTAX_COMEND_FIRST(c) \
|
||||
(SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c)))
|
||||
#define SYNTAX_PREFIX(c) (SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c)))
|
||||
static bool
|
||||
SYNTAX_COMEND_FIRST (int c)
|
||||
{
|
||||
return SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c));
|
||||
}
|
||||
|
||||
/* We use these constants in place for comment-style and
|
||||
string-ender-char to distinguish comments/strings started by
|
||||
string-ender-char to distinguish comments/strings started by
|
||||
comment_fence and string_fence codes. */
|
||||
|
||||
#define ST_COMMENT_STYLE (256 + 1)
|
||||
#define ST_STRING_STYLE (256 + 2)
|
||||
enum
|
||||
{
|
||||
ST_COMMENT_STYLE = 256 + 1,
|
||||
ST_STRING_STYLE = 256 + 2
|
||||
};
|
||||
|
||||
static Lisp_Object Qsyntax_table_p;
|
||||
static Lisp_Object Qsyntax_table, Qscan_error;
|
||||
|
||||
#ifndef __GNUC__
|
||||
/* Used as a temporary in SYNTAX_ENTRY and other macros in syntax.h,
|
||||
if not compiled with GCC. No need to mark it, since it is used
|
||||
only very temporarily. */
|
||||
Lisp_Object syntax_temp;
|
||||
#endif
|
||||
|
||||
/* This is the internal form of the parse state used in parse-partial-sexp. */
|
||||
|
||||
struct lisp_parse_state
|
||||
|
|
@ -162,14 +196,107 @@ bset_syntax_table (struct buffer *b, Lisp_Object val)
|
|||
bool
|
||||
syntax_prefix_flag_p (int c)
|
||||
{
|
||||
return SYNTAX_PREFIX (c);
|
||||
return SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c));
|
||||
}
|
||||
|
||||
struct gl_state_s gl_state; /* Global state of syntax parser. */
|
||||
|
||||
#define INTERVALS_AT_ONCE 10 /* 1 + max-number of intervals
|
||||
enum { INTERVALS_AT_ONCE = 10 }; /* 1 + max-number of intervals
|
||||
to scan to property-change. */
|
||||
|
||||
/* Set the syntax entry VAL for char C in table TABLE. */
|
||||
|
||||
static void
|
||||
SET_RAW_SYNTAX_ENTRY (Lisp_Object table, int c, Lisp_Object val)
|
||||
{
|
||||
CHAR_TABLE_SET (table, c, val);
|
||||
}
|
||||
|
||||
/* Set the syntax entry VAL for char-range RANGE in table TABLE.
|
||||
RANGE is a cons (FROM . TO) specifying the range of characters. */
|
||||
|
||||
static void
|
||||
SET_RAW_SYNTAX_ENTRY_RANGE (Lisp_Object table, Lisp_Object range,
|
||||
Lisp_Object val)
|
||||
{
|
||||
Fset_char_table_range (table, range, val);
|
||||
}
|
||||
|
||||
/* Extract the information from the entry for character C
|
||||
in the current syntax table. */
|
||||
|
||||
static Lisp_Object
|
||||
SYNTAX_MATCH (int c)
|
||||
{
|
||||
Lisp_Object ent = SYNTAX_ENTRY (c);
|
||||
return CONSP (ent) ? XCDR (ent) : Qnil;
|
||||
}
|
||||
|
||||
/* This should be called with FROM at the start of forward
|
||||
search, or after the last position of the backward search. It
|
||||
makes sure that the first char is picked up with correct table, so
|
||||
one does not need to call UPDATE_SYNTAX_TABLE immediately after the
|
||||
call.
|
||||
Sign of COUNT gives the direction of the search.
|
||||
*/
|
||||
|
||||
static void
|
||||
SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
|
||||
{
|
||||
SETUP_BUFFER_SYNTAX_TABLE ();
|
||||
gl_state.b_property = BEGV;
|
||||
gl_state.e_property = ZV + 1;
|
||||
gl_state.object = Qnil;
|
||||
gl_state.offset = 0;
|
||||
if (parse_sexp_lookup_properties)
|
||||
if (count > 0 || from > BEGV)
|
||||
update_syntax_table (count > 0 ? from : from - 1, count, 1, Qnil);
|
||||
}
|
||||
|
||||
/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
|
||||
If it is t (which is only used in fast_c_string_match_ignore_case),
|
||||
ignore properties altogether.
|
||||
|
||||
This is meant for regex.c to use. For buffers, regex.c passes arguments
|
||||
to the UPDATE_SYNTAX_TABLE functions which are relative to BEGV.
|
||||
So if it is a buffer, we set the offset field to BEGV. */
|
||||
|
||||
void
|
||||
SETUP_SYNTAX_TABLE_FOR_OBJECT (Lisp_Object object,
|
||||
ptrdiff_t from, ptrdiff_t count)
|
||||
{
|
||||
SETUP_BUFFER_SYNTAX_TABLE ();
|
||||
gl_state.object = object;
|
||||
if (BUFFERP (gl_state.object))
|
||||
{
|
||||
struct buffer *buf = XBUFFER (gl_state.object);
|
||||
gl_state.b_property = 1;
|
||||
gl_state.e_property = BUF_ZV (buf) - BUF_BEGV (buf) + 1;
|
||||
gl_state.offset = BUF_BEGV (buf) - 1;
|
||||
}
|
||||
else if (NILP (gl_state.object))
|
||||
{
|
||||
gl_state.b_property = 1;
|
||||
gl_state.e_property = ZV - BEGV + 1;
|
||||
gl_state.offset = BEGV - 1;
|
||||
}
|
||||
else if (EQ (gl_state.object, Qt))
|
||||
{
|
||||
gl_state.b_property = 0;
|
||||
gl_state.e_property = PTRDIFF_MAX;
|
||||
gl_state.offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_state.b_property = 0;
|
||||
gl_state.e_property = 1 + SCHARS (gl_state.object);
|
||||
gl_state.offset = 0;
|
||||
}
|
||||
if (parse_sexp_lookup_properties)
|
||||
update_syntax_table (from + gl_state.offset - (count <= 0),
|
||||
count, 1, gl_state.object);
|
||||
}
|
||||
|
||||
/* Update gl_state to an appropriate interval which contains CHARPOS. The
|
||||
sign of COUNT give the relative position of CHARPOS wrt the previously
|
||||
valid interval. If INIT, only [be]_property fields of gl_state are
|
||||
|
|
@ -1751,7 +1878,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
|
|||
}
|
||||
|
||||
immediate_quit = 1;
|
||||
/* This code may look up syntax tables using macros that rely on the
|
||||
/* This code may look up syntax tables using functions that rely on the
|
||||
gl_state object. To make sure this object is not out of date,
|
||||
let's initialize it manually.
|
||||
We ignore syntax-table text-properties for now, since that's
|
||||
|
|
@ -2426,11 +2553,13 @@ between them, return t; otherwise return nil. */)
|
|||
}
|
||||
|
||||
/* Return syntax code of character C if C is an ASCII character
|
||||
or `multibyte_symbol_p' is zero. Otherwise, return Ssymbol. */
|
||||
or if MULTIBYTE_SYMBOL_P is false. Otherwise, return Ssymbol. */
|
||||
|
||||
#define SYNTAX_WITH_MULTIBYTE_CHECK(c) \
|
||||
((ASCII_CHAR_P (c) || !multibyte_symbol_p) \
|
||||
? SYNTAX (c) : Ssymbol)
|
||||
static enum syntaxcode
|
||||
syntax_multibyte (int c, bool multibyte_symbol_p)
|
||||
{
|
||||
return ASCII_CHAR_P (c) || !multibyte_symbol_p ? SYNTAX (c) : Ssymbol;
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
||||
|
|
@ -2441,7 +2570,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
int stringterm;
|
||||
bool quoted;
|
||||
bool mathexit = 0;
|
||||
enum syntaxcode code, temp_code, c_code;
|
||||
enum syntaxcode code;
|
||||
EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */
|
||||
int comstyle = 0; /* style of comment encountered */
|
||||
bool comnested = 0; /* whether the comment is nestable or not */
|
||||
|
|
@ -2473,7 +2602,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
UPDATE_SYNTAX_TABLE_FORWARD (from);
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
syntax = SYNTAX_WITH_FLAGS (c);
|
||||
code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
|
||||
code = syntax_multibyte (c, multibyte_symbol_p);
|
||||
comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax);
|
||||
comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
|
||||
comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
|
||||
|
|
@ -2519,10 +2648,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
{
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (from);
|
||||
|
||||
/* Some compilers can't handle this inside the switch. */
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
|
||||
switch (c_code)
|
||||
switch (syntax_multibyte (c, multibyte_symbol_p))
|
||||
{
|
||||
case Scharquote:
|
||||
case Sescape:
|
||||
|
|
@ -2594,18 +2721,17 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
|
||||
while (1)
|
||||
{
|
||||
enum syntaxcode c_code;
|
||||
if (from >= stop)
|
||||
goto lose;
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (from);
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
c_code = syntax_multibyte (c, multibyte_symbol_p);
|
||||
if (code == Sstring
|
||||
? (c == stringterm
|
||||
&& SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
|
||||
: SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring_fence)
|
||||
? c == stringterm && c_code == Sstring
|
||||
: c_code == Sstring_fence)
|
||||
break;
|
||||
|
||||
/* Some compilers can't handle this inside the switch. */
|
||||
c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
|
||||
switch (c_code)
|
||||
{
|
||||
case Scharquote:
|
||||
|
|
@ -2644,7 +2770,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
UPDATE_SYNTAX_TABLE_BACKWARD (from);
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
syntax= SYNTAX_WITH_FLAGS (c);
|
||||
code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
|
||||
code = syntax_multibyte (c, multibyte_symbol_p);
|
||||
if (depth == min_depth)
|
||||
last_good = from;
|
||||
comstyle = 0;
|
||||
|
|
@ -2697,9 +2823,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
temp_pos--;
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
|
||||
c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
|
||||
temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
|
||||
/* Don't allow comment-end to be quoted. */
|
||||
if (temp_code == Sendcomment)
|
||||
if (syntax_multibyte (c1, multibyte_symbol_p) == Sendcomment)
|
||||
goto done2;
|
||||
quoted = char_quoted (from - 1, temp_pos);
|
||||
if (quoted)
|
||||
|
|
@ -2709,11 +2834,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
|
||||
}
|
||||
c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
|
||||
temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
|
||||
if (! (quoted || temp_code == Sword
|
||||
|| temp_code == Ssymbol
|
||||
|| temp_code == Squote))
|
||||
goto done2;
|
||||
if (! quoted)
|
||||
switch (syntax_multibyte (c1, multibyte_symbol_p))
|
||||
{
|
||||
case Sword: case Ssymbol: case Squote: break;
|
||||
default: goto done2;
|
||||
}
|
||||
DEC_BOTH (from, from_byte);
|
||||
}
|
||||
goto done2;
|
||||
|
|
@ -2768,10 +2894,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
goto lose;
|
||||
DEC_BOTH (from, from_byte);
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (from);
|
||||
if (!char_quoted (from, from_byte)
|
||||
&& (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
|
||||
SYNTAX_WITH_MULTIBYTE_CHECK (c) == code))
|
||||
break;
|
||||
if (!char_quoted (from, from_byte))
|
||||
{
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
if (syntax_multibyte (c, multibyte_symbol_p) == code)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code == Sstring_fence && !depth && sexpflag) goto done2;
|
||||
break;
|
||||
|
|
@ -2784,11 +2912,14 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
|
|||
goto lose;
|
||||
DEC_BOTH (from, from_byte);
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (from);
|
||||
if (!char_quoted (from, from_byte)
|
||||
&& (stringterm
|
||||
== (c = FETCH_CHAR_AS_MULTIBYTE (from_byte)))
|
||||
&& SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
|
||||
break;
|
||||
if (!char_quoted (from, from_byte))
|
||||
{
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
if (c == stringterm
|
||||
&& (syntax_multibyte (c, multibyte_symbol_p)
|
||||
== Sstring))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!depth && sexpflag) goto done2;
|
||||
break;
|
||||
|
|
@ -2894,7 +3025,7 @@ This includes chars with "quote" or "prefix" syntax (' or p). */)
|
|||
while (!char_quoted (pos, pos_byte)
|
||||
/* Previous statement updates syntax table. */
|
||||
&& ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote)
|
||||
|| SYNTAX_PREFIX (c)))
|
||||
|| syntax_prefix_flag_p (c)))
|
||||
{
|
||||
opoint = pos;
|
||||
opoint_byte = pos_byte;
|
||||
|
|
@ -3117,10 +3248,8 @@ do { prev_from = from; \
|
|||
symstarted:
|
||||
while (from < end)
|
||||
{
|
||||
/* Some compilers can't handle this inside the switch. */
|
||||
int symchar = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
enum syntaxcode symcharcode = SYNTAX (symchar);
|
||||
switch (symcharcode)
|
||||
switch (SYNTAX (symchar))
|
||||
{
|
||||
case Scharquote:
|
||||
case Sescape:
|
||||
|
|
@ -3206,7 +3335,6 @@ do { prev_from = from; \
|
|||
|
||||
if (from >= end) goto done;
|
||||
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
|
||||
/* Some compilers can't handle this inside the switch. */
|
||||
c_code = SYNTAX (c);
|
||||
|
||||
/* Check C_CODE here so that if the char has
|
||||
|
|
|
|||
336
src/syntax.h
336
src/syntax.h
|
|
@ -18,6 +18,10 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
INLINE_HEADER_BEGIN
|
||||
#ifndef SYNTAX_INLINE
|
||||
# define SYNTAX_INLINE INLINE
|
||||
#endif
|
||||
|
||||
extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object);
|
||||
|
||||
|
|
@ -54,232 +58,13 @@ enum syntaxcode
|
|||
Smax /* Upper bound on codes that are meaningful */
|
||||
};
|
||||
|
||||
/* Set the syntax entry VAL for char C in table TABLE. */
|
||||
|
||||
#define SET_RAW_SYNTAX_ENTRY(table, c, val) \
|
||||
CHAR_TABLE_SET ((table), c, (val))
|
||||
|
||||
/* Set the syntax entry VAL for char-range RANGE in table TABLE.
|
||||
RANGE is a cons (FROM . TO) specifying the range of characters. */
|
||||
|
||||
#define SET_RAW_SYNTAX_ENTRY_RANGE(table, range, val) \
|
||||
Fset_char_table_range ((table), (range), (val))
|
||||
|
||||
/* SYNTAX_ENTRY fetches the information from the entry for character C
|
||||
in syntax table TABLE, or from globally kept data (gl_state).
|
||||
Does inheritance. */
|
||||
/* CURRENT_SYNTAX_TABLE gives the syntax table valid for current
|
||||
position, it is either the buffer's syntax table, or syntax table
|
||||
found in text properties. */
|
||||
|
||||
#ifdef SYNTAX_ENTRY_VIA_PROPERTY
|
||||
# define SYNTAX_ENTRY(c) \
|
||||
(gl_state.use_global ? gl_state.global_code : SYNTAX_ENTRY_INT (c))
|
||||
# define CURRENT_SYNTAX_TABLE gl_state.current_syntax_table
|
||||
#else
|
||||
# define SYNTAX_ENTRY SYNTAX_ENTRY_INT
|
||||
# define CURRENT_SYNTAX_TABLE BVAR (current_buffer, syntax_table)
|
||||
#endif
|
||||
|
||||
#define SYNTAX_ENTRY_INT(c) CHAR_TABLE_REF (CURRENT_SYNTAX_TABLE, (c))
|
||||
|
||||
/* Extract the information from the entry for character C
|
||||
in the current syntax table. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SYNTAX(c) \
|
||||
({ Lisp_Object _syntax_temp; \
|
||||
_syntax_temp = SYNTAX_ENTRY (c); \
|
||||
(CONSP (_syntax_temp) \
|
||||
? (enum syntaxcode) (XINT (XCAR (_syntax_temp)) & 0xff) \
|
||||
: Swhitespace); })
|
||||
|
||||
#define SYNTAX_WITH_FLAGS(c) \
|
||||
({ Lisp_Object _syntax_temp; \
|
||||
_syntax_temp = SYNTAX_ENTRY (c); \
|
||||
(CONSP (_syntax_temp) \
|
||||
? XINT (XCAR (_syntax_temp)) \
|
||||
: Swhitespace); })
|
||||
|
||||
#define SYNTAX_MATCH(c) \
|
||||
({ Lisp_Object _syntax_temp; \
|
||||
_syntax_temp = SYNTAX_ENTRY (c); \
|
||||
(CONSP (_syntax_temp) \
|
||||
? XCDR (_syntax_temp) \
|
||||
: Qnil); })
|
||||
#else
|
||||
extern Lisp_Object syntax_temp;
|
||||
#define SYNTAX(c) \
|
||||
(syntax_temp = SYNTAX_ENTRY ((c)), \
|
||||
(CONSP (syntax_temp) \
|
||||
? (enum syntaxcode) (XINT (XCAR (syntax_temp)) & 0xff) \
|
||||
: Swhitespace))
|
||||
|
||||
#define SYNTAX_WITH_FLAGS(c) \
|
||||
(syntax_temp = SYNTAX_ENTRY ((c)), \
|
||||
(CONSP (syntax_temp) \
|
||||
? XINT (XCAR (syntax_temp)) \
|
||||
: Swhitespace))
|
||||
|
||||
#define SYNTAX_MATCH(c) \
|
||||
(syntax_temp = SYNTAX_ENTRY ((c)), \
|
||||
(CONSP (syntax_temp) \
|
||||
? XCDR (syntax_temp) \
|
||||
: Qnil))
|
||||
#endif
|
||||
|
||||
|
||||
/* Whether the syntax of the character C has the prefix flag set. */
|
||||
extern bool syntax_prefix_flag_p (int c);
|
||||
|
||||
/* This array, indexed by a character less than 256, contains the
|
||||
syntax code which that character signifies (as an unsigned char).
|
||||
For example, syntax_spec_code['w'] == Sword. */
|
||||
|
||||
extern unsigned char const syntax_spec_code[0400];
|
||||
|
||||
/* Indexed by syntax code, give the letter that describes it. */
|
||||
|
||||
extern char const syntax_code_spec[16];
|
||||
|
||||
/* Convert the byte offset BYTEPOS into a character position,
|
||||
for the object recorded in gl_state with SETUP_SYNTAX_TABLE_FOR_OBJECT.
|
||||
|
||||
The value is meant for use in the UPDATE_SYNTAX_TABLE... macros.
|
||||
These macros do nothing when parse_sexp_lookup_properties is 0,
|
||||
so we return 0 in that case, for speed. */
|
||||
|
||||
#define SYNTAX_TABLE_BYTE_TO_CHAR(bytepos) \
|
||||
(! parse_sexp_lookup_properties \
|
||||
? 0 \
|
||||
: STRINGP (gl_state.object) \
|
||||
? string_byte_to_char (gl_state.object, (bytepos)) \
|
||||
: BUFFERP (gl_state.object) \
|
||||
? buf_bytepos_to_charpos (XBUFFER (gl_state.object), \
|
||||
(bytepos) + BUF_BEGV_BYTE (XBUFFER (gl_state.object)) - 1) - BUF_BEGV (XBUFFER (gl_state.object)) + 1 \
|
||||
: NILP (gl_state.object) \
|
||||
? BYTE_TO_CHAR ((bytepos) + BEGV_BYTE - 1) - BEGV + 1 \
|
||||
: (bytepos))
|
||||
|
||||
/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
|
||||
currently good for a position before CHARPOS. */
|
||||
|
||||
#define UPDATE_SYNTAX_TABLE_FORWARD(charpos) \
|
||||
(parse_sexp_lookup_properties \
|
||||
&& (charpos) >= gl_state.e_property \
|
||||
? (update_syntax_table ((charpos) + gl_state.offset, 1, 0, \
|
||||
gl_state.object), \
|
||||
1) \
|
||||
: 0)
|
||||
|
||||
/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
|
||||
currently good for a position after CHARPOS. */
|
||||
|
||||
#define UPDATE_SYNTAX_TABLE_BACKWARD(charpos) \
|
||||
(parse_sexp_lookup_properties \
|
||||
&& (charpos) < gl_state.b_property \
|
||||
? (update_syntax_table ((charpos) + gl_state.offset, -1, 0, \
|
||||
gl_state.object), \
|
||||
1) \
|
||||
: 0)
|
||||
|
||||
/* Make syntax table good for CHARPOS. */
|
||||
|
||||
#define UPDATE_SYNTAX_TABLE(charpos) \
|
||||
(parse_sexp_lookup_properties \
|
||||
&& (charpos) < gl_state.b_property \
|
||||
? (update_syntax_table ((charpos) + gl_state.offset, -1, 0, \
|
||||
gl_state.object), \
|
||||
1) \
|
||||
: (parse_sexp_lookup_properties \
|
||||
&& (charpos) >= gl_state.e_property \
|
||||
? (update_syntax_table ((charpos) + gl_state.offset, 1, 0,\
|
||||
gl_state.object), \
|
||||
1) \
|
||||
: 0))
|
||||
|
||||
/* This macro sets up the buffer-global syntax table. */
|
||||
#define SETUP_BUFFER_SYNTAX_TABLE() \
|
||||
do \
|
||||
{ \
|
||||
gl_state.use_global = 0; \
|
||||
gl_state.current_syntax_table = BVAR (current_buffer, syntax_table);\
|
||||
} while (0)
|
||||
|
||||
/* This macro should be called with FROM at the start of forward
|
||||
search, or after the last position of the backward search. It
|
||||
makes sure that the first char is picked up with correct table, so
|
||||
one does not need to call UPDATE_SYNTAX_TABLE immediately after the
|
||||
call.
|
||||
Sign of COUNT gives the direction of the search.
|
||||
*/
|
||||
|
||||
#define SETUP_SYNTAX_TABLE(FROM, COUNT) \
|
||||
do \
|
||||
{ \
|
||||
SETUP_BUFFER_SYNTAX_TABLE (); \
|
||||
gl_state.b_property = BEGV; \
|
||||
gl_state.e_property = ZV + 1; \
|
||||
gl_state.object = Qnil; \
|
||||
gl_state.offset = 0; \
|
||||
if (parse_sexp_lookup_properties) \
|
||||
if ((COUNT) > 0 || (FROM) > BEGV) \
|
||||
update_syntax_table ((COUNT) > 0 ? (FROM) : (FROM) - 1, (COUNT),\
|
||||
1, Qnil); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
|
||||
If it is t (which is only used in fast_c_string_match_ignore_case),
|
||||
ignore properties altogether.
|
||||
|
||||
This is meant for regex.c to use. For buffers, regex.c passes arguments
|
||||
to the UPDATE_SYNTAX_TABLE macros which are relative to BEGV.
|
||||
So if it is a buffer, we set the offset field to BEGV. */
|
||||
|
||||
#define SETUP_SYNTAX_TABLE_FOR_OBJECT(OBJECT, FROM, COUNT) \
|
||||
do \
|
||||
{ \
|
||||
SETUP_BUFFER_SYNTAX_TABLE (); \
|
||||
gl_state.object = (OBJECT); \
|
||||
if (BUFFERP (gl_state.object)) \
|
||||
{ \
|
||||
struct buffer *buf = XBUFFER (gl_state.object); \
|
||||
gl_state.b_property = 1; \
|
||||
gl_state.e_property = BUF_ZV (buf) - BUF_BEGV (buf) + 1; \
|
||||
gl_state.offset = BUF_BEGV (buf) - 1; \
|
||||
} \
|
||||
else if (NILP (gl_state.object)) \
|
||||
{ \
|
||||
gl_state.b_property = 1; \
|
||||
gl_state.e_property = ZV - BEGV + 1; \
|
||||
gl_state.offset = BEGV - 1; \
|
||||
} \
|
||||
else if (EQ (gl_state.object, Qt)) \
|
||||
{ \
|
||||
gl_state.b_property = 0; \
|
||||
gl_state.e_property = PTRDIFF_MAX; \
|
||||
gl_state.offset = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
gl_state.b_property = 0; \
|
||||
gl_state.e_property = 1 + SCHARS (gl_state.object); \
|
||||
gl_state.offset = 0; \
|
||||
} \
|
||||
if (parse_sexp_lookup_properties) \
|
||||
update_syntax_table (((FROM) + gl_state.offset \
|
||||
+ (COUNT > 0 ? 0 : -1)), \
|
||||
COUNT, 1, gl_state.object); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
struct gl_state_s
|
||||
{
|
||||
Lisp_Object object; /* The object we are scanning. */
|
||||
ptrdiff_t start; /* Where to stop. */
|
||||
ptrdiff_t stop; /* Where to stop. */
|
||||
int use_global; /* Whether to use global_code
|
||||
bool use_global; /* Whether to use global_code
|
||||
or c_s_t. */
|
||||
Lisp_Object global_code; /* Syntax code of current char. */
|
||||
Lisp_Object current_syntax_table; /* Syntax table for current pos. */
|
||||
|
|
@ -299,4 +84,115 @@ struct gl_state_s
|
|||
};
|
||||
|
||||
extern struct gl_state_s gl_state;
|
||||
|
||||
/* Fetch the information from the entry for character C
|
||||
in syntax table TABLE, or from globally kept data (gl_state).
|
||||
Does inheritance. */
|
||||
|
||||
SYNTAX_INLINE Lisp_Object
|
||||
SYNTAX_ENTRY (int c)
|
||||
{
|
||||
#ifdef SYNTAX_ENTRY_VIA_PROPERTY
|
||||
return (gl_state.use_global
|
||||
? gl_state.global_code
|
||||
: CHAR_TABLE_REF (gl_state.current_syntax_table, c));
|
||||
#else
|
||||
return CHAR_TABLE_REF (BVAR (current_buffer, syntax_table), c);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Extract the information from the entry for character C
|
||||
in the current syntax table. */
|
||||
|
||||
SYNTAX_INLINE int
|
||||
SYNTAX_WITH_FLAGS (int c)
|
||||
{
|
||||
Lisp_Object ent = SYNTAX_ENTRY (c);
|
||||
return CONSP (ent) ? XINT (XCAR (ent)) : Swhitespace;
|
||||
}
|
||||
|
||||
SYNTAX_INLINE enum syntaxcode
|
||||
SYNTAX (int c)
|
||||
{
|
||||
return SYNTAX_WITH_FLAGS (c) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* Whether the syntax of the character C has the prefix flag set. */
|
||||
extern bool syntax_prefix_flag_p (int c);
|
||||
|
||||
/* This array, indexed by a character less than 256, contains the
|
||||
syntax code which that character signifies (as an unsigned char).
|
||||
For example, syntax_spec_code['w'] == Sword. */
|
||||
|
||||
extern unsigned char const syntax_spec_code[0400];
|
||||
|
||||
/* Indexed by syntax code, give the letter that describes it. */
|
||||
|
||||
extern char const syntax_code_spec[16];
|
||||
|
||||
/* Convert the byte offset BYTEPOS into a character position,
|
||||
for the object recorded in gl_state with SETUP_SYNTAX_TABLE_FOR_OBJECT.
|
||||
|
||||
The value is meant for use in code that does nothing when
|
||||
parse_sexp_lookup_properties is 0, so return 0 in that case, for speed. */
|
||||
|
||||
SYNTAX_INLINE ptrdiff_t
|
||||
SYNTAX_TABLE_BYTE_TO_CHAR (ptrdiff_t bytepos)
|
||||
{
|
||||
return (! parse_sexp_lookup_properties
|
||||
? 0
|
||||
: STRINGP (gl_state.object)
|
||||
? string_byte_to_char (gl_state.object, bytepos)
|
||||
: BUFFERP (gl_state.object)
|
||||
? ((buf_bytepos_to_charpos
|
||||
(XBUFFER (gl_state.object),
|
||||
(bytepos + BUF_BEGV_BYTE (XBUFFER (gl_state.object)) - 1)))
|
||||
- BUF_BEGV (XBUFFER (gl_state.object)) + 1)
|
||||
: NILP (gl_state.object)
|
||||
? BYTE_TO_CHAR (bytepos + BEGV_BYTE - 1) - BEGV + 1
|
||||
: bytepos);
|
||||
}
|
||||
|
||||
/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
|
||||
currently good for a position before CHARPOS. */
|
||||
|
||||
SYNTAX_INLINE void
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos)
|
||||
{
|
||||
if (parse_sexp_lookup_properties && charpos >= gl_state.e_property)
|
||||
update_syntax_table (charpos + gl_state.offset, 1, 0, gl_state.object);
|
||||
}
|
||||
|
||||
/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
|
||||
currently good for a position after CHARPOS. */
|
||||
|
||||
SYNTAX_INLINE void
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (ptrdiff_t charpos)
|
||||
{
|
||||
if (parse_sexp_lookup_properties && charpos < gl_state.b_property)
|
||||
update_syntax_table (charpos + gl_state.offset, -1, 0, gl_state.object);
|
||||
}
|
||||
|
||||
/* Make syntax table good for CHARPOS. */
|
||||
|
||||
SYNTAX_INLINE void
|
||||
UPDATE_SYNTAX_TABLE (ptrdiff_t charpos)
|
||||
{
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (charpos);
|
||||
}
|
||||
|
||||
/* Set up the buffer-global syntax table. */
|
||||
|
||||
SYNTAX_INLINE void
|
||||
SETUP_BUFFER_SYNTAX_TABLE (void)
|
||||
{
|
||||
gl_state.use_global = 0;
|
||||
gl_state.current_syntax_table = BVAR (current_buffer, syntax_table);
|
||||
}
|
||||
|
||||
extern ptrdiff_t scan_words (ptrdiff_t, EMACS_INT);
|
||||
extern void SETUP_SYNTAX_TABLE_FOR_OBJECT (Lisp_Object, ptrdiff_t, ptrdiff_t);
|
||||
|
||||
INLINE_HEADER_END
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue