summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c34
-rw-r--r--txr.129
2 files changed, 24 insertions, 39 deletions
diff --git a/ffi.c b/ffi.c
index d34a1bb6..055d88d1 100644
--- a/ffi.c
+++ b/ffi.c
@@ -618,15 +618,15 @@ static val ffi_str_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
return ret;
}
-static void ffi_wstr_put(struct txr_ffi_type *tft, val s, mem_t *dst,
- val self)
+static val ffi_wstr_in(struct txr_ffi_type *tft, int copy,
+ mem_t *src, val obj, val self)
{
- if (s == nil) {
- *coerce(const wchar_t **, dst) = 0;
- } else {
- const wchar_t *ws = c_str(s);
- *coerce(const wchar_t **, dst) = ws;
- }
+ wchar_t **loc = coerce(wchar_t **, src);
+ if (copy)
+ obj = if2(*loc, string(*loc));
+ free(*loc);
+ *loc = 0;
+ return obj;
}
static val ffi_wstr_get(struct txr_ffi_type *tft, mem_t *src, val self)
@@ -635,7 +635,7 @@ static val ffi_wstr_get(struct txr_ffi_type *tft, mem_t *src, val self)
return p ? string(p) : 0;
}
-static void ffi_wstr_d_put(struct txr_ffi_type *tft, val s, mem_t *dst,
+static void ffi_wstr_put(struct txr_ffi_type *tft, val s, mem_t *dst,
val self)
{
if (s == nil) {
@@ -1689,12 +1689,20 @@ static void ffi_init_types(void)
ffi_typedef(str_d_s, make_ffi_type_builtin(str_d_s, str_s,
sizeof (mem_t *), &ffi_type_pointer,
ffi_str_put, ffi_str_d_get));
- ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s,
- sizeof (mem_t *), &ffi_type_pointer,
- ffi_wstr_put, ffi_wstr_get));
+ {
+ val type = ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s,
+ sizeof (mem_t *),
+ &ffi_type_pointer,
+ ffi_wstr_put,
+ ffi_wstr_get));
+ struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->in = ffi_wstr_in;
+ ffi_typedef(wstr_s, type);
+ }
+
ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s,
sizeof (mem_t *), &ffi_type_pointer,
- ffi_wstr_d_put, ffi_wstr_d_get));
+ ffi_wstr_put, ffi_wstr_d_get));
ffi_typedef(bstr_d_s, make_ffi_type_builtin(bstr_d_s, str_s,
sizeof (mem_t *), &ffi_type_pointer,
ffi_bstr_put, ffi_bstr_d_get));
diff --git a/txr.1 b/txr.1
index ccb5f611..86a6a3ab 100644
--- a/txr.1
+++ b/txr.1
@@ -53390,34 +53390,11 @@ corresponds to the C type
.code "wchar_t *"
pointing to the first character of a null terminated wide string.
It converts between Lisp strings and symbols, and C strings.
-Since \*(TX represents strings in this format natively, the
-.code wstr
-type has a different memory management profile from that of
+The memory management is similar to the
.code str
and
-.codn bstr .
-
-Under the
-.code wstr
-type's put operation, no memory allocation takes place. The internal string
-pointer is retrieved from within the Lisp object, and written into the argument
-space as-is. The type has no in operation, since there is no memory to clean
-up. The get semantics of
-.code wstr
-duplicate the C string, producing a new Lisp object which doesn't share
-storage with the original.
-
-Under the
-.code wstr-d
-type's put operation, memory allocation does take place. A new C string
-is allocated via
-.code malloc
-and that pointer is written into the argument space. The type has no in
-operation. The get semantics of
-.code wstr-d
-produces a Lisp string object which directly takes ownership of the C string.
-The C string will be freed if and when that Lisp string is recognized as
-unreachable by \*(TX's garbage collector.
+.code str-d
+types, except that no UTF-8 conversion takes place.
.ccIP @ buf and @ buf-d
The