* xmenu.c (mouse_position_for_popup):
[bpt/emacs.git] / src / fns.c
index 53819ed..5074ae3 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1697,40 +1697,121 @@ changing the value of a sequence `foo'.  */)
 }
 
 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
-       doc: /* Reverse LIST by modifying cdr pointers.
-Return the reversed list.  Expects a properly nil-terminated list.  */)
-  (Lisp_Object list)
+       doc: /* Reverse order of items in a list, vector or string SEQ.
+If SEQ is a list, it should be nil-terminated.
+This function may destructively modify SEQ to produce the value.  */)
+  (Lisp_Object seq)
 {
-  register Lisp_Object prev, tail, next;
+  if (NILP (seq))
+    return seq;
+  else if (STRINGP (seq))
+    return Freverse (seq);
+  else if (CONSP (seq))
+    {
+      Lisp_Object prev, tail, next;
 
-  if (NILP (list)) return list;
-  prev = Qnil;
-  tail = list;
-  while (!NILP (tail))
+      for (prev = Qnil, tail = seq; !NILP (tail); tail = next)
+       {
+         QUIT;
+         CHECK_LIST_CONS (tail, tail);
+         next = XCDR (tail);
+         Fsetcdr (tail, prev);
+         prev = tail;
+       }
+      seq = prev;
+    }
+  else if (VECTORP (seq))
     {
-      QUIT;
-      CHECK_LIST_CONS (tail, tail);
-      next = XCDR (tail);
-      Fsetcdr (tail, prev);
-      prev = tail;
-      tail = next;
+      ptrdiff_t i, size = ASIZE (seq);
+
+      for (i = 0; i < size / 2; i++)
+       {
+         Lisp_Object tem = AREF (seq, i);
+         ASET (seq, i, AREF (seq, size - i - 1));
+         ASET (seq, size - i - 1, tem);
+       }
+    }
+  else if (BOOL_VECTOR_P (seq))
+    {
+      ptrdiff_t i, size = bool_vector_size (seq);
+
+      for (i = 0; i < size / 2; i++)
+       {
+         bool tem = bool_vector_bitref (seq, i);
+         bool_vector_set (seq, i, bool_vector_bitref (seq, size - i - 1));
+         bool_vector_set (seq, size - i - 1, tem);
+       }
     }
-  return prev;
+  else
+    wrong_type_argument (Qarrayp, seq);
+  return seq;
 }
 
 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
-       doc: /* Reverse LIST, copying.  Return the reversed list.
+       doc: /* Return the reversed copy of list, vector, or string SEQ.
 See also the function `nreverse', which is used more often.  */)
-  (Lisp_Object list)
+  (Lisp_Object seq)
 {
   Lisp_Object new;
 
-  for (new = Qnil; CONSP (list); list = XCDR (list))
+  if (NILP (seq))
+    return Qnil;
+  else if (CONSP (seq))
     {
-      QUIT;
-      new = Fcons (XCAR (list), new);
+      for (new = Qnil; CONSP (seq); seq = XCDR (seq))
+       {
+         QUIT;
+         new = Fcons (XCAR (seq), new);
+       }
+      CHECK_LIST_END (seq, seq);
+    }
+  else if (VECTORP (seq))
+    {
+      ptrdiff_t i, size = ASIZE (seq);
+      
+      new = make_uninit_vector (size);
+      for (i = 0; i < size; i++)
+       ASET (new, i, AREF (seq, size - i - 1));
+    }
+  else if (BOOL_VECTOR_P (seq))
+    {
+      ptrdiff_t i;
+      EMACS_INT nbits = bool_vector_size (seq);
+
+      new = make_uninit_bool_vector (nbits);
+      for (i = 0; i < nbits; i++)
+       bool_vector_set (new, i, bool_vector_bitref (seq, nbits - i - 1));
+    }
+  else if (STRINGP (seq))
+    {
+      ptrdiff_t size = SCHARS (seq), bytes = SBYTES (seq);
+      
+      if (size == bytes)
+       {
+         ptrdiff_t i;
+
+         new = make_uninit_string (size);
+         for (i = 0; i < size; i++)
+           SSET (new, i, SREF (seq, size - i - 1));
+       }
+      else
+       {
+         unsigned char *p, *q;
+
+         new = make_uninit_multibyte_string (size, bytes);
+         p = SDATA (seq), q = SDATA (new) + bytes;
+         while (q > SDATA (new))
+           {
+             int ch, len;
+             
+             ch = STRING_CHAR_AND_LENGTH (p, len);
+             p += len, q -= len;
+             CHAR_STRING (ch, q);
+           }
+       }
     }
-  CHECK_LIST_END (list, list);
+  else
+    wrong_type_argument (Qsequencep, seq);
   return new;
 }
 \f