diff src/search.c @ 56224:17e2d4a894aa

(Freplace_match): Adjust the match-data more thoroughly when replacing strings in the buffer. search.c (match-data): When INTEGERS is non-nil and the last match was in a buffer, add the buffer as last element to the match data. (Fset_match_data): If an additional element of the match-data is a buffer, restore it to last_thing_searched. (save_search_regs): Save last_thing_searched as part of the match data. (restore_match_data): Restore it again.
author David Kastrup <dak@gnu.org>
date Wed, 23 Jun 2004 19:22:25 +0000
parents b53351ef3125
children b04610e283ce
line wrap: on
line diff
--- a/src/search.c	Wed Jun 23 19:21:14 2004 +0000
+++ b/src/search.c	Wed Jun 23 19:22:25 2004 +0000
@@ -2589,15 +2589,20 @@
   /* Adjust search data for this change.  */
   {
     int oldend = search_regs.end[sub];
+    int oldstart = search_regs.start[sub];
     int change = newpoint - search_regs.end[sub];
     int i;
 
     for (i = 0; i < search_regs.num_regs; i++)
       {
-	if (search_regs.start[i] > oldend)
+	if (search_regs.start[i] >= oldend)
 	  search_regs.start[i] += change;
-	if (search_regs.end[i] > oldend)
+	else if (search_regs.start[i] > oldstart)
+	  search_regs.start[i] = oldstart;
+	if (search_regs.end[i] >= oldend)
 	  search_regs.end[i] += change;
+	else if (search_regs.end[i] > oldstart)
+	  search_regs.end[i] = oldstart;
       }
   }
 
@@ -2666,8 +2671,11 @@
 if the last match was on a buffer; integers or nil if a string was matched.
 Use `store-match-data' to reinstate the data in this list.
 
-If INTEGERS (the optional first argument) is non-nil, always use integers
-\(rather than markers) to represent buffer positions.
+If INTEGERS (the optional first argument) is non-nil, always use
+integers \(rather than markers) to represent buffer positions.  In
+this case, and if the last match was in a buffer, the buffer will get
+stored as one additional element at the end of the list.
+
 If REUSE is a list, reuse it as part of the value.  If REUSE is long enough
 to hold all the values, and if INTEGERS is non-nil, no consing is done.
 
@@ -2684,10 +2692,10 @@
 
   prev = Qnil;
 
-  data = (Lisp_Object *) alloca ((2 * search_regs.num_regs)
+  data = (Lisp_Object *) alloca ((2 * search_regs.num_regs + 1)
 				 * sizeof (Lisp_Object));
 
-  len = -1;
+  len = 0;
   for (i = 0; i < search_regs.num_regs; i++)
     {
       int start = search_regs.start[i];
@@ -2714,22 +2722,29 @@
 	    /* last_thing_searched must always be Qt, a buffer, or Qnil.  */
 	    abort ();
 
-	  len = i;
+	  len = 2*(i+1);
 	}
       else
 	data[2 * i] = data [2 * i + 1] = Qnil;
     }
 
+  if (BUFFERP(last_thing_searched)
+      && ! NILP (integers))
+    {
+      XSETBUFFER(data[len], last_thing_searched);
+      len++;
+    }
+
   /* If REUSE is not usable, cons up the values and return them.  */
   if (! CONSP (reuse))
-    return Flist (2 * len + 2, data);
+    return Flist (len, data);
 
   /* If REUSE is a list, store as many value elements as will fit
      into the elements of REUSE.  */
   for (i = 0, tail = reuse; CONSP (tail);
        i++, tail = XCDR (tail))
     {
-      if (i < 2 * len + 2)
+      if (i < len)
 	XSETCAR (tail, data[i]);
       else
 	XSETCAR (tail, Qnil);
@@ -2738,8 +2753,8 @@
 
   /* If we couldn't fit all value elements into REUSE,
      cons up the rest of them and add them to the end of REUSE.  */
-  if (i < 2 * len + 2)
-    XSETCDR (prev, Flist (2 * len + 2 - i, data + i));
+  if (i < len)
+    XSETCDR (prev, Flist (len - i, data + i));
 
   return reuse;
 }
@@ -2760,8 +2775,8 @@
   if (!CONSP (list) && !NILP (list))
     list = wrong_type_argument (Qconsp, list);
 
-  /* Unless we find a marker with a buffer in LIST, assume that this
-     match data came from a string.  */
+  /* Unless we find a marker with a buffer or an explicit buffer
+     in LIST, assume that this match data came from a string.  */
   last_thing_searched = Qt;
 
   /* Allocate registers if they don't already exist.  */
@@ -2792,42 +2807,49 @@
 
 	search_regs.num_regs = length;
       }
+
+    for (i = 0; i < length; i++)
+      {
+	marker = Fcar (list);
+	if (NILP (marker))
+	  {
+	    search_regs.start[i] = -1;
+	    list = Fcdr (list);
+	  }
+	else
+	  {
+	    int from;
+	    
+	    if (MARKERP (marker))
+	      {
+		if (XMARKER (marker)->buffer == 0)
+		  XSETFASTINT (marker, 0);
+		else
+		  XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
+	      }
+	    
+	    CHECK_NUMBER_COERCE_MARKER (marker);
+	    from = XINT (marker);
+	    list = Fcdr (list);
+	    
+	    marker = Fcar (list);
+	    if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
+	      XSETFASTINT (marker, 0);
+	    
+	    CHECK_NUMBER_COERCE_MARKER (marker);
+	    search_regs.start[i] = from;
+	    search_regs.end[i] = XINT (marker);
+	  }
+	list = Fcdr (list);
+      }
+
+    for (; i < search_regs.num_regs; i++)
+      search_regs.start[i] = -1;
   }
 
-  for (i = 0; i < search_regs.num_regs; i++)
-    {
-      marker = Fcar (list);
-      if (NILP (marker))
-	{
-	  search_regs.start[i] = -1;
-	  list = Fcdr (list);
-	}
-      else
-	{
-	  int from;
-
-	  if (MARKERP (marker))
-	    {
-	      if (XMARKER (marker)->buffer == 0)
-		XSETFASTINT (marker, 0);
-	      else
-		XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
-	    }
-
-	  CHECK_NUMBER_COERCE_MARKER (marker);
-	  from = XINT (marker);
-	  list = Fcdr (list);
-
-	  marker = Fcar (list);
-	  if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
-	    XSETFASTINT (marker, 0);
-
-	  CHECK_NUMBER_COERCE_MARKER (marker);
-	  search_regs.start[i] = from;
-	  search_regs.end[i] = XINT (marker);
-	}
-      list = Fcdr (list);
-    }
+  if (CONSP(list) && BUFFERP(XCAR(list))) {
+    XSETBUFFER(last_thing_searched, XCAR(list));
+  }
 
   return Qnil;
 }
@@ -2836,6 +2858,7 @@
    during the execution of a sentinel or filter. */
 static int search_regs_saved;
 static struct re_registers saved_search_regs;
+static Lisp_Object saved_last_thing_searched;
 
 /* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
    if asynchronous code (filter or sentinel) is running. */
@@ -2847,6 +2870,8 @@
       saved_search_regs.num_regs = search_regs.num_regs;
       saved_search_regs.start = search_regs.start;
       saved_search_regs.end = search_regs.end;
+      saved_last_thing_searched = last_thing_searched;
+      last_thing_searched = Qnil;
       search_regs.num_regs = 0;
       search_regs.start = 0;
       search_regs.end = 0;
@@ -2869,7 +2894,8 @@
       search_regs.num_regs = saved_search_regs.num_regs;
       search_regs.start = saved_search_regs.start;
       search_regs.end = saved_search_regs.end;
-
+      last_thing_searched = saved_last_thing_searched;
+      saved_last_thing_searched = Qnil;
       search_regs_saved = 0;
     }
 }