[Vala] Emitting type symbols, identifiers and type-less parameters. bugzilla 558106



(Relating to bugzilla #558106  http://bugzilla.gnome.org/show_bug.cgi?id=558106)

Jürg invited me to re-open the bug if I could find a better solution. I can't find one which I'm confident will be accepted as making sense from a language point of view.

I think that the fundamental problem is that the vala doesn't make room for, or recognize, that some C API's are macro based, and therefore are in fact explicitly typeless (though usually implicitly typed).

So while this is not part of the direction of vala, it is part of the direction of porting from C to vala, or even vala using some C api, and is of some definite importance in some cases.

I run against these pronlems trying to port C to vala. The type-ifying of the biggest culprit printf does not get rid of typeless macros altogether.

I'll give some example of the typeless-ness of C macros; however (dear reader) please understand that I'm not looking for advice in re-working these examples to work around their typeless nature, or even for belief in how real they are (although they are based on real usages).

They are serving as concrete examples of this type of problem when porting legitimate C to Vala, and the need for Vala to accept vapi function definitions with typeless parameters, and for vala to be able to emit naked typesymbols and identifiers.

For instance it is just not worth trying to write vapi files for samba4 until we can emit type symbols, as the talloc api requires a type symbol for about half of it's macro-based api calls.

Fears that this will pollute the language can be largely set aside as it will only ever work when used against macros based C api.

Examples of legitimate but problematic C:

1. type-less macros

1a. File can be int or char* :
#define open(file) (typeof(file)==int)?(open_id(file)):(open_name(file))


1b. In case that looks too unlikely, here's an example from math.h. x can be float, double or long
#  define signbit(x) \
     (sizeof (x) == sizeof (float)                                            \
      ? __signbitf (x)                                                        \
      : sizeof (x) == sizeof (double)                                         \
      ? __signbit (x) : __signbitl (x))


2. Naked identifiers

This case uses the ##paste operator to compare fields of kerberos credentials. item_name is a naked identifier that does NOT need translating from vala naming to C naming.

#define CRED_ITEM_COMPARE(cred1, cred2, item_name)  \
       ( ( (cred1->item_name##_obtained >= CRED_CALLBACK_RESULT && \
        cred2->item_name##_obtained >= CRED_CALLBACK_RESULT && \
        (0 == strcmp(cred1->item_name, cred2->item_name))) )  || \
        (cred1->item_name##_obtained < CRED_CALLBACK_RESULT && cred2->item_name##_obtained < CRED_CALLBACK_RESULT) )
..
if (!CRED_ITEM_COMPARE(cred1, cred2, principal)) return false;
..

3. Naked type symbols. type is the C type, and as with the patch supplied for bug 558106 does need turning from a vala type to a C type.

#define get_priv_data(session, type) (type *)_get_priv_data_check(session, sizeof(type), #type)
struct mydata* data = "" struct mydata);


Note this is not about writing new vala, but about having new vala link to old and new C.

The question is:
How shall vapi files specify:
  • that an argument may be any type
  • that an argument may be a non-type type, e.g. a type symbol or identifier
Jürg has suggested CCode attributes; so we could try to wrap these examples like this:

1. type-less macros

1a.
#define open(file) (typeof(file)==int)?(open_id(file)):(open_name(file))
becomes
open([CCode untyped] void file);

1b.
#  define signbit(x) \
     (sizeof (x) == sizeof (float)                                            \
      ? __signbitf (x)                                                        \
      : sizeof (x) == sizeof (double)                                         \
      ? __signbit (x) : __signbitl (x))
becomes
signbit([CCode typeclass="numeric"] void x);

2. Naked identifiers

#define CRED_ITEM_COMPARE(cred1, cred2, item_name)  \
       ( ( (cred1->item_name##_obtained >= CRED_CALLBACK_RESULT && \
        cred2->item_name##_obtained >= CRED_CALLBACK_RESULT && \
        (0 == strcmp(cred1->item_name, cred2->item_name))) )  || \
        (cred1->item_name##_obtained < CRED_CALLBACK_RESULT && cred2->item_name##_obtained < CRED_CALLBACK_RESULT) )
becomes
CRED_ITEM_COMPARE(Credentials cred1, Credentials cred2, [CCode identifier] void item_name);

3. Naked type symbols

#define get_priv_data(session, type) (type *)_get_priv_data_check(session, sizeof(type), #type)
becomes
get_priv_data(Session session, [CCode typesymbol] void type);



Sam


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]