+ return Fget_text_property (position, prop, object);
+}
+
+DEFUN ("get-char-property", Fget_char_property, Sget_char_property, 2, 3, 0,
+ doc: /* Return the value of POSITION's property PROP, in OBJECT.
+Both overlay properties and text properties are checked.
+OBJECT is optional and defaults to the current buffer.
+If POSITION is at the end of OBJECT, the value is nil.
+If OBJECT is a buffer, then overlay properties are considered as well as
+text properties.
+If OBJECT is a window, then that window's buffer is used, but window-specific
+overlays are considered only if they are associated with OBJECT. */)
+ (position, prop, object)
+ Lisp_Object position, object;
+ register Lisp_Object prop;
+{
+ return get_char_property_and_overlay (position, prop, object, 0);
+}
+
+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.
+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.
+
+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
+a window, then that window's buffer is used, but window-specific
+overlays are considered only if they are associated with OBJECT. If
+POSITION is at the end of OBJECT, both car and cdr are nil. */)
+ (position, prop, object)
+ Lisp_Object position, object;
+ register Lisp_Object prop;
+{
+ Lisp_Object overlay;
+ Lisp_Object val
+ = get_char_property_and_overlay (position, prop, object, &overlay);
+ return Fcons(val, overlay);
+}
+
+\f
+DEFUN ("next-char-property-change", Fnext_char_property_change,
+ Snext_char_property_change, 1, 2, 0,
+ doc: /* Return the position of next text property or overlay 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.
+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
+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;
+{
+ Lisp_Object temp;
+
+ temp = Fnext_overlay_change (position);
+ if (! NILP (limit))
+ {
+ CHECK_NUMBER_COERCE_MARKER (limit);
+ if (XINT (limit) < XINT (temp))
+ temp = limit;
+ }
+ return Fnext_property_change (position, Qnil, temp);
+}
+
+DEFUN ("previous-char-property-change", Fprevious_char_property_change,
+ Sprevious_char_property_change, 1, 2, 0,
+ doc: /* Return the position of previous text property or overlay 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.
+If none is found since (point-min), the function returns (point-min).
+
+If the optional second argument LIMIT is non-nil, don't search
+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;
+{
+ Lisp_Object temp;
+
+ temp = Fprevious_overlay_change (position);
+ if (! NILP (limit))
+ {
+ CHECK_NUMBER_COERCE_MARKER (limit);
+ if (XINT (limit) > XINT (temp))
+ temp = limit;
+ }
+ return Fprevious_property_change (position, Qnil, temp);
+}
+
+
+DEFUN ("next-single-char-property-change", Fnext_single_char_property_change,
+ Snext_single_char_property_change, 2, 4, 0,
+ doc: /* Return the position of next text property or overlay change for a specific property.
+Scans characters forward from POSITION till it finds
+a change in the PROP property, then returns the position of the change.
+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.
+
+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.
+If the optional fourth argument LIMIT is non-nil, don't search
+past position LIMIT; return LIMIT if nothing is found before LIMIT. */)
+ (position, prop, object, limit)
+ Lisp_Object prop, position, object, limit;
+{
+ if (STRINGP (object))
+ {
+ position = Fnext_single_property_change (position, prop, object, limit);
+ if (NILP (position))
+ {
+ if (NILP (limit))
+ position = make_number (SCHARS (object));
+ else
+ {
+ CHECK_NUMBER (limit);
+ position = limit;
+ }
+ }
+ }
+ else
+ {
+ Lisp_Object initial_value, value;
+ int count = SPECPDL_INDEX ();
+
+ if (! NILP (object))
+ CHECK_BUFFER (object);
+
+ if (BUFFERP (object) && current_buffer != XBUFFER (object))
+ {
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ Fset_buffer (object);
+ }
+
+ CHECK_NUMBER_COERCE_MARKER (position);
+
+ initial_value = Fget_char_property (position, prop, object);
+
+ if (NILP (limit))
+ XSETFASTINT (limit, ZV);
+ else
+ CHECK_NUMBER_COERCE_MARKER (limit);
+
+ if (XFASTINT (position) >= XFASTINT (limit))
+ {
+ 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);
+ }
+
+ return position;