changeset 30510:4a2abe231277

(Fdelete): Make it work on vectors and strings in addition to lists.
author Gerd Moellmann <gerd@gnu.org>
date Thu, 27 Jul 2000 15:44:20 +0000
parents 423583fa92f3
children 2ac427297d38
files src/fns.c
diffstat 1 files changed, 114 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/fns.c	Thu Jul 27 15:42:09 2000 +0000
+++ b/src/fns.c	Thu Jul 27 15:44:20 2000 +0000
@@ -1593,39 +1593,128 @@
 }
 
 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
-  "Delete by side effect any occurrences of ELT as a member of LIST.\n\
-The modified LIST is returned.  Comparison is done with `equal'.\n\
-If the first member of LIST is ELT, deleting it is not a side effect;\n\
-it is simply using a different list.\n\
+  "Delete by side effect any occurrences of ELT as a member of SEQ.\n\
+SEQ must be a list, a vector, or a string.\n\
+The modified SEQ is returned.  Comparison is done with `equal'.\n\
+If SEQ is not a list, or the first member of SEQ is ELT, deleting it\n\
+is not a side effect; it is simply using a different sequence.\n\
 Therefore, write `(setq foo (delete element foo))'\n\
 to be sure of changing the value of `foo'.")
-  (elt, list)
-     register Lisp_Object elt;
-     Lisp_Object list;
+  (elt, seq)
+     Lisp_Object elt, seq;
 {
-  register Lisp_Object tail, prev;
-  register Lisp_Object tem;
-
-  tail = list;
-  prev = Qnil;
-  while (!NILP (tail))
+  if (VECTORP (seq))
+    {
+      EMACS_INT i, n, size;
+
+      for (i = n = 0; i < ASIZE (seq); ++i)
+	if (NILP (Fequal (AREF (seq, i), elt)))
+	  ++n;
+
+      if (n != ASIZE (seq))
+	{
+	  struct Lisp_Vector *p = allocate_vectorlike (n);
+	  
+	  for (i = n = 0; i < ASIZE (seq); ++i)
+	    if (NILP (Fequal (AREF (seq, i), elt)))
+	      p->contents[n++] = AREF (seq, i);
+
+	  p->size = n;
+	  XSETVECTOR (seq, p);
+	}
+    }
+  else if (STRINGP (seq))
     {
-      if (! CONSP (tail))
-	wrong_type_argument (Qlistp, list);
-      tem = XCAR (tail);
-      if (! NILP (Fequal (elt, tem)))
+      EMACS_INT i, ibyte, nchars, nbytes, cbytes;
+      int c;
+
+      for (i = nchars = nbytes = ibyte = 0;
+	   i < XSTRING (seq)->size;
+	   ++i, ibyte += cbytes)
 	{
-	  if (NILP (prev))
-	    list = XCDR (tail);
+	  if (STRING_MULTIBYTE (seq))
+	    {
+	      c = STRING_CHAR (&XSTRING (seq)->data[ibyte],
+			       STRING_BYTES (XSTRING (seq)) - ibyte);
+	      cbytes = CHAR_BYTES (c);
+	    }
 	  else
-	    Fsetcdr (prev, XCDR (tail));
+	    {
+	      c = XSTRING (seq)->data[i];
+	      cbytes = 1;
+	    }
+	  
+	  if (!INTEGERP (elt) || c != XINT (elt))
+	    {
+	      ++nchars;
+	      nbytes += cbytes;
+	    }
 	}
-      else
-	prev = tail;
-      tail = XCDR (tail);
-      QUIT;
+
+      if (nchars != XSTRING (seq)->size)
+	{
+	  Lisp_Object tem;
+
+	  tem = make_uninit_multibyte_string (nchars, nbytes);
+	  if (!STRING_MULTIBYTE (seq))
+	    SET_STRING_BYTES (XSTRING (tem), -1);
+	  
+	  for (i = nchars = nbytes = ibyte = 0;
+	       i < XSTRING (seq)->size;
+	       ++i, ibyte += cbytes)
+	    {
+	      if (STRING_MULTIBYTE (seq))
+		{
+		  c = STRING_CHAR (&XSTRING (seq)->data[ibyte],
+				   STRING_BYTES (XSTRING (seq)) - ibyte);
+		  cbytes = CHAR_BYTES (c);
+		}
+	      else
+		{
+		  c = XSTRING (seq)->data[i];
+		  cbytes = 1;
+		}
+	      
+	      if (!INTEGERP (elt) || c != XINT (elt))
+		{
+		  unsigned char *from = &XSTRING (seq)->data[ibyte];
+		  unsigned char *to   = &XSTRING (tem)->data[nbytes];
+		  EMACS_INT n;
+		  
+		  ++nchars;
+		  nbytes += cbytes;
+		  
+		  for (n = cbytes; n--; )
+		    *to++ = *from++;
+		}
+	    }
+
+	  seq = tem;
+	}
     }
-  return list;
+  else
+    {
+      Lisp_Object tail, prev;
+
+      for (tail = seq, prev = Qnil; !NILP (tail); tail = XCDR (tail))
+	{
+	  if (!CONSP (tail))
+	    wrong_type_argument (Qlistp, seq);
+	  
+	  if (!NILP (Fequal (elt, XCAR (tail))))
+	    {
+	      if (NILP (prev))
+		seq = XCDR (tail);
+	      else
+		Fsetcdr (prev, XCDR (tail));
+	    }
+	  else
+	    prev = tail;
+	  QUIT;
+	}
+    }
+  
+  return seq;
 }
 
 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,