From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Philipp Stephani
The following patch implements such bounding checks for the indices.
Comments are very welcome.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;= ;;;;
>From c076a16716d6b9ad5c971d67375223974df53a40 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sat, 4 Feb 2017 21:53:48 +0900
Subject: [PATCH 1/3] cl--parsing-keywords: Check for negative indices
* lisp/emacs-lisp/cl-seq.el (cl--parsing-keywords):
Throw and error when the user inputs a negative index for the sequence.
---
=C2=A0lisp/emacs-lisp/cl-seq.el | 8 +++++++-
=C2=A01 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lisp/emacs-lisp/cl-seq.el b/lisp/emacs-lisp/cl-seq.el
index 67ff1a00bd..558adf22fe 100644
--- a/lisp/emacs-lisp/cl-seq.el
+++ b/lisp/emacs-lisp/cl-seq.el
@@ -59,7 +59,13 @@ cl--parsing-keywords
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq= mem `(and ,mem (setq cl-if ,mem) t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list (intern
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(format "cl-%s" (substring (symbol-name var) 1)))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0(if (consp x) `(or ,mem ,(car (cdr x))) mem))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0`(if (and (string-match ":\\(start\\|end\\)" (symbol-name ,var= ))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(integerp (or ,mem ,(car (cdr-safe x)= )))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(not (natnump (or ,mem ,(car (cdr-saf= e x))))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (error "Wrong negative index '%s': natnump, = %s"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(substring (symbol-name ,var) = 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(or ,mem ,(car (cdr-safe x))))=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (or ,mem ,(car (cdr-safe x)))))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 kwords)
=C2=A0 =C2=A0 =C2=A0 ,@(append
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(and (not (eq other-keys t))
--
2.11.0
>From 9898718b96109c5815b81f8dc8868de4d86db453 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 5 Feb 2017 00:04:12 +0900
Subject: [PATCH 2/3] cl--check-bound-indices: Check for unbound indices
Throw and error if the user inputs an index higher than the sequence length=
or if :start value is higher than :end value.
* lisp/emacs-lisp/cl-seq.el (cl--check-bound-indices): New defun.
(cl-reduce, cl-fill, cl-replace, cl-remove, cl-delete)
(cl--delete-duplicates, cl-substitute, cl-nsubstitute, cl-position)
(cl-count, cl-mismatch, cl-search): Use it.
---
=C2=A0lisp/emacs-lisp/cl-seq.el | 51 ++++++++++++++++++++++++++++++++++++++= +++++++++
=C2=A01 file changed, 51 insertions(+)
diff --git a/lisp/emacs-lisp/cl-seq.el b/lisp/emacs-lisp/cl-seq.el
index 558adf22fe..0cb7ac7bdd 100644
--- a/lisp/emacs-lisp/cl-seq.el
+++ b/lisp/emacs-lisp/cl-seq.el
@@ -42,6 +42,7 @@
=C2=A0;;; Code:
=C2=A0(require 'cl-lib)
+(eval-when-compile (require 'subr-x))
=C2=A0;; Keyword parsing.
=C2=A0;; This is special-cased here so that we can compile
@@ -118,6 +119,44 @@ cl-test
=C2=A0(defvar cl-if) (defvar cl-if-not)
=C2=A0(defvar cl-key)
+;; Throw an error when :start or :end are > sequence length.
+(defmacro cl--check-bound-indices (cl-seq1 cl-seq2 cl-keys)
+=C2=A0 (declare (debug t))
+=C2=A0 `(let ((len1 (length ,cl-seq1))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(len2 (and ,cl-seq2 (length ,cl-seq2)))<= br class=3D"gmail_msg"> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(kwds (list :start1 :start2 :start :end1= :end2 :end))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(keys ,cl-keys)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0alist)
+=C2=A0 =C2=A0 =C2=A0(while keys
+=C2=A0 =C2=A0 =C2=A0 =C2=A0(when (and (memq (car keys) kwds)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-mat= ch ":\\(start\\|end\\)\\([1-2]?\\)\\'"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (symbol-name (car keys))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(delq (car keys) kwds) ; Ignore succesiv= e equal keys.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let* ((idx (match-string 2 (symbol-name= (car keys))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (len (if (equal id= x "2") len2 len1)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(when (integerp (cadr keys))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(push (cons (car keys) (ca= dr keys)) alist))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(when (> (cadr keys) len)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(error "Wrong boundin= g indices '%s', %s > (length %s), %s"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (sub= string (symbol-name (car keys)) 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cad= r keys)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (con= cat "cl-seq" idx)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 len)= )))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq keys (cddr keys)))
+=C2=A0 =C2=A0 =C2=A0;; Check :start value > :end value.
+=C2=A0 =C2=A0 =C2=A0(mapc (lambda (x)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(and-let* ((start (alist-g= et (car x) alist))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (end (alist-get (cdr x) alist)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(when (> start e= nd)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(error "= ;Bad bounding indices '%s', '%s': %d, %d"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (substring (symbol-name (car x)) 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (substring (symbol-name (cdr x)) 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 start
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 end))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(list (cons :start :end)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cons :start= 1 :end1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cons :start= 2 :end2)))))
+
=C2=A0;;;###autoload
=C2=A0(defun cl-reduce (cl-func cl-seq &rest cl-keys)
=C2=A0 =C2=A0"Reduce two-argument FUNCTION across SEQ.
@@ -134,6 +173,7 @@ cl-reduce
=C2=A0\n(fn FUNCTION SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:from-end (:start 0) :end :initial-valu= e :key) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(or (listp cl-seq) (setq cl-seq (append cl-seq nil))) =C2=A0 =C2=A0 =C2=A0(setq cl-seq (cl-subseq cl-seq cl-start cl-end))
=C2=A0 =C2=A0 =C2=A0(if cl-from-end (setq cl-seq (nreverse cl-seq)))
@@ -155,6 +195,7 @@ cl-fill
=C2=A0\nKeywords supported:=C2=A0 :start :end
=C2=A0\n(fn SEQ ITEM [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords ((:start 0) :end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(if (listp cl-seq)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((p (nthcdr cl-start cl-seq))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (n (and cl-end (- cl-end c= l-start))))
@@ -176,6 +217,7 @@ cl-replace
=C2=A0\nKeywords supported:=C2=A0 :start1 :end1 :start2 :end2
=C2=A0\n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords ((:start1 0) :end1 (:start2 0) :end2) ()=
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq1 cl-seq2 cl-keys)
=C2=A0 =C2=A0 =C2=A0(if (and (eq cl-seq1 cl-seq2) (<=3D cl-start2 cl-sta= rt1))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (or (=3D cl-start1 cl-start2)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((cl-len (length cl-seq1))<= br class=3D"gmail_msg"> @@ -225,6 +267,7 @@ cl-remove
=C2=A0\n(fn ITEM SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not :count= :from-end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start 0) :end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(let ((len (length cl-seq)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(if (<=3D (or cl-count (setq cl-count len)) 0= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 cl-seq
@@ -289,6 +332,7 @@ cl-delete
=C2=A0\n(fn ITEM SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not :count= :from-end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start 0) :end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(let ((len (length cl-seq)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(if (<=3D (or cl-count (setq cl-count len)) 0= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 cl-seq
@@ -362,6 +406,7 @@ cl--delete-duplicates
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; We need to parse :if, otherwise= `cl-if' is unbound.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(:test :test-not :key (:start 0) := end :from-end :if)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ()
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys) =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if cl-from-end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((cl-p (nthcdr cl-start cl-s= eq)) cl-i)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq cl-end (- (or cl-end= (length cl-seq)) cl-start))
@@ -407,6 +452,7 @@ cl-substitute
=C2=A0\n(fn NEW OLD SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not :count=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start 0) :end :from-end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(if (or (eq cl-old cl-new)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (<=3D (or cl-count (setq cl-fr= om-end nil
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cl-count (length cl-seq= ))) 0))
@@ -448,6 +494,7 @@ cl-nsubstitute
=C2=A0\n(fn NEW OLD SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not :count=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start 0) :end :from-end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(let ((len (length cl-seq)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(or (eq cl-old cl-new) (<=3D (or cl-count (se= tq cl-count len)) 0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (and (listp cl-seq) (or (not cl-from= -end) (> cl-count (/ len 2))))
@@ -524,6 +571,7 @@ cl-position
=C2=A0\n(fn ITEM SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start 0) :end :from-end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(cl--position cl-item cl-seq cl-start cl-end cl-from-en= d)))
=C2=A0(defun cl--position (cl-item cl-seq cl-start &optional cl-end cl-= from-end)
@@ -568,6 +616,7 @@ cl-count
=C2=A0\nKeywords supported:=C2=A0 :test :test-not :key :start :end
=C2=A0\n(fn ITEM SEQ [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :if :if-not (:star= t 0) :end) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq nil cl-keys)
=C2=A0 =C2=A0 =C2=A0(let ((cl-count 0) cl-x)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(or cl-end (setq cl-end (length cl-seq)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(if (consp cl-seq) (setq cl-seq (nthcdr cl-start= cl-seq)))
@@ -600,6 +649,7 @@ cl-mismatch
=C2=A0\n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :from-end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start1 0) :end1 (:start2 0) :end2) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq1 cl-seq2 cl-keys)
=C2=A0 =C2=A0 =C2=A0(or cl-end1 (setq cl-end1 (length cl-seq1)))
=C2=A0 =C2=A0 =C2=A0(or cl-end2 (setq cl-end2 (length cl-seq2)))
=C2=A0 =C2=A0 =C2=A0(if cl-from-end
@@ -631,6 +681,7 @@ cl-search
=C2=A0\n(fn SEQ1 SEQ2 [KEYWORD VALUE]...)"
=C2=A0 =C2=A0(cl--parsing-keywords (:test :test-not :key :from-end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (:start1 0) :end1 (:start2 0) :end2) ()
+=C2=A0 =C2=A0 (cl--check-bound-indices cl-seq1 cl-seq2 cl-keys)
=C2=A0 =C2=A0 =C2=A0(or cl-end1 (setq cl-end1 (length cl-seq1)))
=C2=A0 =C2=A0 =C2=A0(or cl-end2 (setq cl-end2 (length cl-seq2)))
=C2=A0 =C2=A0 =C2=A0(if (>=3D cl-start1 cl-end1)
--
2.11.0
>From 50cce9d03fa96d622d20f2218ec5ddcfeb246425 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 5 Feb 2017 01:06:01 +0900
Subject: [PATCH 3/3] * test/lisp/emacs-lisp/cl-seq-tests.el
=C2=A0(cl-seq-check-bounds): New test.
---
=C2=A0test/lisp/emacs-lisp/cl-seq-tests.el | 91 +++++++++++++++++++++++++++= +++++++++
=C2=A01 file changed, 91 insertions(+)
diff --git a/test/lisp/emacs-lisp/cl-seq-tests.el b/test/lisp/emacs-lisp/cl= -seq-tests.el
index 61e3d72033..f5ecfe4b92 100644
--- a/test/lisp/emacs-lisp/cl-seq-tests.el
+++ b/test/lisp/emacs-lisp/cl-seq-tests.el
@@ -294,6 +294,7 @@ cl-seq--with-side-effects
=C2=A0(ert-deftest cl-seq-test-bug24264 ()
=C2=A0 =C2=A0"Test for http://debbugs.gnu.org/2= 4264 ."
+=C2=A0 :tags '(:expensive-test)
=C2=A0 =C2=A0(let ((list=C2=A0 (append (make-list 8000005 1) '(8)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(list2 (make-list 8000005 2)))
=C2=A0 =C2=A0 =C2=A0(should (cl-position 8 list))
@@ -302,6 +303,96 @@ cl-seq--with-side-effects
=C2=A0 =C2=A0 =C2=A0(should (equal '(2 8) (last (cl-replace list list2)= 2)))
=C2=A0 =C2=A0 =C2=A0(should (equal '(1 1) (last (cl-fill list 1) 2)))))=
+(ert-deftest cl-seq-check-bounds ()
+=C2=A0 (let ((lst (list 1 2 3))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (lst2 (list 'a 'b 'c))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; t means pass, nil means fails.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (tests '("((lambda (x y) (cl-reduce #= 'max x :start 1)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-reduce #'max x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-reduce #'max x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-reduce #'max x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-fill x 'b :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-fill x 'b :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-fill x 'b :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-fill x 'b :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start1 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start2 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start1 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start2 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start1 -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start2 -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start1 2 :end1 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-replace x y :start2 2 :end2 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove nil x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove nil x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove nil x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove nil x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-delete nil x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-delete nil x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-delete nil x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-delete nil x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove-duplicates x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove-duplicates x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove-duplicates x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-remove-duplicates x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-substitute 'foo 2 x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-substitute 'foo 2 x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-substitute 'foo 2 x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-substitute 'foo 2 x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-nsubstitute 'foo 2 x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-nsubstitute 'foo 2 x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-nsubstitute 'foo 2 x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-nsubstitute 'foo 2 x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-position 2 x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-position 2 x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-position 2 x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-count 2 x :start 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-count 2 x :start 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-count 2 x :start -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-count 2 x :start 2 :end 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 1 :start2 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 1 :start2 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 4 :start2 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 -1 :start2 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 1 :start2 -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start1 2 :end1 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-mismatch x x :start2 2 :end2 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start1 3 :start2 3)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start1 4 :start2 4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start1 -1 :start2 3)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start1 1 :start2 -1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start1 2 :end1 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-search x x :start2 2 :end2 1)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-subseq x -1)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-subseq x -2 -1)) . t)"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-subseq x -4)))"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"((lamb= da (x y) (cl-subseq x 2 1)))")))
+=C2=A0 =C2=A0 (dolist (limit '("start" "end"))
+=C2=A0 =C2=A0 =C2=A0 (dolist (x tests)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((form
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(car
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (read-from-string<= br class=3D"gmail_msg"> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cond ((stri= ng-match ":start\\([1-2]?\\) \\([0-9-]+\\) :end\\([1-2]?\\)" x) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 x)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0((string=3D limit "start") x)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(t
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (replace-regexp-in-string "start" limit x)))))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (cdr form)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (should (funcall (car for= m) lst lst2))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (should-error (funcall (car form= ) lst lst2))))))))
+
=C2=A0(provide 'cl-seq-tests)
=C2=A0;;; cl-seq-tests.el ends here
--
2.11.0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;= ;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.7)
=C2=A0of 2017-02-04
Repository revision: ff4dd0d39c3f5dfb8f4988f840c2c05621db32db