+/* Find all the overlays in the current buffer that touch position POS.
+ Return the number found, and store them in a vector in VEC
+ of length LEN. */
+
+static int
+overlays_around (pos, vec, len)
+ int pos;
+ Lisp_Object *vec;
+ int len;
+{
+ Lisp_Object tail, overlay, start, end;
+ int startpos, endpos;
+ int idx = 0;
+
+ for (tail = current_buffer->overlays_before;
+ GC_CONSP (tail);
+ tail = XCDR (tail))
+ {
+ overlay = XCAR (tail);
+
+ end = OVERLAY_END (overlay);
+ endpos = OVERLAY_POSITION (end);
+ if (endpos < pos)
+ break;
+ start = OVERLAY_START (overlay);
+ startpos = OVERLAY_POSITION (start);
+ if (startpos <= pos)
+ {
+ if (idx < len)
+ vec[idx] = overlay;
+ /* Keep counting overlays even if we can't return them all. */
+ idx++;
+ }
+ }
+
+ for (tail = current_buffer->overlays_after;
+ GC_CONSP (tail);
+ tail = XCDR (tail))
+ {
+ overlay = XCAR (tail);
+
+ start = OVERLAY_START (overlay);
+ startpos = OVERLAY_POSITION (start);
+ if (pos < startpos)
+ break;
+ end = OVERLAY_END (overlay);
+ endpos = OVERLAY_POSITION (end);
+ if (pos <= endpos)
+ {
+ if (idx < len)
+ vec[idx] = overlay;
+ idx++;
+ }
+ }
+
+ return idx;
+}
+
+/* Return the value of property PROP, in OBJECT at POSITION.
+ It's the value of PROP that a char inserted at POSITION would get.
+ OBJECT is optional and defaults to the current buffer.
+ 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. */
+Lisp_Object
+get_pos_property (position, prop, object)
+ Lisp_Object position, object;
+ register Lisp_Object prop;
+{
+ struct window *w = 0;
+
+ CHECK_NUMBER_COERCE_MARKER (position);
+
+ if (NILP (object))
+ XSETBUFFER (object, current_buffer);
+
+ if (WINDOWP (object))
+ {
+ w = XWINDOW (object);
+ object = w->buffer;
+ }
+ if (BUFFERP (object))
+ {
+ int posn = XINT (position);
+ int noverlays;
+ Lisp_Object *overlay_vec, tem;
+ struct buffer *obuf = current_buffer;
+
+ set_buffer_temp (XBUFFER (object));
+
+ /* First try with room for 40 overlays. */
+ noverlays = 40;
+ overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
+ noverlays = overlays_around (posn, overlay_vec, noverlays);
+
+ /* If there are more than 40,
+ make enough space for all, and try again. */
+ if (noverlays > 40)
+ {
+ overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
+ noverlays = overlays_around (posn, overlay_vec, noverlays);
+ }
+ noverlays = sort_overlays (overlay_vec, noverlays, NULL);
+
+ set_buffer_temp (obuf);
+
+ /* Now check the overlays in order of decreasing priority. */
+ while (--noverlays >= 0)
+ {
+ Lisp_Object ol = overlay_vec[noverlays];
+ tem = Foverlay_get (ol, prop);
+ if (!NILP (tem))
+ {
+ /* Check the overlay is indeed active at point. */
+ Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol);
+ if ((OVERLAY_POSITION (start) == posn
+ && XMARKER (start)->insertion_type == 1)
+ || (OVERLAY_POSITION (finish) == posn
+ && XMARKER (finish)->insertion_type == 0))
+ ; /* The overlay will not cover a char inserted at point. */
+ else
+ {
+ return tem;
+ }
+ }
+ }
+
+ }
+
+ { /* Now check the text-properties. */
+ int stickiness = text_property_stickiness (prop, position);
+ if (stickiness > 0)
+ return Fget_text_property (position, prop, Qnil);
+ else if (stickiness < 0 && XINT (position) > BEGV)
+ return Fget_text_property (make_number (XINT (position) - 1),
+ prop, Qnil);
+ else
+ return Qnil;
+ }
+}
+