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 */