1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-29 11:02:01 +00:00

Move proper-list-p to C

Since C code can use it and it’s simple, we might as well use C.
* lisp/subr.el (proper-list-p): Move to C code.
* src/eval.c (signal_error): Simplify by using Fproper_list_p.
* src/fns.c (Fproper_list_p): New function, moved here from Lisp.

Simplify signal_error
* src/eval.c (signal_error): Simplify by using FOR_EACH_TAIL_SAFE.
This commit is contained in:
Paul Eggert 2018-07-24 15:58:46 -07:00
parent 0ed21b7b3e
commit 200195e824
4 changed files with 26 additions and 25 deletions

View File

@ -555,12 +555,6 @@ If N is omitted or nil, remove the last element."
(if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil))
list))))
(defun proper-list-p (object)
"Return OBJECT's length if it is a proper list, nil otherwise.
A proper list is neither circular nor dotted (i.e., its last cdr
is nil)."
(and (listp object) (ignore-errors (length object))))
(defun delete-dups (list)
"Destructively remove `equal' duplicates from LIST.
Store the result in LIST and return it. LIST must be a proper list.

View File

@ -1732,28 +1732,12 @@ xsignal3 (Lisp_Object error_symbol, Lisp_Object arg1, Lisp_Object arg2, Lisp_Obj
}
/* Signal `error' with message S, and additional arg ARG.
If ARG is not a genuine list, make it a one-element list. */
If ARG is not a proper list, make it a one-element list. */
void
signal_error (const char *s, Lisp_Object arg)
{
Lisp_Object tortoise, hare;
hare = tortoise = arg;
while (CONSP (hare))
{
hare = XCDR (hare);
if (!CONSP (hare))
break;
hare = XCDR (hare);
tortoise = XCDR (tortoise);
if (EQ (hare, tortoise))
break;
}
if (!NILP (hare))
if (NILP (Fproper_list_p (arg)))
arg = list1 (arg);
xsignal (Qerror, Fcons (build_string (s), arg));

View File

@ -144,6 +144,28 @@ which is at least the number of distinct elements. */)
return make_fixnum_or_float (len);
}
DEFUN ("proper-list-p", Fproper_list_p, Sproper_list_p, 1, 1, 0,
doc: /* Return OBJECT's length if it is a proper list, nil otherwise.
A proper list is neither circular nor dotted (i.e., its last cdr is nil). */
attributes: const)
(Lisp_Object object)
{
intptr_t len = 0;
Lisp_Object last_tail = object;
Lisp_Object tail = object;
FOR_EACH_TAIL_SAFE (tail)
{
len++;
rarely_quit (len);
last_tail = XCDR (tail);
}
if (!NILP (last_tail))
return Qnil;
if (MOST_POSITIVE_FIXNUM < len)
xsignal0 (Qoverflow_error);
return make_number (len);
}
DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
doc: /* Return the number of bytes in STRING.
If STRING is multibyte, this may be greater than the length of STRING. */)
@ -5295,6 +5317,7 @@ this variable. */);
defsubr (&Srandom);
defsubr (&Slength);
defsubr (&Ssafe_length);
defsubr (&Sproper_list_p);
defsubr (&Sstring_bytes);
defsubr (&Sstring_distance);
defsubr (&Sstring_equal);

View File

@ -4699,7 +4699,7 @@ enum
#define FOR_EACH_TAIL(tail) \
FOR_EACH_TAIL_INTERNAL (tail, circular_list (tail), true)
/* Like FOR_EACH_TAIL (LIST), except do not signal or quit.
/* Like FOR_EACH_TAIL (TAIL), except do not signal or quit.
If the loop exits due to a cycle, TAILs value is undefined. */
#define FOR_EACH_TAIL_SAFE(tail) \