summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-01-17 01:42:29 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-01-17 01:42:29 -0800
commitdfafb4879c1e65657ad89232e57f60c7a07f8c66 (patch)
tree4e107acd046cb5f835fa38b54e1c8fb24cdd8c50
parent50a7e813d251a91ae027b3edfbb1d25b24b9de48 (diff)
downloadtxr-dfafb4879c1e65657ad89232e57f60c7a07f8c66.tar.gz
txr-dfafb4879c1e65657ad89232e57f60c7a07f8c66.tar.bz2
txr-dfafb4879c1e65657ad89232e57f60c7a07f8c66.zip
carray: fix vec/list conversion bug.
If a zero-length carray is converted with vec-carray or list-carray and the null-term-p argument is t, there is an exception about a negative index. An empty vector or list should be returned in this case, and the documentation says exactly that. Also, if a carray of unknown length is converted, there is an exception from vec-carray, as documented, but it's an uninformative one that is incidentally produced when -1 is passed to the vec function. The list-carray just returns nil, contravening the documentation. * ffi.c (vec_carray, list_carray): Fix the problems described above. * txr.1: Reviewing the documentation for these functions, an improperly terminated sentence was found.
-rw-r--r--ffi.c42
-rw-r--r--txr.12
2 files changed, 31 insertions, 13 deletions
diff --git a/ffi.c b/ffi.c
index b1f00d76..07e361ae 100644
--- a/ffi.c
+++ b/ffi.c
@@ -4887,13 +4887,22 @@ val vec_carray(val carray, val null_term_p)
val nt_p = default_null_arg(null_term_p);
struct carray *scry = carray_struct_checked(self, carray);
cnum i, l = if3(nt_p, scry->nelem - 1, scry->nelem);
- val vec = vector(num(l), nil);
- for (i = 0; i < l; i++) {
- val ni = num_fast(i);
- val el = carray_ref(carray, ni);
- set(vecref_l(vec, ni), el);
+
+ if (l >= 0) {
+ val vec = vector(num(l), nil);
+ for (i = 0; i < l; i++) {
+ val ni = num_fast(i);
+ val el = carray_ref(carray, ni);
+ set(vecref_l(vec, ni), el);
+ }
+ return vec;
+ } else if (scry->nelem >= 0) {
+ return vector(zero, nil);
+ } else {
+ uw_throwf(error_s,
+ lit("~a: cannot convert unknown length carray to vector"),
+ self, nao);
}
- return vec;
}
val list_carray(val carray, val null_term_p)
@@ -4902,13 +4911,22 @@ val list_carray(val carray, val null_term_p)
val nt_p = default_null_arg(null_term_p);
struct carray *scry = carray_struct_checked(self, carray);
cnum i, l = if3(nt_p, scry->nelem - 1, scry->nelem);
- list_collect_decl (list, ptail);
- for (i = 0; i < l; i++) {
- val ni = num_fast(i);
- val el = carray_ref(carray, ni);
- ptail = list_collect(ptail, el);
+
+ if (l >= 0) {
+ list_collect_decl (list, ptail);
+ for (i = 0; i < l; i++) {
+ val ni = num_fast(i);
+ val el = carray_ref(carray, ni);
+ ptail = list_collect(ptail, el);
+ }
+ return list;
+ } else if (scry->nelem >= 0) {
+ return nil;
+ } else {
+ uw_throwf(error_s,
+ lit("~a: cannot convert unknown length carray to list"),
+ self, nao);
}
- return list;
}
val carray_ref(val carray, val idx)
diff --git a/txr.1 b/txr.1
index 7014d37e..861bb2af 100644
--- a/txr.1
+++ b/txr.1
@@ -62519,7 +62519,7 @@ and a zero-length vector or list is returned.
Conversion of the foreign array to the vector or list is performed
by iterating over all of its elements, starting from element zero, up to the
-element before the effective length,
+element before the effective length.
.coNP Functions @ carray-get and @ carray-getz
.synb