diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-10 10:34:52 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-10 10:34:52 -0700 |
commit | 8720c828d956fd29d9266d0e06cb7ead69d5ab95 (patch) | |
tree | 3d94a9bf47d5d5135e2bd7a03927062f620b5439 /ffi.c | |
parent | 8557121c01f072f7e194c93c1e545e0b51ed563d (diff) | |
download | txr-8720c828d956fd29d9266d0e06cb7ead69d5ab95.tar.gz txr-8720c828d956fd29d9266d0e06cb7ead69d5ab95.tar.bz2 txr-8720c828d956fd29d9266d0e06cb7ead69d5ab95.zip |
ffi: bugfix: string semantics for incomplete zarray.
The problem is that the get semantics (zarray char)
produces a vector of characters, not a string. Ditto for
bchar and wchar.
* ffi.c (ffi_varray_null_term_in): Check for the char_conv,
wchar_conv or bchar_conv flag and delegate to
ffi_array_get_common.
(ffi_type_compile): Set char_conv, wchar_conv or bchar_conv
flag for incomplete zarray.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 45 |
1 files changed, 28 insertions, 17 deletions
@@ -2479,30 +2479,35 @@ static val ffi_varray_null_term_in(struct txr_ffi_type *tft, int copy, mem_t *sr static val ffi_varray_null_term_get(struct txr_ffi_type *tft, mem_t *src, val self) { - val vec = vector(zero, nil); val eltype = tft->eltype; - struct txr_ffi_type *etft = ffi_type_struct(eltype); - cnum elsize = etft->size; - cnum offs, i; - for (i = 0, offs = 0; ; i++) { - mem_t *el = src + offs, *p; + if (tft->char_conv || tft->wchar_conv || tft->bchar_conv) { + return ffi_array_get_common(tft, src, self, INT_PTR_MAX); + } else { + val vec = vector(zero, nil); + struct txr_ffi_type *etft = ffi_type_struct(eltype); + cnum elsize = etft->size; + cnum offs, i; - for (p = el; p < el + elsize; p++) - if (*p) - break; + for (i = 0, offs = 0; ; i++) { + mem_t *el = src + offs, *p; - if (p == el + elsize) - break; + for (p = el; p < el + elsize; p++) + if (*p) + break; - { - val elval = etft->get(etft, src + offs, self); - vec_push(vec, elval); - offs += elsize; + if (p == el + elsize) + break; + + { + val elval = etft->get(etft, src + offs, self); + vec_push(vec, elval); + offs += elsize; + } } - } - return vec; + return vec; + } } static void ffi_varray_release(struct txr_ffi_type *tft, val vec, mem_t *dst) @@ -3037,6 +3042,12 @@ val ffi_type_compile(val syntax) tft->get = ffi_varray_null_term_get; tft->in = ffi_varray_null_term_in; } + if (etft->syntax == char_s) + tft->char_conv = 1; + else if (etft->syntax == wchar_s) + tft->wchar_conv = 1; + else if (etft->syntax == bchar_s) + tft->bchar_conv = 1; tft->alloc = ffi_varray_alloc; tft->free = free; tft->size = 0; |