summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-07-10 04:15:22 -0700
committerKaz Kylheku <kaz@kylheku.com>2024-07-10 04:15:22 -0700
commita51888496ffbe18b3fcd7b27fec5c743a629a719 (patch)
tree1840aa344821eb04fee84c8081a971ba0b433887
parent36a83b0c6ba341377a3fe0595993599d172e70a8 (diff)
downloadtxr-a51888496ffbe18b3fcd7b27fec5c743a629a719.tar.gz
txr-a51888496ffbe18b3fcd7b27fec5c743a629a719.tar.bz2
txr-a51888496ffbe18b3fcd7b27fec5c743a629a719.zip
partition, split, split*: bug handling negative indices.
* lib.c (partition_func, split_func, split_star_func): When negative indices occur after the sequence has already been shortened, the conversion to positivce must take into account the base. This must be added so that the positive index produced is relative to the original length of the input sequence. When index_rebased is calculated, the base is subtracted out again. If we based the positive index off the shortened length, it's as if we are subtracting base twice. * tests/012/seq.tl: Dubious test cases for split* are replaced with the new results that make sense. Additional test cases are added which cover this issue, for not only split* but split and partition.
-rw-r--r--lib.c7
-rw-r--r--tests/012/seq.tl50
2 files changed, 35 insertions, 22 deletions
diff --git a/lib.c b/lib.c
index eb4c9b8c..2b246e69 100644
--- a/lib.c
+++ b/lib.c
@@ -4205,7 +4205,8 @@ static val partition_func(val base, val lcons)
if (iter_more(indices)) {
val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
- plus(raw_index, if3(len, len, len = length(seq))),
+ plus(plus(raw_index, if3(len, len, len = length(seq))),
+ base),
raw_index);
val index_rebased = minus(index, base);
@@ -4247,7 +4248,7 @@ static val split_func(val base, val lcons)
val len = if3(le, le, le = length(seq));
val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
- plus(raw_index, len),
+ plus(plus(raw_index, len), base),
raw_index);
val index_rebased = minus(index, base);
@@ -4290,7 +4291,7 @@ static val split_star_func(val base, val lcons)
val len = if3(le, le, le = length(seq));
val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
- plus(raw_index, len),
+ plus(plus(raw_index, len), base),
raw_index);
val index_rebased = minus(index, base);
diff --git a/tests/012/seq.tl b/tests/012/seq.tl
index 9164516a..5746939b 100644
--- a/tests/012/seq.tl
+++ b/tests/012/seq.tl
@@ -1107,6 +1107,10 @@
(split 2..5 '(2 3)) ((2 3) (4) nil))
(mtest
+ (split "abcdef" '(4 -1)) ("abcd" "e" "f")
+ (split "abcdef" '(4 5)) ("abcd" "e" "f"))
+
+(mtest
(split* nil -3) nil
(split* nil -2) nil
(split* nil -1) nil
@@ -1203,12 +1207,12 @@
(split* '(a b) 1) ((a) nil)
(split* '(a b) 2) ((a b) nil)
(split* '(a b) 3) ((a b))
- (split* '(a b) '(0 -1)) (nil (b)) ;; questionable
- (split* '(a b) '(0 1)) (nil nil nil) ;; questionabble
- (split* '(a b) '(0 -1 2)) (nil (b) nil) ;; questionable
- (split* '(a b) '(0 1 2)) (nil nil nil) ;; questionable
+ (split* '(a b) '(0 -1)) (nil nil nil)
+ (split* '(a b) '(0 1)) (nil nil nil)
+ (split* '(a b) '(0 -1 2)) (nil nil nil)
+ (split* '(a b) '(0 1 2)) (nil nil nil)
(split* '(a b) '(1 2)) ((a) nil)
- (split* '(a b) '(-1 2)) ((a) nil)) ;; questionable
+ (split* '(a b) '(-1 2)) ((a) nil))
(mtest
(split* #(a b) -4) (#(a b))
@@ -1219,12 +1223,12 @@
(split* #(a b) 1) (#(a) #())
(split* #(a b) 2) (#(a b) #())
(split* #(a b) 3) (#(a b))
- (split* #(a b) '(0 -1)) (#() #(b)) ;; questionable
- (split* #(a b) '(0 1)) (#() #() #()) ;; questionable
- (split* #(a b) '(0 -1 2)) (#() #(b) #()) ;; questionable
- (split* #(a b) '(0 1 2)) (#() #() #()) ;; questionable
- (split* #(a b) '(1 2)) (#(a) #()) ;; questionable
- (split* #(a b) '(-1 2)) (#(a) #())) ;; questionable
+ (split* #(a b) '(0 -1)) (#() #() #())
+ (split* #(a b) '(0 1)) (#() #() #())
+ (split* #(a b) '(0 -1 2)) (#() #() #())
+ (split* #(a b) '(0 1 2)) (#() #() #())
+ (split* #(a b) '(1 2)) (#(a) #())
+ (split* #(a b) '(-1 2)) (#(a) #()))
(mtest
(split* "ab" -4) ("ab")
@@ -1235,12 +1239,12 @@
(split* "ab" 1) ("a" "")
(split* "ab" 2) ("ab" "")
(split* "ab" 3) ("ab")
- (split* "ab" #(0 -1)) ("" "b") ;; questionable
- (split* "ab" '(0 1)) ("" "" "") ;; questionable
- (split* "ab" '(0 -1 2)) ("" "b" "") ;; questionable
- (split* "ab" '(0 1 2)) ("" "" "") ;; questionable
- (split* "ab" '(1 2)) ("a" "") ;; questionable
- (split* "ab" '(-1 2)) ("a" "")) ;; questionable
+ (split* "ab" #(0 -1)) ("" "" "")
+ (split* "ab" '(0 1)) ("" "" "")
+ (split* "ab" '(0 -1 2)) ("" "" "")
+ (split* "ab" '(0 1 2)) ("" "" "")
+ (split* "ab" '(1 2)) ("a" "")
+ (split* "ab" '(-1 2)) ("a" ""))
(mtest
(split* 2..4 -4) ((2 3))
@@ -1251,9 +1255,9 @@
(split* 2..4 1) ((2) nil)
(split* 2..4 2) ((2 3) nil)
(split* 2..4 3) ((2 3))
- (split* 2..4 '(0 -1)) (nil (3))
+ (split* 2..4 '(0 -1)) (nil nil nil)
(split* 2..4 '(0 1)) (nil nil nil)
- (split* 2..4 '(0 -1 2)) (nil (3) nil)
+ (split* 2..4 '(0 -1 2)) (nil nil nil)
(split* 2..4 '(0 1 2)) (nil nil nil)
(split* 2..4 '(1 2)) ((2) nil)
(split* 2..4 '(-1 2)) ((2) nil))
@@ -1315,6 +1319,10 @@
(split* 2..5 '(2 3)) ((2 3) nil))
(mtest
+ (split* "abcdef" '(4 -1)) ("abcd" "" "")
+ (split* "abcdef" '(4 5)) ("abcd" "" ""))
+
+(mtest
(partition nil -3) nil
(partition nil -2) nil
(partition nil -1) nil
@@ -1525,3 +1533,7 @@
(partition 2..5 '(1 2)) ((2) (3) (4))
(partition 2..5 '(1 3)) ((2) (3 4))
(partition 2..5 '(2 3)) ((2 3) (4)))
+
+(mtest
+ (partition "abcdef" '(4 -1)) ("abcd" "e" "f")
+ (partition "abcdef" '(4 5)) ("abcd" "e" "f"))