File Coverage

blib/lib/ExtUtils/Typemaps/OutputMap.pm
Criterion Covered Total %
statement 43 44 97.7
branch 14 16 87.5
condition 3 6 50.0
subroutine 9 9 100.0
pod 5 5 100.0
total 74 80 92.5


line stmt bran cond sub pod time code
1             package ExtUtils::Typemaps::OutputMap;
2 15     15   226 use 5.006001;
  15         48  
3 15     15   83 use strict;
  15         40  
  15         313  
4 15     15   65 use warnings;
  15         33  
  15         7739  
5             our $VERSION = '3.44';
6              
7             =head1 NAME
8              
9             ExtUtils::Typemaps::OutputMap - Entry in the OUTPUT section of a typemap
10              
11             =head1 SYNOPSIS
12              
13             use ExtUtils::Typemaps;
14             ...
15             my $output = $typemap->get_output_map('T_NV');
16             my $code = $output->code();
17             $output->code("...");
18              
19             =head1 DESCRIPTION
20              
21             Refer to L for details.
22              
23             =head1 METHODS
24              
25             =cut
26              
27             =head2 new
28              
29             Requires C and C parameters.
30              
31             =cut
32              
33             sub new {
34 2408     2408 1 20114 my $prot = shift;
35 2408   66     5364 my $class = ref($prot)||$prot;
36 2408         4146 my %args = @_;
37              
38 2408 100       4126 if (!ref($prot)) {
39 841 50 33     2633 if (not defined $args{xstype} or not defined $args{code}) {
40 0         0 die("Need xstype and code parameters");
41             }
42             }
43              
44 2408 100       7626 my $self = bless(
45             (ref($prot) ? {%$prot} : {})
46             => $class
47             );
48              
49 2408 100       5499 $self->{xstype} = $args{xstype} if defined $args{xstype};
50 2408 100       4420 $self->{code} = $args{code} if defined $args{code};
51 2408         5581 $self->{code} =~ s/^(?=\S)/\t/mg;
52              
53 2408         5600 return $self;
54             }
55              
56             =head2 code
57              
58             Returns or sets the OUTPUT mapping code for this entry.
59              
60             =cut
61              
62             sub code {
63 193 50   193 1 350 $_[0]->{code} = $_[1] if @_ > 1;
64 193         392 return $_[0]->{code};
65             }
66              
67             =head2 xstype
68              
69             Returns the name of the XS type of the OUTPUT map.
70              
71             =cut
72              
73             sub xstype {
74 3178     3178 1 8372 return $_[0]->{xstype};
75             }
76              
77             =head2 cleaned_code
78              
79             Returns a cleaned-up copy of the code to which certain transformations
80             have been applied to make it more ANSI compliant.
81              
82             =cut
83              
84             sub cleaned_code {
85 17     17 1 32 my $self = shift;
86 17         40 my $code = $self->code;
87              
88             # Move C pre-processor instructions to column 1 to be strictly ANSI
89             # conformant. Some pre-processors are fussy about this.
90 17         37 $code =~ s/^\s+#/#/mg;
91 17         171 $code =~ s/\s*\z/\n/;
92              
93 17         50 return $code;
94             }
95              
96             =head2 targetable
97              
98             This is an obscure but effective optimization that used to
99             live in C directly. Not implementing it
100             should never result in incorrect use of typemaps, just less
101             efficient code.
102              
103             In a nutshell, this will check whether the output code
104             involves calling C, C, C, C or
105             C to set the special C<$arg> placeholder to a new value
106             B. If that is the case, the code is
107             eligible for using the C-related macros to optimize this.
108             Thus the name of the method: C.
109              
110             If this optimization is applicable, C will
111             emit a C definition at the start of the generated XSUB code,
112             and type (see below) dependent code to set C and push it on
113             the stack at the end of the generated XSUB code.
114              
115             If the optimization can not be applied, this returns undef.
116             If it can be applied, this method returns a hash reference containing
117             the following information:
118              
119             type: Any of the characters i, u, n, p
120             with_size: Bool indicating whether this is the sv_setpvn variant
121             what: The code that actually evaluates to the output scalar
122             what_size: If "with_size", this has the string length (as code,
123             not constant, including leading comma)
124              
125             =cut
126              
127             sub targetable {
128 109     109 1 251 my $self = shift;
129 109 100       343 return $self->{targetable} if exists $self->{targetable};
130              
131 55         58 our $bal; # ()-balanced
132             $bal = qr[
133             (?:
134             (?>[^()]+)
135             |
136             \( (??{ $bal }) \)
137             )*
138 55         392 ]x;
139             my $bal_no_comma = qr[
140             (?:
141             (?>[^(),]+)
142             |
143             \( (??{ $bal }) \)
144             )+
145 55         217 ]x;
146              
147             # matches variations on (SV*)
148 55         109 my $sv_cast = qr[
149             (?:
150             \( \s* SV \s* \* \s* \) \s*
151             )?
152             ]x;
153              
154             my $size = qr[ # Third arg (to setpvn)
155             , \s* (??{ $bal })
156 55         182 ]xo;
157              
158 55         121 my $code = $self->code;
159              
160             # We can still bootstrap compile 're', because in code re.pm is
161             # available to miniperl, and does not attempt to load the XS code.
162 15     15   165 use re 'eval';
  15         37  
  15         1959  
163              
164 55         548 my ($type, $with_size, $arg, $sarg) =
165             ($code =~
166             m[^
167             \s+
168             sv_set([iunp])v(n)? # Type, is_setpvn
169             \s*
170             \( \s*
171             $sv_cast \$arg \s* , \s*
172             ( $bal_no_comma ) # Set from
173             ( $size )? # Possible sizeof set-from
174             \s* \) \s* ; \s* $
175             ]xo
176             );
177              
178 55         95 my $rv = undef;
179 55 100       108 if ($type) {
180 29         128 $rv = {
181             type => $type,
182             with_size => $with_size,
183             what => $arg,
184             what_size => $sarg,
185             };
186             }
187 55         92 $self->{targetable} = $rv;
188 55         254 return $rv;
189             }
190              
191             =head1 SEE ALSO
192              
193             L
194              
195             =head1 AUTHOR
196              
197             Steffen Mueller C<>
198              
199             =head1 COPYRIGHT & LICENSE
200              
201             Copyright 2009, 2010, 2011, 2012 Steffen Mueller
202              
203             This program is free software; you can redistribute it and/or
204             modify it under the same terms as Perl itself.
205              
206             =cut
207              
208             1;
209