changeset 11693:efef31f1c42d

(Qbefore_string, Qafter_string): New vars. (syms_of_buffer): Initialize and staticpro them. (cmp_for_strings, overlay_strings): New functions.
author Karl Heuer <kwzh@gnu.org>
date Fri, 05 May 1995 00:34:00 +0000
parents b7c7710644d3
children 8824bfeef670
files src/buffer.c
diffstat 1 files changed, 234 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c	Thu May 04 22:36:05 1995 +0000
+++ b/src/buffer.c	Fri May 05 00:34:00 1995 +0000
@@ -141,7 +141,7 @@
 
 Lisp_Object Qoverlayp;
 
-Lisp_Object Qpriority, Qwindow, Qevaporate;
+Lisp_Object Qpriority, Qwindow, Qevaporate, Qbefore_string, Qafter_string;
 
 Lisp_Object Qmodification_hooks;
 Lisp_Object Qinsert_in_front_hooks;
@@ -1274,7 +1274,7 @@
 }
 
 /* Switch to buffer B temporarily for redisplay purposes.
-   This avoids certain things thatdon't need to be done within redisplay.  */
+   This avoids certain things that don't need to be done within redisplay.  */
 
 void
 set_buffer_temp (b)
@@ -1534,7 +1534,7 @@
    Store in *LEN_PTR the size allocated for the vector.
    Store in *NEXT_PTR the next position after POS where an overlay starts,
      or ZV if there are no more overlays.
-   Store in *PREV_PTR the previous position after POS where an overlay ends,
+   Store in *PREV_PTR the previous position before POS where an overlay ends,
      or BEGV if there are no previous overlays.
    NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
 
@@ -1776,6 +1776,232 @@
   return (noverlays);
 }
 
+struct sortstr
+{
+  Lisp_Object string;
+  int size;
+  int priority;
+};
+
+/* A comparison function suitable for passing to qsort.  */
+static int
+cmp_for_strings (as1, as2)
+     char *as1, *as2;
+{
+  struct sortstr *s1 = (struct sortstr *)as1;
+  struct sortstr *s2 = (struct sortstr *)as2;
+  if (s1->size != s2->size)
+    return s2->size - s1->size;
+  if (s1->priority != s2->priority)
+    return s1->priority - s2->priority;
+  return 0;
+}
+
+/* Buffers for storing the overlays touching a given position.
+   These are expanded as needed, but never freed.  */
+static struct sortstr *overlay_heads, *overlay_tails;
+static char *overlay_str_buf;
+
+/* Allocated length of those buffers.  */
+static int overlay_heads_len, overlay_tails_len, overlay_str_len;
+
+/* Return the concatenation of the strings associated with overlays that
+   begin or end at POS, ignoring overlays that are specific to a window
+   other than W.  The strings are concatenated in the appropriate order:
+   shorter overlays nest inside longer ones, and higher priority inside
+   lower.  Returns the string length, and stores the contents indirectly
+   through PSTR, if that variable is non-null.  The string may be
+   overwritten by subsequent calls.  */
+int
+overlay_strings (pos, w, pstr)
+     int pos;
+     struct window *w;
+     char **pstr;
+{
+  Lisp_Object ov, overlay, window, str, tem;
+  int ntail = 0, nhead = 0;
+  int total = 0;
+  int startpos, endpos;
+
+  for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr)
+    {
+      overlay = XCONS (ov)->car;
+      if (!OVERLAYP (overlay))
+	abort ();
+
+      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+      if (endpos < pos)
+	break;
+      if (endpos != pos && startpos != pos)
+	continue;
+      window = Foverlay_get (overlay, Qwindow);
+      if (WINDOWP (window) && XWINDOW (window) != w)
+	continue;
+      if (endpos == pos)
+	{
+	  str = Foverlay_get (overlay, Qafter_string);
+	  if (STRINGP (str))
+	    {
+	      if (ntail == overlay_tails_len)
+		{
+		  if (! overlay_tails)
+		    {
+		      overlay_tails_len = 5;
+		      overlay_tails = ((struct sortstr *)
+				       xmalloc (5 * sizeof (struct sortstr)));
+		    }
+		  else
+		    {
+		      overlay_tails_len *= 2;
+		      overlay_tails = ((struct sortstr *)
+				       xrealloc ((overlay_tails_len
+						  * sizeof (struct sortstr))));
+		    }
+		}
+	      overlay_tails[ntail].string = str;
+	      overlay_tails[ntail].size = endpos - startpos;
+	      tem = Foverlay_get (overlay, Qpriority);
+	      overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+	      ntail++;
+	      total += XSTRING (str)->size;
+	    }
+	}
+      if (startpos == pos)
+	{
+	  str = Foverlay_get (overlay, Qbefore_string);
+	  if (STRINGP (str))
+	    {
+	      if (nhead == overlay_heads_len)
+		{
+		  if (! overlay_heads)
+		    {
+		      overlay_heads_len = 5;
+		      overlay_heads = ((struct sortstr *)
+				       xmalloc (5 * sizeof (struct sortstr)));
+		    }
+		  else
+		    {
+		      overlay_heads_len *= 2;
+		      overlay_heads = ((struct sortstr *)
+				       xrealloc ((overlay_heads_len
+						  * sizeof (struct sortstr))));
+		    }
+		}
+	      overlay_heads[nhead].string = str;
+	      overlay_heads[nhead].size = endpos - startpos;
+	      tem = Foverlay_get (overlay, Qpriority);
+	      overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+	      nhead++;
+	      total += XSTRING (str)->size;
+	    }
+	}
+    }
+  for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr)
+    {
+      overlay = XCONS (ov)->car;
+      if (!OVERLAYP (overlay))
+	abort ();
+
+      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+      if (startpos > pos)
+	break;
+      if (endpos == pos)
+	{
+	  str = Foverlay_get (overlay, Qafter_string);
+	  if (STRINGP (str))
+	    {
+	      if (ntail == overlay_tails_len)
+		{
+		  if (! overlay_tails)
+		    {
+		      overlay_tails_len = 5;
+		      overlay_tails = ((struct sortstr *)
+				       xmalloc (5 * sizeof (struct sortstr)));
+		    }
+		  else
+		    {
+		      overlay_tails_len *= 2;
+		      overlay_tails = ((struct sortstr *)
+				       xrealloc ((overlay_tails_len
+						  * sizeof (struct sortstr))));
+		    }
+		}
+	      overlay_tails[ntail].string = str;
+	      overlay_tails[ntail].size = endpos - startpos;
+	      tem = Foverlay_get (overlay, Qpriority);
+	      overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+	      ntail++;
+	      total += XSTRING (str)->size;
+	    }
+	}
+      if (startpos == pos)
+	{
+	  str = Foverlay_get (overlay, Qbefore_string);
+	  if (STRINGP (str))
+	    {
+	      if (nhead == overlay_heads_len)
+		{
+		  if (! overlay_heads)
+		    {
+		      overlay_heads_len = 5;
+		      overlay_heads = ((struct sortstr *)
+				       xmalloc (5 * sizeof (struct sortstr)));
+		    }
+		  else
+		    {
+		      overlay_heads_len *= 2;
+		      overlay_heads = ((struct sortstr *)
+				       xrealloc ((overlay_heads_len
+						  * sizeof (struct sortstr))));
+		    }
+		}
+	      overlay_heads[nhead].string = str;
+	      overlay_heads[nhead].size = endpos - startpos;
+	      tem = Foverlay_get (overlay, Qpriority);
+	      overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+	      nhead++;
+	      total += XSTRING (str)->size;
+	    }
+	}
+    }
+  if (ntail > 1)
+    qsort (overlay_tails, ntail, sizeof (struct sortstr), cmp_for_strings);
+  if (nhead > 1)
+    qsort (overlay_heads, nhead, sizeof (struct sortstr), cmp_for_strings);
+  if (total)
+    {
+      int i;
+      char *p;
+
+      if (total > overlay_str_len)
+	{
+	  if (! overlay_str_buf)
+	    overlay_str_buf = (char *)xmalloc (total);
+	  else
+	    overlay_str_buf = (char *)xrealloc (overlay_str_buf, total);
+	  overlay_str_len = total;
+	}
+      p = overlay_str_buf;
+      for (i = ntail; --i >= 0;)
+	{
+	  tem = overlay_tails[i].string;
+	  bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
+	  p += XSTRING (tem)->size;
+	}
+      for (i = 0; i < nhead; ++i)
+	{
+	  tem = overlay_heads[i].string;
+	  bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
+	  p += XSTRING (tem)->size;
+	}
+      if (pstr)
+	*pstr = overlay_str_buf;
+    }
+  return total;
+}
+
 /* Shift overlays in BUF's overlay lists, to center the lists at POS.  */
 
 void
@@ -2796,7 +3022,7 @@
   buffer_defaults.file_format = Qnil;
   buffer_defaults.overlays_before = Qnil;
   buffer_defaults.overlays_after = Qnil;
-  XSETFASTINT (buffer_defaults.overlay_center, 1);
+  XSETFASTINT (buffer_defaults.overlay_center, BEG);
 
   XSETFASTINT (buffer_defaults.tab_width, 8);
   buffer_defaults.truncate_lines = Qnil;
@@ -2948,6 +3174,10 @@
   staticpro (&Qpriority);
   Qwindow = intern ("window");
   staticpro (&Qwindow);
+  Qbefore_string = intern ("before-string");
+  staticpro (&Qbefore_string);
+  Qafter_string = intern ("after-string");
+  staticpro (&Qafter_string);
 
   Qoverlayp = intern ("overlayp");