Memcached-libmemcached

 view release on metacpan or  search on metacpan

Makefile.PL  view on Meta::CPAN

    $configure_args .= ' --disable-jobserver';
    run("cd $lmcd_src && ./configure --prefix=$lmcd_inst $configure_args");
    #run("cd $lmcd_src && make test") if $is_developer; # XXX
    run("cd $lmcd_src && make install");
}

sub sync_libmemcached_pod {
    return unless -d ".svn";
    # we duplicate the libmemcached pod in svn so that the docs can be read on search.cpan.org
    my $perl_pod_dir = "lib/Memcached/libmemcached";
    my @lmcd_pod;
warn "sync_libmemcached_pod XXXXXXXXXXXXXX";
    for my $src_pod (@lmcd_pod) {
        (my $dst_pod = $src_pod) =~ s!$lmcd_src/docs!$perl_pod_dir!;
        $dst_pod =~ s/\.pod/\.pm/;
        open my $src, "<$src_pod" or die "Can't open $src_pod: $!";
        open my $dst, ">$dst_pod" or die "Can't open $dst_pod: $!";

        # convert path into package
        (my $dst_pkg = $dst_pod) =~ s{/}{::}g;
        $dst_pkg =~ s{ lib:: (.*?) \.\w+ $ }{$1}x;

        print $dst "package $dst_pkg;\n\n"; # for search.cpan.org
        while (<$src>) {
            print $dst $_;
        }
        print $dst "1;\n";
        close $dst or die "Error closing $dst_pod: $!";
        run("svn add -q $dst_pod");
    }
    # XXX svn rm any $perl_pod_dir/memcached_*.pod that weren't in @lmcd_pod
}

sub extract_libmemcached_functions {
    my %libmemcached_func;

    # find all memcached_* functions
    warn "Finding all public functions\n";
    my @headers = <$lmcd_src/libmemcached-$lmcd_api_ver/*.h>;
    for my $src_pod (@headers) {
        open my $fh, "<$src_pod" or die "Can't open $src_pod: $!";
        #warn $src_pod;
        while (<$fh>) {
            next unless /\b(memcached_\w+)\s*\([^3]/;
            $libmemcached_func{$1} = 1
                unless $1 eq 'memcached_return'; # parsing fooled by callback
            #warn "\t$1\t$_";
        }
    }

    # write 
    my $func_pm = "lib/Memcached/libmemcached/func_hash.pl";
    warn "Writing $func_pm\n";
    open my $func_pm_fh, ">$func_pm" or die "Can't open $func_pm: $!";
    local $\ = "\n";
    print $func_pm_fh "# DO NOT EDIT! GENERATED BY $0\n";
    print $func_pm_fh "".Data::Dumper->Dump([\%libmemcached_func], [qw(libmemcached_func)]);
    close $func_pm_fh or die "Error closing $func_pm: $!";

    # sanity check the generated file
    my $loaded = require $func_pm;
    die "$func_pm didn't return a HASH reference ($loaded)"
        unless ref $loaded eq 'HASH';
}

sub extract_libmemcached_constants {
    my %libmemcached_const;

    # find all MEMCACHED_* constants (#define and enum)
    my $in_enum = 0;
    my @const;

    #my @headers = ("$lmcd_src/libmemcached/memcached.h", "$lmcd_src/libmemcached/constants.h");
    my @headers = (
        <$lmcd_src/libmemcached-$lmcd_api_ver/types/*.h>,
        "$lmcd_src/libmemcached-$lmcd_api_ver/limits.h",
        "$lmcd_src/libmemcached-$lmcd_api_ver/defaults.h",
    );
    warn "Reading ".@headers." header files to find all constants\n";
    for my $h (@headers) {
        warn "  $h\n" if $opt_d;
        open my $fh, "<$h" or die "Can't open $h: $!";
        while (<$fh>) {
            if ($in_enum) {
                if (m/^ \s* }/x) { # end of enum
                    $libmemcached_const{$_} = $in_enum for @const;
                    @const = ();
                    $in_enum = 0;
                    warn "  << $in_enum" if $opt_d;
                }
                elsif (m/^ \s* (MEMCACHED_\w+)/x) {
                    my $symbol = $1;
                    if ( $symbol !~ /MEMCACHED_CALLBACK_(MALLOC|REALLOC|FREE)_FUNCTION/) {
                        push @const, $symbol;
                        warn "  enum $_" if $opt_d;
                    }
                }
            }
            elsif (m/^ \s* (?:typedef \s+)? enum \s+ (\w+) \s+ {/x) {
                $in_enum = $1;
                warn "  >> $_" if $opt_d;
            }
            elsif (m/\# \s* define \s+ (MEMCACHED_\w+)/x) {
                my $symbol = $1;
                if ($symbol !~ /_H$/) {
                    $libmemcached_const{$1} = "defines";
                    warn "  $_" if $opt_d;
                }
            }
        }
    }

    # write raw hash of const names
    my $const_pl = "lib/Memcached/libmemcached/const_hash.pl";
    warn "Writing $const_pl\n";
    open my $const_pl_fh, ">$const_pl" or die "Can't open $const_pl: $!";
    local $\ = "\n";
    print $const_pl_fh "# DO NOT EDIT! GENERATED BY $0\n";
    print $const_pl_fh "".Data::Dumper->Dump([\%libmemcached_const], [qw(libmemcached_const)]);
    close $const_pl_fh or die "Error closing $const_pl: $!";

    # sanity check the generated file
    my $loaded = require $const_pl;
    die "$const_pl didn't return a HASH reference ($loaded)"
        unless ref $loaded eq 'HASH';

    # write raw hash of const names
    my $const_xs = "const-xs.inc";
    warn "Writing $const_xs\n";
    open my $const_xs_fh, ">$const_xs" or die "Can't open $const_xs: $!";
    local $\ = "\n";
    print $const_xs_fh "# DO NOT EDIT! GENERATED BY $0\n";
    print $const_xs_fh "IV\nconstant()";
    print $const_xs_fh "\tALIAS:";
    print $const_xs_fh "\t$_ = $_" for sort keys %libmemcached_const;
    print $const_xs_fh "\tCODE:";
    print $const_xs_fh "\tRETVAL = ix;";
    print $const_xs_fh "\tOUTPUT:";
    print $const_xs_fh "\tRETVAL";
    close $const_xs_fh or die "Error closing $const_xs: $!";

    # now write a pod file to document the constants and tags

    # invert libmemcached_const into hash of tags with arrays of name
    my %libmemcached_tags;
    push @{ $libmemcached_tags{ $libmemcached_const{$_} } }, $_ for keys %libmemcached_const;
    # open file and write prologue
    my $const_pm = "lib/Memcached/libmemcached/constants.pm";
    warn "Writing $const_pm\n";
    open my $const_pm_fh, ">$const_pm" or die "Can't open $const_pm: $!";
    local $\ = "\n";
    print $const_pm_fh "# DO NOT EDIT! GENERATED BY $0\n";
    print $const_pm_fh $_ for (
        "=head1 NAME\n",
        "Memcached::libmemcached::constants - document list of constants defined by libmemcached\n",
        "=head1 DESCRIPTION\n",
        "This file just lists all the constants defined by libmemcached which are available to import via the L</Memcached::libmemcached> module.\n",
        "Each constant can be imported individually by name. "
        ."Groups of related constants, such as the elements of an C<enum> type, "
        ."can be imported as a set using a C<:tag> name. "
        ."See L<Exporter> for more information about tags.\n",
    );
    # write out tags and their constants
    print $const_pm_fh "=head1 TAGS\n";
    for my $tag (sort keys %libmemcached_tags) {
        my $names = $libmemcached_tags{$tag} or die "panic";
        print $const_pm_fh "=head2 :$tag\n";
        print $const_pm_fh "  $_"
            for sort @$names;
        print $const_pm_fh "";
    }
    # close up
    print $const_pm_fh "=cut\n\n1;\n";
    close $const_pm_fh or die "Error closing $const_pm: $!";
#    run("svn add -q $const_pm") if $is_developer;
}



( run in 3.319 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )