File Coverage

lib/Dist/Zilla/Plugin/MathInt64.pm
Criterion Covered Total %
statement 35 36 97.2
branch 9 10 90.0
condition n/a
subroutine 7 7 100.0
pod 0 3 0.0
total 51 56 91.0


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::MathInt64;
2              
3 2     2   512567 use Moose;
  2         276486  
  2         12  
4 2     2   9455 use Dist::Zilla::File::InMemory;
  2         260050  
  2         68  
5 2     2   559 use ExtUtils::Typemaps;
  2         21805  
  2         47  
6 2     2   848 use File::ShareDir qw( dist_dir );
  2         7449  
  2         840  
7              
8             # ABSTRACT: Include the Math::Int64 C client API in your distribution
9             our $VERSION = '0.08'; # VERSION
10              
11              
12             with 'Dist::Zilla::Role::Plugin';
13             with 'Dist::Zilla::Role::FileGatherer';
14             with 'Dist::Zilla::Role::FileMunger';
15             with 'Dist::Zilla::Role::PrereqSource';
16              
17             has dir => (
18             is => 'ro',
19             );
20              
21             has typemap => (
22             is => 'ro',
23             default => 1,
24             );
25              
26             has typemap_path => (
27             is => 'ro',
28             default => 'typemap',
29             );
30              
31             has _source_dir => (
32             is => 'ro',
33             lazy => 1,
34             default => sub {
35             if(defined $ENV{DIST_ZILLA_PLUGIN_MATH64_TEST})
36             {
37             require Path::Class::Dir;
38             return Path::Class::Dir->new($ENV{DIST_ZILLA_PLUGIN_MATH64_TEST});
39             }
40             elsif(defined $Dist::Zilla::Plugin::MathInt64::VERSION)
41             {
42             require Path::Class::Dir;
43             return Path::Class::Dir->new(dist_dir('Dist-Zilla-Plugin-MathInt64'));
44             }
45             else
46             {
47             require Path::Class::File;
48             return Path::Class::File->new(__FILE__)
49             ->parent
50             ->parent
51             ->parent
52             ->parent
53             ->parent
54             ->absolute
55             ->subdir('share');
56             }
57             },
58             );
59              
60             sub gather_files
61             {
62 5     5 0 237469 my($self) = @_;
63            
64 5         13 foreach my $source_name (qw( perl_math_int64.c perl_math_int64.h perl_math_int64_types.h ))
65             {
66 15 100       6540 my $dst = defined $self->dir
67             ? join('/', $self->dir, $source_name)
68             : $source_name;
69            
70 15         40 $self->log("create $dst");
71 15         3486 $self->add_file(
72             Dist::Zilla::File::InMemory->new(
73             name => $dst,
74             content => scalar $self->_source_dir->file($source_name)->slurp,
75             ),
76             );
77             }
78            
79 5 100       3011 return unless $self->typemap;
80            
81 4 100       5 unless(grep { $_->name eq $self->typemap_path } @{ $self->zilla->files })
  21         111  
  4         76  
82             {
83 3         68 $self->log("create " . $self->typemap_path);
84 3         624 $self->add_file(
85             Dist::Zilla::File::InMemory->new(
86             name => $self->typemap_path,
87             content => ExtUtils::Typemaps->new->as_string,
88             ),
89             );
90             }
91             }
92              
93             sub munge_files
94             {
95 5     5 0 14620 my($self) = @_;
96            
97 5 100       133 return unless $self->typemap;
98            
99 4         5 my($file) = grep { $_->name eq $self->typemap_path } @{ $self->zilla->files };
  24         143  
  4         82  
100              
101 4 50       10 unless(defined $file)
102             {
103 0         0 $self->log_fatal("unable to find " . $self->typemap_path . " which I should have created, perhaps another plugin pruned it?");
104             }
105            
106 4         89 $self->log("update " . $self->typemap_path);
107              
108 4         916 my $typemap = ExtUtils::Typemaps->new(string => $file->content);
109 4         1411 $typemap->merge(
110             typemap => ExtUtils::Typemaps->new(
111             string => scalar $self->_source_dir->file('typemap')->slurp,
112             ),
113             );
114 4         3510 $file->content($typemap->as_string);
115             }
116              
117             sub register_prereqs
118             {
119 5     5 0 3919 my($self) = @_;
120            
121 5         115 $self->zilla->register_prereqs(
122             { type => 'requires', phase => 'runtime' },
123             'Math::Int64' => '0.28',
124             );
125             }
126              
127             1;
128              
129             __END__
130              
131             =pod
132              
133             =encoding UTF-8
134              
135             =head1 NAME
136              
137             Dist::Zilla::Plugin::MathInt64 - Include the Math::Int64 C client API in your distribution
138              
139             =head1 VERSION
140              
141             version 0.08
142              
143             =head1 SYNOPSIS
144              
145             in your dist.ini
146              
147             [PPPort]
148             [MathInt64]
149             [ModuleBuild]
150             mb_class = MyDist::ModuleBuild
151              
152             in your xs (lib/MyDist.xs):
153              
154             #include "EXTERN.h"
155             #include "perl.h"
156             #include "XSUB.h"
157             #include "ppport.h"
158            
159             /* provides int64_t and uint64_t if not *
160             * already available */
161             #include "perl_math_int64_types.h"
162            
163             /* #define MATH_INT64_NATIVE_IF_AVAILABLE */
164             #include "perl_math_int64.h"
165            
166             MODULE = MyDist PACKAGE = MyDist
167            
168             int64_t
169             function_that_returns_64bit_integer()
170            
171             void
172             function_that_takes_64bit_integer(number)
173             int64_t number
174            
175             SV *
176             same_idea_but_with_xs(sv_number)
177             SV *sv_number
178             CODE:
179             int64_t native_number = SvI64(sv_number);
180             ...
181             RETVAL = newSVi64(native_number);
182             OUTPUT:
183             RETVAL
184              
185             See L<Math::Int64#C-API> for details.
186              
187             in your Module::Build subclass (inc/MyDist/ModuleBuild.pm):
188              
189             package MyDist::ModuleBuild;
190            
191             use base qw( Module::Build );
192            
193             sub new
194             {
195             my($class, %args) = @_;
196             $args{c_source} = '.';
197             $class->SUPER::new(%args);
198             }
199              
200             =head1 DESCRIPTION
201              
202             L<Math::Int64> provides an API for Perl and XS modules for dealing
203             with 64 bit integers.
204              
205             This plugin imports the C client API from L<Math::Int64> into your
206             distribution. The C client API depends on ppport.h, so make sure
207             that you also get that (the easiest way is via the
208             L<PPPort plugin|Dist::Zilla::Plugin::PPPort>.
209              
210             This plugin will also create an appropriate C<typemap> or update
211             an existing C<typemap> to automatically support the types C<int64_t>
212             and C<uint64_t> in your XS code. (You can turn this off by setting
213             typemap = 0).
214              
215             This plugin will also declare L<Math::Int64> as a prerequisite for
216             your distribution.
217              
218             One thing this plugin does NOT do is, it doesn't tell either
219             L<Module::Build> or L<ExtUtils::MakeMaker> where to find the C
220             and XS sources. One way of doing this would be to create
221             your own L<Module::Build> subclass and set the C<c_source> attribute
222             to where the C header and source code go (see the synopsis above
223             as an example).
224              
225             =head1 ATTRIBUTES
226              
227             =head2 dir
228              
229             Directory to dump the C source and header files into.
230             If not specified, they go into the distribution root.
231             If you use this option you probably need to tell the
232             L<PPPort plugin|Dist::Zilla::Plugin::PPPort> to put
233             the C<ppport.h> file in the same place.
234              
235             [PPPort]
236             filename = xs/ppport.h
237             [MathInt64]
238             dir = xs
239              
240             =head2 typemap
241              
242             If set to true (the default), then create a typemap
243             file if it does not already exist with the appropriate
244             typemaps for 64 bit integers, or if a typemap already
245             exists, add the 64 bit integer mappings.
246              
247             =head2 typemap_path
248              
249             The path to the typemap file (if typemap is true).
250             The default is simply 'typemap'.
251              
252             =head1 CAVEATS
253              
254             This plugin uses L<ExtUtils::Typemaps> to munge the typemaps
255             file, which strips any comments from the typemap file, but
256             should be semantically identical. Versions prior to 0.05
257             did its own parsing but would retain comments.
258              
259             =head1 BUNDLED SOFTWARE
260              
261             This distribution comes bundled with C source code placed
262             in the public domain by Salvador Fandino.
263              
264             Thanks to Salvador Fandino for writing L<Math::Int64> and
265             providing a XS / C Client API for other distribution authors.
266              
267             =head1 AUTHOR
268              
269             Graham Ollis <plicease@cpan.org>
270              
271             =head1 COPYRIGHT AND LICENSE
272              
273             This software is copyright (c) 2013 by Graham Ollis.
274              
275             This is free software; you can redistribute it and/or modify it under
276             the same terms as the Perl 5 programming language system itself.
277              
278             =cut