File Coverage

blib/lib/Config/AutoConf/INI.pm
Criterion Covered Total %
statement 112 114 98.2
branch 25 30 83.3
condition 11 20 55.0
subroutine 23 23 100.0
pod 1 1 100.0
total 172 188 91.4


line stmt bran cond sub pod time code
1 1     1   29221 use strict;
  1         1  
  1         24  
2 1     1   3 use warnings FATAL => 'all';
  1         2  
  1         37  
3              
4             package Config::AutoConf::INI;
5 1     1   3 use Carp qw/croak/;
  1         1  
  1         65  
6 1     1   670 use Config::AutoConf 0.313 qw//;
  1         21045  
  1         26  
7 1     1   384 use Config::Tiny::Ordered qw//;
  1         1557  
  1         21  
8 1     1   4 use File::Basename qw/fileparse/;
  1         1  
  1         48  
9 1     1   4 use File::Path qw//;
  1         1  
  1         14  
10 1     1   3 use Scalar::Util qw/looks_like_number blessed/;
  1         1  
  1         36  
11 1     1   3 use parent qw/Config::AutoConf/;
  1         1  
  1         6  
12              
13             # ABSTRACT: Drive Config::AutoConf with an INI file
14              
15             our $VERSION = '0.005'; # VERSION
16              
17             our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY
18              
19             our $_make_path;
20             BEGIN {
21             #
22             # Old versions of File::Path does not provide make_path, but the legacy mkpath
23             #
24 1   33 1   908 $_make_path = File::Path->can('make_path') || File::Path->can('mkpath');
25             }
26              
27              
28             sub check {
29 2     2 1 1452 my ($self, $config_ini) = @_;
30              
31 2   50     8 $config_ini //= 'config_autoconf.ini';
32              
33 2 100       22 $self = __PACKAGE__->new() unless blessed $self;
34              
35             #
36             # Internal setup
37             #
38 2         66 $self->{_headers_order} = 0;
39 2         7 $self->{_headers_ok} = {};
40 2 50       27 $self->{_config_ini} = $config_ini ? Config::Tiny::Ordered->read($config_ini) : {};
41              
42             #
43             # Setup
44             #
45 2         1229 $self->_process_from_config(section => 'includes', stub_name => 'push_includes');
46 2         5 $self->_process_from_config(section => 'preprocess_flags', stub_name => 'push_preprocess_flags');
47 2         5 $self->_process_from_config(section => 'compiler_flags', stub_name => 'push_compiler_flags');
48 2         4 $self->_process_from_config(section => 'link_flags', stub_name => 'push_link_flags');
49              
50             #
51             # Run - the order has been choosen carefully
52             #
53 2         5 $self->_process_from_config(section => 'files', stub_name => 'check_file',
54             force_msg => 'file %s');
55 2         17 $self->_process_from_config(section => 'progs', stub_name => 'check_prog',
56             stub_names => {
57             #
58             # Specific implementations
59             #
60             yacc => 'check_prog_yacc',
61             awk => 'check_prog_awk',
62             egrep => 'check_prog_egrep',
63             lex => 'check_prog_lex',
64             sed => 'check_prog_sed',
65             pkg_config => 'check_prog_pkg_config',
66             cc => 'check_prog_cc'
67             }
68             );
69 2         26 $self->_process_from_config(section => 'headers', stub_name => 'check_header', args => \&_args_check_header);
70 2         14 $self->_process_from_config(section => 'bundle', stub_name => '_check_bundle');
71 2         17 $self->_process_from_config(section => 'decls', stub_name => 'check_decl', args => \&_args_check);
72 2         33 $self->_process_from_config(section => 'funcs', stub_name => 'check_func', args => \&_args_check);
73 2         21 $self->_process_from_config(section => 'types', stub_name => 'check_type', args => \&_args_check);
74 2         19 $self->_process_from_config(section => 'sizeof_types', stub_name => 'check_sizeof_type', args => \&_args_check);
75 2         18 $self->_process_from_config(section => 'alignof_types', stub_name => 'check_alignof_type', args => \&_args_check);
76 2         17 $self->_process_from_config(section => 'members', stub_name => 'check_member', args => \&_args_check);
77              
78 2         14 $self->_process_from_config(section => 'outputs', stub_name => '_write_config_h');
79              
80 2         3 map { delete $self->{$_} } qw/_config_ini _headers_ok _headers_order/;
  6         123  
81              
82 2         24 $self;
83             }
84              
85             #
86             # Bundle check
87             #
88             sub _check_bundle {
89 6     6   9 my ($self, $bundle) = @_;
90              
91 6         21 my @args = $self->_args_check_headers;
92              
93 6 100       35 if ($bundle eq 'stdc_headers') {
    100          
    50          
94 2         37 $self->check_stdc_headers(@args)
95             } elsif ($bundle eq 'default_headers') {
96 2         34 $self->check_default_headers(@args)
97             } elsif ($bundle eq 'dirent_headers') {
98 2         49 $self->check_dirent_header(@args)
99             }
100             }
101              
102             #
103             # We want to make sure that the dirname of path exist
104             #
105             sub _write_config_h {
106 4     4   8 my ($self, $path) = @_;
107              
108             #
109             # We do not mind about suffixes, only directory name
110             # Note that File::Basename says that fileparse()
111             # should be used instead of dirname()
112             #
113 4         117 my ($filename, $dirs, $suffix) = fileparse($path);
114 4 50       10 if ($dirs) {
115 4         323 &$_make_path($dirs); # This will croak in case of failure
116             }
117 4         39 $self->write_config_h($path);
118             }
119              
120             #
121             # Config::AutoConf does not honor all the found headers, so we generate
122             # ourself the prologue
123             #
124             sub _ordered_headers {
125 28     28   33 my ($self) = @_;
126              
127 28         33 my @rc = sort { $self->{_headers_ok}->{$a} <=> $self->{_headers_ok}->{$b} } keys %{$self->{_headers_ok}};
  1280         1158  
  28         323  
128             return @rc
129 28         110 }
130              
131             sub _prologue {
132 28     28   32 my ($self) = @_;
133              
134 28         110 my $prologue = join("\n", map { "#include <$_>" } $self->_ordered_headers) . "\n";
  398         544  
135              
136 28         142 return $prologue
137             }
138              
139             #
140             # Standard option, containing prologue
141             #
142             sub _args_option {
143 28     28   40 my ($self) = @_;
144              
145 28         88 return { prologue => $self->_prologue }
146             }
147              
148             #
149             # Standard list of arguments: the original one and a hash containing the prologue
150             #
151             sub _args_check {
152 22     22   52 my ($self, $check) = @_;
153              
154 22         74 return ($check, $self->_args_option())
155             }
156              
157             #
158             # For headers, we want to remember ourself those that are ok for the prologue generation
159             #
160             sub _header_ok {
161 48     48   221 my ($self, @headers) = @_;
162              
163 48 50       110 map { $self->{_headers_ok}->{$_} = $self->{_headers_order}++ unless exists $self->{_headers_ok}->{$_} } @headers
  48         775  
164             }
165              
166             sub _args_check_header {
167 10     10   29 my ($self, $header) = @_;
168              
169 10         34 my @args_check = $self->_args_check($header);
170 10     10   61 $args_check[1]->{action_on_true} = sub { $self->_header_ok($header) };
  10         391082  
171              
172             return @args_check
173 10         17 }
174              
175             #
176             # For check_headers callback, semantic is different
177             #
178             sub _args_check_headers {
179 6     6   9 my ($self) = @_;
180              
181 6         18 my @args_check = ($self->_args_option());
182 6     38   35 $args_check[1]->{action_on_header_true} = sub { $self->_header_ok(@_) };
  38         1235748  
183              
184             return @args_check
185 6         19 }
186              
187             sub _process_from_config {
188 30     30   117 my ($self, %args) = @_;
189              
190 30   33     97 my $section = $args{section} || croak 'Internal error, section not set';
191 30   33     68 my $stub_name = $args{stub_name} || croak 'Internal error, stub_name not set';
192 30   100     167 my $stub_names = $args{stub_names} // {};
193 30   100     116 my $force_msg = $args{force_msg} // '';
194 30         30 my $args = $args{args};
195              
196 30         55 my $sectionp = $self->{_config_ini}->{$section};
197 30   50     68 $sectionp //= [];
198              
199 30         35 foreach (@{$sectionp}) {
  30         64  
200 54         627 my $key = $_->{'key'};
201 54         113 my $rhs = $_->{'value'};
202             #
203             # No check if rhs is not a true value
204             #
205 54 100       98 next unless $rhs;
206              
207             #
208             # Get the implementation
209             #
210 52   66     219 my $stub_realname = $stub_names->{$key} || $stub_name;
211 52         386 my $stub_code = $self->can($stub_realname);
212 52 50       119 if (! $stub_code) {
213             #
214             # We warn because this should not happen
215             #
216 0         0 warn "$self cannot \"$stub_realname\"";
217 0         0 next;
218             }
219              
220             #
221             # If there is an explicit implementation it is assumed
222             # that it is handling itself any message
223             #
224 52 100       100 $force_msg = '' if $stub_realname ne $stub_name;
225              
226             #
227             # Do the work
228             #
229 52 100       127 $self->msg_checking(sprintf($force_msg, $key)) if $force_msg;
230 52 100       686 my @args = $args ? $self->$args($key) : ($key);
231 52         188 my $value = $self->$stub_code(@args);
232 52 100       4181738 $self->define_var($rhs, $value) unless looks_like_number($rhs);
233 52 100       469 $self->msg_result($value ? 'yes' : 'no') if $force_msg;
    100          
234             }
235              
236             $self
237 30         302 }
238              
239              
240             1;
241              
242             __END__