[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] bind egg and strings
From: |
Andrei Barbu |
Subject: |
Re: [Chicken-users] bind egg and strings |
Date: |
Thu, 14 Mar 2013 03:23:25 -0400 |
On Fri, Feb 15, 2013 at 5:53 AM, Felix
<address@hidden> wrote:
> From: Andrei Barbu <address@hidden>
> Subject: Re: [Chicken-users] bind egg and strings
> Date: Mon, 11 Feb 2013 02:04:16 -0500
>
>> Attached is a trivial patch that does the strdup.
>>
>>> I've been using the bind egg and encountered some strange behaviour.
>>> I have:
>>>
>>> struct a {
>>> char *b;
>>> };
>>>
>>> Bind generates:
>>>
>>> (begin
>>> (define a-b
>>> (foreign-lambda* c-string (((c-pointer (struct "a")) s))
>>> "return(s->b);"))
>>> (define make-a
>>> (foreign-lambda*
>>> (c-pointer (struct "a"))
>>> ((c-string b))
>>> "struct a *tmp_ = (struct a *)C_malloc(sizeof(struct
>>> a));\ntmp_->b = b;\n\nC_return(tmp_);")))
>>>
> No, you're not missing anything. A strdup is perhaps not the perfect
> solution, since you can never now what the user intended, and whether
> this is a temporary data structure or a permanent one. The generated
> code should probably take a c-pointer argument and leave it the user
> to create a statically allocated string and convert it to a pointer.
Having to do the static allocation manually all the time when all you
want is an strdup is rather unpleasant.
How about a patch that does both?
This patch allows you to pass in either a string (will do an strdup)
or a pointer to make-<structure-name>.
<structure-name>-<field-name> performs the strdup as above when
setting the field and returns a string when getting it.
<structure-name>-<field-name>* takes a pointer and fetches a pointer.
This gives the user the option of either behaviour.
With mutable fields given:
struct a {
char *b;
};
bind currently generates:
(begin
(define a-b
(getter-with-setter
(foreign-lambda* c-string (((c-pointer (struct "a")) s)) "return(s->b);")
(foreign-lambda*
void
(((c-pointer (struct "a")) s) (c-string x))
"s->b = strdup(x);")))
(define make-a
(foreign-lambda*
(c-pointer (struct "a"))
((c-string b))
"struct a *tmp_ = (struct a *)C_malloc(sizeof(struct
a));\ntmp_->b = strdup(b);\n\nC_return(tmp_);")))
This patch modifies it to generate:
(begin
(define a-b
(getter-with-setter
(foreign-lambda* c-string (((c-pointer (struct "a")) s)) "return(s->b);")
(foreign-lambda*
void
(((c-pointer (struct "a")) s) (c-string x))
"s->b = strdup(x);")))
(define a-b*
(getter-with-setter
(foreign-lambda*
c-pointer
(((c-pointer (struct "a")) s))
"return(s->b);")
(foreign-lambda*
void
(((c-pointer (struct "a")) s) (c-pointer x))
"s->b = x;")))
(define-foreign-type
bind-string
c-pointer
(lambda (a)
(if (string? a)
((foreign-lambda* c-pointer ((c-string a)) "C_return(strdup(a));") a)
a))
(foreign-lambda* c-string ((c-pointer a)) "C_return(a);"))
(define make-a
(foreign-lambda*
(c-pointer (struct "a"))
((bind-string b))
"struct a *tmp_ = (struct a *)C_malloc(sizeof(struct
a));\ntmp_->b = b;\n\nC_return(tmp_);")))
This introduces the foreign-type 'bind-string' to make
make-<structure-name> work. It's a bit of a wart that each structure
reintroduces this foreign type, but that doesn't matter as all
'bind-string' definitions are identical.
Andrei
bind-string.diff
Description: Binary data
- Re: [Chicken-users] bind egg and strings,
Andrei Barbu <=