File Coverage

blib/lib/Config/AutoConf/INI.pm
Criterion Covered Total %
statement 104 107 97.2
branch 24 28 85.7
condition 10 17 58.8
subroutine 20 21 95.2
pod 1 1 100.0
total 159 174 91.3


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