File Coverage

blib/lib/ExtUtils/XSBuilder/MapUtil.pm
Criterion Covered Total %
statement 36 139 25.9
branch 0 42 0.0
condition 0 12 0.0
subroutine 12 24 50.0
pod 0 6 0.0
total 48 223 21.5


line stmt bran cond sub pod time code
1             package ExtUtils::XSBuilder::MapUtil;
2              
3 1     1   5 use strict;
  1         2  
  1         31  
4 1     1   6 use warnings;
  1         2  
  1         22  
5 1     1   5 use Exporter ();
  1         1  
  1         15  
6 1     1   1352 use Data::Dumper ;
  1         25710  
  1         76  
7 1     1   1090 use IO::Handle ;
  1         8450  
  1         70  
8 1     1   10 use ExtUtils::XSBuilder::TypeMap ;
  1         2  
  1         173  
9              
10             our @EXPORT_OK = qw(list_first disabled_reason
11             function_table structure_table
12             callback_table callback_hash
13             );
14              
15             our @ISA = qw(Exporter);
16              
17             my %disabled_map = (
18             '!' => 'disabled or not yet implemented',
19             '~' => 'implemented but not auto-generated',
20             '-' => 'likely never be available to Perl',
21             '>' => '"private" to apache',
22             '?' => 'unclassified',
23             '+' => 'automaticly added',
24             );
25              
26             # ============================================================================
27              
28             my $function_table = [];
29              
30             sub function_table {
31 0 0   0 0   return $function_table if @$function_table;
32              
33 0           my $parsesource = shift -> parsesource_objects ;
34              
35 0           $function_table = [] ;
36              
37 0           foreach my $src (@$parsesource) {
38 0           require $src -> pm_path ('FunctionTable.pm') ;
39 1     1   6 no strict ;
  1         2  
  1         50  
40 0           push @$function_table, @${$src -> package . '::FunctionTable'} ;
  0            
41 1     1   6 use strict ;
  1         2  
  1         145  
42             }
43              
44 0           return $function_table;
45             }
46              
47             # ============================================================================
48              
49             my $callback_table = [];
50              
51             sub callback_table {
52 0 0   0 0   return $callback_table if @$callback_table;
53 0           my $parsesource = shift -> parsesource_objects ;
54              
55 0           $callback_table = [] ;
56              
57 0           foreach my $src (@$parsesource) {
58 0           require $src -> pm_path ('CallbackTable.pm') ;
59 1     1   6 no strict ;
  1         3  
  1         54  
60 0           push @$callback_table, @${$src -> package . '::CallbackTable'} ;
  0            
61 1     1   6 use strict ;
  1         2  
  1         183  
62             }
63 0           return $callback_table;
64             }
65              
66              
67             # ============================================================================
68              
69             my $callback_hash ;
70              
71             sub callback_hash {
72 0 0   0 0   return $callback_hash if $callback_hash ;
73              
74 0           my %callbacks = map { $_->{name}, $_ } @{ callback_table(shift) };
  0            
  0            
75              
76 0           $callback_hash = \%callbacks ;
77             }
78              
79             # ============================================================================
80              
81             my $structure_table = [];
82              
83             sub structure_table {
84 0 0   0 0   return $structure_table if @$structure_table;
85 0           $structure_table = [] ;
86              
87 0           my $parsesource = shift -> parsesource_objects ;
88 0           foreach my $src (@$parsesource) {
89 0           require $src -> pm_path ('StructureTable.pm') ;
90 1     1   6 no strict ;
  1         1  
  1         53  
91 0           push @$structure_table, @${$src -> package . '::StructureTable'} ;
  0            
92 1     1   11 use strict ;
  1         2  
  1         1242  
93             }
94 0           return $structure_table;
95             }
96              
97             # ============================================================================
98              
99             sub disabled_reason {
100 0 0   0 0   $disabled_map{+shift} || 'unknown';
101             }
102              
103              
104             # ============================================================================
105              
106             sub list_first (&@) {
107 0     0 0   my $code = shift;
108              
109 0           for (@_) {
110 0 0         return $_ if $code->();
111             }
112              
113 0           undef;
114             }
115              
116             # ============================================================================
117              
118             package ExtUtils::XSBuilder::MapBase;
119              
120             *function_table = \&ExtUtils::XSBuilder::function_table;
121             *structure_table = \&ExtUtils::XSBuilder::structure_table;
122              
123             sub readline {
124 0     0     my $fh = shift;
125              
126 0           while (<$fh>) {
127 0           chomp;
128 0           s/^\s+//; s/\s+$//;
  0            
129 0           s/^\#.*//;
130 0           s/\s*\#.*//;
131              
132 0 0         next unless $_;
133              
134 0 0         if (s:\\$::) {
135 0           my $cur = $_;
136 0           $_ = $cur . $fh->readline;
137 0           return $_;
138             }
139              
140 0           return $_;
141             }
142             }
143              
144             my $map_classes = join '|', qw(type structure function callback);
145              
146             sub map_files {
147 0     0     my $self = shift;
148 0   0       my $package = ref($self) || $self;
149              
150 0           my($wanted) = $package =~ /($map_classes)/io;
151              
152 0           my(@dirs) = ($self -> {wrapxs} -> xs_map_dir(), $self -> {wrapxs} -> xs_glue_dirs());
153              
154 0           my @files;
155              
156 0 0         my @searchdirs = map { -d "$_/maps" ? "$_/maps" : $_ } @dirs ;
  0            
157 0           for my $dir (@searchdirs) {
158 0 0         opendir my $dh, $dir or warn "opendir $dir: $!";
159              
160 0           for (readdir $dh) {
161 0 0         next unless /\.map$/;
162              
163 0           my $file = "$dir/$_";
164              
165 0 0         if ($wanted) {
166 0 0         next unless $file =~ /$wanted/i;
167             }
168              
169             #print "$package => $file\n";
170 0           push @files, $file;
171             }
172              
173 0           closedir $dh;
174             }
175              
176 0 0         print 'WARNING: No *_' . lc($wanted) . ".map file found in @searchdirs\n" if (!@files) ;
177 0           return @files;
178             }
179              
180             sub new_map_file {
181 0     0     my $self = shift;
182 0   0       my $package = ref($self) || $self;
183              
184 0           my($wanted) = $package =~ /($map_classes)/io;
185              
186 0           my(@dirs) = ($self -> {wrapxs} -> xs_map_dir(), $self -> {wrapxs} -> xs_glue_dirs());
187              
188 0           my @files;
189              
190 0 0         my @searchdirs = map { -d "$_/maps" ? "$_/maps" : $_ } @dirs ;
  0            
191            
192              
193 0 0         if (!@searchdirs)
194             {
195 0           print "WARNING: No maps directory found\n" ;
196 0           return undef ;
197             }
198              
199            
200 0           return $searchdirs[0] . '/new_' . lc($wanted) . '.map' ;
201             }
202              
203              
204             sub parse_keywords {
205 0     0     my($self, $line) = @_;
206 0           my %words;
207              
208 0           for my $pair (split /\s+/, $line) {
209 0           my($key, $val) = split /=/, $pair;
210              
211 0 0 0       unless ($key and $val) {
212 0           die "parse error ($ExtUtils::XSBuilder::MapFile line $.)";
213             }
214              
215 0           $words{$key} = $val;
216             }
217              
218 0           %words;
219             }
220              
221             sub parse_map_files {
222 0     0     my($self) = @_;
223              
224 0           my $map = {};
225              
226 0           for my $file (map_files($self)) {
227 0           print "Parse $file...\n" ;
228 0 0         open my $fh, $file or die "open $file: $!";
229 0           local $ExtUtils::XSBuilder::MapFile = $file;
230 0           bless $fh, __PACKAGE__;
231 0           $self->parse($fh, $map);
232 0           close $fh;
233             }
234              
235 0           return $map;
236             }
237              
238             sub write_map_file {
239 0     0     my($self, $newentries, $prefix) = @_;
240              
241 0 0 0       return if (!$newentries || !@$newentries) ;
242              
243 0 0         my $file = $self -> new_map_file or die ;
244              
245 0           print "Write $file...\n" ;
246 0 0         open my $fh, '>>', $file or die "open $file: $!";
247 0           local $ExtUtils::XSBuilder::MapFile = $file;
248             #bless $fh, __PACKAGE__;
249              
250 0           $fh -> print ( "\n### Added " . scalar(localtime) . " ###\n\n" );
251              
252 0           $self->write($fh, $newentries, $prefix);
253 0           close $fh;
254             }
255              
256              
257             1;
258             __END__