comparison src/syntax.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 859a2309aef8
children c7528f8e288d
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02111-1307, USA. */
21 21
22 /* Synched up with: FSF 19.28. */ 22 /* Synched up with: FSF 19.28. */
23 23
24 /* This file has been Mule-ized. */
25
24 #include <config.h> 26 #include <config.h>
25 #include "lisp.h" 27 #include "lisp.h"
26 28
27 #include "buffer.h" 29 #include "buffer.h"
28 #include "commands.h" 30 #include "commands.h"
29 #include "insdel.h" 31 #include "insdel.h"
30 #include "syntax.h" 32 #include "syntax.h"
33
34 /* Here is a comment from Ken'ichi HANDA <handa@etl.go.jp>
35 explaining the purpose of the Sextword syntax category:
36
37 Japanese words are not separated by spaces, which makes finding word
38 boundaries very difficult. Theoretically it's impossible without
39 using natural language processing techniques. But, by defining
40 pseudo-words as below (much simplified for letting you understand it
41 easily) for Japanese, we can have a convenient forward-word function
42 for Japanese.
43
44 A Japanese word is a sequence of characters that consists of
45 zero or more Kanji characters followed by zero or more
46 Hiragana characters.
47
48 Then, the problem is that now we can't say that a sequence of
49 word-constituents makes up a WORD. For instance, both Hiragana "A"
50 and Kanji "KAN" are word-constituents but the sequence of these two
51 letters can't be a single word.
52
53 So, we introduced Sextword for Japanese letters. A character of
54 Sextword is a word-constituent but a word boundary may exist between
55 two such characters. */
56
57 /* Mule 2.4 doesn't seem to have Sextword - I'm removing it -- mrb */
31 58
32 Lisp_Object Qsyntax_table_p; 59 Lisp_Object Qsyntax_table_p;
33 60
34 int words_include_escapes; 61 int words_include_escapes;
35 62
89 116
90 static Bufpos 117 static Bufpos
91 find_defun_start (struct buffer *buf, Bufpos pos) 118 find_defun_start (struct buffer *buf, Bufpos pos)
92 { 119 {
93 Bufpos tem; 120 Bufpos tem;
94 Lisp_Object syntaxtab = buf->syntax_table; 121 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
95 122
96 /* Use previous finding, if it's valid and applies to this inquiry. */ 123 /* Use previous finding, if it's valid and applies to this inquiry. */
97 if (buf == find_start_buffer 124 if (buf == find_start_buffer
98 /* Reuse the defun-start even if POS is a little farther on. 125 /* Reuse the defun-start even if POS is a little farther on.
99 POS might be in the next defun, but that's ok. 126 POS might be in the next defun, but that's ok.
108 tem = find_next_newline (buf, pos, -1); 135 tem = find_next_newline (buf, pos, -1);
109 136
110 while (tem > BUF_BEGV (buf)) 137 while (tem > BUF_BEGV (buf))
111 { 138 {
112 /* Open-paren at start of line means we found our defun-start. */ 139 /* Open-paren at start of line means we found our defun-start. */
113 if (SYNTAX (syntaxtab, BUF_FETCH_CHAR (buf, tem)) == Sopen) 140 if (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, tem)) == Sopen)
114 break; 141 break;
115 /* Move to beg of previous line. */ 142 /* Move to beg of previous line. */
116 tem = find_next_newline (buf, tem, -2); 143 tem = find_next_newline (buf, tem, -2);
117 } 144 }
118 145
130 Return t if ARG is a syntax table. 157 Return t if ARG is a syntax table.
131 Any vector of 256 elements will do. 158 Any vector of 256 elements will do.
132 */ 159 */
133 (obj)) 160 (obj))
134 { 161 {
135 if (VECTORP (obj) && vector_length (XVECTOR (obj)) == 0400) 162 if (CHAR_TABLEP (obj) && XCHAR_TABLE_TYPE (obj) == CHAR_TABLE_TYPE_SYNTAX)
136 return Qt; 163 return Qt;
137 return Qnil; 164 return Qnil;
138 } 165 }
139 166
140 static Lisp_Object 167 static Lisp_Object
171 It is a copy of the TABLE, which defaults to the standard syntax table. 198 It is a copy of the TABLE, which defaults to the standard syntax table.
172 */ 199 */
173 (table)) 200 (table))
174 { 201 {
175 if (NILP (Vstandard_syntax_table)) 202 if (NILP (Vstandard_syntax_table))
176 /* Can only be null during initialization */ 203 return Fmake_char_table (Qsyntax);
177 return make_vector (0400, Qzero);
178 204
179 table = check_syntax_table (table, Vstandard_syntax_table); 205 table = check_syntax_table (table, Vstandard_syntax_table);
180 return Fcopy_sequence (table); 206 return Fcopy_char_table (table);
181 } 207 }
182 208
183 DEFUN ("set-syntax-table", Fset_syntax_table, 1, 2, 0, /* 209 DEFUN ("set-syntax-table", Fset_syntax_table, 1, 2, 0, /*
184 Select a new syntax table for BUFFER. 210 Select a new syntax table for BUFFER.
185 One argument, a syntax table. 211 One argument, a syntax table.
188 (table, buffer)) 214 (table, buffer))
189 { 215 {
190 struct buffer *buf = decode_buffer (buffer, 0); 216 struct buffer *buf = decode_buffer (buffer, 0);
191 table = check_syntax_table (table, Qnil); 217 table = check_syntax_table (table, Qnil);
192 buf->syntax_table = table; 218 buf->syntax_table = table;
219 buf->mirror_syntax_table = XCHAR_TABLE (table)->mirror_table;
193 /* Indicate that this buffer now has a specified syntax table. */ 220 /* Indicate that this buffer now has a specified syntax table. */
194 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table); 221 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table);
195 return table; 222 return table;
196 } 223 }
197 224
198 /* Convert a letter which signifies a syntax code 225 /* Convert a letter which signifies a syntax code
199 into the code it signifies. 226 into the code it signifies.
200 This is used by modify-syntax-entry, and other things. */ 227 This is used by modify-syntax-entry, and other things. */
201 228
202 CONST unsigned char syntax_spec_code[0400] = 229 CONST unsigned char syntax_spec_code[0400] =
203 { 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 230 { 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
204 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 231 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
205 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 232 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
206 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 233 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
207 (char) Swhitespace, 0377, (char) Sstring, 0377, 234 (char) Swhitespace, 0377, (char) Sstring, 0377,
208 (char) Smath, 0377, 0377, (char) Squote, 235 (char) Smath, 0377, 0377, (char) Squote,
209 (char) Sopen, (char) Sclose, 0377, 0377, 236 (char) Sopen, (char) Sclose, 0377, 0377,
210 0377, (char) Swhitespace, (char) Spunct, (char) Scharquote, 237 0377, (char) Swhitespace, (char) Spunct, (char) Scharquote,
211 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 238 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
212 0377, 0377, 0377, 0377, 239 0377, 0377, 0377, 0377,
213 (char) Scomment, 0377, (char) Sendcomment, 0377, 240 (char) Scomment, 0377, (char) Sendcomment, 0377,
214 (char) Sinherit, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* @, A ... */ 241 (char) Sinherit, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* @, A ... */
215 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 242 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
216 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, 243 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,
217 0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol, 244 0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol,
218 0377, 0377, 0377, 0377, 0377, Sextword, 0377, 0377, /* `, a, ... */ 245 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* `, a, ... */
219 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 246 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377,
220 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, 247 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword,
221 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377 248 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377
222 }; 249 };
223 250
224 CONST unsigned char syntax_code_spec[] = 251 CONST unsigned char syntax_code_spec[] = " .w_()'\"$\\/<>@";
225 {
226 ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>', '@',
227 'e', '\0'
228 };
229 252
230 DEFUN ("syntax-designator-chars", Fsyntax_designator_chars, 0, 0, 0, /* 253 DEFUN ("syntax-designator-chars", Fsyntax_designator_chars, 0, 0, 0, /*
231 Return a string of the recognized syntax designator chars. 254 Return a string of the recognized syntax designator chars.
232 The chars are ordered by their internal syntax codes, which are 255 The chars are ordered by their internal syntax codes, which are
233 numbered starting at 0. 256 numbered starting at 0.
245 Optional second argument TABLE defaults to the current buffer's 268 Optional second argument TABLE defaults to the current buffer's
246 syntax table. 269 syntax table.
247 */ 270 */
248 (ch, table)) 271 (ch, table))
249 { 272 {
273 struct Lisp_Char_Table *mirrortab;
274
250 CHECK_CHAR_COERCE_INT (ch); 275 CHECK_CHAR_COERCE_INT (ch);
251 table = check_syntax_table (table, current_buffer->syntax_table); 276 table = check_syntax_table (table, current_buffer->syntax_table);
252 277 mirrortab = XCHAR_TABLE (XCHAR_TABLE (table)->mirror_table);
253 return make_int (syntax_code_spec[(int) SYNTAX (table, XINT (ch))]); 278 return make_char (syntax_code_spec[(int) SYNTAX (mirrortab, XCHAR (ch))]);
254 } 279 }
255 280
281 #ifdef MULE
282
283 enum syntaxcode
284 charset_syntax (struct buffer *buf, Lisp_Object charset, int *multi_p_out)
285 {
286 *multi_p_out = 1;
287 /* #### get this right */
288 return Spunct;
289 }
290
291 #endif
256 292
257 Lisp_Object 293 Lisp_Object
258 syntax_match (Lisp_Object table, Emchar ch) 294 syntax_match (Lisp_Object table, Emchar ch)
259 { 295 {
260 unsigned char stringterm = ((SYNTAX_CODE (table, ch) >> 8) & 0377); 296 Lisp_Object code = CHAR_TABLE_VALUE_UNSAFE (XCHAR_TABLE (table), ch);
261 297 Lisp_Object code2 = code;
262 if (stringterm == 0) 298
299 if (CONSP (code))
300 code2 = XCAR (code);
301 if (SYNTAX_FROM_CODE (XINT (code2)) == Sinherit)
302 code = CHAR_TABLE_VALUE_UNSAFE (XCHAR_TABLE (Vstandard_syntax_table),
303 ch);
304 if (CONSP (code))
305 return XCDR (code);
306 else
263 return Qnil; 307 return Qnil;
264 else
265 return make_char (stringterm);
266 } 308 }
267 309
268 DEFUN ("matching-paren", Fmatching_paren, 1, 2, 0, /* 310 DEFUN ("matching-paren", Fmatching_paren, 1, 2, 0, /*
269 Return the matching parenthesis of CHAR, or nil if none. 311 Return the matching parenthesis of CHAR, or nil if none.
270 Optional second argument TABLE defaults to the current buffer's 312 Optional second argument TABLE defaults to the current buffer's
271 syntax table. 313 syntax table.
272 */ 314 */
273 (ch, table)) 315 (ch, table))
274 { 316 {
317 struct Lisp_Char_Table *mirrortab;
275 int code; 318 int code;
319
276 CHECK_CHAR_COERCE_INT (ch); 320 CHECK_CHAR_COERCE_INT (ch);
277
278 table = check_syntax_table (table, current_buffer->syntax_table); 321 table = check_syntax_table (table, current_buffer->syntax_table);
279 code = SYNTAX (table, XCHAR (ch)); 322 mirrortab = XCHAR_TABLE (XCHAR_TABLE (table)->mirror_table);
323 code = SYNTAX (mirrortab, XCHAR (ch));
280 if (code == Sopen || code == Sclose || code == Sstring) 324 if (code == Sopen || code == Sclose || code == Sstring)
281 return syntax_match (table, XCHAR (ch)); 325 return syntax_match (table, XCHAR (ch));
282 return Qnil; 326 return Qnil;
283 } 327 }
284 328
285 329
330
331 INLINE int
332 word_constituent_p (struct buffer *buf, Bufpos pos,
333 struct Lisp_Char_Table *tab)
334 {
335 enum syntaxcode code = SYNTAX_UNSAFE (tab, BUF_FETCH_CHAR (buf, pos));
336 return ((words_include_escapes &&
337 (code == Sescape || code == Scharquote))
338 || (code == Sword));
339 }
340
286 /* Return the position across COUNT words from FROM. 341 /* Return the position across COUNT words from FROM.
287 If that many words cannot be found before the end of the buffer, return 0. 342 If that many words cannot be found before the end of the buffer, return 0.
288 COUNT negative means scan backward and stop at word beginning. */ 343 COUNT negative means scan backward and stop at word beginning. */
289 344
290 Bufpos 345 Bufpos
291 scan_words (struct buffer *buf, Bufpos from, int count) 346 scan_words (struct buffer *buf, Bufpos from, int count)
292 { 347 {
293 Bufpos beg = BUF_BEGV (buf); 348 Bufpos limit = count > 0 ? BUF_ZV (buf) : BUF_BEGV (buf);
294 Bufpos end = BUF_ZV (buf); 349 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
295 enum syntaxcode code;
296 Lisp_Object table = buf->syntax_table;
297
298 while (count > 0) 350 while (count > 0)
299 { 351 {
300 QUIT; 352 QUIT;
301 353
302 while (1) 354 while (1)
303 { 355 {
304 Emchar ch; 356 if (from == limit)
305 if (from == end) 357 return 0;
306 { 358 if (word_constituent_p (buf, from, mirrortab))
307 return 0;
308 }
309 ch = BUF_FETCH_CHAR (buf, from);
310 code = SYNTAX_UNSAFE (table, ch);
311 if (words_include_escapes
312 && (code == Sescape || code == Scharquote))
313 break;
314 if (code == Sword || code == Sextword)
315 break; 359 break;
316 from++; 360 from++;
317 } 361 }
318 362
319 QUIT; 363 QUIT;
320 364
365 while ((from != limit) && word_constituent_p (buf, from, mirrortab))
366 {
367 from++;
368 }
369 count--;
370 }
371
372 while (count < 0)
373 {
374 QUIT;
375
321 while (1) 376 while (1)
322 { 377 {
323 Emchar ch; 378 if (from == limit)
324 if (from == end) break; 379 return 0;
325 ch = BUF_FETCH_CHAR (buf, from); 380 if (word_constituent_p (buf, from - 1, mirrortab))
326 code = SYNTAX_UNSAFE (table, ch);
327 if (!(words_include_escapes
328 && (code == Sescape || code == Scharquote)))
329 if (code != Sword && code != Sextword)
330 break;
331 from++;
332 }
333
334 count--;
335 }
336 while (count < 0)
337 {
338 QUIT;
339
340 while (1)
341 {
342 Emchar ch;
343 if (from == beg)
344 {
345 return 0;
346 }
347 ch = BUF_FETCH_CHAR (buf, from - 1);
348 code = SYNTAX_UNSAFE (table, ch);
349 if (words_include_escapes
350 && (code == Sescape || code == Scharquote))
351 break;
352 if (code == Sword || code == Sextword)
353 break; 381 break;
354 from--; 382 from--;
355 } 383 }
356 384
357 QUIT; 385 QUIT;
358 386
359 while (1) 387 while ((from != limit) && word_constituent_p (buf, from - 1, mirrortab))
360 { 388 {
361 Emchar ch;
362 if (from == beg) break;
363 ch = BUF_FETCH_CHAR (buf, from - 1);
364 code = SYNTAX_UNSAFE (table, ch);
365 if (!(words_include_escapes
366 && (code == Sescape || code == Scharquote)))
367 if (code != Sword && code != Sextword)
368 break;
369 from--; 389 from--;
370 } 390 }
371 count++; 391 count++;
372 } 392 }
373 393
405 static int 425 static int
406 find_start_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask) 426 find_start_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask)
407 { 427 {
408 Emchar c; 428 Emchar c;
409 enum syntaxcode code; 429 enum syntaxcode code;
410 Lisp_Object table = buf->syntax_table; 430 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
411 431
412 /* Look back, counting the parity of string-quotes, 432 /* Look back, counting the parity of string-quotes,
413 and recording the comment-starters seen. 433 and recording the comment-starters seen.
414 When we reach a safe place, assume that's not in a string; 434 When we reach a safe place, assume that's not in a string;
415 then step the main scan to the earliest comment-starter seen 435 then step the main scan to the earliest comment-starter seen
432 { 452 {
433 /* Move back and examine a character. */ 453 /* Move back and examine a character. */
434 from--; 454 from--;
435 455
436 c = BUF_FETCH_CHAR (buf, from); 456 c = BUF_FETCH_CHAR (buf, from);
437 code = SYNTAX_UNSAFE (table, c); 457 code = SYNTAX_UNSAFE (mirrortab, c);
438 458
439 /* is this a 1-char comment end sequence? if so, try 459 /* is this a 1-char comment end sequence? if so, try
440 to see if style matches previously extracted mask */ 460 to see if style matches previously extracted mask */
441 if (code == Sendcomment) 461 if (code == Sendcomment)
442 { 462 {
443 styles_match_p = SYNTAX_STYLES_MATCH_1CHAR_P (table, c, mask); 463 styles_match_p = SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask);
444 } 464 }
445 465
446 /* otherwise, is this a 2-char comment end sequence? */ 466 /* otherwise, is this a 2-char comment end sequence? */
447 else if (from >= stop 467 else if (from >= stop
448 && SYNTAX_END_P (table, c, BUF_FETCH_CHAR (buf, from+1))) 468 && SYNTAX_END_P (mirrortab, c, BUF_FETCH_CHAR (buf, from+1)))
449 { 469 {
450 code = Sendcomment; 470 code = Sendcomment;
451 styles_match_p = 471 styles_match_p =
452 SYNTAX_STYLES_MATCH_END_P (table, c, 472 SYNTAX_STYLES_MATCH_END_P (mirrortab, c,
453 BUF_FETCH_CHAR (buf, from+1), 473 BUF_FETCH_CHAR (buf, from+1),
454 mask); 474 mask);
455 } 475 }
456 476
457 /* or are we looking at a 1-char comment start sequence 477 /* or are we looking at a 1-char comment start sequence
458 of the style matching mask? */ 478 of the style matching mask? */
459 else if (code == Scomment 479 else if (code == Scomment
460 && SYNTAX_STYLES_MATCH_1CHAR_P (table, c, mask)) 480 && SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask))
461 { 481 {
462 styles_match_p = 1; 482 styles_match_p = 1;
463 } 483 }
464 484
465 /* or possibly, a 2-char comment start sequence */ 485 /* or possibly, a 2-char comment start sequence */
466 else if (from >= stop 486 else if (from >= stop
467 && SYNTAX_STYLES_MATCH_START_P (table, c, 487 && SYNTAX_STYLES_MATCH_START_P (mirrortab, c,
468 BUF_FETCH_CHAR (buf, from+1), 488 BUF_FETCH_CHAR (buf, from+1),
469 mask)) 489 mask))
470 { 490 {
471 code = Scomment; 491 code = Scomment;
472 styles_match_p = 1; 492 styles_match_p = 1;
539 559
540 static Bufpos 560 static Bufpos
541 find_end_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask) 561 find_end_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask)
542 { 562 {
543 int c; 563 int c;
544 Lisp_Object table = buf->syntax_table; 564 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
545 565
546 while (1) 566 while (1)
547 { 567 {
548 if (from == stop) 568 if (from == stop)
549 { 569 {
550 return -1; 570 return -1;
551 } 571 }
552 c = BUF_FETCH_CHAR (buf, from); 572 c = BUF_FETCH_CHAR (buf, from);
553 if (SYNTAX_UNSAFE (table, c) == Sendcomment 573 if (SYNTAX_UNSAFE (mirrortab, c) == Sendcomment
554 && SYNTAX_STYLES_MATCH_1CHAR_P (table, c, mask)) 574 && SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask))
555 /* we have encountered a comment end of the same style 575 /* we have encountered a comment end of the same style
556 as the comment sequence which began this comment 576 as the comment sequence which began this comment
557 section */ 577 section */
558 break; 578 break;
559 579
560 from++; 580 from++;
561 if (from < stop 581 if (from < stop
562 && SYNTAX_STYLES_MATCH_END_P (table, c, 582 && SYNTAX_STYLES_MATCH_END_P (mirrortab, c,
563 BUF_FETCH_CHAR (buf, from), mask)) 583 BUF_FETCH_CHAR (buf, from), mask))
564 /* we have encountered a comment end of the same style 584 /* we have encountered a comment end of the same style
565 as the comment sequence which began this comment 585 as the comment sequence which began this comment
566 section */ 586 section */
567 { from++; break; } 587 { from++; break; }
592 Bufpos stop; 612 Bufpos stop;
593 Emchar c; 613 Emchar c;
594 enum syntaxcode code; 614 enum syntaxcode code;
595 int count; 615 int count;
596 struct buffer *buf = decode_buffer (buffer, 0); 616 struct buffer *buf = decode_buffer (buffer, 0);
597 Lisp_Object table = buf->syntax_table; 617 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
598 618
599 CHECK_INT (n); 619 CHECK_INT (n);
600 count = XINT (n); 620 count = XINT (n);
601 621
602 from = BUF_PT (buf); 622 from = BUF_PT (buf);
615 from++; 635 from++;
616 continue; 636 continue;
617 } 637 }
618 638
619 c = BUF_FETCH_CHAR (buf, from); 639 c = BUF_FETCH_CHAR (buf, from);
620 code = SYNTAX (table, c); 640 code = SYNTAX (mirrortab, c);
621 641
622 if (code == Scomment) 642 if (code == Scomment)
623 { 643 {
624 /* we have encountered a single character comment start 644 /* we have encountered a single character comment start
625 sequence, and we are ignoring all text inside comments. 645 sequence, and we are ignoring all text inside comments.
626 we must record the comment style this character begins 646 we must record the comment style this character begins
627 so that later, only a comment end of the same style actually 647 so that later, only a comment end of the same style actually
628 ends the comment section */ 648 ends the comment section */
629 mask = SYNTAX_COMMENT_1CHAR_MASK (table, c); 649 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c);
630 } 650 }
631 651
632 else if (from < stop 652 else if (from < stop
633 && SYNTAX_START_P (table, c, BUF_FETCH_CHAR (buf, from+1))) 653 && SYNTAX_START_P (mirrortab, c, BUF_FETCH_CHAR (buf, from+1)))
634 { 654 {
635 /* we have encountered a 2char comment start sequence and we 655 /* we have encountered a 2char comment start sequence and we
636 are ignoring all text inside comments. we must record 656 are ignoring all text inside comments. we must record
637 the comment style this sequence begins so that later, 657 the comment style this sequence begins so that later,
638 only a comment end of the same style actually ends 658 only a comment end of the same style actually ends
639 the comment section */ 659 the comment section */
640 code = Scomment; 660 code = Scomment;
641 mask = SYNTAX_COMMENT_MASK_START (table, c, 661 mask = SYNTAX_COMMENT_MASK_START (mirrortab, c,
642 BUF_FETCH_CHAR (buf, from+1)); 662 BUF_FETCH_CHAR (buf, from+1));
643 from++; 663 from++;
644 } 664 }
645 665
646 if (code == Scomment) 666 if (code == Scomment)
688 from--; 708 from--;
689 continue; 709 continue;
690 } 710 }
691 711
692 c = BUF_FETCH_CHAR (buf, from); 712 c = BUF_FETCH_CHAR (buf, from);
693 code = SYNTAX (table, c); 713 code = SYNTAX (mirrortab, c);
694 714
695 if (code == Sendcomment) 715 if (code == Sendcomment)
696 { 716 {
697 /* we have found a single char end comment. we must record 717 /* we have found a single char end comment. we must record
698 the comment style encountered so that later, we can match 718 the comment style encountered so that later, we can match
699 only the proper comment begin sequence of the same style */ 719 only the proper comment begin sequence of the same style */
700 mask = SYNTAX_COMMENT_1CHAR_MASK (table, c); 720 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c);
701 } 721 }
702 722
703 else if (from > stop 723 else if (from > stop
704 && SYNTAX_END_P (table, BUF_FETCH_CHAR (buf, from - 1), c) 724 && SYNTAX_END_P (mirrortab, BUF_FETCH_CHAR (buf, from - 1), c)
705 && !char_quoted (buf, from - 1)) 725 && !char_quoted (buf, from - 1))
706 { 726 {
707 /* We must record the comment style encountered so that 727 /* We must record the comment style encountered so that
708 later, we can match only the proper comment begin 728 later, we can match only the proper comment begin
709 sequence of the same style. */ 729 sequence of the same style. */
710 code = Sendcomment; 730 code = Sendcomment;
711 mask = SYNTAX_COMMENT_MASK_END (table, 731 mask = SYNTAX_COMMENT_MASK_END (mirrortab,
712 BUF_FETCH_CHAR (buf, from - 1), 732 BUF_FETCH_CHAR (buf, from - 1),
713 c); 733 c);
714 from--; 734 from--;
715 } 735 }
716 736
719 from = find_start_of_comment (buf, from, stop, mask); 739 from = find_start_of_comment (buf, from, stop, mask);
720 break; 740 break;
721 } 741 }
722 742
723 else if (code != Swhitespace 743 else if (code != Swhitespace
724 && SYNTAX (table, c) != Scomment 744 && SYNTAX (mirrortab, c) != Scomment
725 && SYNTAX (table, c) != Sendcomment) 745 && SYNTAX (mirrortab, c) != Sendcomment)
726 { 746 {
727 BUF_SET_PT (buf, from + 1); 747 BUF_SET_PT (buf, from + 1);
728 return Qnil; 748 return Qnil;
729 } 749 }
730 } 750 }
745 Emchar c; 765 Emchar c;
746 int quoted; 766 int quoted;
747 int mathexit = 0; 767 int mathexit = 0;
748 enum syntaxcode code; 768 enum syntaxcode code;
749 int min_depth = depth; /* Err out if depth gets less than this. */ 769 int min_depth = depth; /* Err out if depth gets less than this. */
750 Lisp_Object table = buf->syntax_table; 770 Lisp_Object syntaxtab = buf->syntax_table;
771 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
751 772
752 if (depth > 0) min_depth = 0; 773 if (depth > 0) min_depth = 0;
753 774
754 while (count > 0) 775 while (count > 0)
755 { 776 {
759 while (from < stop) 780 while (from < stop)
760 { 781 {
761 int mask = 0; /* mask for finding matching comment style */ 782 int mask = 0; /* mask for finding matching comment style */
762 783
763 c = BUF_FETCH_CHAR (buf, from); 784 c = BUF_FETCH_CHAR (buf, from);
764 code = SYNTAX_UNSAFE (table, c); 785 code = SYNTAX_UNSAFE (mirrortab, c);
765 from++; 786 from++;
766 787
767 /* a 1-char comment start sequence */ 788 /* a 1-char comment start sequence */
768 if (code == Scomment && parse_sexp_ignore_comments) 789 if (code == Scomment && parse_sexp_ignore_comments)
769 { 790 {
770 mask = SYNTAX_COMMENT_1CHAR_MASK (table, c); 791 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c);
771 } 792 }
772 793
773 /* else, a 2-char comment start sequence? */ 794 /* else, a 2-char comment start sequence? */
774 else if (from < stop 795 else if (from < stop
775 && SYNTAX_START_P (table, c, BUF_FETCH_CHAR (buf, from)) 796 && SYNTAX_START_P (mirrortab, c, BUF_FETCH_CHAR (buf, from))
776 && parse_sexp_ignore_comments) 797 && parse_sexp_ignore_comments)
777 { 798 {
778 /* we have encountered a comment start sequence and we 799 /* we have encountered a comment start sequence and we
779 are ignoring all text inside comments. we must record 800 are ignoring all text inside comments. we must record
780 the comment style this sequence begins so that later, 801 the comment style this sequence begins so that later,
781 only a comment end of the same style actually ends 802 only a comment end of the same style actually ends
782 the comment section */ 803 the comment section */
783 code = Scomment; 804 code = Scomment;
784 mask = SYNTAX_COMMENT_MASK_START (table, c, 805 mask = SYNTAX_COMMENT_MASK_START (mirrortab, c,
785 BUF_FETCH_CHAR (buf, from)); 806 BUF_FETCH_CHAR (buf, from));
786 from++; 807 from++;
787 } 808 }
788 809
789 if (SYNTAX_PREFIX_UNSAFE (table, c)) 810 if (SYNTAX_PREFIX_UNSAFE (mirrortab, c))
790 continue; 811 continue;
791 812
792 switch (code) 813 switch (code)
793 { 814 {
794 case Sescape: 815 case Sescape:
795 case Scharquote: 816 case Scharquote:
796 if (from == stop) goto lose; 817 if (from == stop) goto lose;
797 from++; 818 from++;
798 /* treat following character as a word constituent */ 819 /* treat following character as a word constituent */
799 case Sword: 820 case Sword:
800 case Sextword:
801 case Ssymbol: 821 case Ssymbol:
802 if (depth || !sexpflag) break; 822 if (depth || !sexpflag) break;
803 /* This word counts as a sexp; return at end of it. */ 823 /* This word counts as a sexp; return at end of it. */
804 while (from < stop) 824 while (from < stop)
805 { 825 {
806 switch (SYNTAX (table, BUF_FETCH_CHAR (buf, from))) 826 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from)))
807 { 827 {
808 case Scharquote: 828 case Scharquote:
809 case Sescape: 829 case Sescape:
810 from++; 830 from++;
811 if (from == stop) goto lose; 831 if (from == stop) goto lose;
812 break; 832 break;
813 case Sword: 833 case Sword:
814 case Sextword:
815 case Ssymbol: 834 case Ssymbol:
816 case Squote: 835 case Squote:
817 break; 836 break;
818 default: 837 default:
819 goto done; 838 goto done;
868 887
869 case Sstring: 888 case Sstring:
870 { 889 {
871 /* XEmacs change: call syntax_match on character */ 890 /* XEmacs change: call syntax_match on character */
872 Emchar ch = BUF_FETCH_CHAR (buf, from - 1); 891 Emchar ch = BUF_FETCH_CHAR (buf, from - 1);
873 Lisp_Object stermobj = syntax_match (table, ch); 892 Lisp_Object stermobj = syntax_match (syntaxtab, ch);
874 Emchar stringterm; 893 Emchar stringterm;
875 894
876 if (CHARP (stermobj)) 895 if (CHARP (stermobj))
877 stringterm = XCHAR (stermobj); 896 stringterm = XCHAR (stermobj);
878 else 897 else
882 { 901 {
883 if (from >= stop) 902 if (from >= stop)
884 goto lose; 903 goto lose;
885 if (BUF_FETCH_CHAR (buf, from) == stringterm) 904 if (BUF_FETCH_CHAR (buf, from) == stringterm)
886 break; 905 break;
887 switch (SYNTAX (table, BUF_FETCH_CHAR (buf, from))) 906 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from)))
888 { 907 {
889 case Scharquote: 908 case Scharquote:
890 case Sescape: 909 case Sescape:
891 from++; 910 from++;
892 break; 911 break;
929 quoted = char_quoted (buf, from); 948 quoted = char_quoted (buf, from);
930 if (quoted) 949 if (quoted)
931 from--; 950 from--;
932 951
933 c = BUF_FETCH_CHAR (buf, from); 952 c = BUF_FETCH_CHAR (buf, from);
934 code = SYNTAX_UNSAFE (table, c); 953 code = SYNTAX_UNSAFE (mirrortab, c);
935 954
936 if (code == Sendcomment && parse_sexp_ignore_comments) 955 if (code == Sendcomment && parse_sexp_ignore_comments)
937 { 956 {
938 /* we have found a single char end comment. we must record 957 /* we have found a single char end comment. we must record
939 the comment style encountered so that later, we can match 958 the comment style encountered so that later, we can match
940 only the proper comment begin sequence of the same style */ 959 only the proper comment begin sequence of the same style */
941 mask = SYNTAX_COMMENT_1CHAR_MASK (table, c); 960 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c);
942 } 961 }
943 962
944 else if (from > stop 963 else if (from > stop
945 && SYNTAX_END_P (table, BUF_FETCH_CHAR (buf, from-1), c) 964 && SYNTAX_END_P (mirrortab, BUF_FETCH_CHAR (buf, from-1), c)
946 && !char_quoted (buf, from - 1) 965 && !char_quoted (buf, from - 1)
947 && parse_sexp_ignore_comments) 966 && parse_sexp_ignore_comments)
948 { 967 {
949 /* we must record the comment style encountered so that 968 /* we must record the comment style encountered so that
950 later, we can match only the proper comment begin 969 later, we can match only the proper comment begin
951 sequence of the same style */ 970 sequence of the same style */
952 code = Sendcomment; 971 code = Sendcomment;
953 mask = SYNTAX_COMMENT_MASK_END (table, 972 mask = SYNTAX_COMMENT_MASK_END (mirrortab,
954 BUF_FETCH_CHAR (buf, from - 1), 973 BUF_FETCH_CHAR (buf, from - 1),
955 c); 974 c);
956 from--; 975 from--;
957 } 976 }
958 977
959 if (SYNTAX_PREFIX_UNSAFE (table, c)) 978 if (SYNTAX_PREFIX_UNSAFE (mirrortab, c))
960 continue; 979 continue;
961 980
962 switch (((quoted) ? Sword : code)) 981 switch (((quoted) ? Sword : code))
963 { 982 {
964 case Sword: 983 case Sword:
965 case Sextword:
966 case Ssymbol: 984 case Ssymbol:
967 if (depth || !sexpflag) break; 985 if (depth || !sexpflag) break;
968 /* This word counts as a sexp; count object finished after 986 /* This word counts as a sexp; count object finished after
969 passing it. */ 987 passing it. */
970 while (from > stop) 988 while (from > stop)
974 992
975 if (quoted) 993 if (quoted)
976 from--; 994 from--;
977 if (! (quoted 995 if (! (quoted
978 || (syncode = 996 || (syncode =
979 SYNTAX (table, BUF_FETCH_CHAR (buf, from - 1))) 997 SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from - 1)))
980 == Sword 998 == Sword
981 || syncode == Sextword
982 || syncode == Ssymbol 999 || syncode == Ssymbol
983 || syncode == Squote)) 1000 || syncode == Squote))
984 goto done2; 1001 goto done2;
985 from--; 1002 from--;
986 } 1003 }
1020 1037
1021 case Sstring: 1038 case Sstring:
1022 { 1039 {
1023 /* XEmacs change: call syntax_match() on character */ 1040 /* XEmacs change: call syntax_match() on character */
1024 Emchar ch = BUF_FETCH_CHAR (buf, from); 1041 Emchar ch = BUF_FETCH_CHAR (buf, from);
1025 Lisp_Object stermobj = syntax_match (table, ch); 1042 Lisp_Object stermobj = syntax_match (syntaxtab, ch);
1026 Emchar stringterm; 1043 Emchar stringterm;
1027 1044
1028 if (CHARP (stermobj)) 1045 if (CHARP (stermobj))
1029 stringterm = XCHAR (stermobj); 1046 stringterm = XCHAR (stermobj);
1030 else 1047 else
1068 char_quoted (struct buffer *buf, Bufpos pos) 1085 char_quoted (struct buffer *buf, Bufpos pos)
1069 { 1086 {
1070 enum syntaxcode code; 1087 enum syntaxcode code;
1071 Bufpos beg = BUF_BEGV (buf); 1088 Bufpos beg = BUF_BEGV (buf);
1072 int quoted = 0; 1089 int quoted = 0;
1073 Lisp_Object table = buf->syntax_table; 1090 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
1074 1091
1075 while (pos > beg 1092 while (pos > beg
1076 && ((code = SYNTAX (table, BUF_FETCH_CHAR (buf, pos - 1))) 1093 && ((code = SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1)))
1077 == Scharquote 1094 == Scharquote
1078 || code == Sescape)) 1095 || code == Sescape))
1079 pos--, quoted = !quoted; 1096 pos--, quoted = !quoted;
1080 return quoted; 1097 return quoted;
1081 } 1098 }
1150 (buffer)) 1167 (buffer))
1151 { 1168 {
1152 struct buffer *buf = decode_buffer (buffer, 0); 1169 struct buffer *buf = decode_buffer (buffer, 0);
1153 Bufpos beg = BUF_BEGV (buf); 1170 Bufpos beg = BUF_BEGV (buf);
1154 Bufpos pos = BUF_PT (buf); 1171 Bufpos pos = BUF_PT (buf);
1155 Lisp_Object table = buf->syntax_table; 1172 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
1156 1173
1157 while (pos > beg && !char_quoted (buf, pos - 1) 1174 while (pos > beg && !char_quoted (buf, pos - 1)
1158 && (SYNTAX (table, BUF_FETCH_CHAR (buf, pos - 1)) == Squote 1175 && (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1)) == Squote
1159 || SYNTAX_PREFIX (table, BUF_FETCH_CHAR (buf, pos - 1)))) 1176 || SYNTAX_PREFIX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1))))
1160 pos--; 1177 pos--;
1161 1178
1162 BUF_SET_PT (buf, pos); 1179 BUF_SET_PT (buf, pos);
1163 1180
1164 return Qnil; 1181 return Qnil;
1187 int depth; /* Paren depth of current scanning location. 1204 int depth; /* Paren depth of current scanning location.
1188 level - levelstart equals this except 1205 level - levelstart equals this except
1189 when the depth becomes negative. */ 1206 when the depth becomes negative. */
1190 int mindepth; /* Lowest DEPTH value seen. */ 1207 int mindepth; /* Lowest DEPTH value seen. */
1191 int start_quoted = 0; /* Nonzero means starting after a char quote */ 1208 int start_quoted = 0; /* Nonzero means starting after a char quote */
1192 Lisp_Object table = buf->syntax_table;
1193 Lisp_Object tem; 1209 Lisp_Object tem;
1194 int mask; /* comment mask */ 1210 int mask; /* comment mask */
1211 Lisp_Object syntaxtab = buf->syntax_table;
1212 struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
1195 1213
1196 if (NILP (oldstate)) 1214 if (NILP (oldstate))
1197 { 1215 {
1198 depth = 0; 1216 depth = 0;
1199 state.instring = -1; 1217 state.instring = -1;
1250 1268
1251 while (from < end) 1269 while (from < end)
1252 { 1270 {
1253 QUIT; 1271 QUIT;
1254 1272
1255 code = SYNTAX (table, BUF_FETCH_CHAR (buf, from)); 1273 code = SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from));
1256 from++; 1274 from++;
1257 1275
1258 if (code == Scomment) 1276 if (code == Scomment)
1259 { 1277 {
1260 /* record the comment style we have entered so that only the 1278 /* record the comment style we have entered so that only the
1261 comment-ender sequence (or single char) of the same style 1279 comment-ender sequence (or single char) of the same style
1262 actually terminates the comment section. */ 1280 actually terminates the comment section. */
1263 mask = SYNTAX_COMMENT_1CHAR_MASK (table, 1281 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab,
1264 BUF_FETCH_CHAR (buf, from-1)); 1282 BUF_FETCH_CHAR (buf, from-1));
1265 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B); 1283 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
1266 state.comstart = from - 1; 1284 state.comstart = from - 1;
1267 } 1285 }
1268 1286
1269 else if (from < end && 1287 else if (from < end &&
1270 SYNTAX_START_P (table, BUF_FETCH_CHAR (buf, from-1), 1288 SYNTAX_START_P (mirrortab, BUF_FETCH_CHAR (buf, from-1),
1271 BUF_FETCH_CHAR (buf, from))) 1289 BUF_FETCH_CHAR (buf, from)))
1272 { 1290 {
1273 /* Record the comment style we have entered so that only 1291 /* Record the comment style we have entered so that only
1274 the comment-end sequence of the same style actually 1292 the comment-end sequence of the same style actually
1275 terminates the comment section. */ 1293 terminates the comment section. */
1276 code = Scomment; 1294 code = Scomment;
1277 mask = SYNTAX_COMMENT_MASK_START (table, 1295 mask = SYNTAX_COMMENT_MASK_START (mirrortab,
1278 BUF_FETCH_CHAR (buf, from-1), 1296 BUF_FETCH_CHAR (buf, from-1),
1279 BUF_FETCH_CHAR (buf, from)); 1297 BUF_FETCH_CHAR (buf, from));
1280 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B); 1298 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
1281 state.comstart = from-1; 1299 state.comstart = from-1;
1282 from++; 1300 from++;
1283 } 1301 }
1284 1302
1285 if (SYNTAX_PREFIX (table, BUF_FETCH_CHAR (buf, from - 1))) 1303 if (SYNTAX_PREFIX (mirrortab, BUF_FETCH_CHAR (buf, from - 1)))
1286 continue; 1304 continue;
1287 switch (code) 1305 switch (code)
1288 { 1306 {
1289 case Sescape: 1307 case Sescape:
1290 case Scharquote: 1308 case Scharquote:
1294 if (from == end) goto endquoted; 1312 if (from == end) goto endquoted;
1295 from++; 1313 from++;
1296 goto symstarted; 1314 goto symstarted;
1297 /* treat following character as a word constituent */ 1315 /* treat following character as a word constituent */
1298 case Sword: 1316 case Sword:
1299 case Sextword:
1300 case Ssymbol: 1317 case Ssymbol:
1301 if (stopbefore) goto stop; /* this arg means stop at sexp start */ 1318 if (stopbefore) goto stop; /* this arg means stop at sexp start */
1302 curlevel->last = from - 1; 1319 curlevel->last = from - 1;
1303 symstarted: 1320 symstarted:
1304 while (from < end) 1321 while (from < end)
1305 { 1322 {
1306 switch (SYNTAX (table, BUF_FETCH_CHAR (buf, from))) 1323 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from)))
1307 { 1324 {
1308 case Scharquote: 1325 case Scharquote:
1309 case Sescape: 1326 case Sescape:
1310 from++; 1327 from++;
1311 if (from == end) goto endquoted; 1328 if (from == end) goto endquoted;
1312 break; 1329 break;
1313 case Sword: 1330 case Sword:
1314 case Sextword:
1315 case Ssymbol: 1331 case Ssymbol:
1316 case Squote: 1332 case Squote:
1317 break; 1333 break;
1318 default: 1334 default:
1319 goto symdone; 1335 goto symdone;
1351 curlevel->last = from - 1; 1367 curlevel->last = from - 1;
1352 if (++curlevel == endlevel) 1368 if (++curlevel == endlevel)
1353 error ("Nesting too deep for parser"); 1369 error ("Nesting too deep for parser");
1354 curlevel->prev = -1; 1370 curlevel->prev = -1;
1355 curlevel->last = -1; 1371 curlevel->last = -1;
1356 if (targetdepth == depth) goto done; 1372 if (!--targetdepth) goto done;
1357 break; 1373 break;
1358 1374
1359 case Sclose: 1375 case Sclose:
1360 depth--; 1376 depth--;
1361 if (depth < mindepth) 1377 if (depth < mindepth)
1362 mindepth = depth; 1378 mindepth = depth;
1363 if (curlevel != levelstart) 1379 if (curlevel != levelstart)
1364 curlevel--; 1380 curlevel--;
1365 curlevel->prev = curlevel->last; 1381 curlevel->prev = curlevel->last;
1366 if (targetdepth == depth) goto done; 1382 if (!++targetdepth) goto done;
1367 break; 1383 break;
1368 1384
1369 case Sstring: 1385 case Sstring:
1370 { 1386 {
1371 Emchar ch; 1387 Emchar ch;
1372 if (stopbefore) goto stop; /* this arg means stop at sexp start */ 1388 if (stopbefore) goto stop; /* this arg means stop at sexp start */
1373 curlevel->last = from - 1; 1389 curlevel->last = from - 1;
1374 /* XEmacs change: call syntax_match() on character */ 1390 /* XEmacs change: call syntax_match() on character */
1375 ch = BUF_FETCH_CHAR (buf, from - 1); 1391 ch = BUF_FETCH_CHAR (buf, from - 1);
1376 { 1392 {
1377 Lisp_Object stermobj = syntax_match (table, ch); 1393 Lisp_Object stermobj = syntax_match (syntaxtab, ch);
1378 1394
1379 if (CHARP (stermobj)) 1395 if (CHARP (stermobj))
1380 state.instring = XCHAR (stermobj); 1396 state.instring = XCHAR (stermobj);
1381 else 1397 else
1382 state.instring = ch; 1398 state.instring = ch;
1385 startinstring: 1401 startinstring:
1386 while (1) 1402 while (1)
1387 { 1403 {
1388 if (from >= end) goto done; 1404 if (from >= end) goto done;
1389 if (BUF_FETCH_CHAR (buf, from) == state.instring) break; 1405 if (BUF_FETCH_CHAR (buf, from) == state.instring) break;
1390 switch (SYNTAX (table, BUF_FETCH_CHAR (buf, from))) 1406 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from)))
1391 { 1407 {
1392 case Scharquote: 1408 case Scharquote:
1393 case Sescape: 1409 case Sescape:
1394 { 1410 {
1395 from++; 1411 from++;
1505 1521
1506 return (Flist (8, retval)); 1522 return (Flist (8, retval));
1507 } 1523 }
1508 } 1524 }
1509 1525
1526
1527 /* Updating of the mirror syntax table.
1528
1529 Each syntax table has a corresponding mirror table in it.
1530 Whenever we make a change to a syntax table, we call
1531 update_syntax_table() on it.
1532
1533 #### We really only need to map over the changed range.
1534
1535 If we change the standard syntax table, we need to map over
1536 all tables because any of them could be inheriting from the
1537 standard syntax table.
1538
1539 When `set-syntax-table' is called, we set the buffer's mirror
1540 syntax table as well.
1541 */
1542
1543 struct cmst_arg
1544 {
1545 Lisp_Object mirrortab;
1546 int check_inherit;
1547 };
1548
1549 static int
1550 cmst_mapfun (struct chartab_range *range, Lisp_Object val, void *arg)
1551 {
1552 struct cmst_arg *closure = (struct cmst_arg *) arg;
1553
1554 if (CONSP (val))
1555 val = XCAR (val);
1556 if (SYNTAX_FROM_CODE (XINT (val)) == Sinherit
1557 && closure->check_inherit)
1558 {
1559 struct cmst_arg recursive;
1560
1561 recursive.mirrortab = closure->mirrortab;
1562 recursive.check_inherit = 0;
1563 map_char_table (XCHAR_TABLE (Vstandard_syntax_table), range,
1564 cmst_mapfun, &recursive);
1565 }
1566 else
1567 put_char_table (XCHAR_TABLE (closure->mirrortab), range, val);
1568 return 0;
1569 }
1570
1571 static void
1572 update_just_this_syntax_table (struct Lisp_Char_Table *ct)
1573 {
1574 struct chartab_range range;
1575 struct cmst_arg arg;
1576
1577 arg.mirrortab = ct->mirror_table;
1578 arg.check_inherit = (CHAR_TABLEP (Vstandard_syntax_table)
1579 && ct != XCHAR_TABLE (Vstandard_syntax_table));
1580 range.type = CHARTAB_RANGE_ALL;
1581 map_char_table (ct, &range, cmst_mapfun, &arg);
1582 }
1583
1584 /* Called from chartab.c when a change is made to a syntax table.
1585 If this is the standard syntax table, we need to recompute
1586 *all* syntax tables (yuck). Otherwise we just recompute this
1587 one. */
1588
1589 void
1590 update_syntax_table (struct Lisp_Char_Table *ct)
1591 {
1592 /* Don't be stymied at startup. */
1593 if (CHAR_TABLEP (Vstandard_syntax_table)
1594 && ct == XCHAR_TABLE (Vstandard_syntax_table))
1595 {
1596 Lisp_Object syntab;
1597
1598 for (syntab = Vall_syntax_tables; !NILP (syntab);
1599 syntab = XCHAR_TABLE (syntab)->next_table)
1600 update_just_this_syntax_table (XCHAR_TABLE (syntab));
1601 }
1602 else
1603 update_just_this_syntax_table (ct);
1604 }
1605
1510 1606
1511 /************************************************************************/ 1607 /************************************************************************/
1512 /* initialization */ 1608 /* initialization */
1513 /************************************************************************/ 1609 /************************************************************************/
1514 1610
1553 } 1649 }
1554 1650
1555 void 1651 void
1556 complex_vars_of_syntax (void) 1652 complex_vars_of_syntax (void)
1557 { 1653 {
1558 struct Lisp_Vector *v;
1559 int i;
1560
1561 /* Set this now, so first buffer creation can refer to it. */ 1654 /* Set this now, so first buffer creation can refer to it. */
1562 /* Make it nil before calling copy-syntax-table 1655 /* Make it nil before calling copy-syntax-table
1563 so that copy-syntax-table will know not to try to copy from garbage */ 1656 so that copy-syntax-table will know not to try to copy from garbage */
1564 Vstandard_syntax_table = Qnil; 1657 Vstandard_syntax_table = Qnil;
1565 Vstandard_syntax_table = Fcopy_syntax_table (Qnil); 1658 Vstandard_syntax_table = Fcopy_syntax_table (Qnil);
1567 1660
1568 Vsyntax_designator_chars_string = make_pure_string (syntax_code_spec, 1661 Vsyntax_designator_chars_string = make_pure_string (syntax_code_spec,
1569 Smax, Qnil, 1); 1662 Smax, Qnil, 1);
1570 staticpro (&Vsyntax_designator_chars_string); 1663 staticpro (&Vsyntax_designator_chars_string);
1571 1664
1572 v = XVECTOR (Vstandard_syntax_table); 1665 fill_char_table (XCHAR_TABLE (Vstandard_syntax_table),
1573 1666 make_int (Spunct));
1574 for (i = 'a'; i <= 'z'; i++) 1667
1575 v->contents[i] = make_int ((int) Sword);
1576 for (i = 'A'; i <= 'Z'; i++)
1577 v->contents[i] = make_int ((int) Sword);
1578 for (i = '0'; i <= '9'; i++)
1579 v->contents[i] = make_int ((int) Sword);
1580 v->contents['$'] = make_int ((int) Sword);
1581 v->contents['%'] = make_int ((int) Sword);
1582
1583 v->contents['('] = make_int ((int) Sopen + (')' << 8));
1584 v->contents[')'] = make_int ((int) Sclose + ('(' << 8));
1585 v->contents['['] = make_int ((int) Sopen + (']' << 8));
1586 v->contents[']'] = make_int ((int) Sclose + ('[' << 8));
1587 v->contents['{'] = make_int ((int) Sopen + ('}' << 8));
1588 v->contents['}'] = make_int ((int) Sclose + ('{' << 8));
1589 v->contents['"'] = make_int ((int) Sstring);
1590 v->contents['\\'] = make_int ((int) Sescape);
1591
1592 { 1668 {
1593 CONST char *p; 1669 Emchar i;
1594 1670
1595 for (p = "_-+*/&|<>="; *p; p++) 1671 for (i = 0; i <= 32; i++)
1596 v->contents[(int) *p] = make_int ((int) Ssymbol); 1672 Fput_char_table (make_char (i), make_int ((int) Swhitespace),
1673 Vstandard_syntax_table);
1674 for (i = 127; i <= 159; i++)
1675 Fput_char_table (make_char (i), make_int ((int) Swhitespace),
1676 Vstandard_syntax_table);
1677
1678 for (i = 'a'; i <= 'z'; i++)
1679 Fput_char_table (make_char (i), make_int ((int) Sword),
1680 Vstandard_syntax_table);
1681 for (i = 'A'; i <= 'Z'; i++)
1682 Fput_char_table (make_char (i), make_int ((int) Sword),
1683 Vstandard_syntax_table);
1684 for (i = '0'; i <= '9'; i++)
1685 Fput_char_table (make_char (i), make_int ((int) Sword),
1686 Vstandard_syntax_table);
1687 Fput_char_table (make_char ('$'), make_int ((int) Sword),
1688 Vstandard_syntax_table);
1689 Fput_char_table (make_char ('%'), make_int ((int) Sword),
1690 Vstandard_syntax_table);
1691
1692 {
1693 Fput_char_table (make_char ('('), Fcons (make_int ((int) Sopen),
1694 make_char (')')),
1695 Vstandard_syntax_table);
1696 Fput_char_table (make_char (')'), Fcons (make_int ((int) Sclose),
1697 make_char ('(')),
1698 Vstandard_syntax_table);
1699 Fput_char_table (make_char ('['), Fcons (make_int ((int) Sopen),
1700 make_char (']')),
1701 Vstandard_syntax_table);
1702 Fput_char_table (make_char (']'), Fcons (make_int ((int) Sclose),
1703 make_char ('[')),
1704 Vstandard_syntax_table);
1705 Fput_char_table (make_char ('{'), Fcons (make_int ((int) Sopen),
1706 make_char ('}')),
1707 Vstandard_syntax_table);
1708 Fput_char_table (make_char ('}'), Fcons (make_int ((int) Sclose),
1709 make_char ('{')),
1710 Vstandard_syntax_table);
1711 }
1712
1713 Fput_char_table (make_char ('"'), make_int ((int) Sstring),
1714 Vstandard_syntax_table);
1715 Fput_char_table (make_char ('\\'), make_int ((int) Sescape),
1716 Vstandard_syntax_table);
1597 1717
1598 for (p = ".,;:?!#@~^'`"; *p; p++) 1718 {
1599 v->contents[(int) *p] = make_int ((int) Spunct); 1719 CONST char *p;
1720 for (p = "_-+*/&|<>="; *p; p++)
1721 Fput_char_table (make_char (*p), make_int ((int) Ssymbol),
1722 Vstandard_syntax_table);
1723
1724 for (p = ".,;:?!#@~^'`"; *p; p++)
1725 Fput_char_table (make_char (*p), make_int ((int) Spunct),
1726 Vstandard_syntax_table);
1727 }
1600 } 1728 }
1601 } 1729 }