Affix

 view release on metacpan or  search on metacpan

lib/Affix/Wrap.pod  view on Meta::CPAN

=pod

=encoding utf-8

=head1 NAME

Affix::Wrap - Frictionless C/C++ Binding Generator for Affix

=head1 SYNOPSIS

    use Affix::Wrap;

    my $wrapper = Affix::Wrap->new(
        project_files => ['/usr/include/sqlite3.h'],
        include_dirs  => ['/usr/include'],
        types         => {
            'sqlite3' => 'Pointer[Void]' # Custom override
        }
    );

    # Option 1: Instantly wrap and inject into the current namespace
    # You may call functions exported by the lib immediately
    $wrapper->wrap('libsqlite3.so', __PACKAGE__);

    # Option 2: Generate a standalone Perl module file to disk
    # This should get you started on a library wrapper you'll eventually put on CPAN
    $wrapper->generate('libsqlite3.so', 'My::SQLite', 'lib/My/SQLite.pm');

=head1 DESCRIPTION

C<Affix::Wrap> is a frictionless binding generator that bridges C/C++ header files and L<Affix>. It parses headers to
extract functions, structs, enums, typedefs, macros, and global variables, automatically converting this information
into L<Affix> definitions.

It is designed to facilitate two primary developer workflows:

=over

=item 1. B<Rapid Prototyping (Runtime Wrapping)>

Parse headers on the fly and inject bindings directly into your running Perl environment via C<wrap()>. This is perfect
for private tooling, experimental scripts, or whenever you want to avoid the boilerplate of a dedicated FFI module.

=item 2. B<Distribution (Static Generation)>

Generate standalone F<.pm> files for CPAN via C<generate()>. This produces a pure-Perl module that depends only on
L<Affix>, ensuring fast load times and zero development dependencies (like C<Clang> or C<Affix::Wrap> itself) for your
end users.

=back

=head2 Parsing Drivers

C<Affix::Wrap> employs a dual-driver strategy:

=over

=item * B<Clang Driver (Recommended)>

The primary driver. It leverages C<clang -Xclang -ast-dump=json> to perform compiler-grade analysis of your headers. It
is highly accurate and handles complex C++ templates, macros, and deep inclusion chains with ease.

=item * B<Regex Driver (Fallback)>

A pure-Perl heuristic parser. While less capable than the Clang driver (it may struggle with complex macros or nested
C++ constructs), it requires no external dependencies and is sufficient for many straightforward C headers.

=back

=head1 Supported Features

C<Affix::Wrap> extracts and bridges:

=over

=item * Function signatures (including pointer-to-function arguments)

=item * Nested Structs and Unions

=item * Enums (maps them to Affix Dualvar Enums)

=item * Macros (numeric and string constants)

=item * Typedefs (follows deep typedef chains)

=item * Extern Global Variables (binds them via C<Affix::pin>)

=item * Doxygen/Markdown Comments (extracts to POD when generating modules)

=back

=head1 CONSTRUCTOR

lib/Affix/Wrap.pod  view on Meta::CPAN


=over

=item * C<definition>: If the member defines a nested struct/union inline, this holds that definition object.

=item * C<affix_type>: Returns the signature of the type OR the nested definition.

=back

=head2 Affix::Wrap::Function

A C function declaration.

=over

=item * C<affix_type>: Returns a complete Perl string to bind this function (e.g., C<affix $lib, name =E<gt> ...>).

=item * C<affix( $lib, $pkg )>: Installs the function into C<$pkg>.

=back

=head2 Affix::Wrap::Struct

A C struct or union definition.

=over

=item * C<tag>: Either 'struct' or 'union'.

=item * C<affix_type>: Returns signature string C<Struct[ ... ]> or C<Union[ ... ]>.

=back

=head2 Affix::Wrap::Typedef

A name alias for another type.

=over

=item * C<underlying>: The type object being aliased.

=item * C<affix_type>: Returns string C<typedef Name =E<gt> UnderlyingType>.

=back

B<Note:> In C, C<typedef struct { ... } Name;> results in a C<Typedef> object where B<underlying> is the C<Struct>
object.

=head2 Affix::Wrap::Enum

An enumeration.

=over

=item * C<affix_type>: Returns signature string C<Enum[ Name =E<gt> Val, ... ]>. String values/expressions in enums are quoted automatically to prevent eval errors.

=back

=head2 Affix::Wrap::Variable

A global C<extern> variable.

=over

=item * C<affix_type>: Returns string C<pin my $var, $lib, name =E<gt> Type>.

=item * C<affix( $lib, $pkg )>: Installs the variable accessor into C<$pkg>.

=back

=head2 Affix::Wrap::Macro

A preprocessor C<#define>. Only simple value macros are captured.

=over

=item * C<affix_type>: Returns string C<use constant Name =E<gt> Value>. Expressions (e.g., C<A + B>) are quoted as strings, while literals are preserved.

=item * C<affix( undef, $pkg )>: Installs the constant into C<$pkg>.

=back

=head1 Tutorials

=head2 Runtime Library Wrappers

If you want to use a C library immediately without creating a separate Perl module file, use the C<wrap> method.

    use Affix;
    use Affix::Wrap;

    my $lib = load_library('demo');

    # This parses demo.h and installs subroutines, constants,
    # and types directly into the calling package.
    Affix::Wrap->new( project_files => ['demo.h'] )->wrap($lib);

    # Now you can use them:
    my $obj = Demo_CreateStruct();

=head3 Manual Control

If you need to filter which functions are bound or rename them, you can iterate over the AST manually instead of
calling C<wrap>:

    my $binder = Affix::Wrap->new( project_files => ['demo.h'] );
    for my $node ( $binder->parse ) {
        next if $node->name =~ m[^Internal_]; # Skip internal functions
        # Manually bind
        if ( $node->can('affix') ) {
            $node->affix($lib);
        }
    }

=head2 Generating Affix Modules for CPAN

To create a distributable module (e.g., C<My::Lib.pm>) without requiring your users to have C<Clang> or C<Affix::Wrap>
installed at runtime, use the C<generate> method:

    use Affix::Wrap;



( run in 0.782 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )