October 22, 2012
correction regarding macros:

myheader.h:
#define MEX_INFORMATION_VERSION 1

interface file myheader.i:
%{
%include "myheader.h"
%}
%include myheader.h

generated d file will contain:

int MEX_INFORMATION_VERSION() @property {
  auto ret = swig.mex_im.swig_mex_MEX_INFORMATION_VERSION_get();
  return ret;
}

which allows one to use the macro from D. Certainly not the best way (an enum would be preferable) but it works. Again, swig could be improved. Also if static libraries could be generated, the overhead above wouldn't be such a big deal with link time optimization.

For functional macros, I'm not sure, but once can write a C function that calls the macro, and then swig will convert to D function. Ideally, swig would directly convert it to a templated function.


I think maintaining a repository of interface files would be a better idea than maintaining manually converted C files. The former would be much smaller & easier to maintain, and for 99% cases stay in sync with library updates. The latter would end up as a graveyard of never up to date partially-portable C ports that no-one will want to maintain.


October 22, 2012
On Monday, 22 October 2012 at 06:28:12 UTC, Jacob Carlborg wrote:
> On 2012-10-21 21:45, timotheecour wrote:
>> Manually porting of C/C++ libraries shouldn't be the way to go (a
>> major problem being when said library gets updated, human errors,
>> porting to different architectures etc).
>
> SWIG requires some kind of interface files, which I assume one must have to manually write. Then what's the difference?

Huge difference.  It's not necessary to figure out corresponding type sizes on every system.  I only need to figure out what needs to be in there.  And once all the work of creating the interface file is done, the work of porting to another architecture or operating system or compiler is much reduced.

It's not necessary to figure out which api calls are macros on arch XYZ or are simply not there:

cdcl Tcl_IncrRefCount
clib Tcl_IncrRefCount
# if Tcl_IncrRefCount is not defined as a library call, search for the macro.
if lib_Tcl_IncrRefCount ! _clib_Tcl_IncrRefCount
 cmacro Tcl_IncrRefCount tcl.h void 'Tcl_Obj *'
endif

My example Tck/Tk conversion doesn't handle 8.6, but the effort to add it will be very minimal.  All of the hard work of discovering the needed typedefs has been done.

> [...]
> I don't think SWIG is the right approach because:
>
> * You have to create these interface files
> * It seem to not handle all code

I don't know SWIG, but the idea is the same for my tool.

If you try to automate processing of the pre-processed headers, all of the included system headers will be processed and too much that isn't needed will be output. The included system definitions will conflict with D definitions.

I'm not sure that handling *all* code is necessary.  How often do you see
this sort of thing in C code?
    _XPrivate .private9, .private10;
Rather than spend effort on handling *every* possible obscure C/C++/ObjC construct, it's easier to simply handle those in the interface file.

Other constructs that are more common can be added to SWIG or to my tool.
They're both open source.

  -- Brad

October 22, 2012
On 2012-10-22 19:27, timotheecour wrote:
>> SWIG requires some kind of interface files, which I assume one must
>> have to manually write. Then what's the difference?
>
> These can be as small as:
>
>
> sfml.i:
> %{
> #include <SFML/Audio.hpp>
> %}
> %include SFML/Config.hpp
> %include SFML/Audio/Export.hpp
>
> In practice, some additional tweaks may be needed to support certain
> constructs like multiple inheritance, etc, but nothing daunting (~ 50
> lines of code for my sfml interface file)
>
>> I don't think SWIG is the right approach because:
>> * You have to create these interface files
>
> =>
> see above. Interface files can be very small.
>
>> * It seem to not handle all code
> I was still able to port large libraries like sfml and opencv, using
> tweaks to the interface files and enhancing swig to support C++template
> to D template conversion. There's a small number of cases where swig
> currently chokes, some of which could be easily fixed if there's enough
> demand.
>
>> * No support for Objective-C
>
> =>
> http://www.swig.org/Doc1.1/HTML/SWIG.html#n7
> One of SWIG's most recent additions is support for Objective-C parsing.
> This is currently an experimental feature that may be improved in future
> releases.
>
>> BTW, how does SWIG handle macros and documentation?
> You'd have to write a C/C++ function that does what the macro does in
> the interface file, which would in turn be converted to a D function.
>
> For exporting C documentation to D, I've asked on stackoverflow:
> http://stackoverflow.com/questions/12413957/export-comments-in-swig-wrapper
> I'm not sure it's supported ATM, but that's definitely something
> possible since swig has a full blown C++ parser.

Ok, I see.

If SWIG has a full blown C++ parser, then why is it choking on some code? Or does it need a semantic analyzer as well.

-- 
/Jacob Carlborg
October 22, 2012
On 2012-10-22 20:38, Brad Lanam wrote:

> Huge difference.  It's not necessary to figure out corresponding type
> sizes on every system.  I only need to figure out what needs to be in
> there.  And once all the work of creating the interface file is done,
> the work of porting to another architecture or operating system or
> compiler is much reduced.
>
> It's not necessary to figure out which api calls are macros on arch XYZ
> or are simply not there:
>
> cdcl Tcl_IncrRefCount
> clib Tcl_IncrRefCount
> # if Tcl_IncrRefCount is not defined as a library call, search for the
> macro.
> if lib_Tcl_IncrRefCount ! _clib_Tcl_IncrRefCount
>   cmacro Tcl_IncrRefCount tcl.h void 'Tcl_Obj *'
> endif
>
> My example Tck/Tk conversion doesn't handle 8.6, but the effort to add
> it will be very minimal.  All of the hard work of discovering the needed
> typedefs has been done.
>
>> [...]
>> I don't think SWIG is the right approach because:
>>
>> * You have to create these interface files
>> * It seem to not handle all code
>
> I don't know SWIG, but the idea is the same for my tool.
>
> If you try to automate processing of the pre-processed headers, all of
> the included system headers will be processed and too much that isn't
> needed will be output. The included system definitions will conflict
> with D definitions.
>
> I'm not sure that handling *all* code is necessary.  How often do you see
> this sort of thing in C code?
>      _XPrivate .private9, .private10;
> Rather than spend effort on handling *every* possible obscure C/C++/ObjC
> construct, it's easier to simply handle those in the interface file.
>
> Other constructs that are more common can be added to SWIG or to my tool.
> They're both open source.

I prefer the approach I took when I created DStep, it uses libclang. The tool can parse all C(++) and Objective-C(++) code that clang can. Although it currently won't generate code for everything, at least it doesn't choke any code.

I also get all bug fixes and new languages features for free when they're added to clang.

No need to create interface files.

-- 
/Jacob Carlborg
October 22, 2012
On 2012-10-22 19:27, timotheecour wrote:

> http://www.swig.org/Doc1.1/HTML/SWIG.html#n7
> One of SWIG's most recent additions is support for Objective-C parsing.
> This is currently an experimental feature that may be improved in future
> releases.

Will this generate C code or can it be made to generate something like this:

http://michelf.ca/projects/d-objc/syntax/

-- 
/Jacob Carlborg
October 22, 2012
On Monday, 22 October 2012 at 19:12:46 UTC, Jacob Carlborg wrote:
> On 2012-10-22 20:38, Brad Lanam wrote:
> I prefer the approach I took when I created DStep, it uses libclang. The tool can parse all C(++) and Objective-C(++) code that clang can. Although it currently won't generate code for everything, at least it doesn't choke any code.
>
> I also get all bug fixes and new languages features for free when they're added to clang.
>
> No need to create interface files.

Nothing wrong with that.
I had different goals -- portability and legacy systems.  My tool is all bourne shell and awk.  There aren't many systems it does not work on (e.g. ULTRIX shell runs out of memory).

I should also state my tool was written as a build configuration tool (like autoconf/iffe/dist), not a conversion tool.  SWIG is better supported, faster and supports more languages.

If you need to write code that runs on multiple systems and works with low level system calls (rpc, et.al.), my tool might be a better choice.

This sort of thing (from the D compiler):

#if __sun
#include        <alloca.h>
#endif

Is nuts.  I thought everyone had gotten away from that sort of thing (it died out in the mid-eighties!), but I still see it in code everywhere.  The system should be tested for its capabilities and what it has available, not whether it is a sun machine.

  -- Brad

October 22, 2012
On Monday, 22 October 2012 at 19:12:46 UTC, Jacob Carlborg wrote:
> On 2012-10-22 20:38, Brad Lanam wrote:
> I prefer the approach I took when I created DStep, it uses libclang. The tool can parse all C(++) and Objective-C(++) code that clang can. Although it currently won't generate code for everything, at least it doesn't choke any code.
>
> I also get all bug fixes and new languages features for free when they're added to clang.
>
> No need to create interface files.

Nothing wrong with that.
I had different goals -- portability and legacy systems.  My tool is all bourne shell and awk.  There aren't many systems it does not work on (e.g. ULTRIX shell runs out of memory).

I should also state my tool was written as a build configuration tool (like autoconf/iffe/dist), not a conversion tool.  SWIG is better supported, faster and supports more languages.

If you need to write code that runs on multiple systems and works with low level system calls (rpc, et.al.), my tool might be a better choice.

This sort of thing (from the D compiler):

#if __sun
#include        <alloca.h>
#endif

Is nuts.  I thought everyone had gotten away from that sort of thing (it died out in the mid-eighties!), but I still see it in code everywhere.  The system should be tested for its capabilities and what it has available, not whether it is a sun machine.

  -- Brad

October 23, 2012
>If you try to automate processing of the pre-processed headers,
> all of the included system headers will be processed and too much that isn't needed will be output.

Swig has lots of customization to control what gets translated. For example, we recursively translate the contents of header files or just the contents minus without looking into the include statements (the default):

b.h:
void funb();
a.h:
#include b.h
void funa();

%{
%include "a.h"
%}
%include a.h

=> the default is NOT to inlude funb(), which is inside an include statement.

>> If SWIG has a full blown C++ parser, then why is it choking on some
code?
One example is when there's no D equivalent, eg multiple inheritance. But there are more:
actually in the example above, if I understand correctly, the stuff inside the %{ %} uses the full blown C++ parser, whereas the stuff after has some swig specificities and sometimes can't handle certain rare constructs if one uses the lazy approach that I've taken of translating the whole header file (%include a.h):

some stuff it choked on:
A) typedef Matx<_Tp, MIN(m, n), 1> diag_type;
B) void addParam(   int (Algorithm::*getter)()=0)


> Will this generate C code or can it be made to generate something like this:
> http://michelf.ca/projects/d-objc/syntax/

I haven't tried, I'd be curious to know.



October 23, 2012
On 2012-10-22 21:48, Brad Lanam wrote:

> Nothing wrong with that.
> I had different goals -- portability and legacy systems.  My tool is all
> bourne shell and awk.  There aren't many systems it does not work on
> (e.g. ULTRIX shell runs out of memory).

How can you mention bourne shell and portability in the same sentence? I doesn't work on Windows (yes I know about cygwin and mingw). Clang does work on Windows, I just haven't been able to compile DStep for Windows yet due to optlink not cooperating.

Sure, if you're satisfied with Posix then I guess that's fine. But it's not really easy to build cross-platform code with shell script.

> I should also state my tool was written as a build configuration tool
> (like autoconf/iffe/dist), not a conversion tool.  SWIG is better
> supported, faster and supports more languages.
>
> If you need to write code that runs on multiple systems and works with
> low level system calls (rpc, et.al.), my tool might be a better choice.

Why would that make a difference.

> This sort of thing (from the D compiler):
>
> #if __sun
> #include        <alloca.h>
> #endif
>
> Is nuts.  I thought everyone had gotten away from that sort of thing (it
> died out in the mid-eighties!), but I still see it in code everywhere.
> The system should be tested for its capabilities and what it has
> available, not whether it is a sun machine.

DMD (DMC) is from the eighties. It sill uses the .c for its C++ files.

-- 
/Jacob Carlborg
October 23, 2012
On 2012-10-23 07:09, timotheecour wrote:
>> If you try to automate processing of the pre-processed headers,
>> all of the included system headers will be processed and too much that
>> isn't needed will be output.
>
> Swig has lots of customization to control what gets translated. For
> example, we recursively translate the contents of header files or just
> the contents minus without looking into the include statements (the
> default):
>
> b.h:
> void funb();
> a.h:
> #include b.h
> void funa();
>
> %{
> %include "a.h"
> %}
> %include a.h
>
> => the default is NOT to inlude funb(), which is inside an include
> statement.

I'm only translating what's in the "main" header file, i.e. the one you gave on the command line. I have access to source information of where a given symbol is declared, if it doesn't match the main header file it's not translated.

>>> If SWIG has a full blown C++ parser, then why is it choking on some
> code?
> One example is when there's no D equivalent, eg multiple inheritance.
> But there are more:
> actually in the example above, if I understand correctly, the stuff
> inside the %{ %} uses the full blown C++ parser, whereas the stuff after
> has some swig specificities and sometimes can't handle certain rare
> constructs if one uses the lazy approach that I've taken of translating
> the whole header file (%include a.h):
>
> some stuff it choked on:
> A) typedef Matx<_Tp, MIN(m, n), 1> diag_type;
> B) void addParam(   int (Algorithm::*getter)()=0)

If there's something I can't translate to D I just skip it. I could output a warning, some kind of static assert in the code or whatever. The tool can still handle the file.

-- 
/Jacob Carlborg