Function: cl--do-arglist
cl--do-arglist is a byte-compiled function defined in cl-macs.el.gz.
Signature
(cl--do-arglist ARGS EXPR &optional NUM)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/cl-macs.el.gz
(defun cl--do-arglist (args expr &optional num) ; uses cl--bind-*
(if (nlistp args)
(if (or (memq args cl--lambda-list-keywords) (not (symbolp args)))
(error "Invalid argument name: %s" args)
(push (list args expr) cl--bind-lets))
(setq args (cl-copy-list args))
(let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
(let ((p (memq '&body args))) (if p (setcar p '&rest)))
(if (memq '&environment args) (error "&environment used incorrectly"))
(let ((restarg (memq '&rest args))
(safety (if (macroexp-compiling-p) cl--optimize-safety 3))
(keys t)
(laterarg nil) (exactarg nil) minarg)
(or num (setq num 0))
(setq restarg (if (listp (cadr restarg))
(make-symbol "--cl-rest--")
(cadr restarg)))
(push (list restarg expr) cl--bind-lets)
(if (eq (car args) '&whole)
(push (list (cl--pop2 args) restarg) cl--bind-lets))
(let ((p args))
(setq minarg restarg)
(while (and p (not (memq (car p) cl--lambda-list-keywords)))
(or (eq p args) (setq minarg (list 'cdr minarg)))
(setq p (cdr p)))
(if (memq (car p) '(nil &aux))
(setq minarg `(= (length ,restarg)
,(length (cl-ldiff args p)))
exactarg (not (eq args p)))))
(while (and args (not (memq (car args) cl--lambda-list-keywords)))
(let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car-safe)
restarg)))
(cl--do-arglist
(pop args)
(if (or laterarg (= safety 0)) poparg
`(if ,minarg ,poparg
(signal 'wrong-number-of-arguments
(list ,(and (not (eq cl--bind-block 'cl-none))
`',cl--bind-block)
(length ,restarg)))))))
(setq num (1+ num) laterarg t))
(while (and (eq (car args) '&optional) (pop args))
(while (and args (not (memq (car args) cl--lambda-list-keywords)))
(let ((arg (pop args)))
(or (consp arg) (setq arg (list arg)))
(if (cddr arg) (cl--do-arglist (nth 2 arg) `(and ,restarg t)))
(let ((def (if (cdr arg) (nth 1 arg)
(or (car cl--bind-defs)
(nth 1 (assq (car arg) cl--bind-defs)))))
(poparg `(pop ,restarg)))
(and def cl--bind-enquote (setq def `',def))
(cl--do-arglist (car arg)
(if def `(if ,restarg ,poparg ,def) poparg))
(setq num (1+ num))))))
(if (eq (car args) '&rest)
(let ((arg (cl--pop2 args)))
(if (consp arg) (cl--do-arglist arg restarg)))
(or (eq (car args) '&key) (= safety 0) exactarg
(push `(if ,restarg
(signal 'wrong-number-of-arguments
(list
,(and (not (eq cl--bind-block 'cl-none))
`',cl--bind-block)
(+ ,num (length ,restarg)))))
cl--bind-forms)))
(while (and (eq (car args) '&key) (pop args))
(unless (listp keys) (setq keys nil))
(while (and args (not (memq (car args) cl--lambda-list-keywords)))
(let ((arg (pop args)))
(or (consp arg) (setq arg (list arg)))
(let* ((karg (if (consp (car arg)) (caar arg)
(let ((name (symbol-name (car arg))))
;; Strip a leading underscore, since it only
;; means that this argument is unused, but
;; shouldn't affect the key's name (bug#12367).
(if (eq ?_ (aref name 0))
(setq name (substring name 1)))
(intern (format ":%s" name)))))
(varg (if (consp (car arg)) (cadar arg) (car arg)))
(def (if (cdr arg) (cadr arg)
;; The ordering between those two or clauses is
;; irrelevant, since in practice only one of the two
;; is ever non-nil (the car is only used for
;; cl-deftype which doesn't use the cdr).
(or (car cl--bind-defs)
(cadr (assq varg cl--bind-defs)))))
(look `(plist-member ,restarg ',karg)))
(and def cl--bind-enquote (setq def `',def))
(if (cddr arg)
(let* ((temp (or (nth 2 arg) (make-symbol "--cl-var--")))
(val `(car (cdr ,temp))))
(cl--do-arglist temp look)
(cl--do-arglist varg
`(if ,temp
(prog1 ,val (setq ,temp t))
,def)))
(cl--do-arglist
varg
`(car (cdr ,(if (null def)
look
`(or ,look
,(if (eq (cl--const-expr-p def) t)
`'(nil ,(cl--const-expr-val def))
`(list nil ,def))))))))
(push karg keys)))))
(when (consp keys) (setq keys (nreverse keys)))
(or (and (eq (car args) '&allow-other-keys) (pop args))
(= safety 0)
(cond
((eq keys t) nil) ;No &keys at all
((null keys) ;A &key but no actual keys specified.
(push `(when ,restarg
(error ,(format "Keyword argument %%s not one of %s"
keys)
(car ,restarg)))
cl--bind-forms))
(t
(let* ((var (make-symbol "--cl-keys--"))
(allow '(:allow-other-keys))
(check `(while ,var
(cond
((memq (car ,var) ',(append keys allow))
(unless (cdr ,var)
(error "Missing argument for %s" (car ,var)))
(setq ,var (cdr (cdr ,var))))
((car (cdr (memq (quote ,@allow) ,restarg)))
(setq ,var nil))
(t
(error
,(format "Keyword argument %%s not one of %s"
keys)
(car ,var)))))))
(push `(let ((,var ,restarg)) ,check) cl--bind-forms)))))
(cl--do-&aux args)
nil)))