diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-01-17 01:42:29 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-01-17 01:42:29 -0800 |
commit | dfafb4879c1e65657ad89232e57f60c7a07f8c66 (patch) | |
tree | 4e107acd046cb5f835fa38b54e1c8fb24cdd8c50 | |
parent | 50a7e813d251a91ae027b3edfbb1d25b24b9de48 (diff) | |
download | txr-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.c | 42 | ||||
-rw-r--r-- | txr.1 | 2 |
2 files changed, 31 insertions, 13 deletions
@@ -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) @@ -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 |