summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-04 21:19:13 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-04 21:19:13 -0700
commit7f841abd8218c68f8d69fe798b8d5e9d322b4de8 (patch)
tree0e334842c9c4e9f47b7c9f0174edd50e0c10c28b /ffi.c
parent33c229bbbbf75ab8b3f048579eb2b7a63acaae7d (diff)
downloadtxr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.tar.gz
txr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.tar.bz2
txr-7f841abd8218c68f8d69fe798b8d5e9d322b4de8.zip
ffi: map (array n bchar) to Lisp string.
* ffi.c (struct txr_ffi_type): New bitfield flag, bchar_conv. (ffi_array_in, ffi_array_get): Handle bchar_conv. (ffi_type_compile): Set bchar_conv flag for array of bchar. * lib.c (string_8bit_size): New function. * lib.h (string_8bit_size): Declared.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index 0cccd46e..a6c872e9 100644
--- a/ffi.c
+++ b/ffi.c
@@ -96,6 +96,7 @@ struct txr_ffi_type {
unsigned null_term : 1;
unsigned char_conv : 1;
unsigned wchar_conv : 1;
+ unsigned bchar_conv : 1;
void (*put)(struct txr_ffi_type *, val obj, mem_t *dst, val self);
val (*get)(struct txr_ffi_type *, mem_t *src, val self);
val (*in)(struct txr_ffi_type *, mem_t *src, val obj, val self);
@@ -959,6 +960,19 @@ static val ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec,
}
}
vec = if3(vec, replace(vec, str, zero, t), str);
+ } else if (tft->bchar_conv) {
+ val str;
+
+ if (nelem == 0) {
+ str = null_string;
+ } else {
+ const unsigned char *chptr = coerce(const unsigned char *, src);
+ if (chptr[tft->size - 1] == 0)
+ str = string_8bit(chptr);
+ else
+ str = string_8bit_size(chptr, tft->size);
+ }
+ vec = if3(vec, replace(vec, str, zero, t), str);
} else {
ucnum offs = 0;
struct txr_ffi_type *etft = ffi_type_struct(eltype);
@@ -1060,6 +1074,16 @@ static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self)
return init_str(ustr, wchptr);
}
}
+ } else if (tft->bchar_conv) {
+ if (nelem == 0) {
+ return null_string;
+ } else {
+ const unsigned char *chptr = coerce(const unsigned char *, src);
+ if (chptr[tft->size - 1] == 0)
+ return string_8bit(chptr);
+ else
+ return string_8bit_size(chptr, tft->size);
+ }
} else {
cnum znelem = if3(tft->null_term && nelem > 0, nelem - 1, nelem);
val vec = vector(num_fast(znelem), nil);
@@ -1295,6 +1319,8 @@ val ffi_type_compile(val syntax)
tft->char_conv = 1;
else if (eltype_syntax == wchar_s)
tft->wchar_conv = 1;
+ else if (eltype_syntax == bchar_s)
+ tft->bchar_conv = 1;
return type;
}
} else if (sym == ptr_in_s) {