[cairo] Re: Munging header files for export (and other) attributes

Doodle doodle at scenergy.dfmk.hu
Tue Aug 30 03:40:08 PDT 2005


Carl Worth wrote:
> Every once in a while, someone asks to decorate cairo.h with some sort
> of per-function attribute. Something along the lines of:
> 
> 	CAIRO_PUBLIC(cairo_t *)
> 	cairo_create (cairo_surface_t *target);
> 
> I have readability objections to the above, (I've also proposed hacks
> to hide the worst of those), that I won't bother repeating here.

I wouldn't like to be a troll but I don't see why a header file has to
be so much readable.

First, changing the lines to something like
CAIROEXPORT cairo_t *
CAIROCALL   cairo_create (cairo_surface_t *target);
doesn't make it any less readable, but of course it's only IMHO.

Second, header files should be interpreted by the compiler, the users
of the library should take their information from Docs, not from header
files. (This doesn't mean of course that all the header files should be
a mess, I agree that it should be kept as clean as possible to ease the
maintenance.)

> Beyond the ugliness, another problem with having attributes like this
> is the maintenance problem of always remembering to include them when
> adding new functions to the public header files, (and here my hacks to
> hide the syntax actually make this problem worse).

I don't see it as a problem. Once all the public functions are
"decorated", people will get used to it.

> 
> But there's a more fundamental issue underlying each of the above
> problems. For both consumers and maintainers of public header files,
> export attributes are pure noise since there are no non-exported
> functions in any of these files.

Well, thinking more in this way, one should say that writing the
'void' in front of function prototypes that return no value is
a pure noise, since these functions does not return anything, but
still, it is the way to tell the compiler that it returns nothing.
The same applies to public functions: this is the way for a number
of compilers (Watcom, MSVC) to tell that a function should be exported
or not. It is simply needed if somebody wants to give such information
about the functions.

> 
> Since we have a very strict structure for our header files, this
> should be very easy to automate. In fact, here's a script that takes
> any public header file as they now exist and decorates each function
> type with both CAIRO_PRE_DECL before the function return type and
> CAIRO_POST_DECL after the function return type:
> 
>     sed -n -e '/^cairo.*(/ {x;s/\(.*\)/CAIRO_PRE_DECL \1 CAIRO_POST_DECL/;p;d}' \
>            -e '{x;p}'
> 
> This script just expects to be fed a header file on stdin and it
> produces a munged header file on stdout.

Unfortunately this assumes that every platform has sed installed.
(However I see your point, and if one would want to do it in the
way you described, then sed is the best solution, because it has the
most probability of being available on all platforms).

I've done a similar decoration with a .c code, but more about it later.

> 
> I think we should be able to use this script as part of a good
> solution that meets my criteria above. One option would be to make the
> internal header files #include an appropriate sed-modified version of
> the header files, under Makefile control, (but with the munged files
> likely not under revision control). Another option would be to make
> the build process temporarily replace the header files with their
> sed-modified versions and then restore them afterwards (so that we
> don't commit modified versions to CVS). 

I think the first one is better, because there is a slight possibility
in the second that if the compilation is interrupted, then some header
files will remain modified, some unmodified.


> 
> Of course, another piece of the solution is the platform-specific
> identification of what these CAIRO_PRE_DECL and CAIRO_POST_DECL
> strings should actually be. I'm sure that interested parties of
> relevant platforms can supply the correct strings easily enough.
> 
> Anyone, there's a starting point for anyone that wants to propose a
> more complete solution.

I had to modify quite some stuffs for the OS/2 version of Cairo,
once I finish fighting with the fbmmx.c file to be compiled with
OpenWatcom, I'll publish my modifications/additions here, but
meanwhile here is the cairo.h file used on OS/2 (modified by a .c code),
and the cairo-features.h file which is generated by the OpenWatcom
makefile:
http://scenergy.dfmk.hu/doodle/caos2.zip

This solves the problem of exported/non-exported functions,
and also solves the problem of always generating the .def file in a
way that there is no need for the .def file anymore, because of the
CAIROEXPORT keywords.


Bye,
   Doodle


More information about the cairo mailing list