jacob-carlborg / dstep

A tool for converting C and Objective-C headers to D modules
204 stars 37 forks source link

typedef function prototypes don't retain arguments #262

Open jblachly opened 3 years ago

jblachly commented 3 years ago
typedef char *kgets_func(char *, int, void *);

int f(char *s, kgets_func *fgets, void *fp);

int g(char *s, char* (*fun)(char *, int, void *), void *fp);

Results in:

extern (C):

alias kgets_func = char* function (char*, int, void*);

int f (char* s, char* function () fgets, void* fp);

int g (char* s, char* function (char*, int, void*) fun, void* fp);

Note f was not translated correctly; its second parameter takes type char* function() but should take char* function(char* int, void *) or more simply kgets_func via the alias.

jblachly commented 3 years ago

Actually, thinking more carefully about the title, I haven't proved that the typedef does not retain the function arguments, but I THINK that is the case given that g translates correctly

jacob-carlborg commented 3 years ago

The AST looks different for f and g. I guess that's why it fails to do a proper translation. Are you trying to create bindings for an existing library? Or is there a reason to declare f like that?

Based on the title of this issue, I think you're misunderstanding the code. kgets_func is not a function pointer, it's a function prototype. Then it becomes a function pointer when you declare parameter fgets. You might be looking for this code:

typedef char *(*kgets_func)(char *, int, void *);
int f(char *s, kgets_func fgets, void *fp);

Which is properly translated to:

extern (C):

alias kgets_func = char* function (char*, int, void*);
int f (char* s, kgets_func fgets, void* fp);
jacob-carlborg commented 3 years ago

The example you have provided is still a bug. But it might not be the code you want to write.

jblachly commented 3 years ago

f comes directly from a library to which I maintain bindings:

    typedef char *kgets_func(char *, int, void *);

    int kgetline(kstring_t *s, kgets_func *fgets_fn, void *fp);

https://github.com/samtools/htslib/blob/51275bcbda6d1e0849d0e50d0edd13814d38ebd1/htslib/kstring.h#L116-L118

jblachly commented 3 years ago

I see now it is a function prototype. C programmer habit of attaching pointer operator to the RHS drives me crazy.

typedef char* kgets_func(char *, int, void*) is more clear

Either way, appreciate insight into the bug as it requires manual intervention after dstep