+(eval-and-compile
+ (declare-function sasl-cl-coerce "sasl-scram-rfc")
+ (declare-function sasl-cl-mapcar-many "sasl-scram-rfc")
+ (if (fboundp 'cl-map)
+ (defalias 'sasl-cl-map 'cl-map)
+ (defun sasl-cl-mapcar-many (func seqs)
+ (if (cdr (cdr seqs))
+ (let* ((res nil)
+ (n (apply 'min (mapcar 'length seqs)))
+ (i 0)
+ (args (copy-sequence seqs))
+ p1 p2)
+ (setq seqs (copy-sequence seqs))
+ (while (< i n)
+ (setq p1 seqs p2 args)
+ (while p1
+ (setcar p2
+ (if (consp (car p1))
+ (prog1 (car (car p1))
+ (setcar p1 (cdr (car p1))))
+ (aref (car p1) i)))
+ (setq p1 (cdr p1) p2 (cdr p2)))
+ (push (apply func args) res)
+ (setq i (1+ i)))
+ (nreverse res))
+ (let ((res nil)
+ (x (car seqs))
+ (y (nth 1 seqs)))
+ (let ((n (min (length x) (length y)))
+ (i -1))
+ (while (< (setq i (1+ i)) n)
+ (push (funcall func
+ (if (consp x) (pop x) (aref x i))
+ (if (consp y) (pop y) (aref y i)))
+ res)))
+ (nreverse res))))
+
+ (defun sasl-cl-coerce (x type)
+ "Coerce OBJECT to type TYPE.
+TYPE is a Common Lisp type specifier.
+\n(fn OBJECT TYPE)"
+ (cond ((eq type 'list) (if (listp x) x (append x nil)))
+ ((eq type 'vector) (if (vectorp x) x (vconcat x)))
+ ((eq type 'string) (if (stringp x) x (concat x)))
+ ((eq type 'array) (if (arrayp x) x (vconcat x)))
+ ((and (eq type 'character) (stringp x) (= (length x) 1)) (aref x 0))
+ ((and (eq type 'character) (symbolp x))
+ (sasl-cl-coerce (symbol-name x) type))
+ ((eq type 'float) (float x))
+ ;;((cl-typep x type) x)
+ (t (error "Can't coerce %s to type %s" x type))))
+
+ (defun sasl-cl-map (type func seq &rest rest)
+ "Map a FUNCTION across one or more SEQUENCEs, returning a sequence.
+TYPE is the sequence type to return.
+\n(fn TYPE FUNCTION SEQUENCE...)"
+ (let (res y)
+ (if rest
+ (if (or (cdr rest) (nlistp seq) (nlistp (car rest)))
+ (setq res (sasl-cl-mapcar-many func (cons seq rest)))
+ (setq y (car rest))
+ (while (and seq y)
+ (push (funcall func (pop seq) (pop y)) res))
+ (setq res (nreverse res)))
+ (setq res (mapcar func seq)))
+ (and type (sasl-cl-coerce res type)))))
+
+ (if (fboundp 'string-prefix-p)
+ (defalias 'sasl-string-prefix-p 'string-prefix-p)
+ (defun sasl-string-prefix-p (prefix string &optional ignore-case)
+ "Return non-nil if PREFIX is a prefix of STRING.
+If IGNORE-CASE is non-nil, the comparison is done without paying attention
+to case differences."
+ (let ((prefix-length (length prefix)))
+ (cond ((> prefix-length (length string)) nil)
+ (ignore-case
+ (string-equal (downcase prefix)
+ (downcase (substring string 0 prefix-length))))
+ (t
+ (string-equal prefix (substring string 0 prefix-length))))))))
+