Mercurial > hg > xemacs-beta
comparison src/syntax.c @ 1296:87084e8445a7
[xemacs-hg @ 2003-02-14 09:50:15 by ben]
syntax-table fixes
1. the updating of mirror tables every time a syntax table was modified
was taking up huge amounts of time so i added a dirty flag and made the
updating "just-in-time".
2. no-longer-used char-table-entries were not getting "freed", generating
tons of garbage.
3. syntax_match() was being incorrectly called on mirror tables in the
cache, not the original syntax table.
buffer.c, syntax.c: Move syntax table description from buffer.c to syntax.c.
chartab.c, chartab.h: Free extra char table entries to avoid excessive garbage.
Add flags for dirty and mirror_table_p to char tables.
Add a back pointer from mirror tables to the original syntax table.
When modifying a syntax table, don't update the mirror table right
away, just mark as dirty.
Add various asserts to make sure we are dealing with the right type
of table (mirror or non-mirror).
font-lock.c, syntax.c, syntax.h: Add entry to syntax caches for the non-mirror table. Set it
appropriately when initializing the syntax table. Use it, not
the mirror table, for calls to syntax_match().
Don't create a bogus float each time, just once at startup.
Add some asserts, as in chartab.c.
syntax.h: When retrieving the syntax code, check the dirty flag and update
the mirror tables as appropriate.
Add some asserts, as above.
author | ben |
---|---|
date | Fri, 14 Feb 2003 09:50:17 +0000 |
parents | 79c6ff3eef26 |
children | 70921960b980 |
comparison
equal
deleted
inserted
replaced
1295:064ef1d07d63 | 1296:87084e8445a7 |
---|---|
1 /* XEmacs routines to deal with syntax tables; also word and list parsing. | 1 /* XEmacs routines to deal with syntax tables; also word and list parsing. |
2 Copyright (C) 1985-1994 Free Software Foundation, Inc. | 2 Copyright (C) 1985-1994 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 2001, 2002 Ben Wing. | 4 Copyright (C) 2001, 2002, 2003 Ben Wing. |
5 | 5 |
6 This file is part of XEmacs. | 6 This file is part of XEmacs. |
7 | 7 |
8 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
83 Lisp_Object Vstandard_syntax_table; | 83 Lisp_Object Vstandard_syntax_table; |
84 | 84 |
85 Lisp_Object Vsyntax_designator_chars_string; | 85 Lisp_Object Vsyntax_designator_chars_string; |
86 | 86 |
87 Lisp_Object Vtemp_table_for_use_updating_syntax_tables; | 87 Lisp_Object Vtemp_table_for_use_updating_syntax_tables; |
88 | |
89 /* A value that is guaranteed not be in a syntax table. */ | |
90 Lisp_Object Vbogus_syntax_table_value; | |
88 | 91 |
89 static void syntax_cache_table_was_changed (struct buffer *buf); | 92 static void syntax_cache_table_was_changed (struct buffer *buf); |
90 | 93 |
91 /* This is the internal form of the parse state used in parse-partial-sexp. */ | 94 /* This is the internal form of the parse state used in parse-partial-sexp. */ |
92 | 95 |
269 { | 272 { |
270 xzero (*cache); | 273 xzero (*cache); |
271 cache->object = object; | 274 cache->object = object; |
272 cache->buffer = buffer; | 275 cache->buffer = buffer; |
273 cache->no_syntax_table_prop = 1; | 276 cache->no_syntax_table_prop = 1; |
274 cache->current_syntax_table = | 277 cache->syntax_table = |
278 BUFFER_SYNTAX_TABLE (cache->buffer); | |
279 cache->mirror_table = | |
275 BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | 280 BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); |
276 cache->start = Qnil; | 281 cache->start = Qnil; |
277 cache->end = Qnil; | 282 cache->end = Qnil; |
278 if (infinite) | 283 if (infinite) |
279 { | 284 { |
306 from); | 311 from); |
307 } | 312 } |
308 if (!(from >= cache->prev_change && from < cache->next_change)) | 313 if (!(from >= cache->prev_change && from < cache->next_change)) |
309 update_syntax_cache (cache, from, count); | 314 update_syntax_cache (cache, from, count); |
310 } | 315 } |
316 #ifdef NOT_WORTH_THE_EFFORT | |
317 update_mirror_syntax_if_dirty (cache->mirror_table); | |
318 #endif /* NOT_WORTH_THE_EFFORT */ | |
311 return cache; | 319 return cache; |
312 } | 320 } |
313 | 321 |
314 struct syntax_cache * | 322 struct syntax_cache * |
315 setup_buffer_syntax_cache (struct buffer *buffer, Charxpos from, int count) | 323 setup_buffer_syntax_cache (struct buffer *buffer, Charxpos from, int count) |
316 { | 324 { |
317 return setup_syntax_cache (NULL, wrap_buffer (buffer), buffer, from, count); | 325 return setup_syntax_cache (NULL, wrap_buffer (buffer), buffer, from, count); |
318 } | 326 } |
327 | |
328 static const struct memory_description syntax_cache_description_1 [] = { | |
329 { XD_LISP_OBJECT, offsetof (struct syntax_cache, object) }, | |
330 { XD_LISP_OBJECT, offsetof (struct syntax_cache, buffer) }, | |
331 { XD_LISP_OBJECT, offsetof (struct syntax_cache, syntax_table) }, | |
332 { XD_LISP_OBJECT, offsetof (struct syntax_cache, mirror_table) }, | |
333 { XD_LISP_OBJECT, offsetof (struct syntax_cache, start) }, | |
334 { XD_LISP_OBJECT, offsetof (struct syntax_cache, end) }, | |
335 { XD_END } | |
336 }; | |
337 | |
338 const struct sized_memory_description syntax_cache_description = { | |
339 sizeof (struct syntax_cache), | |
340 syntax_cache_description_1 | |
341 }; | |
319 | 342 |
320 void | 343 void |
321 mark_buffer_syntax_cache (struct buffer *buf) | 344 mark_buffer_syntax_cache (struct buffer *buf) |
322 { | 345 { |
323 struct syntax_cache *cache = buf->syntax_cache; | 346 struct syntax_cache *cache = buf->syntax_cache; |
324 if (!cache) /* Vbuffer_defaults and such don't have caches */ | 347 if (!cache) /* Vbuffer_defaults and such don't have caches */ |
325 return; | 348 return; |
326 mark_object (cache->object); | 349 mark_object (cache->object); |
327 if (cache->buffer) | 350 if (cache->buffer) |
328 mark_object (wrap_buffer (cache->buffer)); | 351 mark_object (wrap_buffer (cache->buffer)); |
329 mark_object (cache->current_syntax_table); | 352 mark_object (cache->syntax_table); |
353 mark_object (cache->mirror_table); | |
330 mark_object (cache->start); | 354 mark_object (cache->start); |
331 mark_object (cache->end); | 355 mark_object (cache->end); |
332 } | 356 } |
333 | 357 |
334 static void | 358 static void |
349 buf->syntax_cache = xnew_and_zero (struct syntax_cache); | 373 buf->syntax_cache = xnew_and_zero (struct syntax_cache); |
350 cache = buf->syntax_cache; | 374 cache = buf->syntax_cache; |
351 cache->object = wrap_buffer (buf); | 375 cache->object = wrap_buffer (buf); |
352 cache->buffer = buf; | 376 cache->buffer = buf; |
353 cache->no_syntax_table_prop = 1; | 377 cache->no_syntax_table_prop = 1; |
354 cache->current_syntax_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | 378 cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer); |
379 cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | |
355 cache->start = Fmake_marker (); | 380 cache->start = Fmake_marker (); |
356 cache->end = Fmake_marker (); | 381 cache->end = Fmake_marker (); |
357 reset_buffer_cache_range (cache, cache->object); | 382 reset_buffer_cache_range (cache, cache->object); |
358 } | 383 } |
359 | 384 |
368 static void | 393 static void |
369 syntax_cache_table_was_changed (struct buffer *buf) | 394 syntax_cache_table_was_changed (struct buffer *buf) |
370 { | 395 { |
371 struct syntax_cache *cache = buf->syntax_cache; | 396 struct syntax_cache *cache = buf->syntax_cache; |
372 if (cache->no_syntax_table_prop) | 397 if (cache->no_syntax_table_prop) |
373 cache->current_syntax_table = | 398 { |
374 BUFFER_MIRROR_SYNTAX_TABLE (buf); | 399 cache->syntax_table = |
400 BUFFER_SYNTAX_TABLE (buf); | |
401 cache->mirror_table = | |
402 BUFFER_MIRROR_SYNTAX_TABLE (buf); | |
403 } | |
375 } | 404 } |
376 | 405 |
377 /* The syntax-table property on the range covered by EXTENT may be changing, | 406 /* The syntax-table property on the range covered by EXTENT may be changing, |
378 either because EXTENT has a syntax-table property and is being attached | 407 either because EXTENT has a syntax-table property and is being attached |
379 or detached (this includes having its endpoints changed), or because | 408 or detached (this includes having its endpoints changed), or because |
493 } | 522 } |
494 | 523 |
495 if (!NILP (Fsyntax_table_p (tmp_table))) | 524 if (!NILP (Fsyntax_table_p (tmp_table))) |
496 { | 525 { |
497 cache->use_code = 0; | 526 cache->use_code = 0; |
498 cache->current_syntax_table = | 527 cache->syntax_table = tmp_table; |
499 XCHAR_TABLE (tmp_table)->mirror_table; | 528 cache->mirror_table = XCHAR_TABLE (tmp_table)->mirror_table; |
500 cache->no_syntax_table_prop = 0; | 529 cache->no_syntax_table_prop = 0; |
530 #ifdef NOT_WORTH_THE_EFFORT | |
531 update_mirror_syntax_if_dirty (cache->mirror_table); | |
532 #endif /* NOT_WORTH_THE_EFFORT */ | |
501 } | 533 } |
502 else if (CONSP (tmp_table) && INTP (XCAR (tmp_table))) | 534 else if (CONSP (tmp_table) && INTP (XCAR (tmp_table))) |
503 { | 535 { |
504 cache->use_code = 1; | 536 cache->use_code = 1; |
505 cache->syntax_code = XINT (XCAR (tmp_table)); | 537 cache->syntax_code = XINT (XCAR (tmp_table)); |
507 } | 539 } |
508 else | 540 else |
509 { | 541 { |
510 cache->use_code = 0; | 542 cache->use_code = 0; |
511 cache->no_syntax_table_prop = 1; | 543 cache->no_syntax_table_prop = 1; |
512 cache->current_syntax_table = | 544 cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer); |
513 BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | 545 cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); |
546 #ifdef NOT_WORTH_THE_EFFORT | |
547 update_mirror_syntax_if_dirty (cache->mirror_table); | |
548 #endif /* NOT_WORTH_THE_EFFORT */ | |
514 } | 549 } |
515 } | 550 } |
516 | 551 |
517 /* Convert a letter which signifies a syntax code | 552 /* Convert a letter which signifies a syntax code |
518 into the code it signifies. | 553 into the code it signifies. |
1405 if (code != Sstring_fence) | 1440 if (code != Sstring_fence) |
1406 { | 1441 { |
1407 /* XEmacs change: call syntax_match on character */ | 1442 /* XEmacs change: call syntax_match on character */ |
1408 Ichar ch = BUF_FETCH_CHAR (buf, from - 1); | 1443 Ichar ch = BUF_FETCH_CHAR (buf, from - 1); |
1409 Lisp_Object stermobj = | 1444 Lisp_Object stermobj = |
1410 syntax_match (scache->current_syntax_table, ch); | 1445 syntax_match (scache->syntax_table, ch); |
1411 | 1446 |
1412 if (CHARP (stermobj)) | 1447 if (CHARP (stermobj)) |
1413 stringterm = XCHAR (stermobj); | 1448 stringterm = XCHAR (stermobj); |
1414 else | 1449 else |
1415 stringterm = ch; | 1450 stringterm = ch; |
1585 if (code != Sstring_fence) | 1620 if (code != Sstring_fence) |
1586 { | 1621 { |
1587 /* XEmacs change: call syntax_match() on character */ | 1622 /* XEmacs change: call syntax_match() on character */ |
1588 Ichar ch = BUF_FETCH_CHAR (buf, from); | 1623 Ichar ch = BUF_FETCH_CHAR (buf, from); |
1589 Lisp_Object stermobj = | 1624 Lisp_Object stermobj = |
1590 syntax_match (scache->current_syntax_table, ch); | 1625 syntax_match (scache->syntax_table, ch); |
1591 | 1626 |
1592 if (CHARP (stermobj)) | 1627 if (CHARP (stermobj)) |
1593 stringterm = XCHAR (stermobj); | 1628 stringterm = XCHAR (stermobj); |
1594 else | 1629 else |
1595 stringterm = ch; | 1630 stringterm = ch; |
2010 else | 2045 else |
2011 { | 2046 { |
2012 /* XEmacs change: call syntax_match() on character */ | 2047 /* XEmacs change: call syntax_match() on character */ |
2013 Ichar ch = BUF_FETCH_CHAR (buf, from - 1); | 2048 Ichar ch = BUF_FETCH_CHAR (buf, from - 1); |
2014 Lisp_Object stermobj = | 2049 Lisp_Object stermobj = |
2015 syntax_match (scache->current_syntax_table, ch); | 2050 syntax_match (scache->syntax_table, ch); |
2016 | 2051 |
2017 if (CHARP (stermobj)) | 2052 if (CHARP (stermobj)) |
2018 state.instring = XCHAR (stermobj); | 2053 state.instring = XCHAR (stermobj); |
2019 else | 2054 else |
2020 state.instring = ch; | 2055 state.instring = ch; |
2179 } | 2214 } |
2180 | 2215 |
2181 | 2216 |
2182 /* Updating of the mirror syntax table. | 2217 /* Updating of the mirror syntax table. |
2183 | 2218 |
2184 Each syntax table has a corresponding mirror table in it. | 2219 Each syntax table has a corresponding mirror table in it. Whenever we |
2185 Whenever we make a change to a syntax table, we call | 2220 make a change to a syntax table, we set a dirty flag. When accessing a |
2186 update_syntax_table() on it. | 2221 value from the mirror table and the table is dirty, we call |
2222 update_syntax_table() to clean it up. | |
2187 | 2223 |
2188 #### We really only need to map over the changed range. | 2224 #### We really only need to map over the changed range. |
2189 | 2225 |
2190 If we change the standard syntax table, we need to map over | 2226 If we change the standard syntax table, we need to map over |
2191 all tables because any of them could be inheriting from the | 2227 all tables because any of them could be inheriting from the |
2206 if (SYNTAX_FROM_CODE (XINT (val)) != Sinherit) | 2242 if (SYNTAX_FROM_CODE (XINT (val)) != Sinherit) |
2207 put_char_table (mirrortab, range, val); | 2243 put_char_table (mirrortab, range, val); |
2208 return 0; | 2244 return 0; |
2209 } | 2245 } |
2210 | 2246 |
2211 struct cinap | |
2212 { | |
2213 Lisp_Object mirrortab; | |
2214 Lisp_Object bogus; | |
2215 }; | |
2216 | |
2217 static int | 2247 static int |
2218 copy_if_not_already_present (struct chartab_range *range, Lisp_Object table, | 2248 copy_if_not_already_present (struct chartab_range *range, Lisp_Object table, |
2219 Lisp_Object val, void *arg) | 2249 Lisp_Object val, void *arg) |
2220 { | 2250 { |
2221 struct cinap *a = (struct cinap *) arg; | 2251 Lisp_Object mirrortab = VOID_TO_LISP (arg); |
2222 | |
2223 if (CONSP (val)) | 2252 if (CONSP (val)) |
2224 val = XCAR (val); | 2253 val = XCAR (val); |
2225 if (SYNTAX_FROM_CODE (XINT (val)) != Sinherit) | 2254 if (SYNTAX_FROM_CODE (XINT (val)) != Sinherit) |
2226 { | 2255 { |
2227 Lisp_Object existing = | 2256 Lisp_Object existing = |
2228 get_range_char_table (range, a->mirrortab, a->bogus); | 2257 updating_mirror_get_range_char_table (range, mirrortab, |
2258 Vbogus_syntax_table_value); | |
2229 if (NILP (existing)) | 2259 if (NILP (existing)) |
2230 /* nothing at all */ | 2260 /* nothing at all */ |
2231 put_char_table (a->mirrortab, range, val); | 2261 put_char_table (mirrortab, range, val); |
2232 else if (!EQ (existing, a->bogus)) | 2262 else if (!EQ (existing, Vbogus_syntax_table_value)) |
2233 /* full */ | 2263 /* full */ |
2234 ; | 2264 ; |
2235 else | 2265 else |
2236 { | 2266 { |
2237 Freset_char_table (Vtemp_table_for_use_updating_syntax_tables); | 2267 Freset_char_table (Vtemp_table_for_use_updating_syntax_tables); |
2238 copy_char_table_range | 2268 copy_char_table_range |
2239 (a->mirrortab, | 2269 (mirrortab, Vtemp_table_for_use_updating_syntax_tables, range); |
2240 Vtemp_table_for_use_updating_syntax_tables, | 2270 put_char_table (mirrortab, range, val); |
2241 range); | |
2242 put_char_table (a->mirrortab, range, val); | |
2243 copy_char_table_range | 2271 copy_char_table_range |
2244 (Vtemp_table_for_use_updating_syntax_tables, | 2272 (Vtemp_table_for_use_updating_syntax_tables, mirrortab, range); |
2245 a->mirrortab, range); | |
2246 } | 2273 } |
2247 } | 2274 } |
2248 | 2275 |
2249 return 0; | 2276 return 0; |
2250 } | 2277 } |
2253 update_just_this_syntax_table (Lisp_Object table) | 2280 update_just_this_syntax_table (Lisp_Object table) |
2254 { | 2281 { |
2255 struct chartab_range range; | 2282 struct chartab_range range; |
2256 Lisp_Object mirrortab = XCHAR_TABLE (table)->mirror_table; | 2283 Lisp_Object mirrortab = XCHAR_TABLE (table)->mirror_table; |
2257 | 2284 |
2285 assert (!XCHAR_TABLE (table)->mirror_table_p); | |
2258 range.type = CHARTAB_RANGE_ALL; | 2286 range.type = CHARTAB_RANGE_ALL; |
2259 Freset_char_table (mirrortab); | 2287 Freset_char_table (mirrortab); |
2288 | |
2260 /* First, copy the tables values other than inherit into the mirror | 2289 /* First, copy the tables values other than inherit into the mirror |
2261 table. Then, for tables other than the standard syntax table, map | 2290 table. Then, for tables other than the standard syntax table, map |
2262 over the standard table, copying values into the mirror table only if | 2291 over the standard table, copying values into the mirror table only if |
2263 entries don't already exist in that table. (The copying step requires | 2292 entries don't already exist in that table. (The copying step requires |
2264 another mapping.) | 2293 another mapping.) |
2266 | 2295 |
2267 map_char_table (table, &range, copy_to_mirrortab, LISP_TO_VOID (mirrortab)); | 2296 map_char_table (table, &range, copy_to_mirrortab, LISP_TO_VOID (mirrortab)); |
2268 /* second clause catches bootstrapping problems when initializing the | 2297 /* second clause catches bootstrapping problems when initializing the |
2269 standard syntax table */ | 2298 standard syntax table */ |
2270 if (!EQ (table, Vstandard_syntax_table) && !NILP (Vstandard_syntax_table)) | 2299 if (!EQ (table, Vstandard_syntax_table) && !NILP (Vstandard_syntax_table)) |
2271 { | 2300 map_char_table (Vstandard_syntax_table, &range, |
2272 struct cinap cinap; | 2301 copy_if_not_already_present, LISP_TO_VOID (mirrortab)); |
2273 struct gcpro gcpro1; | |
2274 cinap.mirrortab = mirrortab; | |
2275 /* Something that won't be in the table. */ | |
2276 cinap.bogus = make_float (0.0); | |
2277 GCPRO1 (cinap.bogus); | |
2278 map_char_table (Vstandard_syntax_table, &range, | |
2279 copy_if_not_already_present, &cinap); | |
2280 UNGCPRO; | |
2281 } | |
2282 /* The resetting made the default be Qnil. Put it back to Spunct. */ | 2302 /* The resetting made the default be Qnil. Put it back to Spunct. */ |
2283 set_char_table_default (mirrortab, make_int (Spunct)); | 2303 set_char_table_default (mirrortab, make_int (Spunct)); |
2304 XCHAR_TABLE (mirrortab)->dirty = 0; | |
2284 } | 2305 } |
2285 | 2306 |
2286 /* Called from chartab.c when a change is made to a syntax table. | 2307 /* Called from chartab.c when a change is made to a syntax table. |
2287 If this is the standard syntax table, we need to recompute | 2308 If this is the standard syntax table, we need to recompute |
2288 *all* syntax tables (yuck). Otherwise we just recompute this | 2309 *all* syntax tables (yuck). Otherwise we just recompute this |
2289 one. */ | 2310 one. */ |
2290 | 2311 |
2291 void | 2312 void |
2292 update_syntax_table (Lisp_Object table) | 2313 update_syntax_table (Lisp_Object table) |
2293 { | 2314 { |
2294 if (EQ (table, Vstandard_syntax_table)) | 2315 Lisp_Object nonmirror = XCHAR_TABLE (table)->mirror_table; |
2316 assert (XCHAR_TABLE (table)->mirror_table_p); | |
2317 if (EQ (nonmirror, Vstandard_syntax_table)) | |
2295 { | 2318 { |
2296 Lisp_Object syntab; | 2319 Lisp_Object syntab; |
2297 | 2320 |
2298 for (syntab = Vall_syntax_tables; !NILP (syntab); | 2321 for (syntab = Vall_syntax_tables; !NILP (syntab); |
2299 syntab = XCHAR_TABLE (syntab)->next_table) | 2322 syntab = XCHAR_TABLE (syntab)->next_table) |
2300 update_just_this_syntax_table (syntab); | 2323 update_just_this_syntax_table (syntab); |
2301 } | 2324 } |
2302 else | 2325 else |
2303 update_just_this_syntax_table (table); | 2326 update_just_this_syntax_table (nonmirror); |
2304 } | 2327 } |
2305 | 2328 |
2306 | 2329 |
2307 /************************************************************************/ | 2330 /************************************************************************/ |
2308 /* initialization */ | 2331 /* initialization */ |
2363 Non-nil means `forward-word', etc., should treat escape chars part of words. | 2386 Non-nil means `forward-word', etc., should treat escape chars part of words. |
2364 */ ); | 2387 */ ); |
2365 words_include_escapes = 0; | 2388 words_include_escapes = 0; |
2366 | 2389 |
2367 no_quit_in_re_search = 0; | 2390 no_quit_in_re_search = 0; |
2391 | |
2392 Vbogus_syntax_table_value = make_float (0.0); | |
2393 staticpro (&Vbogus_syntax_table_value); | |
2368 } | 2394 } |
2369 | 2395 |
2370 static void | 2396 static void |
2371 define_standard_syntax (const char *p, enum syntaxcode syn) | 2397 define_standard_syntax (const char *p, enum syntaxcode syn) |
2372 { | 2398 { |