File Coverage

blib/lib/Dist/Zilla/Plugin/MathInt64.pm
Criterion Covered Total %
statement 40 41 97.5
branch 9 10 90.0
condition n/a
subroutine 8 8 100.0
pod 0 3 0.0
total 57 62 91.9


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