+ if (WINDOWP (object))
+ {
+ w = XWINDOW (object);
+ object = w->buffer;
+ }
+ if (BUFFERP (object))
+ {
+ int posn = XINT (position);
+ int noverlays;
+ Lisp_Object *overlay_vec, tem;
+ int next_overlay;
+ int len;
+ struct buffer *obuf = current_buffer;
+
+ set_buffer_temp (XBUFFER (object));
+
+ /* First try with room for 40 overlays. */
+ len = 40;
+ overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
+
+ noverlays = overlays_at (posn, 0, &overlay_vec, &len,
+ &next_overlay, NULL);
+
+ /* If there are more than 40,
+ make enough space for all, and try again. */
+ if (noverlays > len)
+ {
+ len = noverlays;
+ overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
+ noverlays = overlays_at (posn, 0, &overlay_vec, &len,
+ &next_overlay, NULL);
+ }
+ noverlays = sort_overlays (overlay_vec, noverlays, w);
+
+ set_buffer_temp (obuf);
+
+ /* Now check the overlays in order of decreasing priority. */
+ while (--noverlays >= 0)
+ {
+ tem = Foverlay_get (overlay_vec[noverlays], prop);
+ if (!NILP (tem))
+ return (tem);
+ }
+ }
+ /* Not a buffer, or no appropriate overlay, so fall through to the
+ simpler case. */
+ return (Fget_text_property (position, prop, object));
+}
+\f
+DEFUN ("next-char-property-change", Fnext_char_property_change,
+ Snext_char_property_change, 1, 2, 0,
+ "Return the position of next text property or overlay change.\n\
+This scans characters forward from POSITION in OBJECT till it finds\n\
+a change in some text property, or the beginning or end of an overlay,\n\
+and returns the position of that.\n\
+If none is found, the function returns (point-max).\n\
+\n\
+If the optional third argument LIMIT is non-nil, don't search\n\
+past position LIMIT; return LIMIT if nothing is found before LIMIT.")
+ (position, limit)
+ Lisp_Object position, limit;
+{
+ Lisp_Object temp;
+
+ temp = Fnext_overlay_change (position);
+ if (! NILP (limit))
+ {
+ CHECK_NUMBER (limit, 2);
+ 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,
+ "Return the position of previous text property or overlay change.\n\
+Scans characters backward from POSITION in OBJECT till it finds\n\
+a change in some text property, or the beginning or end of an overlay,\n\
+and returns the position of that.\n\
+If none is found, the function returns (point-max).\n\
+\n\
+If the optional third argument LIMIT is non-nil, don't search\n\
+past position LIMIT; return LIMIT if nothing is found before LIMIT.")
+ (position, limit)
+ Lisp_Object position, limit;
+{
+ Lisp_Object temp;
+
+ temp = Fprevious_overlay_change (position);
+ if (! NILP (limit))
+ {
+ CHECK_NUMBER (limit, 2);
+ 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,
+ "Return the position of next text property or overlay change for a specific property.\n\
+Scans characters forward from POSITION till it finds\n\
+a change in the PROP property, then returns the position of the change.\n\
+The optional third argument OBJECT is the string or buffer to scan.\n\
+The property values are compared with `eq'.\n\
+Return nil if the property is constant all the way to the end of OBJECT.\n\
+If the value is non-nil, it is a position greater than POSITION, never equal.\n\n\
+If the optional fourth argument LIMIT is non-nil, don't search\n\
+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 (XSTRING (object)->size);
+ else
+ position = limit;
+ }
+ }
+ else
+ {
+ Lisp_Object initial_value, value;
+ int count = specpdl_ptr - specpdl;
+
+ if (! NILP (object))
+ CHECK_BUFFER (object, 0);
+
+ if (BUFFERP (object) && current_buffer != XBUFFER (object))
+ {
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ Fset_buffer (object);
+ }
+
+ initial_value = Fget_char_property (position, prop, object);
+
+ if (NILP (limit))
+ XSETFASTINT (limit, BUF_ZV (current_buffer));
+ else
+ CHECK_NUMBER_COERCE_MARKER (limit, 0);
+
+ for (;;)
+ {
+ 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);
+ }