changeset 5395:ccf7e84fe265

Correct some interactions of :from-end and :count, #'delete*, #'remove* src/ChangeLog addition: 2011-04-04 Aidan Kehoe <kehoea@parhasard.net> * fns.c (count_with_tail): This can be legitimately called from #'delete* with a specified COUNT keyword value, accept this in the assertion. * fns.c (FdeleteX): * fns.c (FremoveX): If COUNT is specified and FROM-END is non-nil, set COUNT to nil in the argument vector, so count_with_tail doesn't see it when calculating the total number of times an item occurs. Fixes problems with the interaction of :count and :from-end.
author Aidan Kehoe <kehoea@parhasard.net>
date Mon, 04 Apr 2011 20:34:17 +0100
parents 484b437fc7b4
children 75469840109b
files src/ChangeLog src/fns.c
diffstat 2 files changed, 50 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Apr 04 09:12:39 2011 +0100
+++ b/src/ChangeLog	Mon Apr 04 20:34:17 2011 +0100
@@ -1,3 +1,15 @@
+2011-04-04  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (count_with_tail):
+	This can be legitimately called from #'delete* with a specified
+	COUNT keyword value, accept this in the assertion.
+	* fns.c (FdeleteX):
+	* fns.c (FremoveX):
+	If COUNT is specified and FROM-END is non-nil, set COUNT to nil in
+	the argument vector, so count_with_tail doesn't see it when
+	calculating the total number of times an item occurs.  Fixes
+	problems with the interaction of :count and :from-end.
+
 2011-04-04  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* fns.c (FremoveX):
--- a/src/fns.c	Mon Apr 04 09:12:39 2011 +0100
+++ b/src/fns.c	Mon Apr 04 20:34:17 2011 +0100
@@ -999,7 +999,7 @@
       assert (counting >= 0);
       /* And we're not prepared to handle COUNT from any other caller at the
 	 moment. */
-      assert (EQ (caller, QremoveX));
+      assert (EQ (caller, QremoveX)|| EQ (caller, QdeleteX));
     }
 
   check_test = get_check_test_function (item, &test, test_not, if_, if_not,
@@ -3279,7 +3279,25 @@
 	    {
 	      return sequence;
 	    }
-	}
+
+          if (!NILP (from_end))
+            {
+              /* Sigh, this is inelegant. Force count_with_tail () to ignore
+                 the count keyword, so we get the actual number of matching
+                 elements, and can start removing from the beginning for the
+                 from-end case.  */
+              for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FdeleteX))->min_args;
+                   ii < nargs; ii += 2)
+                {
+                  if (EQ (args[ii], Q_count))
+                    {
+                      args[ii + 1] = Qnil;
+                      break;
+                    }
+                }
+              ii = 0;
+            }
+        }
     }
 
   check_test = get_check_test_function (item, &test, test_not, if_, if_not,
@@ -3627,6 +3645,24 @@
 	{
 	  return sequence;
 	}
+
+      if (!NILP (from_end))
+        {
+	  /* Sigh, this is inelegant. Force count_with_tail () to ignore the
+	     count keyword, so we get the actual number of matching
+	     elements, and can start removing from the beginning for the
+	     from-end case.  */
+          for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FremoveX))->min_args;
+               ii < nargs; ii += 2)
+            {
+              if (EQ (args[ii], Q_count))
+                {
+                  args[ii + 1] = Qnil;
+                  break;
+                }
+            }
+          ii = 0;
+        }
     }
 
   check_test = get_check_test_function (item, &test, test_not, if_, if_not,