aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2019-03-01 17:35:12 +0000
committerAlan Mackenzie2019-03-01 17:37:56 +0000
commit31182c1d17f6f7bc946d5e4576e025c9b975e0b5 (patch)
tree49f54fc69a83fbc5f7a7c01a82fe1e1417a94a59 /src
parent287f2a676405009a6927fe7c33e36299a86b2827 (diff)
downloademacs-31182c1d17f6f7bc946d5e4576e025c9b975e0b5.tar.gz
emacs-31182c1d17f6f7bc946d5e4576e025c9b975e0b5.zip
Maintain interval ->position fields correctly in update_interval
Also fix some anomalies in the handling of byte positions in regexp-emacs.c This fixes bug #34525. * src/intervals.c (SET_PARENT_POSITION): New macro. (update_interval): When moving to an interval's parent, set that parent's ->position field, to maintain the consistency of the tree. * src/intervals.h (struct interval): Amend the comment describing when ->position is valid. * src/pdumper.c: Update the hash associated with struct interval. * src/regex-emacs.c: (re_match_2_internal): Only invoke POINTER_TO_OFFSET on a known character boundary. Only perform arithmetic on character positions, not on byte positions. Correct the argument to an invocation of UPDATE_SYNTAX_TABLE_FORWARD by adding 1 to it (in case wordend:). * src/syntax.c: (update_syntax_table): Remove the now redundant code that set the ->position field of all parents of the interval found by update_interval.
Diffstat (limited to 'src')
-rw-r--r--src/intervals.c30
-rw-r--r--src/intervals.h14
-rw-r--r--src/pdumper.c2
-rw-r--r--src/regex-emacs.c14
-rw-r--r--src/syntax.c14
5 files changed, 40 insertions, 34 deletions
diff --git a/src/intervals.c b/src/intervals.c
index 524bb944e51..8f39c45762f 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -713,11 +713,21 @@ previous_interval (register INTERVAL interval)
713 return NULL; 713 return NULL;
714} 714}
715 715
716/* Find the interval containing POS given some non-NULL INTERVAL 716/* Set the ->position field of I's parent, based on I->position. */
717 in the same tree. Note that we need to update interval->position 717#define SET_PARENT_POSITION(i) \
718 if we go down the tree. 718 if (AM_LEFT_CHILD (i)) \
719 To speed up the process, we assume that the ->position of 719 INTERVAL_PARENT (i)->position = \
720 I and all its parents is already uptodate. */ 720 i->position + TOTAL_LENGTH (i) - LEFT_TOTAL_LENGTH (i); \
721 else \
722 INTERVAL_PARENT (i)->position = \
723 i->position - LEFT_TOTAL_LENGTH (i) \
724 - LENGTH (INTERVAL_PARENT (i))
725
726/* Find the interval containing POS, given some non-NULL INTERVAL in
727 the same tree. Note that we update interval->position in each
728 interval we traverse, assuming it is already correctly set for the
729 argument I. We don't assume that any other interval already has a
730 correctly set ->position. */
721INTERVAL 731INTERVAL
722update_interval (register INTERVAL i, ptrdiff_t pos) 732update_interval (register INTERVAL i, ptrdiff_t pos)
723{ 733{
@@ -738,7 +748,10 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
738 else if (NULL_PARENT (i)) 748 else if (NULL_PARENT (i))
739 error ("Point before start of properties"); 749 error ("Point before start of properties");
740 else 750 else
741 i = INTERVAL_PARENT (i); 751 {
752 SET_PARENT_POSITION (i);
753 i = INTERVAL_PARENT (i);
754 }
742 continue; 755 continue;
743 } 756 }
744 else if (pos >= INTERVAL_LAST_POS (i)) 757 else if (pos >= INTERVAL_LAST_POS (i))
@@ -753,7 +766,10 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
753 else if (NULL_PARENT (i)) 766 else if (NULL_PARENT (i))
754 error ("Point %"pD"d after end of properties", pos); 767 error ("Point %"pD"d after end of properties", pos);
755 else 768 else
756 i = INTERVAL_PARENT (i); 769 {
770 SET_PARENT_POSITION (i);
771 i = INTERVAL_PARENT (i);
772 }
757 continue; 773 continue;
758 } 774 }
759 else 775 else
diff --git a/src/intervals.h b/src/intervals.h
index 9c5adf33a14..e9166946d9a 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -31,11 +31,15 @@ struct interval
31 /* The first group of entries deal with the tree structure. */ 31 /* The first group of entries deal with the tree structure. */
32 ptrdiff_t total_length; /* Length of myself and both children. */ 32 ptrdiff_t total_length; /* Length of myself and both children. */
33 ptrdiff_t position; /* Cache of interval's character position. */ 33 ptrdiff_t position; /* Cache of interval's character position. */
34 /* This field is usually updated 34 /* This field is valid in the final
35 simultaneously with an interval 35 target interval returned by
36 traversal, there is no guarantee 36 find_interval, next_interval,
37 that it is valid for a random 37 previous_interval and
38 interval. */ 38 update_interval. It cannot be
39 depended upon in any intermediate
40 intervals traversed by these
41 functions, or any other
42 interval. */
39 struct interval *left; /* Intervals which precede me. */ 43 struct interval *left; /* Intervals which precede me. */
40 struct interval *right; /* Intervals which succeed me. */ 44 struct interval *right; /* Intervals which succeed me. */
41 45
diff --git a/src/pdumper.c b/src/pdumper.c
index 4d35fd1233f..bba43370a14 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2064,7 +2064,7 @@ dump_interval_tree (struct dump_context *ctx,
2064 INTERVAL tree, 2064 INTERVAL tree,
2065 dump_off parent_offset) 2065 dump_off parent_offset)
2066{ 2066{
2067#if CHECK_STRUCTS && !defined (HASH_interval_9110163DA0) 2067#if CHECK_STRUCTS && !defined (HASH_interval_1B38941C37)
2068# error "interval changed. See CHECK_STRUCTS comment." 2068# error "interval changed. See CHECK_STRUCTS comment."
2069#endif 2069#endif
2070 // TODO: output tree breadth-first? 2070 // TODO: output tree breadth-first?
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index b667a43a37f..45b4f8107c7 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -4732,8 +4732,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1,
4732 int c1, c2; 4732 int c1, c2;
4733 int s1, s2; 4733 int s1, s2;
4734 int dummy; 4734 int dummy;
4735 ptrdiff_t offset = PTR_TO_OFFSET (d - 1); 4735 ptrdiff_t offset = PTR_TO_OFFSET (d);
4736 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset); 4736 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4737 UPDATE_SYNTAX_TABLE (charpos); 4737 UPDATE_SYNTAX_TABLE (charpos);
4738 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4738 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4739 s1 = SYNTAX (c1); 4739 s1 = SYNTAX (c1);
@@ -4811,8 +4811,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1,
4811 int c1, c2; 4811 int c1, c2;
4812 int s1, s2; 4812 int s1, s2;
4813 int dummy; 4813 int dummy;
4814 ptrdiff_t offset = PTR_TO_OFFSET (d) - 1; 4814 ptrdiff_t offset = PTR_TO_OFFSET (d);
4815 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset); 4815 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4816 UPDATE_SYNTAX_TABLE (charpos); 4816 UPDATE_SYNTAX_TABLE (charpos);
4817 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4817 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4818 s1 = SYNTAX (c1); 4818 s1 = SYNTAX (c1);
@@ -4826,7 +4826,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1,
4826 { 4826 {
4827 PREFETCH_NOLIMIT (); 4827 PREFETCH_NOLIMIT ();
4828 GET_CHAR_AFTER (c2, d, dummy); 4828 GET_CHAR_AFTER (c2, d, dummy);
4829 UPDATE_SYNTAX_TABLE_FORWARD (charpos); 4829 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
4830 s2 = SYNTAX (c2); 4830 s2 = SYNTAX (c2);
4831 4831
4832 /* ... and S2 is Sword, and WORD_BOUNDARY_P (C1, C2) 4832 /* ... and S2 is Sword, and WORD_BOUNDARY_P (C1, C2)
@@ -4890,8 +4890,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1,
4890 is the character at D, and S2 is the syntax of C2. */ 4890 is the character at D, and S2 is the syntax of C2. */
4891 int c1, c2; 4891 int c1, c2;
4892 int s1, s2; 4892 int s1, s2;
4893 ptrdiff_t offset = PTR_TO_OFFSET (d) - 1; 4893 ptrdiff_t offset = PTR_TO_OFFSET (d);
4894 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset); 4894 ptrdiff_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset) - 1;
4895 UPDATE_SYNTAX_TABLE (charpos); 4895 UPDATE_SYNTAX_TABLE (charpos);
4896 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); 4896 GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
4897 s1 = SYNTAX (c1); 4897 s1 = SYNTAX (c1);
diff --git a/src/syntax.c b/src/syntax.c
index dd2f56f2cfa..fe1e2d236b9 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -340,20 +340,6 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
340 invalidate = false; 340 invalidate = false;
341 if (!i) 341 if (!i)
342 return; 342 return;
343 /* interval_of updates only ->position of the return value, so
344 update the parents manually to speed up update_interval. */
345 while (!NULL_PARENT (i))
346 {
347 if (AM_RIGHT_CHILD (i))
348 INTERVAL_PARENT (i)->position = i->position
349 - LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */
350 - TOTAL_LENGTH (INTERVAL_PARENT (i))
351 + LEFT_TOTAL_LENGTH (INTERVAL_PARENT (i));
352 else
353 INTERVAL_PARENT (i)->position = i->position - LEFT_TOTAL_LENGTH (i)
354 + TOTAL_LENGTH (i);
355 i = INTERVAL_PARENT (i);
356 }
357 i = gl_state.forward_i; 343 i = gl_state.forward_i;
358 gl_state.b_property = i->position - gl_state.offset; 344 gl_state.b_property = i->position - gl_state.offset;
359 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; 345 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;