ffi/ffi-swig-generator — pull request #15 by phemmer (2013-10-18 03:12:44+00:00)
Title: Add support for %import

*This pull request includes commits from the pull request for [adding typedef support](https://github.com/ffi/ffi-swig-generator/pull/14). This is done because this change was built on top of the other, and it would otherwise result in merge conflicts if both are merged.*

This commit adds support for the swig `%import` directive. Previously `%import` was treated the same as `%include`. The 2 are not supposed to be equivalent. `%import` is meant for using a specified swig/header file without the resulting output actually including definitions specified in that file.

Use case:
The corosync library has several services offered (CPG, SAM, Quorum, Votequorum, & CMAP). All of them are completely independent of each other, however they all depend on a common corosync library. While creating a ruby gem to provide an interface to these corosync services, it is desirable to only load the module for the service being used. As such each needs to be split up into a separate file that can be `required` when needed.

For example:

**common.i** (which creates `common.rb`)

%module Corosync
%{
require 'ffi'
module Corosync
extend FFI::Library
ffi_lib 'libcorosync_common'
%}
%include <corosync/corotypes.h>
%{
end
%}

**cpg.i**

%module Corosync
%{
require File.expand_path('../common.rb', __FILE__)
module Corosync
extend FFI::Library
ffi_lib 'libcpg'
%}
%import "common.i"
%include <corosync/cpg.h>
%{
end
%}

Notice the `%import "common.i"` (there are several types provided by `common` needed in `cpg`). Without this patch it would result in `cpg.rb` including all the same code that `common.rb` has. Also note that they both reside in the `Corosync` module. Thus if you try and load both you'll get lots of warnings/errors about things being redefined.
You might argue that they should be in separate modules, but I don't agree with this. This results in a duplication of all the common types in every single module. Also it doesn't make sense to reference something like a struct in common as `Corosync::CPG::SomeStruct` when it's not really part of CPG at all.
This is just the reality of working with external C libraries. C was not meant to be scoped.

The result of this change is that you can now create a `Corosync::CPG` class and `require 'ffi/cpg.rb'`, and that class will get everything it needs to interface with the CPG service of corosync.