File Coverage

blib/lib/ctflags.pm
Criterion Covered Total %
statement 64 80 80.0
branch 10 18 55.5
condition n/a
subroutine 16 19 84.2
pod 2 7 28.5
total 92 124 74.1


line stmt bran cond sub pod time code
1             package ctflags;
2              
3             our $VERSION = '0.04';
4              
5 1     1   26002 use 5.006;
  1         4  
  1         35  
6              
7 1     1   6 use strict;
  1         2  
  1         36  
8 1     1   5 use warnings;
  1         7  
  1         30  
9              
10 1     1   5 use Carp;
  1         1  
  1         82  
11              
12 1     1   539 use ctflags::memory;
  1         3  
  1         73  
13 1     1   4 use ctflags::check;
  1         2  
  1         170  
14              
15 1     1   5 use constant PREFIX => "ctflag_";
  1         1  
  1         245  
16              
17             # set and get functions are wrappers around
18             # ctflags::memory::(set|get)_ctflag, wrappers capture errors an report
19             # them via croak
20              
21             sub set ($$$ ) {
22 4     4 1 3023 eval { &set_ctflag };
  4         11  
23 4 50       196 if ($@) { chomp $@; croak $@ };
  0         0  
  0         0  
24             }
25              
26             sub get ($$ ) {
27 7     7 1 15 my $r=eval { &get_ctflag };
  7         18  
28 7 50       16 if ($@) { chomp $@; croak $@ };
  0         0  
  0         0  
29 7         28 return $r;
30             }
31              
32              
33             # parse_flags breaks a string defining a flag set maybe with default
34             # values. If strings is '*' it expand it to all the flags allowed in
35             # the namespace (allowed ctflags are not the flags defined but the
36             # ones configured with ctflags::memory::restrict_ctflags() subrutine).
37              
38             sub parse_flags ($$) {
39 4     4 0 6 my ($ns, $flags)=@_;
40 4 50       10 return allowed_ctflags($ns)
41             if $flags eq '*';
42              
43 4         33 return ($flags=~/\G$flag_re$value_re?/go)
44             }
45              
46              
47             # export_sub creates the constant subrutine in the given package
48              
49             sub export_sub ($$$ ) {
50 8     8 0 11 my $qname=$_[0].'::'.$_[1];
51 8         7 my $value=$_[2];
52              
53 1     1   10 no strict 'refs';
  1         1  
  1         77  
54 8     0   84 *$qname = sub () { $value };
  0         0  
55             }
56              
57             sub export_subsub ($$$ ) {
58 0     0 0 0 my $qname=$_[0].'::'.$_[1];
59 0         0 my $sub=$_[2];
60              
61 1     1   5 no strict 'refs';
  1         1  
  1         500  
62 0         0 *$qname = $sub
63             }
64              
65             # export_ctflags_as combine ctflag set with arithmetic or and export
66             # constant with the resulting value
67              
68             sub export_ctflags_as ($$$$) {
69 2     2 0 8 my ($package, $ns, $flags, $name)=@_;
70 2         3 my $acu=0;
71 2         3 $acu|=get_ctflag($ns, $_) foreach (parse_flags $ns, $flags);
72 2         6 export_sub $package, $name, $acu;
73             }
74              
75              
76             # export every flag specified in $flags as package::prefix_flag
77              
78             sub export_ctflags ($$$$) {
79 2     2 0 3 my ($package, $ns, $flags, $prefix)=@_;
80 2         4 foreach my $fe (parse_flags $ns, $flags) {
81 6         15 my ($f)=split '', $fe;
82 6         14 my $v=get_ctflag($ns, $fe);
83 6         24 my $sub=get_ctflag_call($ns, $f);
84 6 50       11 if ($sub) {
85 0     0   0 export_subsub $package, $prefix,
86 0         0 sub () {&$sub($ns, $f, $v); $v}
87 0         0 }
88             else {
89 6         14 export_sub $package, $prefix.$f, $v;
90             }
91             }
92             }
93              
94              
95             # see pod docs below for import description.
96              
97             sub import {
98 4     4   25 my $self=shift;
99 4         5 my $prefix=PREFIX; # prefix to use until another one is defined.
100 4         9 my ($package)=caller; # by default constants are exported to calling
101             # package
102 4         6 eval {
103 4         11 while (@_) {
104 5         5 my $key=shift;
105 5 100       127 if (my ($name, $ns, $flags)=
    50          
    0          
106             $key=~m{^ # all the string should match.
107             (?:($identifier_re)=)? # name for the constant, optional.
108             ($ns_re) # namespace.
109             : # namespace/flags separator ':'
110             (
111             \* # asterisk
112             | # or
113             (?:$flag_re # flag name
114             $value_re?) # maybe with default value,
115             * # several allowed
116             )$
117             }xo ) {
118             # option is a ctflags -> constants conversion specification.
119 4 100       6 if ($name) {
120 2         6 export_ctflags_as($package, $ns, $flags, $name)
121             }
122             else {
123 2         5 export_ctflags($package, $ns, $flags, $prefix)
124             }
125             }
126             elsif ($key eq 'prefix') {
127 1         1 $prefix=shift;
128 1         4 check_cntprefix $prefix;
129             }
130             elsif ($key eq 'package') {
131 0         0 $package=shift;
132 0         0 check_package $package;
133             }
134             else {
135 0         0 die "unknow option or invalid ctflags specification '$key'\n";
136             }
137             }
138             };
139 4 50       1691 if ($@) { chomp $@; croak $@ };
  0            
  0            
140             }
141              
142              
143             1;
144             __END__