File Coverage

blib/lib/Config/AutoConf/INI.pm
Criterion Covered Total %
statement 111 113 98.2
branch 25 30 83.3
condition 10 17 58.8
subroutine 22 22 100.0
pod 1 1 100.0
total 169 183 92.3


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