8ea4fcbc1c5b7b393a8031cc085b366baaa34edc
[chise/xemacs-chise.git.1] / src / syntax.h
1 /* Declarations having to do with XEmacs syntax tables.
2    Copyright (C) 1985, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: FSF 19.28. */
22
23 #ifndef INCLUDED_syntax_h_
24 #define INCLUDED_syntax_h_
25
26 #include "chartab.h"
27
28 /* A syntax table is a type of char table.
29
30 The low 7 bits of the integer is a code, as follows. The 8th bit is
31 used as the prefix bit flag (see below).
32
33 The values in a syntax table are either integers or conses of
34 integers and chars.  The lowest 7 bits of the integer are the syntax
35 class.  If this is Sinherit, then the actual syntax value needs to
36 be retrieved from the standard syntax table.
37
38 Since the logic involved in finding the actual integer isn't very
39 complex, you'd think the time required to retrieve it is not a
40 factor.  If you thought that, however, you'd be wrong, due to the
41 high number of times (many per character) that the syntax value is
42 accessed in functions such as scan_lists().  To speed this up,
43 we maintain a mirror syntax table that contains the actual
44 integers.  We can do this successfully because syntax tables are
45 now an abstract type, where we control all access.
46 */
47
48 enum syntaxcode
49 {
50   Swhitespace,  /* whitespace character */
51   Spunct,       /* random punctuation character */
52   Sword,        /* word constituent */
53   Ssymbol,      /* symbol constituent but not word constituent */
54   Sopen,        /* a beginning delimiter */
55   Sclose,       /* an ending delimiter */
56   Squote,       /* a prefix character like Lisp ' */
57   Sstring,      /* a string-grouping character like Lisp " */
58   Smath,        /* delimiters like $ in TeX. */
59   Sescape,      /* a character that begins a C-style escape */
60   Scharquote,   /* a character that quotes the following character */
61   Scomment,     /* a comment-starting character */
62   Sendcomment,  /* a comment-ending character */
63   Sinherit,     /* use the standard syntax table for this character */
64   Scomment_fence, /* Starts/ends comment which is delimited on the
65                      other side by a char with the same syntaxcode.  */
66   Sstring_fence,  /* Starts/ends string which is delimited on the
67                      other side by a char with the same syntaxcode.  */
68   Smax   /* Upper bound on codes that are meaningful */
69 };
70
71 enum syntaxcode charset_syntax (struct buffer *buf, Lisp_Object charset,
72                                 int *multi_p_out);
73
74 /* Return the syntax code for a particular character and mirror table. */
75
76 #define SYNTAX_CODE_UNSAFE(table, c) \
77    XINT (CHAR_TABLE_VALUE_UNSAFE (table, c))
78
79 INLINE_HEADER int SYNTAX_CODE (Lisp_Char_Table *table, Emchar c);
80 INLINE_HEADER int
81 SYNTAX_CODE (Lisp_Char_Table *table, Emchar c)
82 {
83   return SYNTAX_CODE_UNSAFE (table, c);
84 }
85
86 #define SYNTAX_UNSAFE(table, c) \
87   ((enum syntaxcode) (SYNTAX_CODE_UNSAFE (table, c) & 0177))
88
89 #define SYNTAX_FROM_CODE(code) ((enum syntaxcode) ((code) & 0177))
90 #define SYNTAX(table, c) SYNTAX_FROM_CODE (SYNTAX_CODE (table, c))
91
92 INLINE_HEADER int WORD_SYNTAX_P (Lisp_Char_Table *table, Emchar c);
93 INLINE_HEADER int
94 WORD_SYNTAX_P (Lisp_Char_Table *table, Emchar c)
95 {
96   return SYNTAX (table, c) == Sword;
97 }
98
99 /* OK, here's a graphic diagram of the format of the syntax values:
100
101    Bit number:
102
103  [ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ]
104  [ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ]
105
106    <-----> <-----> <-------------> <-------------> ^  <----------->
107     ELisp  unused  |comment bits |     unused      |   syntax code
108      tag           | | | | | | | |                 |
109     stuff          | | | | | | | |                 |
110                    | | | | | | | |                 |
111                    | | | | | | | |                 `--> prefix flag
112                    | | | | | | | |
113                    | | | | | | | `--> comment end style B, second char
114                    | | | | | | `----> comment end style A, second char
115                    | | | | | `------> comment end style B, first char
116                    | | | | `--------> comment end style A, first char
117                    | | | `----------> comment start style B, second char
118                    | | `------------> comment start style A, second char
119                    | `--------------> comment start style B, first char
120                    `----------------> comment start style A, first char
121
122   In a 64-bit integer, there would be 32 more unused bits between
123   the tag and the comment bits.
124
125   Clearly, such a scheme will not work for Mule, because the matching
126   paren could be any character and as such requires 19 bits, which
127   we don't got.
128
129   Remember that under Mule we use char tables instead of vectors.
130   So what we do is use another char table for the matching paren
131   and store a pointer to it in the first char table. (This frees
132   code from having to worry about passing two tables around.)
133 */
134
135
136 /* The prefix flag bit for backward-prefix-chars is now put into bit 7. */
137
138 #define SYNTAX_PREFIX_UNSAFE(table, c) \
139   ((SYNTAX_CODE_UNSAFE (table, c) >> 7) & 1)
140 #define SYNTAX_PREFIX(table, c) \
141   ((SYNTAX_CODE (table, c) >> 7) & 1)
142
143 /* Bits 23-16 are used to implement up to two comment styles
144    in a single buffer. They have the following meanings:
145
146   1. first of a one or two character comment-start sequence of style a.
147   2. first of a one or two character comment-start sequence of style b.
148   3. second of a two-character comment-start sequence of style a.
149   4. second of a two-character comment-start sequence of style b.
150   5. first of a one or two character comment-end sequence of style a.
151   6. first of a one or two character comment-end sequence of style b.
152   7. second of a two-character comment-end sequence of style a.
153   8. second of a two-character comment-end sequence of style b.
154
155 From the internals manual:
156
157 Syntax codes are implemented as bitfields in an int.  Bits 0-6 contain
158 the syntax code itself, bit 7 is a special prefix flag used for Lisp,
159 and bits 16-23 contain comment syntax flags.  From the Lisp programmer's
160 point of view, there are 11 flags: 2 styles X 2 characters X @{start,
161 end@} flags for two-character comment delimiters, 2 style flags for
162 one-character comment delimiters, and the prefix flag.
163
164 Internally, however, the characters used in multi-character delimiters
165 will have non-comment-character syntax classes (@emph{e.g.}, the
166 @samp{/} in C's @samp{/}@samp{*} comment-start delimiter has ``punctuation''
167 \(here meaning ``operator-like'') class in C modes).  Thus in a mixed
168 comment style, such as C++'s @samp{//} to end of line, is represented by
169 giving @samp{/} the ``punctuation'' class and the ``style b first
170 character of start sequence'' and ``style b second character of start
171 sequence'' flags.  The fact that class is @emph{not} punctuation allows
172 the syntax scanner to recognize that this is a multi-character
173 delimiter.  The @samp{newline} character is given (single-character)
174 ``comment-end'' @emph{class} and the ``style b first character of end
175 sequence'' @emph{flag}.  The ``comment-end'' class allows the scanner to
176 determine that no second character is needed to terminate the comment.
177  */
178
179 #define SYNTAX_COMMENT_BITS(c) \
180   ((SYNTAX_CODE (mirrortab, c) >> 16) &0xff)
181
182 #define SYNTAX_FIRST_OF_START_A  0x80
183 #define SYNTAX_FIRST_OF_START_B  0x40
184 #define SYNTAX_SECOND_OF_START_A 0x20
185 #define SYNTAX_SECOND_OF_START_B 0x10
186 #define SYNTAX_FIRST_OF_END_A    0x08
187 #define SYNTAX_FIRST_OF_END_B    0x04
188 #define SYNTAX_SECOND_OF_END_A   0x02
189 #define SYNTAX_SECOND_OF_END_B   0x01
190
191 #define SYNTAX_COMMENT_STYLE_A   0xaa
192 #define SYNTAX_COMMENT_STYLE_B   0x55
193 #define SYNTAX_FIRST_CHAR_START  0xc0
194 #define SYNTAX_FIRST_CHAR_END    0x0c
195 #define SYNTAX_FIRST_CHAR        0xcc
196 #define SYNTAX_SECOND_CHAR_START 0x30
197 #define SYNTAX_SECOND_CHAR_END   0x03
198 #define SYNTAX_SECOND_CHAR       0x33
199
200
201 /* #### These are now more or less equivalent to
202    SYNTAX_COMMENT_MATCH_START ...*/
203 /* a and b must be first and second start chars for a common type */
204 #define SYNTAX_START_P(a, b)                                     \
205   (((SYNTAX_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_START) >> 2)    \
206    & (SYNTAX_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_START))
207
208 /* ... and  SYNTAX_COMMENT_MATCH_END */
209 /* a and b must be first and second end chars for a common type */
210 #define SYNTAX_END_P(a, b)                                       \
211   (((SYNTAX_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_END) >> 2)      \
212    & (SYNTAX_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_END))
213
214 #define SYNTAX_STYLES_MATCH_START_P(a, b, mask)                 \
215   ((SYNTAX_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_START & (mask)) \
216    && (SYNTAX_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_START & (mask)))
217
218 #define SYNTAX_STYLES_MATCH_END_P(a, b, mask)                   \
219   ((SYNTAX_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_END & (mask))   \
220    && (SYNTAX_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_END & (mask)))
221
222 #define SYNTAX_STYLES_MATCH_1CHAR_P(a, mask)    \
223   ((SYNTAX_COMMENT_BITS (a) & (mask)))
224
225 #define STYLE_FOUND_P(a, b, startp, style)              \
226   ((SYNTAX_COMMENT_BITS (a) &                           \
227     ((startp) ? SYNTAX_FIRST_CHAR_START :               \
228      SYNTAX_FIRST_CHAR_END) & (style))                  \
229    && (SYNTAX_COMMENT_BITS (b) &                        \
230     ((startp) ? SYNTAX_SECOND_CHAR_START :              \
231      SYNTAX_SECOND_CHAR_END) & (style)))
232
233 #define SYNTAX_COMMENT_MASK_START(a, b)                 \
234   ((STYLE_FOUND_P (a, b, 1, SYNTAX_COMMENT_STYLE_A)     \
235     ? SYNTAX_COMMENT_STYLE_A                            \
236     : (STYLE_FOUND_P (a, b, 1, SYNTAX_COMMENT_STYLE_B)  \
237          ? SYNTAX_COMMENT_STYLE_B                       \
238          : 0)))
239
240 #define SYNTAX_COMMENT_MASK_END(a, b)                   \
241   ((STYLE_FOUND_P (a, b, 0, SYNTAX_COMMENT_STYLE_A)     \
242    ? SYNTAX_COMMENT_STYLE_A                             \
243    : (STYLE_FOUND_P (a, b, 0, SYNTAX_COMMENT_STYLE_B)   \
244       ? SYNTAX_COMMENT_STYLE_B                          \
245       : 0)))
246
247 #define STYLE_FOUND_1CHAR_P(a, style)   \
248   ((SYNTAX_COMMENT_BITS (a) & (style)))
249
250 #define SYNTAX_COMMENT_1CHAR_MASK(a)                    \
251   ((STYLE_FOUND_1CHAR_P (a, SYNTAX_COMMENT_STYLE_A)     \
252    ? SYNTAX_COMMENT_STYLE_A                             \
253    : (STYLE_FOUND_1CHAR_P (a, SYNTAX_COMMENT_STYLE_B)   \
254       ? SYNTAX_COMMENT_STYLE_B                          \
255          : 0)))
256
257 EXFUN (Fchar_syntax, 2);
258 EXFUN (Fforward_word, 2);
259
260 /* The standard syntax table is stored where it will automatically
261    be used in all new buffers.  */
262 extern Lisp_Object Vstandard_syntax_table;
263
264 /* This array, indexed by a character, contains the syntax code which
265    that character signifies (as a char).
266    For example, (enum syntaxcode) syntax_spec_code['w'] is Sword. */
267
268 extern const unsigned char syntax_spec_code[0400];
269
270 /* Indexed by syntax code, give the letter that describes it. */
271
272 extern const unsigned char syntax_code_spec[];
273
274 Lisp_Object scan_lists (struct buffer *buf, Bufpos from, int count,
275                         int depth, int sexpflag, int no_error);
276 int char_quoted (struct buffer *buf, Bufpos pos);
277
278 /* NOTE: This does not refer to the mirror table, but to the
279    syntax table itself. */
280 Lisp_Object syntax_match (Lisp_Object table, Emchar ch);
281
282 extern int no_quit_in_re_search;
283 extern struct buffer *regex_emacs_buffer;
284
285 /* Target text (string or buffer), used for syntax-table properties. */
286 extern Lisp_Object regex_match_object;
287
288 void update_syntax_table (Lisp_Char_Table *ct);
289
290 /* The syntax table cache */
291
292 /*
293    The *-single-property-change versions turn out to be unbearably slow.
294    Do not enable them in a production or distribution version.
295 */
296 #define NEXT_SINGLE_PROPERTY_CHANGE             0
297 #define PREVIOUS_SINGLE_PROPERTY_CHANGE         0
298
299 /* Test instruments, used in macros below.
300    Define SYNTAX_CACHE_STATISTICS to enable them. */
301 /* #undef SYNTAX_CACHE_STATISTICS */
302
303 #ifdef SYNTAX_CACHE_STATISTICS
304 #define SYNTAX_CACHE_STATISTICS_REPORT_INTERVAL 100000
305
306 enum syntax_cache_statistics_functions {
307   scs_no_function = -1,
308   scs_find_context = 0,
309   scs_find_defun_start,
310   scs_scan_words,
311   scs_Fforward_comment,
312   scs_scan_lists,
313   scs_Fbackward_prefix_characters,
314   scs_scan_sexps_forward,
315   scs_number_of_functions
316 };
317
318 /* keep this in synch with syntax.c */
319 extern char* syntax_cache_statistics_function_names[scs_number_of_functions];
320
321 struct syntax_cache_statistics {
322   /* inits + misses_hi + misses_lo + #HITS = total_updates */
323   int total_updates;
324   int inits;
325   int misses_lo;
326   int misses_hi;
327   int min_length;
328   int max_length;
329   double mean_length;
330   double mean_length_on_miss;
331   enum syntax_cache_statistics_functions this_function;
332   int functions[scs_number_of_functions];
333 };
334
335 extern struct syntax_cache_statistics scs_statistics;
336
337 #define SCS_STATISTICS_SET_FUNCTION(fndx) scs_statistics.this_function = fndx
338 /* used in macros below */
339 #define SYNTAX_CACHE_STATISTICS_COUNT_INIT scs_statistics.inits++
340
341 #else
342
343 #define SCS_STATISTICS_SET_FUNCTION(fndx)
344 #define SYNTAX_CACHE_STATISTICS_COUNT_INIT
345
346 #endif /* SYNTAX_CACHE_STATISTICS */
347
348 /* Theory of the syntax table cache
349
350    This cache cooperates with but is conceptually different from the
351    mirror table.  The mirror table precomputes (and caches, if you like)
352    the syntax codes for characters in a given syntax table, taking into
353    account possible inheritance from a table given by a parent text object.
354    The syntax table cache checks for overriding tables defined by
355    _subobjects_.
356
357    This implementation defines the "subobjects" by _extent properties_.
358    We may restrict them to _text_ properties.  There are two lookup
359    styles for the cache, "single code" and "full table".  In the "single
360    code" style, a given syntax code, kept in the `syntax_code' member, is
361    applied to the entire range (#### check this).  In the "full table"
362    style, a syntax table kept in the `current_syntax_table' member is
363    checked for each character in the range.  If the flag `use_code' is
364    non-zero, the "single code" is used, otherwise the "full table".
365
366    The cache is valid for the range `[prev_change, next_change)' in the
367    text object (buffer or string) `object'.
368
369    If the current position is outside the range valid for the cache, the
370    cache is updated by checking for the text property `syntax-table'.  If
371    present, its value is either a syntax code or a syntax table, and the
372    appropriate member and `use_code' are updated accordingly.  If absent
373    or nil, the default syntax table from the `buffer' member is used.  The
374    extent of the property is used to reinitialize the cache's validity
375    range.  (We would like to improve this by checking the property value
376    against `old_prop', and if the same, extend the validity range of the
377    cache by the extent of the property.)
378
379    Note: the values Qt and Qnil for `object' are not supported in this
380    implementation.  GNU Emacs uses them for reasons not yet (####) clear.
381 */
382
383 extern int lookup_syntax_properties;
384
385 struct syntax_cache
386 {
387   int use_code;                         /* Whether to use syntax_code
388                                            or current_syntax_table. */
389   struct buffer* buffer;                /* The buffer providing the default
390                                            syntax table to the cache. */
391   Lisp_Object object;                   /* The buffer or string the current
392                                            syntax cache applies to. */
393   int syntax_code;                      /* Syntax code of current char. */
394   Lisp_Object current_syntax_table;     /* Syntax table for current pos. */
395   Lisp_Object old_prop;                 /* Syntax-table prop at prev pos. */
396
397   Bufpos next_change;                   /* Position of the next extent
398                                            change. */
399   Bufpos prev_change;                   /* Position of the previous
400                                            extent change. */
401 };
402 extern struct syntax_cache syntax_cache;
403
404 /*
405    The macros below handle the internal structure of the cache.
406    ALWAYS USE THE MACROS TO MANIPULATE THE CACHE.
407
408    o Use the SETUP_SYNTAX_CACHE* macros to set the object and buffer members.
409
410      OBJECT is either a Lisp buffer or a Lisp string.  BUFFER is a
411      pointer to struct buffer.  If OBJECT is a buffer, it must refer to
412      BUFFER.  If OBJECT is a string, then BUFFER will supply the default
413      syntax table when the `syntax-table' property is nil.
414
415      For convenience and backward compatibility, the values Qt and Qnil are
416      accepted for OBJECT.  These are taken to refer to the current buffer,
417      and that substitution is made immediately.  The value Qt is treated
418      specially in the *BYTE_TO_CHAR macros below.  This appears (####) to
419      be a GNU kludge related to `enable-multibyte-characters' and was used
420      only in dired.c.
421
422      FROM is the starting character position in OBJECT.
423      COUNT is currently used only as a flag.  If positive, we are proceeding
424      forward through OBJECT, otherwise in reverse.
425
426    o All other members are updated using the update_syntax_cache
427      function, normally wrapped in the UPDATE_SYNTAX_CACHE* macros.
428 */
429
430 void update_syntax_cache (int pos, int count);
431
432 /* in one example the high misses vastly outweigh the low ones
433    seems plausible, since we typically are moving forward through the buffer */
434 #define UPDATE_SYNTAX_CACHE_INTERNAL(pos, dir)  \
435    ((lookup_syntax_properties &&                \
436      (pos >= syntax_cache.next_change ||                \
437       pos < syntax_cache.prev_change))          \
438     ? (update_syntax_cache ((pos), dir), 1)     \
439     : 0)
440
441 /* In the current implementation, all of the following are identical. */
442 /* Make syntax cache state good for CHARPOS, assuming it is
443    currently good for a position before CHARPOS.  */
444 #define UPDATE_SYNTAX_CACHE_FORWARD(pos) UPDATE_SYNTAX_CACHE_INTERNAL(pos, 1)
445
446 /* Make syntax cache state good for CHARPOS, assuming it is
447    currently good for a position after CHARPOS.  */
448 #define UPDATE_SYNTAX_CACHE_BACKWARD(pos) UPDATE_SYNTAX_CACHE_INTERNAL(pos, -1)
449
450 /* Make syntax cache state good for CHARPOS */
451 #define UPDATE_SYNTAX_CACHE(pos) UPDATE_SYNTAX_CACHE_INTERNAL(pos, 0)
452
453 #define SYNTAX_FROM_CACHE(table, c)                     \
454    SYNTAX_FROM_CODE (SYNTAX_CODE_FROM_CACHE (table, c))
455
456 #define SYNTAX_CODE_FROM_CACHE(table, c)                                \
457   ( syntax_cache.use_code                                               \
458       ? syntax_cache.syntax_code                                        \
459       : SYNTAX_CODE (XCHAR_TABLE (syntax_cache.current_syntax_table),   \
460                      c)                                                 \
461  )
462
463 /* Convert the byte offset BYTEPOS into a character position,
464    for the object recorded in syntax_cache with SETUP_SYNTAX_CACHE*.
465
466    The value is meant for use in the UPDATE_SYNTAX_CACHE... macros.
467    These macros do nothing when lookup_syntax_properties is 0,
468    so we return 0 in that case, for speed.
469
470    The default case does no conversion; this seems (####) to be an
471    evil hangover from GNU Emacs. */
472 #define SYNTAX_CACHE_OBJECT_BYTE_TO_CHAR(obj, buf, bytepos)     \
473   (! lookup_syntax_properties                                   \
474    ? 0                                                          \
475    : STRINGP (obj)                                              \
476    ? bytecount_to_charcount (XSTRING_DATA (obj), bytepos)       \
477    : (BUFFERP (obj) || NILP (obj))                              \
478    ? bytind_to_bufpos (buf, bytepos + BI_BUF_BEGV (buf))        \
479    : (bytepos))
480
481 #define SYNTAX_CACHE_BYTE_TO_CHAR(bytepos)                                     \
482   SYNTAX_CACHE_OBJECT_BYTE_TO_CHAR (syntax_cache.object, syntax_cache.buffer,  \
483                                     (bytepos))
484
485 #define SETUP_SYNTAX_CACHE(FROM, COUNT)                         \
486   SETUP_SYNTAX_CACHE_FOR_BUFFER (current_buffer, (FROM), (COUNT))
487
488 #define SETUP_SYNTAX_CACHE_FOR_BUFFER(BUFFER, FROM, COUNT)      \
489   SETUP_SYNTAX_CACHE_FOR_OBJECT (Qnil, (BUFFER), (FROM), (COUNT))
490
491 #define SETUP_SYNTAX_CACHE_FOR_OBJECT(OBJECT, BUFFER, FROM, COUNT)      \
492   do {                                                                  \
493     syntax_cache.buffer = (BUFFER);                                     \
494     syntax_cache.object = (OBJECT);                                     \
495     if (NILP (syntax_cache.object))                                     \
496       {                                                                 \
497         XSETBUFFER (syntax_cache.object, syntax_cache.buffer);          \
498       }                                                                 \
499     else if (EQ (syntax_cache.object, Qt))                              \
500       {                                                                 \
501         XSETBUFFER (syntax_cache.object, syntax_cache.buffer);          \
502       }                                                                 \
503     else if (STRINGP (syntax_cache.object))                             \
504       {                                                                 \
505         /* do nothing */;                                               \
506       }                                                                 \
507     else if (BUFFERP (syntax_cache.object))                             \
508       {                                                                 \
509         syntax_cache.buffer = XBUFFER (syntax_cache.object);            \
510       }                                                                 \
511     else                                                                \
512       {                                                                 \
513         /* OBJECT must be buffer/string/t/nil */                        \
514         assert(0);                                                      \
515       }                                                                 \
516     syntax_cache.current_syntax_table                                   \
517       = syntax_cache.buffer->mirror_syntax_table;                       \
518     syntax_cache.use_code = 0;                                          \
519     if (lookup_syntax_properties)                                       \
520       {                                                                 \
521         SYNTAX_CACHE_STATISTICS_COUNT_INIT;                             \
522         update_syntax_cache ((FROM) + ((COUNT) > 0 ? 0 : -1), (COUNT)); \
523       }                                                                 \
524   } while (0)
525
526 #define SYNTAX_CODE_PREFIX(c) \
527   ((c >> 7) & 1)
528
529 #define SYNTAX_CODE_COMMENT_BITS(c) \
530   ((c >> 16) &0xff)
531
532 #define SYNTAX_CODES_START_P(a, b)                                    \
533   (((SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_START) >> 2)    \
534    & (SYNTAX_CODE_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_START))
535
536 #define SYNTAX_CODES_END_P(a, b)                                    \
537   (((SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_END) >> 2)    \
538    & (SYNTAX_CODE_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_END))
539
540 #define SYNTAX_CODES_COMMENT_MASK_START(a, b)                   \
541   (SYNTAX_CODES_MATCH_START_P (a, b, SYNTAX_COMMENT_STYLE_A)    \
542    ? SYNTAX_COMMENT_STYLE_A                                     \
543    : (SYNTAX_CODES_MATCH_START_P (a, b, SYNTAX_COMMENT_STYLE_B) \
544       ? SYNTAX_COMMENT_STYLE_B                                  \
545       : 0))
546 #define SYNTAX_CODES_COMMENT_MASK_END(a, b)                     \
547   (SYNTAX_CODES_MATCH_END_P (a, b, SYNTAX_COMMENT_STYLE_A)      \
548    ? SYNTAX_COMMENT_STYLE_A                                     \
549    : (SYNTAX_CODES_MATCH_END_P (a, b, SYNTAX_COMMENT_STYLE_B)   \
550       ? SYNTAX_COMMENT_STYLE_B                                  \
551       : 0))
552
553 #define SYNTAX_CODE_START_FIRST_P(a) \
554   (SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_START)
555
556 #define SYNTAX_CODE_START_SECOND_P(a) \
557   (SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_SECOND_CHAR_START)
558
559 #define SYNTAX_CODE_END_FIRST_P(a) \
560   (SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_END)
561
562 #define SYNTAX_CODE_END_SECOND_P(a) \
563   (SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_SECOND_CHAR_END)
564
565
566 #define SYNTAX_CODES_MATCH_START_P(a, b, mask)                          \
567   ((SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_START & (mask))    \
568    && (SYNTAX_CODE_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_START & (mask)))
569
570 #define SYNTAX_CODES_MATCH_END_P(a, b, mask)                            \
571   ((SYNTAX_CODE_COMMENT_BITS (a) & SYNTAX_FIRST_CHAR_END & (mask))      \
572    && (SYNTAX_CODE_COMMENT_BITS (b) & SYNTAX_SECOND_CHAR_END & (mask)))
573
574 #define SYNTAX_CODE_MATCHES_1CHAR_P(a, mask)    \
575   ((SYNTAX_CODE_COMMENT_BITS (a) & (mask)))
576
577 #define SYNTAX_CODE_COMMENT_1CHAR_MASK(a)                       \
578   ((SYNTAX_CODE_MATCHES_1CHAR_P (a, SYNTAX_COMMENT_STYLE_A)     \
579     ? SYNTAX_COMMENT_STYLE_A                                    \
580     : (SYNTAX_CODE_MATCHES_1CHAR_P (a, SYNTAX_COMMENT_STYLE_B)  \
581        ? SYNTAX_COMMENT_STYLE_B                                 \
582        : 0)))
583
584 #if 0
585 /* These are the things that need to be #defined away to create a
586    no syntax-table property version. */
587
588 /* This should be entirely encapsulated in macros
589 #define update_syntax_cache(pos, count)
590 */
591 #define lookup_syntax_properties 0
592
593 #define SETUP_SYNTAX_CACHE(FROM, COUNT)
594 #define SETUP_SYNTAX_CACHE_FOR_BUFFER(BUFFER, FROM, COUNT)
595 #define SETUP_SYNTAX_CACHE_FOR_OBJECT(OBJECT, BUFFER, FROM, COUNT)
596 #define UPDATE_SYNTAX_CACHE_FORWARD(pos)
597 #define UPDATE_SYNTAX_CACHE_BACKWARD(pos)
598 #define UPDATE_SYNTAX_CACHE(pos)
599
600 #define SYNTAX_FROM_CACHE SYNTAX
601 #define SYNTAX_CODE_FROM_CACHE SYNTAX_CODE
602
603 #define SYNTAX_CACHE_BYTE_TO_CHAR(x) 0
604
605 /* cache statistics */
606 #define SCS_STATISTICS_SET_FUNCTION(fndx)
607 #define SYNTAX_CACHE_STATISTICS_COUNT_INIT
608
609 #endif /* 0 */
610 #endif /* INCLUDED_syntax_h_ */