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   282 use 5.006001;
  15         53  
3 15     15   83 use strict;
  15         29  
  15         369  
4 15     15   85 use warnings;
  15         39  
  15         9166  
5             our $VERSION = '3.43_02';
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 21209 my $prot = shift;
35 2408   66     5596 my $class = ref($prot)||$prot;
36 2408         4331 my %args = @_;
37              
38 2408 100       4207 if (!ref($prot)) {
39 841 50 33     2643 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       8325 my $self = bless(
45             (ref($prot) ? {%$prot} : {})
46             => $class
47             );
48              
49 2408 100       5651 $self->{xstype} = $args{xstype} if defined $args{xstype};
50 2408 100       4722 $self->{code} = $args{code} if defined $args{code};
51 2408         5935 $self->{code} =~ s/^(?=\S)/\t/mg;
52              
53 2408         6212 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 189 50   189 1 393 $_[0]->{code} = $_[1] if @_ > 1;
64 189         507 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 8503 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 14     14 1 24 my $self = shift;
86 14         35 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 14         29 $code =~ s/^\s+#/#/mg;
91 14         174 $code =~ s/\s*\z/\n/;
92              
93 14         44 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 105     105 1 273 my $self = shift;
129 105 100       383 return $self->{targetable} if exists $self->{targetable};
130              
131 54         65 our $bal; # ()-balanced
132             $bal = qr[
133             (?:
134             (?>[^()]+)
135             |
136             \( (??{ $bal }) \)
137             )*
138 54         433 ]x;
139             my $bal_no_comma = qr[
140             (?:
141             (?>[^(),]+)
142             |
143             \( (??{ $bal }) \)
144             )+
145 54         187 ]x;
146              
147             # matches variations on (SV*)
148 54         135 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 54         210 ]xo;
157              
158 54         116 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   145 use re 'eval';
  15         51  
  15         2112  
163              
164 54         586 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 54         111 my $rv = undef;
179 54 100       104 if ($type) {
180 29         135 $rv = {
181             type => $type,
182             with_size => $with_size,
183             what => $arg,
184             what_size => $sarg,
185             };
186             }
187 54         122 $self->{targetable} = $rv;
188 54         285 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