comparison src/syntax.c @ 3252:a66d0a29e183

[xemacs-hg @ 2006-02-22 03:30:06 by stephent] Fix out-of-order definition. <87fymcnkdu.fsf@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Wed, 22 Feb 2006 03:30:08 +0000
parents 2b8bb4938bb4
children efa52de8c279
comparison
equal deleted inserted replaced
3251:4ae19a15d5b0 3252:a66d0a29e183
236 syntax_cache_table_was_changed (buf); 236 syntax_cache_table_was_changed (buf);
237 /* Indicate that this buffer now has a specified syntax table. */ 237 /* Indicate that this buffer now has a specified syntax table. */
238 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table); 238 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table);
239 return syntax_table; 239 return syntax_table;
240 } 240 }
241
242
241 243
244 /*
245 * Syntax caching
246 */
247
248 /* syntax_cache object implementation */
249
250 static const struct memory_description syntax_cache_description_1 [] = {
251 { XD_LISP_OBJECT, offsetof (struct syntax_cache, object) },
252 { XD_LISP_OBJECT, offsetof (struct syntax_cache, buffer) },
253 { XD_LISP_OBJECT, offsetof (struct syntax_cache, syntax_table) },
254 { XD_LISP_OBJECT, offsetof (struct syntax_cache, mirror_table) },
255 { XD_LISP_OBJECT, offsetof (struct syntax_cache, start) },
256 { XD_LISP_OBJECT, offsetof (struct syntax_cache, end) },
257 { XD_END }
258 };
259
260 #ifdef NEW_GC
261 DEFINE_LRECORD_IMPLEMENTATION ("syntax-cache", syntax_cache,
262 1, /*dumpable-flag*/
263 0, 0, 0, 0, 0,
264 syntax_cache_description_1,
265 Lisp_Syntax_Cache);
266 #else /* not NEW_GC */
267
268 const struct sized_memory_description syntax_cache_description = {
269 sizeof (struct syntax_cache),
270 syntax_cache_description_1
271 };
272 #endif /* not NEW_GC */
273
274 /* static syntax cache utilities */
275
276 static void
277 syntax_cache_table_was_changed (struct buffer *buf)
278 {
279 struct syntax_cache *cache = buf->syntax_cache;
280 if (cache->no_syntax_table_prop)
281 {
282 cache->syntax_table =
283 BUFFER_SYNTAX_TABLE (buf);
284 cache->mirror_table =
285 BUFFER_MIRROR_SYNTAX_TABLE (buf);
286 }
287 }
288
289 static void
290 reset_buffer_syntax_cache_range (struct syntax_cache *cache,
291 Lisp_Object buffer, int infinite)
292 {
293 Fset_marker (cache->start, make_int (1), buffer);
294 Fset_marker (cache->end, make_int (1), buffer);
295 Fset_marker_insertion_type (cache->start, Qt);
296 Fset_marker_insertion_type (cache->end, Qnil);
297 /* #### Should we "cache->no_syntax_table_prop = 1;" here? */
298 /* #### Cf comment on INFINITE in init_syntax_cache. -- sjt */
299 if (infinite)
300 {
301 cache->prev_change = EMACS_INT_MIN;
302 cache->next_change = EMACS_INT_MAX;
303 }
304 else
305 {
306 cache->prev_change = -1;
307 cache->next_change = -1;
308 }
309 }
242 310
243 static void 311 static void
244 init_syntax_cache (struct syntax_cache *cache, Lisp_Object object, 312 init_syntax_cache (struct syntax_cache *cache, Lisp_Object object,
245 struct buffer *buffer, int infinite) 313 struct buffer *buffer, int infinite)
246 { 314 {
269 cache->prev_change = -1; 337 cache->prev_change = -1;
270 cache->next_change = -1; 338 cache->next_change = -1;
271 } 339 }
272 } 340 }
273 341
342 /* external syntax cache API */
343
274 /* #### This function and associated logic still needs work, and especially 344 /* #### This function and associated logic still needs work, and especially
275 documentation. */ 345 documentation. */
276 struct syntax_cache * /* return CACHE or the cache of OBJECT */ 346 struct syntax_cache * /* return CACHE or the cache of OBJECT */
277 setup_syntax_cache (struct syntax_cache *cache, /* syntax cache, may be NULL 347 setup_syntax_cache (struct syntax_cache *cache, /* syntax cache, may be NULL
278 if OBJECT is a buffer */ 348 if OBJECT is a buffer */
314 384
315 struct syntax_cache * 385 struct syntax_cache *
316 setup_buffer_syntax_cache (struct buffer *buffer, Charxpos from, int count) 386 setup_buffer_syntax_cache (struct buffer *buffer, Charxpos from, int count)
317 { 387 {
318 return setup_syntax_cache (NULL, wrap_buffer (buffer), buffer, from, count); 388 return setup_syntax_cache (NULL, wrap_buffer (buffer), buffer, from, count);
319 }
320
321 static const struct memory_description syntax_cache_description_1 [] = {
322 { XD_LISP_OBJECT, offsetof (struct syntax_cache, object) },
323 { XD_LISP_OBJECT, offsetof (struct syntax_cache, buffer) },
324 { XD_LISP_OBJECT, offsetof (struct syntax_cache, syntax_table) },
325 { XD_LISP_OBJECT, offsetof (struct syntax_cache, mirror_table) },
326 { XD_LISP_OBJECT, offsetof (struct syntax_cache, start) },
327 { XD_LISP_OBJECT, offsetof (struct syntax_cache, end) },
328 { XD_END }
329 };
330
331 #ifdef NEW_GC
332 DEFINE_LRECORD_IMPLEMENTATION ("syntax-cache", syntax_cache,
333 1, /*dumpable-flag*/
334 0, 0, 0, 0, 0,
335 syntax_cache_description_1,
336 Lisp_Syntax_Cache);
337 #else /* not NEW_GC */
338
339 const struct sized_memory_description syntax_cache_description = {
340 sizeof (struct syntax_cache),
341 syntax_cache_description_1
342 };
343 #endif /* not NEW_GC */
344
345 void
346 mark_buffer_syntax_cache (struct buffer *buf)
347 {
348 struct syntax_cache *cache = buf->syntax_cache;
349 if (!cache) /* Vbuffer_defaults and such don't have caches */
350 return;
351 mark_object (cache->object);
352 if (cache->buffer)
353 mark_object (wrap_buffer (cache->buffer));
354 mark_object (cache->syntax_table);
355 mark_object (cache->mirror_table);
356 mark_object (cache->start);
357 mark_object (cache->end);
358 }
359
360 static void
361 reset_buffer_syntax_cache_range (struct syntax_cache *cache,
362 Lisp_Object buffer, int infinite)
363 {
364 Fset_marker (cache->start, make_int (1), buffer);
365 Fset_marker (cache->end, make_int (1), buffer);
366 Fset_marker_insertion_type (cache->start, Qt);
367 Fset_marker_insertion_type (cache->end, Qnil);
368 /* #### Should we "cache->no_syntax_table_prop = 1;" here? */
369 /* #### Cf comment on INFINITE in init_syntax_cache. -- sjt */
370 if (infinite)
371 {
372 cache->prev_change = EMACS_INT_MIN;
373 cache->next_change = EMACS_INT_MAX;
374 }
375 else
376 {
377 cache->prev_change = -1;
378 cache->next_change = -1;
379 }
380 }
381
382 void
383 init_buffer_syntax_cache (struct buffer *buf)
384 {
385 struct syntax_cache *cache;
386 #ifdef NEW_GC
387 buf->syntax_cache = alloc_lrecord_type (struct syntax_cache,
388 &lrecord_syntax_cache);
389 #else /* not NEW_GC */
390 buf->syntax_cache = xnew_and_zero (struct syntax_cache);
391 #endif /* not NEW_GC */
392 cache = buf->syntax_cache;
393 cache->object = wrap_buffer (buf);
394 cache->buffer = buf;
395 cache->no_syntax_table_prop = 1;
396 cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer);
397 cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
398 cache->start = Fmake_marker ();
399 cache->end = Fmake_marker ();
400 reset_buffer_syntax_cache_range (cache, cache->object, 0);
401 }
402
403 /* finalize the syntax cache for BUF */
404 void
405 uninit_buffer_syntax_cache (struct buffer *buf)
406 {
407 #ifdef NEW_GC
408 mc_free (buf->syntax_cache);
409 #else /* not NEW_GC */
410 xfree (buf->syntax_cache, struct syntax_cache *);
411 #endif /* not NEW_GC */
412 buf->syntax_cache = 0;
413 }
414
415
416 static void
417 syntax_cache_table_was_changed (struct buffer *buf)
418 {
419 struct syntax_cache *cache = buf->syntax_cache;
420 if (cache->no_syntax_table_prop)
421 {
422 cache->syntax_table =
423 BUFFER_SYNTAX_TABLE (buf);
424 cache->mirror_table =
425 BUFFER_MIRROR_SYNTAX_TABLE (buf);
426 }
427 }
428
429 /* The syntax-table property on the range covered by EXTENT may be changing,
430 either because EXTENT has a syntax-table property and is being attached
431 or detached (this includes having its endpoints changed), or because
432 the value of EXTENT's syntax-table property is changing. */
433
434 void
435 signal_syntax_cache_extent_changed (EXTENT extent)
436 {
437 Lisp_Object buffer = Fextent_object (wrap_extent (extent));
438 if (BUFFERP (buffer))
439 {
440 /* This was getting called with the buffer's start and end null, eg in
441 cperl mode, which triggers an assert in byte_marker_position. Cf
442 thread rooted at <yxz7j7xzk97.fsf@gimli.holgi.priv> on xemacs-beta.
443 <yxzfymklb6p.fsf@gimli.holgi.priv> has a recipe, but you also need
444 to delete or type SPC to get the crash.
445 #### Delete this comment when setup_syntax_cache is made sane. */
446 struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache;
447 /* #### would this be slower or less accurate in character terms? */
448 Bytexpos start = extent_endpoint_byte (extent, 0);
449 Bytexpos end = extent_endpoint_byte (extent, 1);
450 Bytexpos start2 = byte_marker_position (cache->start);
451 Bytexpos end2 = byte_marker_position (cache->end);
452 /* If the extent is entirely before or entirely after the cache
453 range, it doesn't overlap. Otherwise, invalidate the range. */
454 if (!(end < start2 || start > end2))
455 reset_buffer_syntax_cache_range (cache, buffer, 0);
456 }
457 }
458
459 /* Extents have been adjusted for insertion or deletion, so we need to
460 refetch the start and end position of the extent */
461 void
462 signal_syntax_cache_extent_adjust (struct buffer *buf)
463 {
464 struct syntax_cache *cache = buf->syntax_cache;
465 /* If the cache was invalid before, leave it that way. We only want
466 to update the limits of validity when they were actually valid. */
467 if (cache->prev_change < 0)
468 return;
469 cache->prev_change = marker_position (cache->start);
470 cache->next_change = marker_position (cache->end);
471 } 389 }
472 390
473 /* 391 /*
474 Update syntax_cache to an appropriate setting for position POS 392 Update syntax_cache to an appropriate setting for position POS
475 393
577 #ifdef NOT_WORTH_THE_EFFORT 495 #ifdef NOT_WORTH_THE_EFFORT
578 update_mirror_syntax_if_dirty (cache->mirror_table); 496 update_mirror_syntax_if_dirty (cache->mirror_table);
579 #endif /* NOT_WORTH_THE_EFFORT */ 497 #endif /* NOT_WORTH_THE_EFFORT */
580 } 498 }
581 } 499 }
500
501 /* buffer-specific APIs used in buffer.c
502 #### This is really unclean;
503 the syntax cache should just be a LISP object */
504
505 void
506 mark_buffer_syntax_cache (struct buffer *buf)
507 {
508 struct syntax_cache *cache = buf->syntax_cache;
509 if (!cache) /* Vbuffer_defaults and such don't have caches */
510 return;
511 mark_object (cache->object);
512 if (cache->buffer)
513 mark_object (wrap_buffer (cache->buffer));
514 mark_object (cache->syntax_table);
515 mark_object (cache->mirror_table);
516 mark_object (cache->start);
517 mark_object (cache->end);
518 }
519
520 void
521 init_buffer_syntax_cache (struct buffer *buf)
522 {
523 struct syntax_cache *cache;
524 #ifdef NEW_GC
525 buf->syntax_cache = alloc_lrecord_type (struct syntax_cache,
526 &lrecord_syntax_cache);
527 #else /* not NEW_GC */
528 buf->syntax_cache = xnew_and_zero (struct syntax_cache);
529 #endif /* not NEW_GC */
530 cache = buf->syntax_cache;
531 cache->object = wrap_buffer (buf);
532 cache->buffer = buf;
533 cache->no_syntax_table_prop = 1;
534 cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer);
535 cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
536 cache->start = Fmake_marker ();
537 cache->end = Fmake_marker ();
538 reset_buffer_syntax_cache_range (cache, cache->object, 0);
539 }
540
541 /* finalize the syntax cache for BUF */
542
543 void
544 uninit_buffer_syntax_cache (struct buffer *buf)
545 {
546 #ifdef NEW_GC
547 mc_free (buf->syntax_cache);
548 #else /* not NEW_GC */
549 xfree (buf->syntax_cache, struct syntax_cache *);
550 #endif /* not NEW_GC */
551 buf->syntax_cache = 0;
552 }
553
554 /* extent-specific APIs used in extents.c and insdel.c */
555
556 /* The syntax-table property on the range covered by EXTENT may be changing,
557 either because EXTENT has a syntax-table property and is being attached
558 or detached (this includes having its endpoints changed), or because
559 the value of EXTENT's syntax-table property is changing. */
560
561 void
562 signal_syntax_cache_extent_changed (EXTENT extent)
563 {
564 Lisp_Object buffer = Fextent_object (wrap_extent (extent));
565 if (BUFFERP (buffer))
566 {
567 /* This was getting called with the buffer's start and end null, eg in
568 cperl mode, which triggers an assert in byte_marker_position. Cf
569 thread rooted at <yxz7j7xzk97.fsf@gimli.holgi.priv> on xemacs-beta.
570 <yxzfymklb6p.fsf@gimli.holgi.priv> has a recipe, but you also need
571 to delete or type SPC to get the crash.
572 #### Delete this comment when setup_syntax_cache is made sane. */
573 struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache;
574 /* #### would this be slower or less accurate in character terms? */
575 Bytexpos start = extent_endpoint_byte (extent, 0);
576 Bytexpos end = extent_endpoint_byte (extent, 1);
577 Bytexpos start2 = byte_marker_position (cache->start);
578 Bytexpos end2 = byte_marker_position (cache->end);
579 /* If the extent is entirely before or entirely after the cache
580 range, it doesn't overlap. Otherwise, invalidate the range. */
581 if (!(end < start2 || start > end2))
582 reset_buffer_syntax_cache_range (cache, buffer, 0);
583 }
584 }
585
586 /* Extents have been adjusted for insertion or deletion, so we need to
587 refetch the start and end position of the extent */
588 void
589 signal_syntax_cache_extent_adjust (struct buffer *buf)
590 {
591 struct syntax_cache *cache = buf->syntax_cache;
592 /* If the cache was invalid before, leave it that way. We only want
593 to update the limits of validity when they were actually valid. */
594 if (cache->prev_change < 0)
595 return;
596 cache->prev_change = marker_position (cache->start);
597 cache->next_change = marker_position (cache->end);
598 }
599
600
582 601
583 /* Convert a letter which signifies a syntax code 602 /* Convert a letter which signifies a syntax code
584 into the code it signifies. 603 into the code it signifies.
585 This is used by modify-syntax-entry, and other things. */ 604 This is used by modify-syntax-entry, and other things. */
586 605