Mercurial > hg > xemacs-beta
comparison src/syntax.c @ 5543:fbe90e6f7a43
Initialize start and end properly (to new markers, not Qnil).
* * *
Refactor syntax cache initialization.
* * *
Refactor setup_syntax_cache.
author | Stephen J. Turnbull <stephen@xemacs.org> |
---|---|
date | Mon, 08 Aug 2011 13:57:20 +0900 |
parents | dab422055bab |
children | c2301b2c88c8 |
comparison
equal
deleted
inserted
replaced
5542:dab422055bab | 5543:fbe90e6f7a43 |
---|---|
282 BUFFER_MIRROR_SYNTAX_TABLE (buf); | 282 BUFFER_MIRROR_SYNTAX_TABLE (buf); |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 static void | 286 static void |
287 reset_buffer_syntax_cache_range (struct syntax_cache *cache, | 287 reset_syntax_cache_range (struct syntax_cache *cache, /* initialized cache */ |
288 Lisp_Object buffer, int infinite) | 288 Lisp_Object object) /* string or buffer */ |
289 { | 289 { |
290 Fset_marker (cache->start, make_int (1), buffer); | 290 /* reinitialize cache parameters */ |
291 Fset_marker (cache->end, make_int (1), buffer); | 291 if (BUFFERP (object)) |
292 Fset_marker_insertion_type (cache->start, Qt); | 292 { |
293 Fset_marker_insertion_type (cache->end, Qnil); | 293 /* make known region zero-length and reset insertion behavior */ |
294 /* #### Should we "cache->no_syntax_table_prop = 1;" here? */ | 294 Fset_marker (cache->start, make_int (1), object); |
295 /* #### Cf comment on INFINITE in init_syntax_cache. -- sjt */ | 295 Fset_marker (cache->end, make_int (1), object); |
296 if (infinite) | 296 Fset_marker_insertion_type (cache->start, Qt); |
297 Fset_marker_insertion_type (cache->end, Qnil); | |
298 } | |
299 else | |
300 { | |
301 /* invalidate the known region markers */ | |
302 Fset_marker (cache->start, Qnil, Qnil); | |
303 Fset_marker (cache->end, Qnil, Qnil); | |
304 } | |
305 cache->no_syntax_table_prop = 1; | |
306 if (lookup_syntax_properties) | |
307 { | |
308 cache->prev_change = -1; | |
309 cache->next_change = -1; | |
310 } | |
311 else | |
297 { | 312 { |
298 cache->prev_change = EMACS_INT_MIN; | 313 cache->prev_change = EMACS_INT_MIN; |
299 cache->next_change = EMACS_INT_MAX; | 314 cache->next_change = EMACS_INT_MAX; |
300 } | 315 } |
301 else | |
302 { | |
303 cache->prev_change = -1; | |
304 cache->next_change = -1; | |
305 } | |
306 } | 316 } |
307 | 317 |
308 static void | 318 static void |
309 init_syntax_cache (struct syntax_cache *cache, Lisp_Object object, | 319 init_syntax_cache (struct syntax_cache *cache, /* cache must be zero'ed */ |
310 struct buffer *buffer, int infinite) | 320 Lisp_Object object, /* string or buffer */ |
311 { | 321 struct buffer *buffer) /* may not be NULL */ |
312 xzero (*cache); | 322 { |
323 /* initialize cache resources */ | |
313 cache->object = object; | 324 cache->object = object; |
314 cache->buffer = buffer; | 325 cache->buffer = buffer; |
315 cache->no_syntax_table_prop = 1; | |
316 cache->syntax_table = | 326 cache->syntax_table = |
317 BUFFER_SYNTAX_TABLE (cache->buffer); | 327 BUFFER_SYNTAX_TABLE (cache->buffer); |
318 cache->mirror_table = | 328 cache->mirror_table = |
319 BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | 329 BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); |
320 cache->start = Qnil; | 330 cache->start = Fmake_marker(); |
321 cache->end = Qnil; | 331 cache->end = Fmake_marker(); |
322 /* #### I'm not sure what INFINITE is for, but it's apparently needed by | |
323 setup_syntax_cache(). It looks like it's supposed to guarantee that | |
324 the test for POS outside of cache-valid range will never succeed, so | |
325 that update_syntax_cache won't get called, but it's hard to be sure. | |
326 Cf reset_buffer_syntax_cache_range. -- sjt */ | |
327 if (infinite) | |
328 { | |
329 cache->prev_change = EMACS_INT_MIN; | |
330 cache->next_change = EMACS_INT_MAX; | |
331 } | |
332 else | |
333 { | |
334 cache->prev_change = -1; | |
335 cache->next_change = -1; | |
336 } | |
337 } | 332 } |
338 | 333 |
339 /* external syntax cache API */ | 334 /* external syntax cache API */ |
340 | 335 |
341 /* #### This function and associated logic still needs work, and especially | 336 /* #### This function and associated logic still needs work, and especially |
345 if OBJECT is a buffer */ | 340 if OBJECT is a buffer */ |
346 Lisp_Object object, /* the object (if any) cache | 341 Lisp_Object object, /* the object (if any) cache |
347 is associated with */ | 342 is associated with */ |
348 struct buffer *buffer, /* the buffer to use as source | 343 struct buffer *buffer, /* the buffer to use as source |
349 of the syntax table */ | 344 of the syntax table */ |
350 Charxpos from, /* initial position of cache */ | 345 Charxpos UNUSED (from), /* initial position of cache */ |
351 int count) /* direction? see code */ | 346 int UNUSED (count)) /* direction? see code */ |
352 { | 347 { |
353 /* If OBJECT is a buffer, use its cache. Initialize cache. Make it valid | 348 /* If OBJECT is a buffer, use its cache, otherwise use CACHE. |
354 for the whole buffer if the syntax-table property is not being respected. | 349 Initialize CACHE. Invalidate the cache if the syntax-table property is |
355 Else if OBJECT is not a buffer, initialize the cache passed in CACHE. | 350 being respected, otherwise make it valid for the whole object. */ |
356 If the syntax-table property is being respected, update the cache. */ | |
357 if (BUFFERP (object)) | 351 if (BUFFERP (object)) |
358 { | 352 { |
359 cache = XBUFFER (object)->syntax_cache; | 353 cache = XBUFFER (object)->syntax_cache; |
360 if (!lookup_syntax_properties) | |
361 reset_buffer_syntax_cache_range (cache, object, 1); | |
362 } | 354 } |
363 else | 355 else |
364 init_syntax_cache (cache, object, buffer, 0); | 356 { |
365 if (lookup_syntax_properties) | 357 xzero (*cache); |
366 { | 358 init_syntax_cache (cache, object, buffer); |
367 if (count <= 0) | 359 } |
368 { | 360 reset_syntax_cache_range (cache, object); |
369 from--; | 361 |
370 from = buffer_or_string_clip_to_accessible_char (cache->object, | |
371 from); | |
372 } | |
373 if (!(from >= cache->prev_change && from < cache->next_change)) | |
374 update_syntax_cache (cache, from, count); | |
375 } | |
376 #ifdef NOT_WORTH_THE_EFFORT | 362 #ifdef NOT_WORTH_THE_EFFORT |
377 update_mirror_syntax_if_dirty (cache->mirror_table); | 363 update_mirror_syntax_if_dirty (cache->mirror_table); |
378 #endif /* NOT_WORTH_THE_EFFORT */ | 364 #endif /* NOT_WORTH_THE_EFFORT */ |
379 return cache; | 365 return cache; |
380 } | 366 } |
515 } | 501 } |
516 | 502 |
517 void | 503 void |
518 init_buffer_syntax_cache (struct buffer *buf) | 504 init_buffer_syntax_cache (struct buffer *buf) |
519 { | 505 { |
520 struct syntax_cache *cache; | |
521 #ifdef NEW_GC | 506 #ifdef NEW_GC |
522 buf->syntax_cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache)); | 507 buf->syntax_cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache)); |
523 #else /* not NEW_GC */ | 508 #else /* not NEW_GC */ |
524 buf->syntax_cache = xnew_and_zero (struct syntax_cache); | 509 buf->syntax_cache = xnew_and_zero (struct syntax_cache); |
525 #endif /* not NEW_GC */ | 510 #endif /* not NEW_GC */ |
526 cache = buf->syntax_cache; | 511 |
527 cache->object = wrap_buffer (buf); | 512 init_syntax_cache (buf->syntax_cache, wrap_buffer(buf), buf); |
528 cache->buffer = buf; | 513 reset_syntax_cache_range (buf->syntax_cache, wrap_buffer(buf)); |
529 cache->no_syntax_table_prop = 1; | |
530 cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer); | |
531 cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer); | |
532 cache->start = Fmake_marker (); | |
533 cache->end = Fmake_marker (); | |
534 reset_buffer_syntax_cache_range (cache, cache->object, 0); | |
535 } | 514 } |
536 | 515 |
537 /* finalize the syntax cache for BUF */ | 516 /* finalize the syntax cache for BUF */ |
538 | 517 |
539 void | 518 void |
559 signal_syntax_cache_extent_changed (EXTENT extent) | 538 signal_syntax_cache_extent_changed (EXTENT extent) |
560 { | 539 { |
561 Lisp_Object buffer = Fextent_object (wrap_extent (extent)); | 540 Lisp_Object buffer = Fextent_object (wrap_extent (extent)); |
562 if (BUFFERP (buffer)) | 541 if (BUFFERP (buffer)) |
563 { | 542 { |
564 /* This was getting called with the buffer's start and end null, eg in | |
565 cperl mode, which triggers an assert in byte_marker_position. Cf | |
566 thread rooted at <yxz7j7xzk97.fsf@gimli.holgi.priv> on xemacs-beta. | |
567 <yxzfymklb6p.fsf@gimli.holgi.priv> has a recipe, but you also need | |
568 to delete or type SPC to get the crash. | |
569 #### Delete this comment when setup_syntax_cache is made sane. */ | |
570 struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache; | 543 struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache; |
571 /* #### would this be slower or less accurate in character terms? */ | 544 /* #### would this be slower or less accurate in character terms? */ |
572 Bytexpos start = extent_endpoint_byte (extent, 0); | 545 Bytexpos start = extent_endpoint_byte (extent, 0); |
573 Bytexpos end = extent_endpoint_byte (extent, 1); | 546 Bytexpos end = extent_endpoint_byte (extent, 1); |
574 Bytexpos start2 = byte_marker_position (cache->start); | 547 Bytexpos start2 = byte_marker_position (cache->start); |
575 Bytexpos end2 = byte_marker_position (cache->end); | 548 Bytexpos end2 = byte_marker_position (cache->end); |
576 /* If the extent is entirely before or entirely after the cache | 549 /* If the extent is entirely before or entirely after the cache |
577 range, it doesn't overlap. Otherwise, invalidate the range. */ | 550 range, it doesn't overlap. Otherwise, invalidate the range. */ |
578 if (!(end < start2 || start > end2)) | 551 if (!(end < start2 || start > end2)) |
579 reset_buffer_syntax_cache_range (cache, buffer, 0); | 552 reset_syntax_cache_range (cache, buffer); |
580 } | 553 } |
581 } | 554 } |
582 | 555 |
583 /* Extents have been adjusted for insertion or deletion, so we need to | 556 /* Extents have been adjusted for insertion or deletion, so we need to |
584 refetch the start and end position of the extent */ | 557 refetch the start and end position of the extent */ |