From 31182c1d17f6f7bc946d5e4576e025c9b975e0b5 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 1 Mar 2019 17:35:12 +0000 Subject: 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. --- src/intervals.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'src/intervals.c') 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) return NULL; } -/* Find the interval containing POS given some non-NULL INTERVAL - in the same tree. Note that we need to update interval->position - if we go down the tree. - To speed up the process, we assume that the ->position of - I and all its parents is already uptodate. */ +/* Set the ->position field of I's parent, based on I->position. */ +#define SET_PARENT_POSITION(i) \ + if (AM_LEFT_CHILD (i)) \ + INTERVAL_PARENT (i)->position = \ + i->position + TOTAL_LENGTH (i) - LEFT_TOTAL_LENGTH (i); \ + else \ + INTERVAL_PARENT (i)->position = \ + i->position - LEFT_TOTAL_LENGTH (i) \ + - LENGTH (INTERVAL_PARENT (i)) + +/* Find the interval containing POS, given some non-NULL INTERVAL in + the same tree. Note that we update interval->position in each + interval we traverse, assuming it is already correctly set for the + argument I. We don't assume that any other interval already has a + correctly set ->position. */ INTERVAL update_interval (register INTERVAL i, ptrdiff_t pos) { @@ -738,7 +748,10 @@ update_interval (register INTERVAL i, ptrdiff_t pos) else if (NULL_PARENT (i)) error ("Point before start of properties"); else - i = INTERVAL_PARENT (i); + { + SET_PARENT_POSITION (i); + i = INTERVAL_PARENT (i); + } continue; } else if (pos >= INTERVAL_LAST_POS (i)) @@ -753,7 +766,10 @@ update_interval (register INTERVAL i, ptrdiff_t pos) else if (NULL_PARENT (i)) error ("Point %"pD"d after end of properties", pos); else - i = INTERVAL_PARENT (i); + { + SET_PARENT_POSITION (i); + i = INTERVAL_PARENT (i); + } continue; } else -- cgit v1.2.1