(diary-file): Doc fix.
[bpt/emacs.git] / src / textprop.c
index e2f9c53..ef6dda2 100644 (file)
@@ -1,12 +1,12 @@
 /* Interface code for dealing with text properties.
    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
 /* Interface code for dealing with text properties.
    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -78,6 +78,8 @@ Lisp_Object Vtext_property_default_nonsticky;
 Lisp_Object interval_insert_behind_hooks;
 Lisp_Object interval_insert_in_front_hooks;
 
 Lisp_Object interval_insert_behind_hooks;
 Lisp_Object interval_insert_in_front_hooks;
 
+static void text_read_only P_ ((Lisp_Object)) NO_RETURN;
+
 
 /* Signal a `text-read-only' error.  This function makes it easier
    to capture that error in GDB by putting a breakpoint on it.  */
 
 /* Signal a `text-read-only' error.  This function makes it easier
    to capture that error in GDB by putting a breakpoint on it.  */
@@ -86,7 +88,10 @@ static void
 text_read_only (propval)
      Lisp_Object propval;
 {
 text_read_only (propval)
      Lisp_Object propval;
 {
-  Fsignal (Qtext_read_only, STRINGP (propval) ? Fcons (propval, Qnil) : Qnil);
+  if (STRINGP (propval))
+    xsignal1 (Qtext_read_only, propval);
+
+  xsignal0 (Qtext_read_only);
 }
 
 
 }
 
 
@@ -196,9 +201,9 @@ validate_plist (list)
     {
       register int i;
       register Lisp_Object tail;
     {
       register int i;
       register Lisp_Object tail;
-      for (i = 0, tail = list; !NILP (tail); i++)
+      for (i = 0, tail = list; CONSP (tail); i++)
        {
        {
-         tail = Fcdr (tail);
+         tail = XCDR (tail);
          QUIT;
        }
       if (i & 1)
          QUIT;
        }
       if (i & 1)
@@ -221,18 +226,18 @@ interval_has_all_properties (plist, i)
   register int found;
 
   /* Go through each element of PLIST.  */
   register int found;
 
   /* Go through each element of PLIST.  */
-  for (tail1 = plist; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
+  for (tail1 = plist; CONSP (tail1); tail1 = Fcdr (XCDR (tail1)))
     {
     {
-      sym1 = Fcar (tail1);
+      sym1 = XCAR (tail1);
       found = 0;
 
       /* Go through I's plist, looking for sym1 */
       found = 0;
 
       /* Go through I's plist, looking for sym1 */
-      for (tail2 = i->plist; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
-       if (EQ (sym1, Fcar (tail2)))
+      for (tail2 = i->plist; CONSP (tail2); tail2 = Fcdr (XCDR (tail2)))
+       if (EQ (sym1, XCAR (tail2)))
          {
            /* Found the same property on both lists.  If the
               values are unequal, return zero.  */
          {
            /* Found the same property on both lists.  If the
               values are unequal, return zero.  */
-           if (! EQ (Fcar (Fcdr (tail1)), Fcar (Fcdr (tail2))))
+           if (! EQ (Fcar (XCDR (tail1)), Fcar (XCDR (tail2))))
              return 0;
 
            /* Property has same value on both lists;  go to next one.  */
              return 0;
 
            /* Property has same value on both lists;  go to next one.  */
@@ -258,13 +263,13 @@ interval_has_some_properties (plist, i)
   register Lisp_Object tail1, tail2, sym;
 
   /* Go through each element of PLIST.  */
   register Lisp_Object tail1, tail2, sym;
 
   /* Go through each element of PLIST.  */
-  for (tail1 = plist; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
+  for (tail1 = plist; CONSP (tail1); tail1 = Fcdr (XCDR (tail1)))
     {
     {
-      sym = Fcar (tail1);
+      sym = XCAR (tail1);
 
       /* Go through i's plist, looking for tail1 */
 
       /* Go through i's plist, looking for tail1 */
-      for (tail2 = i->plist; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
-       if (EQ (sym, Fcar (tail2)))
+      for (tail2 = i->plist; CONSP (tail2); tail2 = Fcdr (XCDR (tail2)))
+       if (EQ (sym, XCAR (tail2)))
          return 1;
     }
 
          return 1;
     }
 
@@ -282,12 +287,12 @@ interval_has_some_properties_list (list, i)
   register Lisp_Object tail1, tail2, sym;
 
   /* Go through each element of LIST.  */
   register Lisp_Object tail1, tail2, sym;
 
   /* Go through each element of LIST.  */
-  for (tail1 = list; ! NILP (tail1); tail1 = XCDR (tail1))
+  for (tail1 = list; CONSP (tail1); tail1 = XCDR (tail1))
     {
       sym = Fcar (tail1);
 
       /* Go through i's plist, looking for tail1 */
     {
       sym = Fcar (tail1);
 
       /* Go through i's plist, looking for tail1 */
-      for (tail2 = i->plist; ! NILP (tail2); tail2 = XCDR (XCDR (tail2)))
+      for (tail2 = i->plist; CONSP (tail2); tail2 = XCDR (XCDR (tail2)))
        if (EQ (sym, XCAR (tail2)))
          return 1;
     }
        if (EQ (sym, XCAR (tail2)))
          return 1;
     }
@@ -386,21 +391,21 @@ add_properties (plist, i, object)
   GCPRO3 (tail1, sym1, val1);
 
   /* Go through each element of PLIST.  */
   GCPRO3 (tail1, sym1, val1);
 
   /* Go through each element of PLIST.  */
-  for (tail1 = plist; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
+  for (tail1 = plist; CONSP (tail1); tail1 = Fcdr (XCDR (tail1)))
     {
     {
-      sym1 = Fcar (tail1);
-      val1 = Fcar (Fcdr (tail1));
+      sym1 = XCAR (tail1);
+      val1 = Fcar (XCDR (tail1));
       found = 0;
 
       /* Go through I's plist, looking for sym1 */
       found = 0;
 
       /* Go through I's plist, looking for sym1 */
-      for (tail2 = i->plist; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
-       if (EQ (sym1, Fcar (tail2)))
+      for (tail2 = i->plist; CONSP (tail2); tail2 = Fcdr (XCDR (tail2)))
+       if (EQ (sym1, XCAR (tail2)))
          {
            /* No need to gcpro, because tail2 protects this
               and it must be a cons cell (we get an error otherwise).  */
            register Lisp_Object this_cdr;
 
          {
            /* No need to gcpro, because tail2 protects this
               and it must be a cons cell (we get an error otherwise).  */
            register Lisp_Object this_cdr;
 
-           this_cdr = Fcdr (tail2);
+           this_cdr = XCDR (tail2);
            /* Found the property.  Now check its value.  */
            found = 1;
 
            /* Found the property.  Now check its value.  */
            found = 1;
 
@@ -641,6 +646,10 @@ get_char_property_and_overlay (position, prop, object, overlay)
       Lisp_Object *overlay_vec;
       struct buffer *obuf = current_buffer;
 
       Lisp_Object *overlay_vec;
       struct buffer *obuf = current_buffer;
 
+      if (XINT (position) < BUF_BEGV (XBUFFER (object))
+         || XINT (position) > BUF_ZV (XBUFFER (object)))
+       xsignal1 (Qargs_out_of_range, position);
+
       set_buffer_temp (XBUFFER (object));
 
       GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0);
       set_buffer_temp (XBUFFER (object));
 
       GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0);
@@ -690,10 +699,11 @@ overlays are considered only if they are associated with OBJECT.  */)
 DEFUN ("get-char-property-and-overlay", Fget_char_property_and_overlay,
        Sget_char_property_and_overlay, 2, 3, 0,
        doc: /* Like `get-char-property', but with extra overlay information.
 DEFUN ("get-char-property-and-overlay", Fget_char_property_and_overlay,
        Sget_char_property_and_overlay, 2, 3, 0,
        doc: /* Like `get-char-property', but with extra overlay information.
-Return a cons whose car is the return value of `get-char-property'
-with the same argumentsthat is, the value of POSITION's property
-PROP in OBJECT, and whose cdr is the overlay in which the property was
+The value is a cons cell.  Its car is the return value of `get-char-property'
+with the same arguments--that is, the value of POSITION's property
+PROP in OBJECT.  Its cdr is the overlay in which the property was
 found, or nil, if it was found as a text property or not found at all.
 found, or nil, if it was found as a text property or not found at all.
+
 OBJECT is optional and defaults to the current buffer.  OBJECT may be
 a string, a buffer or a window.  For strings, the cdr of the return
 value is always nil, since strings do not have overlays.  If OBJECT is
 OBJECT is optional and defaults to the current buffer.  OBJECT may be
 a string, a buffer or a window.  For strings, the cdr of the return
 value is always nil, since strings do not have overlays.  If OBJECT is
@@ -707,7 +717,7 @@ POSITION is at the end of OBJECT, both car and cdr are nil.  */)
   Lisp_Object overlay;
   Lisp_Object val
     = get_char_property_and_overlay (position, prop, object, &overlay);
   Lisp_Object overlay;
   Lisp_Object val
     = get_char_property_and_overlay (position, prop, object, &overlay);
-  return Fcons(val, overlay);
+  return Fcons (val, overlay);
 }
 
 \f
 }
 
 \f
@@ -717,10 +727,11 @@ DEFUN ("next-char-property-change", Fnext_char_property_change,
 This scans characters forward in the current buffer from POSITION till
 it finds a change in some text property, or the beginning or end of an
 overlay, and returns the position of that.
 This scans characters forward in the current buffer from POSITION till
 it finds a change in some text property, or the beginning or end of an
 overlay, and returns the position of that.
-If none is found, the function returns (point-max).
+If none is found up to (point-max), the function returns (point-max).
 
 If the optional second argument LIMIT is non-nil, don't search
 
 If the optional second argument LIMIT is non-nil, don't search
-past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
+past position LIMIT; return LIMIT if nothing is found before LIMIT.
+LIMIT is a no-op if it is greater than (point-max).  */)
      (position, limit)
      Lisp_Object position, limit;
 {
      (position, limit)
      Lisp_Object position, limit;
 {
@@ -742,10 +753,11 @@ DEFUN ("previous-char-property-change", Fprevious_char_property_change,
 Scans characters backward in the current buffer from POSITION till it
 finds a change in some text property, or the beginning or end of an
 overlay, and returns the position of that.
 Scans characters backward in the current buffer from POSITION till it
 finds a change in some text property, or the beginning or end of an
 overlay, and returns the position of that.
-If none is found, the function returns (point-max).
+If none is found since (point-min), the function returns (point-min).
 
 If the optional second argument LIMIT is non-nil, don't search
 
 If the optional second argument LIMIT is non-nil, don't search
-past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
+past position LIMIT; return LIMIT if nothing is found before LIMIT.
+LIMIT is a no-op if it is less than (point-min).  */)
      (position, limit)
      Lisp_Object position, limit;
 {
      (position, limit)
      Lisp_Object position, limit;
 {
@@ -771,6 +783,9 @@ If the optional third argument OBJECT is a buffer (or nil, which means
 the current buffer), POSITION is a buffer position (integer or marker).
 If OBJECT is a string, POSITION is a 0-based index into it.
 
 the current buffer), POSITION is a buffer position (integer or marker).
 If OBJECT is a string, POSITION is a 0-based index into it.
 
+In a string, scan runs to the end of the string.
+In a buffer, it runs to (point-max), and the value cannot exceed that.
+
 The property values are compared with `eq'.
 If the property is constant all the way to the end of OBJECT, return the
 last valid position in OBJECT.
 The property values are compared with `eq'.
 If the property is constant all the way to the end of OBJECT, return the
 last valid position in OBJECT.
@@ -812,22 +827,30 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
       initial_value = Fget_char_property (position, prop, object);
 
       if (NILP (limit))
       initial_value = Fget_char_property (position, prop, object);
 
       if (NILP (limit))
-       XSETFASTINT (limit, BUF_ZV (current_buffer));
+       XSETFASTINT (limit, ZV);
       else
        CHECK_NUMBER_COERCE_MARKER (limit);
 
       else
        CHECK_NUMBER_COERCE_MARKER (limit);
 
-      for (;;)
+      if (XFASTINT (position) >= XFASTINT (limit))
        {
        {
-         position = Fnext_char_property_change (position, limit);
-         if (XFASTINT (position) >= XFASTINT (limit)) {
-           position = limit;
-           break;
-         }
-
-         value = Fget_char_property (position, prop, object);
-         if (!EQ (value, initial_value))
-           break;
+         position = limit;
+         if (XFASTINT (position) > ZV)
+           XSETFASTINT (position, ZV);
        }
        }
+      else
+       while (1)
+         {
+           position = Fnext_char_property_change (position, limit);
+           if (XFASTINT (position) >= XFASTINT (limit))
+             {
+               position = limit;
+               break;
+             }
+
+           value = Fget_char_property (position, prop, object);
+           if (!EQ (value, initial_value))
+             break;
+         }
 
       unbind_to (count, Qnil);
     }
 
       unbind_to (count, Qnil);
     }
@@ -845,6 +868,9 @@ If the optional third argument OBJECT is a buffer (or nil, which means
 the current buffer), POSITION is a buffer position (integer or marker).
 If OBJECT is a string, POSITION is a 0-based index into it.
 
 the current buffer), POSITION is a buffer position (integer or marker).
 If OBJECT is a string, POSITION is a 0-based index into it.
 
+In a string, scan runs to the start of the string.
+In a buffer, it runs to (point-min), and the value cannot be less than that.
+
 The property values are compared with `eq'.
 If the property is constant all the way to the start of OBJECT, return the
 first valid position in OBJECT.
 The property values are compared with `eq'.
 If the property is constant all the way to the start of OBJECT, return the
 first valid position in OBJECT.
@@ -883,19 +909,23 @@ back past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
       CHECK_NUMBER_COERCE_MARKER (position);
 
       if (NILP (limit))
       CHECK_NUMBER_COERCE_MARKER (position);
 
       if (NILP (limit))
-       XSETFASTINT (limit, BUF_BEGV (current_buffer));
+       XSETFASTINT (limit, BEGV);
       else
        CHECK_NUMBER_COERCE_MARKER (limit);
 
       if (XFASTINT (position) <= XFASTINT (limit))
       else
        CHECK_NUMBER_COERCE_MARKER (limit);
 
       if (XFASTINT (position) <= XFASTINT (limit))
-       position = limit;
+       {
+         position = limit;
+         if (XFASTINT (position) < BEGV)
+           XSETFASTINT (position, BEGV);
+       }
       else
        {
       else
        {
-         Lisp_Object initial_value =
-           Fget_char_property (make_number (XFASTINT (position) - 1),
-                               prop, object);
+         Lisp_Object initial_value
+           Fget_char_property (make_number (XFASTINT (position) - 1),
+                                 prop, object);
 
 
-         for (;;)
+         while (1)
            {
              position = Fprevious_char_property_change (position, limit);
 
            {
              position = Fprevious_char_property_change (position, limit);
 
@@ -906,9 +936,9 @@ back past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
                }
              else
                {
                }
              else
                {
-                 Lisp_Object value =
-                   Fget_char_property (make_number (XFASTINT (position) - 1),
-                                       prop, object);
+                 Lisp_Object value
+                   Fget_char_property (make_number (XFASTINT (position) - 1),
+                                         prop, object);
 
                  if (!EQ (value, initial_value))
                    break;
 
                  if (!EQ (value, initial_value))
                    break;
@@ -975,17 +1005,16 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
         && (NILP (limit) || next->position < XFASTINT (limit)))
     next = next_interval (next);
 
         && (NILP (limit) || next->position < XFASTINT (limit)))
     next = next_interval (next);
 
-  if (NULL_INTERVAL_P (next))
-    return limit;
-  if (NILP (limit))
-    XSETFASTINT (limit, (STRINGP (object)
-                        ? SCHARS (object)
-                        : BUF_ZV (XBUFFER (object))));
-  if (!(next->position < XFASTINT (limit)))
+  if (NULL_INTERVAL_P (next)
+      || (next->position
+         >= (INTEGERP (limit)
+             ? XFASTINT (limit)
+             : (STRINGP (object)
+                ? SCHARS (object)
+                : BUF_ZV (XBUFFER (object))))))
     return limit;
     return limit;
-
-  XSETFASTINT (position, next->position);
-  return position;
+  else
+    return make_number (next->position);
 }
 
 /* Return 1 if there's a change in some property between BEG and END.  */
 }
 
 /* Return 1 if there's a change in some property between BEG and END.  */
@@ -1057,16 +1086,16 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
         && (NILP (limit) || next->position < XFASTINT (limit)))
     next = next_interval (next);
 
         && (NILP (limit) || next->position < XFASTINT (limit)))
     next = next_interval (next);
 
-  if (NULL_INTERVAL_P (next))
+  if (NULL_INTERVAL_P (next)
+      || (next->position
+         >= (INTEGERP (limit)
+             ? XFASTINT (limit)
+             : (STRINGP (object)
+                ? SCHARS (object)
+                : BUF_ZV (XBUFFER (object))))))
     return limit;
     return limit;
-  if (NILP (limit))
-    XSETFASTINT (limit, (STRINGP (object)
-                        ? SCHARS (object)
-                        : BUF_ZV (XBUFFER (object))));
-  if (!(next->position < XFASTINT (limit)))
-    return limit;
-
-  return make_number (next->position);
+  else
+    return make_number (next->position);
 }
 
 DEFUN ("previous-property-change", Fprevious_property_change,
 }
 
 DEFUN ("previous-property-change", Fprevious_property_change,
@@ -1106,14 +1135,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.  */)
         && (NILP (limit)
             || (previous->position + LENGTH (previous) > XFASTINT (limit))))
     previous = previous_interval (previous);
         && (NILP (limit)
             || (previous->position + LENGTH (previous) > XFASTINT (limit))))
     previous = previous_interval (previous);
-  if (NULL_INTERVAL_P (previous))
-    return limit;
-  if (NILP (limit))
-    XSETFASTINT (limit, (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))));
-  if (!(previous->position + LENGTH (previous) > XFASTINT (limit)))
-    return limit;
 
 
-  return make_number (previous->position + LENGTH (previous));
+  if (NULL_INTERVAL_P (previous)
+      || (previous->position + LENGTH (previous)
+         <= (INTEGERP (limit)
+             ? XFASTINT (limit)
+             : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))))))
+    return limit;
+  else
+    return make_number (previous->position + LENGTH (previous));
 }
 
 DEFUN ("previous-single-property-change", Fprevious_single_property_change,
 }
 
 DEFUN ("previous-single-property-change", Fprevious_single_property_change,
@@ -1158,14 +1188,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.  */)
         && (NILP (limit)
             || (previous->position + LENGTH (previous) > XFASTINT (limit))))
     previous = previous_interval (previous);
         && (NILP (limit)
             || (previous->position + LENGTH (previous) > XFASTINT (limit))))
     previous = previous_interval (previous);
-  if (NULL_INTERVAL_P (previous))
-    return limit;
-  if (NILP (limit))
-    XSETFASTINT (limit, (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))));
-  if (!(previous->position + LENGTH (previous) > XFASTINT (limit)))
-    return limit;
 
 
-  return make_number (previous->position + LENGTH (previous));
+  if (NULL_INTERVAL_P (previous)
+      || (previous->position + LENGTH (previous)
+         <= (INTEGERP (limit)
+             ? XFASTINT (limit)
+             : (STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object))))))
+    return limit;
+  else
+    return make_number (previous->position + LENGTH (previous));
 }
 \f
 /* Callers note, this can GC when OBJECT is a buffer (or nil).  */
 }
 \f
 /* Callers note, this can GC when OBJECT is a buffer (or nil).  */
@@ -1227,7 +1258,7 @@ Return t if any property value actually changed, nil otherwise.  */)
     }
 
   if (BUFFERP (object))
     }
 
   if (BUFFERP (object))
-    modify_region (XBUFFER (object), XINT (start), XINT (end));
+    modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
 
   /* We are at the beginning of interval I, with LEN chars to scan.  */
   for (;;)
 
   /* We are at the beginning of interval I, with LEN chars to scan.  */
   for (;;)
@@ -1367,7 +1398,7 @@ set_text_properties (start, end, properties, object, signal_after_change_p)
     }
 
   if (BUFFERP (object))
     }
 
   if (BUFFERP (object))
-    modify_region (XBUFFER (object), XINT (start), XINT (end));
+    modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
 
   set_text_properties_1 (start, end, properties, object, i);
 
 
   set_text_properties_1 (start, end, properties, object, i);
 
@@ -1515,7 +1546,7 @@ Use set-text-properties if you want to remove all text properties.  */)
     }
 
   if (BUFFERP (object))
     }
 
   if (BUFFERP (object))
-    modify_region (XBUFFER (object), XINT (start), XINT (end));
+    modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
 
   /* We are at the beginning of an interval, with len to scan */
   for (;;)
 
   /* We are at the beginning of an interval, with len to scan */
   for (;;)
@@ -1606,8 +1637,8 @@ Return t if any property was actually removed, nil otherwise.  */)
      The flag `modified' records if changes have been made.
      When object is a buffer, we must call modify_region before changes are
      made and signal_after_change when we are done.
      The flag `modified' records if changes have been made.
      When object is a buffer, we must call modify_region before changes are
      made and signal_after_change when we are done.
-     We call modify_region before calling remove_properties iff modified == 0,
-     and we call signal_after_change before returning iff modified != 0. */
+     We call modify_region before calling remove_properties if modified == 0,
+     and we call signal_after_change before returning if modified != 0. */
   for (;;)
     {
       if (i == 0)
   for (;;)
     {
       if (i == 0)
@@ -1629,7 +1660,7 @@ Return t if any property was actually removed, nil otherwise.  */)
          if (LENGTH (i) == len)
            {
              if (!modified && BUFFERP (object))
          if (LENGTH (i) == len)
            {
              if (!modified && BUFFERP (object))
-               modify_region (XBUFFER (object), XINT (start), XINT (end));
+               modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
              remove_properties (Qnil, properties, i, object);
              if (BUFFERP (object))
                signal_after_change (XINT (start), XINT (end) - XINT (start),
              remove_properties (Qnil, properties, i, object);
              if (BUFFERP (object))
                signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1642,7 +1673,7 @@ Return t if any property was actually removed, nil otherwise.  */)
          i = split_interval_left (i, len);
          copy_properties (unchanged, i);
          if (!modified && BUFFERP (object))
          i = split_interval_left (i, len);
          copy_properties (unchanged, i);
          if (!modified && BUFFERP (object))
-           modify_region (XBUFFER (object), XINT (start), XINT (end));
+           modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
          remove_properties (Qnil, properties, i, object);
          if (BUFFERP (object))
            signal_after_change (XINT (start), XINT (end) - XINT (start),
          remove_properties (Qnil, properties, i, object);
          if (BUFFERP (object))
            signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1653,7 +1684,7 @@ Return t if any property was actually removed, nil otherwise.  */)
       if (interval_has_some_properties_list (properties, i))
        {
          if (!modified && BUFFERP (object))
       if (interval_has_some_properties_list (properties, i))
        {
          if (!modified && BUFFERP (object))
-           modify_region (XBUFFER (object), XINT (start), XINT (end));
+           modify_region (XBUFFER (object), XINT (start), XINT (end), 1);
          remove_properties (Qnil, properties, i, object);
          modified = 1;
        }
          remove_properties (Qnil, properties, i, object);
          modified = 1;
        }
@@ -1767,8 +1798,12 @@ text_property_stickiness (prop, pos, buffer)
        /* PROP is rear-non-sticky.  */
        is_rear_sticky = 0;
     }
        /* PROP is rear-non-sticky.  */
        is_rear_sticky = 0;
     }
+  else
+    return 0;
 
   /* Consider following character.  */
 
   /* Consider following character.  */
+  /* This signals an arg-out-of-range error if pos is outside the
+     buffer's accessible range.  */
   front_sticky = Fget_text_property (pos, Qfront_sticky, buffer);
 
   if (EQ (front_sticky, Qt)
   front_sticky = Fget_text_property (pos, Qfront_sticky, buffer);
 
   if (EQ (front_sticky, Qt)
@@ -1934,10 +1969,10 @@ text_property_list (object, start, end, prop)
          plist = i->plist;
 
          if (!NILP (prop))
          plist = i->plist;
 
          if (!NILP (prop))
-           for (; !NILP (plist); plist = Fcdr (Fcdr (plist)))
-             if (EQ (Fcar (plist), prop))
+           for (; CONSP (plist); plist = Fcdr (XCDR (plist)))
+             if (EQ (XCAR (plist), prop))
                {
                {
-                 plist = Fcons (prop, Fcons (Fcar (Fcdr (plist)), Qnil));
+                 plist = Fcons (prop, Fcons (Fcar (XCDR (plist)), Qnil));
                  break;
                }
 
                  break;
                }