changeset 5545:69de75c48efa

Alan Mackenzie's syntax cache bounds fix.
author Stephen J. Turnbull <stephen@xemacs.org>
date Mon, 08 Aug 2011 13:57:20 +0900
parents c2301b2c88c8
children d54278e74d71
files src/ChangeLog src/syntax.c tests/ChangeLog tests/automated/syntax-tests.el
diffstat 4 files changed, 104 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Aug 08 13:57:20 2011 +0900
+++ b/src/ChangeLog	Mon Aug 08 13:57:20 2011 +0900
@@ -1,3 +1,11 @@
+2011-08-08  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* syntax.c (update_syntax_cache):
+	Use buffer_or_string_accessible_*, not buffer_or_string_absolute_*.
+	Patch and test suggested by Alan Mackenzie.
+	Fix initialization of insertion type for start and end in struct
+	syntax_cache.
+
 2011-08-06  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* syntax.c:
--- a/src/syntax.c	Mon Aug 08 13:57:20 2011 +0900
+++ b/src/syntax.c	Mon Aug 08 13:57:20 2011 +0900
@@ -292,8 +292,8 @@
       /* make known region zero-length and reset insertion behavior */
       Fset_marker (cache->start, make_int (1), object);
       Fset_marker (cache->end, make_int (1), object);
-      Fset_marker_insertion_type (cache->start, Qt);
-      Fset_marker_insertion_type (cache->end, Qnil);
+      Fset_marker_insertion_type (cache->start, Qnil);
+      Fset_marker_insertion_type (cache->end, Qt);
     }
   else
     {
@@ -408,19 +408,19 @@
 					      cache->object, -1, 1, 0);
   if (lim < 0)
     {
-      next = buffer_or_string_absolute_end_byte (cache->object);
+      next = buffer_or_string_accessible_end_byte (cache->object);
       at_begin = 1;
     }
   else
     next = lim;
 
-  if (pos < buffer_or_string_absolute_end_byte (cache->object))
+  if (pos < buffer_or_string_accessible_end_byte (cache->object))
     pos = next_bytexpos (cache->object, pos);
   lim = next_previous_single_property_change (pos, Qsyntax_table,
 					      cache->object, -1, 0, 0);
   if (lim < 0)
     {
-      prev = buffer_or_string_absolute_begin_byte (cache->object);
+      prev = buffer_or_string_accessible_begin_byte (cache->object);
       at_end = 1;
     }
   else
--- a/tests/ChangeLog	Mon Aug 08 13:57:20 2011 +0900
+++ b/tests/ChangeLog	Mon Aug 08 13:57:20 2011 +0900
@@ -1,3 +1,8 @@
+2011-08-08  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* automated/syntax-tests.el:
+	Add test of syntax cache suggested by Alan Mackenzie.
+
 2011-08-06  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* automated/syntax-tests.el: Suggest test from old syntax-cache bug.
--- a/tests/automated/syntax-tests.el	Mon Aug 08 13:57:20 2011 +0900
+++ b/tests/automated/syntax-tests.el	Mon Aug 08 13:57:20 2011 +0900
@@ -204,6 +204,92 @@
     ;; special-case check that point didn't move
     (Assert (= (point) 25))))
 
+;; Test inspired by Alan Mackenzie in <20110806200042.GA3406@acm.acm>
+;; on xemacs-beta 2011-08-06.
+;; Known to fail in r5531 (#1b054bc2ac40) plus some additional patches to
+;; syntax code, and passes with Alan's suggested patch ca. r5545.
+;; #### The results of these tests are empirically determined, and will
+;; probably change as the syntax cache is documented and repaired.
+(with-temp-buffer
+  ;; buffer->syntax_cache in just-initialized state.
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "just initialized")
+    (Assert (= 1 (nth 1 sci)) nil "just initialized")
+    (Assert (= -1 (nth 2 sci)) nil "just initialized")
+    (Assert (= -1 (nth 3 sci)) nil "just initialized"))
+  ;; Alan's example uses ?/ not ?, but ?/ has Ssymbol syntax, which would
+  ;; mean it is treated the same as the letters by forward-sexp.
+  (insert ",regexp, {")
+  ;; Insertion updates markers, but not the cache boundaries.
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "after main insert")
+    (Assert (= 11 (nth 1 sci)) nil "after main insert")
+    (Assert (= -1 (nth 2 sci)) nil "after main insert")
+    (Assert (= -1 (nth 3 sci)) nil "after main insert"))
+  ;; #### Interactively inserting in fundamental mode swaps marker positions!
+  ;; Why?
+  (insert "}")
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "after brace insert")
+    (Assert (= 12 (nth 1 sci)) nil "after brace insert")
+    (Assert (= -1 (nth 2 sci)) nil "after brace insert")
+    (Assert (= -1 (nth 3 sci)) nil "after brace insert"))
+  ;; Motion that ignores the cache should not update the cache.
+  (goto-char (point-min))
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "after movement 0")
+    (Assert (= 12 (nth 1 sci)) nil "after movement 0")
+    (Assert (= -1 (nth 2 sci)) nil "after movement 0")
+    (Assert (= -1 (nth 3 sci)) nil "after movement 0"))
+  ;; Cache should be updated and global since no syntax-table property.
+  (forward-sexp 1)
+  (Assert (= (point) 8) nil "after 1st forward-sexp")
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "after 1st forward-sexp")
+    (Assert (= 12 (nth 1 sci)) nil "after 1st forward-sexp")
+    (Assert (= 1 (nth 2 sci)) nil "after 1st forward-sexp")
+    (Assert (= 12 (nth 3 sci)) nil "after 1st forward-sexp"))
+  ;; Adding the text property should invalidate the cache.
+  (put-text-property 1 2 'syntax-table '(7))
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 1 (nth 0 sci)) nil "after putting property")
+    (Assert (= 1 (nth 1 sci)) nil "after putting property")
+    (Assert (= -1 (nth 2 sci)) nil "after putting property")
+    (Assert (= -1 (nth 3 sci)) nil "after putting property"))
+  (put-text-property 8 9 'syntax-table '(7))
+  (goto-char (point-min))
+  ;; Motion that is stopped by a syntax-table property should impose
+  ;; that property's region on the cache.
+  (forward-sexp 1)
+  (Assert (= (point) 9) nil "after 2d forward-sexp")
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 8 (nth 0 sci)) nil "after 2d forward-sexp")
+    (Assert (= 9 (nth 1 sci)) nil "after 2d forward-sexp")
+    (Assert (= 8 (nth 2 sci)) nil "after 2d forward-sexp")
+    (Assert (= 9 (nth 3 sci)) nil "after 2d forward-sexp"))
+  ;; Narrowing warps point but does not affect the cache.
+  (narrow-to-region 10 12)
+  (Assert (= 10 (point)) nil "after narrowing")
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 8 (nth 0 sci)) nil "after narrowing")
+    (Assert (= 9 (nth 1 sci)) nil "after narrowing")
+    (Assert (= 8 (nth 2 sci)) nil "after narrowing")
+    (Assert (= 9 (nth 3 sci)) nil "after narrowing"))
+  ;; Motion that is stopped by buffer's syntax table should capture
+  ;; the largest region known to not contain a change of syntax-table
+  ;; property.
+  (forward-sexp 1)
+  (let ((sci (syntax-cache-info)))
+    (Assert (= 10 (nth 0 sci)) nil "after 3d forward-sexp")
+    (Assert (= 12 (nth 1 sci)) nil "after 3d forward-sexp")
+    (Assert (= 10 (nth 2 sci)) nil "after 3d forward-sexp")
+    (Assert (= 12 (nth 3 sci)) nil "after 3d forward-sexp"))
+  (widen)
+  (goto-char (point-min))
+  ;; Check that we still respect the syntax table properties.
+  (forward-sexp 1)
+  (Assert (= 9 (point)) nil "after widening"))
+
 ;; #### Add the recipe in <yxzfymklb6p.fsf@gimli.holgi.priv> on xemacs-beta.
 ;; You also need to do a DELETE or type SPC to get the crash in 21.5.24.
 ;http://list-archive.xemacs.org/pipermail/xemacs-beta/2006-February/008430.html