File Coverage

blib/lib/Plugins/SimpleConfig.pm
Criterion Covered Total %
statement 45 60 75.0
branch 15 34 44.1
condition 1 3 33.3
subroutine 8 9 88.8
pod 0 4 0.0
total 69 110 62.7


line stmt bran cond sub pod time code
1              
2             package Plugins::SimpleConfig;
3              
4 1     1   1211 use warnings;
  1         2  
  1         46  
5 1     1   5 use strict;
  1         3  
  1         32  
6 1     1   5 use Carp;
  1         3  
  1         202  
7 1     1   7 use Scalar::Util qw(reftype);
  1         2  
  1         247  
8              
9             our @ISA = qw(Exporter);
10             our @EXPORT = qw(simple_config_line simple_new);
11              
12             our %history;
13              
14             sub simple_config_line
15             {
16 1     1 0 7 my ($defaults, $plugin, $prefix, $configfile, $line, $lineno, $seqno) = @_;
17 1         3 my $callpkg = caller();
18 1 50       5 my $pkg = ref($plugin) ? ref($plugin) : $plugin;
19 1         2 my $debug = \0;
20             {
21 1     1   5 no strict qw(refs);
  1         3  
  1         2505  
  1         5  
22 1         2 $debug = \${"${pkg}::debug"};
  1         7  
23             }
24 1 50 33     33 $prefix eq '' or $line =~ s/^$prefix// or croak "unknown config line at $configfile:$lineno '$line'";
25 1 50       9 $line =~ /^(\S+)\s+(?:"(.*?)"|'(.*?)'|(\S+))\s*$/
26             or croak "Unknown config directive for $callpkg at $configfile:$lineno '$line'\n";
27 1         3 my $key = $1;
28 1         8 my $value = first_defined($2, $3, $4, '');
29              
30              
31 1 50       4 confess unless defined $key;
32 1 50       30 if (ref($defaults->{$key})) {
    50          
33 0         0 refassign($defaults, $key, $value, $plugin, $$debug);
34             } elsif (exists $defaults->{$key}) {
35 1 50       3 if (ref($plugin)) {
36 1         10 $plugin->{$key} = $value;
37             } else {
38             # these need to be saved for new()
39 0         0 $history{$plugin}{$configfile}{$seqno}{$key} = $value;
40 0         0 delete $history{$plugin}{$configfile}{$seqno - 1};
41             }
42             } else {
43 0         0 croak "Unknown config directive ($key) $callpkg at $configfile:$lineno '$line'\n";
44             }
45             }
46              
47             sub simple_new
48             {
49 4     4 0 26 my ($defaults, $pkg, $pconfig, %args) = @_;
50 4         8 my $context = $pconfig->{context};
51 4         23 my $self = bless { context => $context, api => $pconfig->{api} }, $pkg;
52 4         8 my $debug = $defaults->{debug};
53 4 50       11 $debug = $args{debug} if defined $args{debug};
54 4 50       10 print "new $pkg called\n" if $debug;
55              
56 4         14 for my $key (keys %$defaults) {
57 20 50       95 if (ref($defaults->{$key})) {
    100          
    50          
58 0 0       0 refassign($defaults, $key, $args{$key}, $self, $debug)
59             if exists $args{$key};
60             } elsif (exists $args{$key}) {
61 6         24 $self->{$key} = $args{$key};
62             } elsif (exists $history{$pkg}{$context->{configfile}}{$context->{seqno}}) {
63 0         0 $self->{$key} = $history{$pkg}{$context->{configfile}}{$context->{seqno}};
64             } else {
65 14         36 $self->{$key} = $defaults->{$key};
66             }
67 20         36 delete $args{$key};
68             }
69              
70 4         13 for my $key (keys %args) {
71 0         0 croak "unsupported argument to $pkg->new: $key ($context->{configfile}:$context->{lineno})";
72             }
73 4         21 return $self;
74             }
75              
76             sub refassign
77             {
78 0     0 0 0 my ($defaults, $key, $value, $pkgself, $debug) = @_;
79 0         0 my $ref = $defaults->{$key};
80 0 0       0 if (reftype($ref) eq 'SCALAR') {
    0          
    0          
81 0         0 $$ref = $value;
82             } elsif (reftype($ref) eq 'ARRAY') {
83 0         0 push(@$ref, $value);
84             } elsif (reftype($ref) eq 'CODE') {
85 0         0 &$ref($pkgself, $key, $value);
86             } else {
87 0         0 die;
88             }
89             }
90              
91             sub first_defined
92             {
93 1     1 0 3 for my $i (@_) {
94 3 100       16 return $i if defined $i;
95             }
96 0           return undef;
97             }
98              
99             1;
100              
101             =head1 NAME
102              
103             Plugins::SimpleConfig
104              
105             =head1 SYNOPSIS
106              
107             use Plugins::SimpleConfig;
108              
109             {
110             simple_config_line(\%config_items, @_);
111             }
112              
113             sub new
114             {
115             simple_new(\%config_items, @_);
116             }
117              
118             =head1 DESCRIPTION
119              
120             Plugins::SimpleConfig handles the configuration needs of
121             L plugins
122             that do not have complex configuration requirements.
123              
124             It understands a couple of different kinds of items things
125             (as deteremined by the C of the value in the
126             C<%config_items> hash):
127              
128             =over 10
129              
130             =item SCALAR
131              
132             What you would expect.
133              
134             =item ARRAY
135              
136             It pushes the new value onto the end of the array.
137              
138             =item CODE
139              
140             It calls the function with the following arguments:
141              
142             =over 10
143              
144             =item $pkgself
145              
146             Either the class name or an instance object depending on when
147             it was called. It will usually be an instance object.
148              
149             =item $key
150              
151             The configuration item being set.
152              
153             =item $value
154              
155             The new value.
156              
157             =back
158              
159             =back
160              
161             =head1 HOW TO USE IT
162              
163             First, create a hash (C<%config_items>) that maps configuration names
164             to references to configuration variables.
165              
166             Second, include the code from the L in your plugin:
167              
168             use Plugins::SimpleConfig;
169              
170             my $config_var1 = 'value1';
171             my $config_var2 = 'value2';
172              
173             my %config_items = (
174             var1 => \$config_var1;
175             var2 => \$config_var2;
176             );
177              
178             sub config_prefix { return 'myname_' };
179              
180             sub parse_config_line
181             {
182             simple_config_line(\%config_items, @_);
183             }
184              
185             sub new
186             {
187             simple_new(\%config_items, @_);
188             }
189