summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-10 10:34:52 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-10 10:34:52 -0700
commit8720c828d956fd29d9266d0e06cb7ead69d5ab95 (patch)
tree3d94a9bf47d5d5135e2bd7a03927062f620b5439 /ffi.c
parent8557121c01f072f7e194c93c1e545e0b51ed563d (diff)
downloadtxr-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.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/ffi.c b/ffi.c
index 2fa7495c..f0974ddf 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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;