(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 = get_priv_data(session, 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
_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to