Merge from trunk.
[bpt/emacs.git] / src / textprop.c
index a224c12..f9339c6 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface code for dealing with text properties.
-   Copyright (C) 1993-1995, 1997, 1999-2011 Free Software Foundation, Inc.
+   Copyright (C) 1993-1995, 1997, 1999-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -124,7 +124,7 @@ INTERVAL
 validate_interval_range (Lisp_Object object, Lisp_Object *begin, Lisp_Object *end, int force)
 {
   register INTERVAL i;
-  EMACS_INT searchpos;
+  ptrdiff_t searchpos;
 
   CHECK_STRING_OR_BUFFER (object);
   CHECK_NUMBER_COERCE_MARKER (*begin);
@@ -160,7 +160,7 @@ validate_interval_range (Lisp_Object object, Lisp_Object *begin, Lisp_Object *en
     }
   else
     {
-      EMACS_INT len = SCHARS (object);
+      ptrdiff_t len = SCHARS (object);
 
       if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end)
             && XINT (*end) <= len))
@@ -248,7 +248,7 @@ interval_has_all_properties (Lisp_Object plist, INTERVAL i)
 /* Return nonzero if the plist of interval I has any of the
    properties of PLIST, regardless of their values.  */
 
-static INLINE int
+static inline int
 interval_has_some_properties (Lisp_Object plist, INTERVAL i)
 {
   register Lisp_Object tail1, tail2, sym;
@@ -270,7 +270,7 @@ interval_has_some_properties (Lisp_Object plist, INTERVAL i)
 /* Return nonzero if the plist of interval I has any of the
    property names in LIST, regardless of their values.  */
 
-static INLINE int
+static inline int
 interval_has_some_properties_list (Lisp_Object list, INTERVAL i)
 {
   register Lisp_Object tail1, tail2, sym;
@@ -499,7 +499,7 @@ remove_properties (Lisp_Object plist, Lisp_Object list, INTERVAL i, Lisp_Object
 /* Remove all properties from interval I.  Return non-zero
    if this changes the interval.  */
 
-static INLINE int
+static inline int
 erase_properties (INTERVAL i)
 {
   if (NILP (i->plist))
@@ -514,10 +514,10 @@ erase_properties (INTERVAL i)
    POSITION is BEG-based.  */
 
 INTERVAL
-interval_of (EMACS_INT position, Lisp_Object object)
+interval_of (ptrdiff_t position, Lisp_Object object)
 {
   register INTERVAL i;
-  EMACS_INT beg, end;
+  ptrdiff_t beg, end;
 
   if (NILP (object))
     XSETBUFFER (object, current_buffer);
@@ -613,7 +613,7 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
     }
   if (BUFFERP (object))
     {
-      int noverlays;
+      ptrdiff_t noverlays;
       Lisp_Object *overlay_vec;
       struct buffer *obuf = current_buffer;
 
@@ -775,7 +775,7 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
   else
     {
       Lisp_Object initial_value, value;
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
 
       if (! NILP (object))
        CHECK_BUFFER (object);
@@ -838,8 +838,8 @@ 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.
-If the optional fourth argument LIMIT is non-nil, don't search
-back past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
+If the optional fourth argument LIMIT is non-nil, don't search back past
+position LIMIT; return LIMIT if nothing is found before reaching LIMIT.  */)
   (Lisp_Object position, Lisp_Object prop, Lisp_Object object, Lisp_Object limit)
 {
   if (STRINGP (object))
@@ -858,7 +858,7 @@ back past position LIMIT; return LIMIT if nothing is found before LIMIT.  */)
     }
   else
     {
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
 
       if (! NILP (object))
        CHECK_BUFFER (object);
@@ -1140,7 +1140,7 @@ Return t if any property value actually changed, nil otherwise.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object)
 {
   register INTERVAL i, unchanged;
-  register EMACS_INT s, len;
+  register ptrdiff_t s, len;
   register int modified = 0;
   struct gcpro gcpro1;
 
@@ -1170,7 +1170,7 @@ Return t if any property value actually changed, nil otherwise.  */)
          skip it.  */
       if (interval_has_all_properties (properties, i))
        {
-         EMACS_INT got = (LENGTH (i) - (s - i->position));
+         ptrdiff_t got = (LENGTH (i) - (s - i->position));
          if (got >= len)
            RETURN_UNGCPRO (Qnil);
          len -= got;
@@ -1345,18 +1345,21 @@ void
 set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object buffer, INTERVAL i)
 {
   register INTERVAL prev_changed = NULL_INTERVAL;
-  register EMACS_INT s, len;
+  register ptrdiff_t s, len;
   INTERVAL unchanged;
 
-  s = XINT (start);
-  len = XINT (end) - s;
-  if (len == 0)
-    return;
-  if (len < 0)
+  if (XINT (start) < XINT (end))
     {
-      s = s + len;
-      len = - len;
+      s = XINT (start);
+      len = XINT (end) - s;
     }
+  else if (XINT (end) < XINT (start))
+    {
+      s = XINT (end);
+      len = XINT (start) - s;
+    }
+  else
+    return;
 
   if (i == 0)
     i = find_interval (BUF_INTERVALS (XBUFFER (buffer)), s);
@@ -1435,7 +1438,7 @@ Use `set-text-properties' if you want to remove all text properties.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object)
 {
   register INTERVAL i, unchanged;
-  register EMACS_INT s, len;
+  register ptrdiff_t s, len;
   register int modified = 0;
 
   if (NILP (object))
@@ -1454,7 +1457,7 @@ Use `set-text-properties' if you want to remove all text properties.  */)
          it covers the entire region.  */
       if (! interval_has_some_properties (properties, i))
        {
-         EMACS_INT got = (LENGTH (i) - (s - i->position));
+         ptrdiff_t got = (LENGTH (i) - (s - i->position));
          if (got >= len)
            return Qnil;
          len -= got;
@@ -1521,7 +1524,7 @@ Return t if any property was actually removed, nil otherwise.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object list_of_properties, Lisp_Object object)
 {
   register INTERVAL i, unchanged;
-  register EMACS_INT s, len;
+  register ptrdiff_t s, len;
   register int modified = 0;
   Lisp_Object properties;
   properties = list_of_properties;
@@ -1542,7 +1545,7 @@ Return t if any property was actually removed, nil otherwise.  */)
          it covers the entire region.  */
       if (! interval_has_some_properties_list (properties, i))
        {
-         EMACS_INT got = (LENGTH (i) - (s - i->position));
+         ptrdiff_t got = (LENGTH (i) - (s - i->position));
          if (got >= len)
            return Qnil;
          len -= got;
@@ -1622,7 +1625,7 @@ Return t if any property was actually removed, nil otherwise.  */)
 \f
 DEFUN ("text-property-any", Ftext_property_any,
        Stext_property_any, 4, 5, 0,
-       doc: /* Check text from START to END for property PROPERTY equalling VALUE.
+       doc: /* Check text from START to END for property PROPERTY equaling VALUE.
 If so, return the position of the first character whose property PROPERTY
 is `eq' to VALUE.  Otherwise return nil.
 If the optional fifth argument OBJECT is a buffer (or nil, which means
@@ -1631,7 +1634,7 @@ markers).  If OBJECT is a string, START and END are 0-based indices into it.  */
   (Lisp_Object start, Lisp_Object end, Lisp_Object property, Lisp_Object value, Lisp_Object object)
 {
   register INTERVAL i;
-  register EMACS_INT e, pos;
+  register ptrdiff_t e, pos;
 
   if (NILP (object))
     XSETBUFFER (object, current_buffer);
@@ -1658,7 +1661,7 @@ markers).  If OBJECT is a string, START and END are 0-based indices into it.  */
 
 DEFUN ("text-property-not-all", Ftext_property_not_all,
        Stext_property_not_all, 4, 5, 0,
-       doc: /* Check text from START to END for property PROPERTY not equalling VALUE.
+       doc: /* Check text from START to END for property PROPERTY not equaling VALUE.
 If so, return the position of the first character whose property PROPERTY
 is not `eq' to VALUE.  Otherwise, return nil.
 If the optional fifth argument OBJECT is a buffer (or nil, which means
@@ -1667,7 +1670,7 @@ markers).  If OBJECT is a string, START and END are 0-based indices into it.  */
   (Lisp_Object start, Lisp_Object end, Lisp_Object property, Lisp_Object value, Lisp_Object object)
 {
   register INTERVAL i;
-  register EMACS_INT s, e;
+  register ptrdiff_t s, e;
 
   if (NILP (object))
     XSETBUFFER (object, current_buffer);
@@ -1704,10 +1707,14 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
 {
   Lisp_Object prev_pos, front_sticky;
   int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */
+  Lisp_Object defalt = Fassq (prop, Vtext_property_default_nonsticky);
 
   if (NILP (buffer))
     XSETBUFFER (buffer, current_buffer);
 
+  if (CONSP (defalt) && !NILP (XCDR (defalt)))
+    is_rear_sticky = 0;
+
   if (XINT (pos) > BUF_BEGV (XBUFFER (buffer)))
     /* Consider previous character.  */
     {
@@ -1773,7 +1780,7 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_
   Lisp_Object res;
   Lisp_Object stuff;
   Lisp_Object plist;
-  EMACS_INT s, e, e2, p, len;
+  ptrdiff_t s, e, e2, p, len;
   int modified = 0;
   struct gcpro gcpro1, gcpro2;
 
@@ -1785,8 +1792,11 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_
   {
     Lisp_Object dest_start, dest_end;
 
+    e = XINT (pos) + (XINT (end) - XINT (start));
+    if (MOST_POSITIVE_FIXNUM < e)
+      args_out_of_range (pos, end);
     dest_start = pos;
-    XSETFASTINT (dest_end, XINT (dest_start) + (XINT (end) - XINT (start)));
+    XSETFASTINT (dest_end, e);
     /* Apply this to a copy of pos; it will try to increment its arguments,
        which we don't want.  */
     validate_interval_range (dest, &dest_start, &dest_end, soft);
@@ -1870,12 +1880,12 @@ text_property_list (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp
   i = validate_interval_range (object, &start, &end, soft);
   if (!NULL_INTERVAL_P (i))
     {
-      EMACS_INT s = XINT (start);
-      EMACS_INT e = XINT (end);
+      ptrdiff_t s = XINT (start);
+      ptrdiff_t e = XINT (end);
 
       while (s < e)
        {
-         EMACS_INT interval_end, len;
+         ptrdiff_t interval_end, len;
          Lisp_Object plist;
 
          interval_end = i->position + LENGTH (i);
@@ -1953,7 +1963,7 @@ Lisp_Object
 extend_property_ranges (Lisp_Object list, Lisp_Object new_end)
 {
   Lisp_Object prev = Qnil, head = list;
-  EMACS_INT max = XINT (new_end);
+  ptrdiff_t max = XINT (new_end);
 
   for (; CONSP (list); prev = list, list = XCDR (list))
     {
@@ -2007,7 +2017,7 @@ call_mod_hooks (Lisp_Object list, Lisp_Object start, Lisp_Object end)
 
 void
 verify_interval_modification (struct buffer *buf,
-                             EMACS_INT start, EMACS_INT end)
+                             ptrdiff_t start, ptrdiff_t end)
 {
   register INTERVAL intervals = BUF_INTERVALS (buf);
   register INTERVAL i;
@@ -2028,7 +2038,7 @@ verify_interval_modification (struct buffer *buf,
 
   if (start > end)
     {
-      EMACS_INT temp = start;
+      ptrdiff_t temp = start;
       start = end;
       end = temp;
     }
@@ -2220,16 +2230,18 @@ This also inhibits the use of the `intangible' text property.  */);
 
   DEFVAR_LISP ("text-property-default-nonsticky",
               Vtext_property_default_nonsticky,
-              doc: /* Alist of properties vs the corresponding non-stickinesses.
+              doc: /* Alist of properties vs the corresponding non-stickiness.
 Each element has the form (PROPERTY . NONSTICKINESS).
 
 If a character in a buffer has PROPERTY, new text inserted adjacent to
 the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil,
 inherits it if NONSTICKINESS is nil.  The `front-sticky' and
 `rear-nonsticky' properties of the character override NONSTICKINESS.  */);
-  /* Text property `syntax-table' should be nonsticky by default.  */
+  /* Text properties `syntax-table'and `display' should be nonsticky
+     by default.  */
   Vtext_property_default_nonsticky
-    = Fcons (Fcons (intern_c_string ("syntax-table"), Qt), Qnil);
+    = Fcons (Fcons (intern_c_string ("syntax-table"), Qt),
+            Fcons (Fcons (intern_c_string ("display"), Qt), Qnil));
 
   staticpro (&interval_insert_behind_hooks);
   staticpro (&interval_insert_in_front_hooks);
@@ -2239,45 +2251,27 @@ inherits it if NONSTICKINESS is nil.  The `front-sticky' and
 
   /* Common attributes one might give text */
 
-  staticpro (&Qforeground);
-  Qforeground = intern_c_string ("foreground");
-  staticpro (&Qbackground);
-  Qbackground = intern_c_string ("background");
-  staticpro (&Qfont);
-  Qfont = intern_c_string ("font");
-  staticpro (&Qstipple);
-  Qstipple = intern_c_string ("stipple");
-  staticpro (&Qunderline);
-  Qunderline = intern_c_string ("underline");
-  staticpro (&Qread_only);
-  Qread_only = intern_c_string ("read-only");
-  staticpro (&Qinvisible);
-  Qinvisible = intern_c_string ("invisible");
-  staticpro (&Qintangible);
-  Qintangible = intern_c_string ("intangible");
-  staticpro (&Qcategory);
-  Qcategory = intern_c_string ("category");
-  staticpro (&Qlocal_map);
-  Qlocal_map = intern_c_string ("local-map");
-  staticpro (&Qfront_sticky);
-  Qfront_sticky = intern_c_string ("front-sticky");
-  staticpro (&Qrear_nonsticky);
-  Qrear_nonsticky = intern_c_string ("rear-nonsticky");
-  staticpro (&Qmouse_face);
-  Qmouse_face = intern_c_string ("mouse-face");
-  staticpro (&Qminibuffer_prompt);
-  Qminibuffer_prompt = intern_c_string ("minibuffer-prompt");
+  DEFSYM (Qforeground, "foreground");
+  DEFSYM (Qbackground, "background");
+  DEFSYM (Qfont, "font");
+  DEFSYM (Qstipple, "stipple");
+  DEFSYM (Qunderline, "underline");
+  DEFSYM (Qread_only, "read-only");
+  DEFSYM (Qinvisible, "invisible");
+  DEFSYM (Qintangible, "intangible");
+  DEFSYM (Qcategory, "category");
+  DEFSYM (Qlocal_map, "local-map");
+  DEFSYM (Qfront_sticky, "front-sticky");
+  DEFSYM (Qrear_nonsticky, "rear-nonsticky");
+  DEFSYM (Qmouse_face, "mouse-face");
+  DEFSYM (Qminibuffer_prompt, "minibuffer-prompt");
 
   /* Properties that text might use to specify certain actions */
 
-  staticpro (&Qmouse_left);
-  Qmouse_left = intern_c_string ("mouse-left");
-  staticpro (&Qmouse_entered);
-  Qmouse_entered = intern_c_string ("mouse-entered");
-  staticpro (&Qpoint_left);
-  Qpoint_left = intern_c_string ("point-left");
-  staticpro (&Qpoint_entered);
-  Qpoint_entered = intern_c_string ("point-entered");
+  DEFSYM (Qmouse_left, "mouse-left");
+  DEFSYM (Qmouse_entered, "mouse-entered");
+  DEFSYM (Qpoint_left, "point-left");
+  DEFSYM (Qpoint_entered, "point-entered");
 
   defsubr (&Stext_properties_at);
   defsubr (&Sget_text_property);