unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: daniel.lopez999@gmail.com, monnier@IRO.UMontreal.CA,
	34525@debbugs.gnu.org
Subject: bug#34525: replace-regexp missing some matches
Date: Thu, 28 Feb 2019 21:54:14 +0000	[thread overview]
Message-ID: <20190228215414.GE4686@ACM> (raw)
In-Reply-To: <83k1hjkdzb.fsf@gnu.org>

Hello, Eli.

On Thu, Feb 28, 2019 at 19:41:12 +0200, Eli Zaretskii wrote:
> > Date: Thu, 28 Feb 2019 10:50:25 +0000
> > Cc: daniel.lopez999@gmail.com, 34525@debbugs.gnu.org
> > From: Alan Mackenzie <acm@muc.de>

> > (i) Calculate ->position's in previous_interval and next_interval, as my
> >   tentative patch already does.
> > (ii) Calculate the ->position's in update_interval, on moving to
> >   parents.
> > (iii) Do away with update_interval, replacing it in syntax.c with
> >   previous/next_interval in while loops.

> > In (i), the convention for ->position would be that it is valid for the
> > target interval together with all its parents.  In (ii) and (iii), it
> > would only be valid in the final target intervals found by navigation.
> > I think this should be explicitly stated in a comment in struct
> > interval.

Done.

> > So, where do we go from here?  If it were up to me, I would probably
> > chose (i), simply because it's already been done, but I've no strong
> > feelings over it.

> I prefer not to do (i) because it has much wider implications than
> needed.  Either (ii) or (iii) are okay with me.  The former seems to
> be simpler, so I tend to favor it slightly.

OK, I enclose a patch which codes up (ii).  As a matter of interest, it
seems to run a little faster on my benchmark of scrolling through
xdisp.c than the version without the fix.

And it fixes the OP's bug.  :-)



diff --git a/src/intervals.c b/src/intervals.c
index 524bb944e5..2ed913d5fb 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
diff --git a/src/intervals.h b/src/intervals.h
index 9c5adf33a1..7608800116 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -31,11 +31,15 @@ struct interval
   /* The first group of entries deal with the tree structure.  */
   ptrdiff_t total_length;       /* Length of myself and both children.  */
   ptrdiff_t position;	        /* Cache of interval's character position.  */
-				/* This field is usually updated
-				   simultaneously with an interval
-				   traversal, there is no guarantee
-				   that it is valid for a random
-				   interval.  */
+                                /* This field is valid for the final
+                                   target interval returned by
+                                   find_interval, next_interval,
+                                   previous_interval and
+                                   update_interval.  It cannot be
+                                   depended upon for any intermediate
+                                   intevals traversed by these
+                                   functions, or any other
+                                   interval. */
   struct interval *left;	/* Intervals which precede me.  */
   struct interval *right;	/* Intervals which succeed me.  */
 
diff --git a/src/pdumper.c b/src/pdumper.c
index f9638d4357..3aea4ab0d6 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2065,7 +2065,7 @@ dump_interval_tree (struct dump_context *ctx,
                     INTERVAL tree,
                     dump_off parent_offset)
 {
-#if CHECK_STRUCTS && !defined (HASH_interval_9110163DA0)
+#if CHECK_STRUCTS && !defined (HASH_interval_70865541E2)
 # error "interval changed. See CHECK_STRUCTS comment."
 #endif
   // TODO: output tree breadth-first?
diff --git a/src/syntax.c b/src/syntax.c
index 4616ae296f..faea1432cb 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -340,20 +340,6 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
       invalidate = false;
       if (!i)
 	return;
-      /* interval_of updates only ->position of the return value, so
-	 update the parents manually to speed up update_interval.  */
-      while (!NULL_PARENT (i))
-	{
-	  if (AM_RIGHT_CHILD (i))
-	    INTERVAL_PARENT (i)->position = i->position
-	      - LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */
-	      - TOTAL_LENGTH (INTERVAL_PARENT (i))
-	      + LEFT_TOTAL_LENGTH (INTERVAL_PARENT (i));
-	  else
-	    INTERVAL_PARENT (i)->position = i->position - LEFT_TOTAL_LENGTH (i)
-	      + TOTAL_LENGTH (i);
-	  i = INTERVAL_PARENT (i);
-	}
       i = gl_state.forward_i;
       gl_state.b_property = i->position - gl_state.offset;
       gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;


I've just noticed a typo in one of the comments in intervals.h, so the
above can't be final.  Sorry.

-- 
Alan Mackenzie (Nuremberg, Germany).





  reply	other threads:[~2019-02-28 21:54 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-18  8:28 bug#34525: replace-regexp missing some matches Daniel Lopez
     [not found] ` <handler.34525.B.15504786524313.ack@debbugs.gnu.org>
2019-02-18  8:37   ` bug#34525: Acknowledgement (replace-regexp missing some matches) Daniel Lopez
2019-02-18 15:50 ` bug#34525: replace-regexp missing some matches Eli Zaretskii
2019-02-18 16:46   ` Alan Mackenzie
2019-02-18 21:10   ` Alan Mackenzie
2019-02-20 17:07   ` Alan Mackenzie
     [not found]   ` <20190220170722.GA9655@ACM>
2019-02-20 18:02     ` Eli Zaretskii
2019-02-20 18:58       ` Alan Mackenzie
2019-02-20 19:27         ` Eli Zaretskii
2019-02-20 21:30           ` Alan Mackenzie
     [not found]           ` <20190220213003.GC9655@ACM>
2019-02-21  3:40             ` Eli Zaretskii
2019-02-24 17:37               ` Alan Mackenzie
2019-02-24 17:56                 ` Eli Zaretskii
2019-02-24 21:00                   ` Alan Mackenzie
2019-02-25 20:11                     ` Eli Zaretskii
2019-02-25 20:48                       ` Alan Mackenzie
2019-02-26 13:50                       ` Alan Mackenzie
     [not found]                       ` <20190226135048.GA19653@ACM>
2019-02-26 15:00                         ` Alan Mackenzie
2019-02-26 15:39                           ` Eli Zaretskii
2019-02-26 16:11                             ` Alan Mackenzie
2019-02-26 16:42                               ` Eli Zaretskii
2019-02-26 16:55                                 ` Alan Mackenzie
     [not found]                                 ` <20190226165505.GD19653@ACM>
2019-02-26 17:20                                   ` Eli Zaretskii
2019-02-26 17:23                                     ` Alan Mackenzie
2019-02-26 15:36                         ` Eli Zaretskii
2019-02-26 20:09                         ` Stefan Monnier
     [not found]                         ` <jwv8sy2z5yc.fsf-monnier+emacsbugs@gnu.org>
2019-02-26 21:45                           ` Alan Mackenzie
2019-02-26 22:09                             ` Stefan Monnier
2019-02-27 14:22                           ` Alan Mackenzie
     [not found]                           ` <20190227142251.GB4772@ACM>
2019-02-27 15:08                             ` Alan Mackenzie
     [not found]                             ` <20190227150849.GC4772@ACM>
2019-02-27 15:40                               ` Stefan Monnier
2019-02-27 17:10                                 ` Alan Mackenzie
2019-02-27 16:39                             ` Eli Zaretskii
2019-02-27 17:31                               ` Alan Mackenzie
2019-02-27 17:41                               ` Stefan Monnier
     [not found]                               ` <20190227173132.GG4772@ACM>
2019-02-27 18:07                                 ` Eli Zaretskii
2019-02-28 10:50                                   ` Alan Mackenzie
2019-02-28 17:41                                     ` Eli Zaretskii
2019-02-28 21:54                                       ` Alan Mackenzie [this message]
     [not found]                               ` <jwvpnrdb0xj.fsf-monnier+emacsbugs@gnu.org>
2019-02-27 18:48                                 ` Eli Zaretskii
2019-02-27 20:43                                   ` Alan Mackenzie
2019-02-26 23:00                         ` Stefan Monnier
2019-02-20 21:25         ` Daniel Lopez
2019-02-22 16:26           ` Alan Mackenzie
2019-03-01 14:34           ` Alan Mackenzie
     [not found]           ` <20190301143414.GD5674@ACM>
2019-03-01 17:58             ` Daniel Lopez
2019-03-01 17:42 ` Alan Mackenzie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190228215414.GE4686@ACM \
    --to=acm@muc.de \
    --cc=34525@debbugs.gnu.org \
    --cc=daniel.lopez999@gmail.com \
    --cc=eliz@gnu.org \
    --cc=monnier@IRO.UMontreal.CA \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).