Yes, I read Göran Krampe's articel about c2nim yesterday -- but unfortunately there was not really more information as already known from c2nim doc version 0.9.4. His OOP was much more interesting :-). And I have not found much other info -- maybe with next release and new website there will be more?
To start with a very simple wrapper, before continuing work on GTK3, I launched c2nim on cairo.h 1.14.
First a comment about c2nim: Following C typedef is converted this way
typedef struct _cairo_device cairo_device_t; type cairo_device_t* = _cairo_device
So I included curly braces:
typedef struct _cairo_device {} cairo_device_t; type cairo_device_t* = object
May it be possible to make c2nim even smarter to guess the braces?
Now the first more important question: by default c2nim gives us something like
type cairo_surface_t* = object proc cairo_pattern_get_surface*(pattern: ptr cairo_pattern_t; surface: ptr ptr cairo_surface_t): cairo_status_t {. cdecl, importc: "cairo_pattern_get_surface", dynlib: lib.}
From my current understanding now we want something like
type PSurface* = ptr TSurface TSurface* = object SurfacePtr* = PSurface SurfaceObj* = TSurface Surface* = PSurface # mostly used proc get_surface*(pattern: PatternPtr; surface: ptr SurfacePtr): Status {. cdecl, importc: "cairo_pattern_get_surface", dynlib: lib.}
My current intention is to keep P and T prefixes alive for wrappers and add Ptr and Obj aliases as well as an type for the most often usage as above. But in the proc declaration -- makes it sense to use SurfacePtr as type to indicate clear that it is a pointer, or should I use plain Surface because it is the general use case. And finally, what about the initial "ptr ptr cairo_surface_t"? Convert it to "var SurfacePtr"?
Edit: Sorry, forgot that types should start with upper case generally now. Fixed in example. My c2nim still does not generate upper case for first letter of types, maybe nimfix will fix it, or I will use my own script.
May it be possible to make c2nim even smarter to guess the braces?
Sure, but as long as you have to touch the C code for c2nim anyway I see little point in these micro improvements.
should I use plain Surface because it is the general use case?
In my opinion, yes.
what about the initial "ptr ptr cairo_surface_t"? Convert it to "var SurfacePtr"?
Yes. Convert it to var Surface.
Writing a good wrapper takes effort and ultimately you need to provide additional information that the plain C header simply lacks. c2nim can only help with the mechanical transformations. That said, improving c2nim so that is supports SWIG-like type transformation rules would be a possible next step.
type #PSurface* = ptr SurfaceObj TSurface* = SurfaceObj Surface* = ptr SurfaceObj SurfacePtr* = ptr SurfaceObj SurfaceObj* {.final, pure.} = object {.deprecated: [PSurface: Surface].}
My feeling is, that this is a even better solution. When compiling a test program I get a nice warning
test_png.nim(7, 5) Warning: use Surface instead; PSurface is deprecated [Deprecated]
I think I will fix my wrapper that way before trying to upload to github...
And, in case someone reads this -- another question: There exists pragma files in this shape
https://github.com/nim-lang/cairo/blob/master/src/cairo_pragma.nim
I was going to copy that style -- I do understand the part below the leftmost else, but not the pkg-config gorge stuff. And it seems to generate warnings when compiling. Should I use it this way, or modify it in some way?
cairo_pragma.nim(3, 12) Warning: undeclared conditional symbol; use --symbol to declare it: use_pkg_config [User] cairo_pragma.nim(3, 39) Warning: undeclared conditional symbol; use --symbol to declare it: use_pkg_config_static [User]
gorge() is just an alias for staticExec(), it captures the parameters which pkg-config outputs.
Those other two warnings have to do with the recent change where defined has been split into declared.
Well, last weekend I did the latest cairo 1.14 wrapper this way.
OK, created an github account and uploaded cairo module as a first member of the new bigbreak naming scheme. Feel free to comment, glib, gdk3, gtk3 and more in this shape may follow. (I have not touched the old cairo_pragma.nim file, still generates warnings, but works for Linux, and I can not test with other OS currently.)
Nice! I like the way you automate the header to Nim conversion. Just need to submit the pull request to https://github.com/nim-lang/packages now ;-)
edit: or maybe to the original cairo repo
still working on latest glib 2.40.2 ...
we have in C headers:
#define G_THREAD_ERROR g_thread_error_quark () GLIB_AVAILABLE_IN_ALL GQuark g_thread_error_quark (void); typedef enum { G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ } GThreadError;
To make c2nim generating a template from the define I inserted (), resulting in #define G_THREAD_ERROR() ...
Fine, but for the new naming convention we do not insert T prefixes for enums, so we have a name conflict enum, template: G_THREAD_ERROR <==> GThreadError
template G_THREAD_ERROR*(): expr = g_thread_error_quark() proc g_thread_error_quark*(): GQuark {.importc: "g_thread_error_quark", libglib.} type GThreadError* {.size: sizeof(cint).} = enum G_THREAD_ERROR_AGAIN GThreadFunc* = proc (data: gpointer): gpointer
I can remember that in gdk3 and gtk3 we have many conflicts like that, but legacy T prefix for enums avoids it. Arbitrary renaming something is always bad, because people may port C code and wonder about arbitrary renamed identifiers. Removing the template may be OK, it is only an alias. Better ideas?
Uppercased templates are in violation of our style guide. Note: wrappers should adhere to the style guide and not to the original source.
Unfortunately c2nim doesn't know about our style guide yet... :-/
Uppercased templates are in violation of our style guide.
Oh, so we write templates like procs starting with a lower letter generally. Nice, I think that solves most name conflicts for glib/gtk3. Indeed in manual templates start with lower case letter, but in style guide I can not remember a hint to this, and I just scrolled through the style guide but did not see a hint.