File Coverage

lib/MKDoc/Control_List.pm
Criterion Covered Total %
statement 71 71 100.0
branch 9 12 75.0
condition 6 11 54.5
subroutine 13 13 100.0
pod 0 2 0.0
total 99 109 90.8


line stmt bran cond sub pod time code
1             # ------------------------------------------------------------------
2             # MKDoc::Control_List
3             # ------------------------------------------------------------------
4             # Author: Jean-Michel Hiver
5             # Description: Access Control List generalization
6             # ------------------------------------------------------------------
7             package MKDoc::Control_List;
8 2     2   72389 use strict;
  2         5  
  2         67  
9 2     2   11 use warnings;
  2         5  
  2         2855  
10              
11             our $VERSION = '0.31';
12              
13              
14             sub new
15             {
16 2     2 0 23 my $class = shift;
17 2         13 return bless { @_ }, $class;
18             }
19              
20              
21             sub process
22             {
23 4     4 0 870 my $self = shift;
24 4         14 $self->{'caller'} = caller;
25 4         15 my $code = $self->_compile();
26 4         81 my @res = $code->();
27 4         16 return @res;
28             }
29              
30              
31             sub _read_data
32             {
33 2     2   4 my $self = shift;
34 2   66     20 return $self->{data} || $self->_read_file();
35             }
36              
37              
38             sub _read_file
39             {
40 1     1   2 my $self = shift;
41 1         2 my $file = $self->{file};
42 1   50     47 open FP, "<:utf8", $file || die "Cannot read-open $file. Reason: $@";
43 1         39 my $data = join '', ;
44 1         10 close FP;
45 1         6 return $data;
46             }
47              
48              
49             sub _compile
50             {
51 4     4   6 my $self = shift;
52 4   66     18 $self->{_code} ||= do {
53 2         9 my $code = $self->_build_code();
54 2         4 my $VAR1 = undef;
55 2         454 eval $code;
56 2 50       25 $@ && die $@;
57 2         10 $VAR1;
58             };
59            
60 4         10 return $self->{_code};
61             }
62              
63              
64             sub _build_code
65             {
66 2     2   3 my $self = shift;
67 2         7 my $data = $self->_read_data();
68 2         5 my @res = ();
69            
70 2         8 push @res, $self->_build_code_header();
71 2         4 my $count = 0;
72 2         19 foreach my $line (split /\n/, $data)
73             {
74 22         24 $count++;
75 22         29 chomp ($line);
76 22         37 $line =~ s/^\s+//;
77 22         58 $line =~ s/\s+$//;
78 22 50       50 $line =~ /^#/ && next;
79 22 100       37 $line || next;
80            
81             push @res, $self->_build_code_condition ($line) ||
82             $self->_build_code_ret_value ($line) ||
83 18   33     42 $self->_build_code_rule ($line) || do {
84             warn "Cannot parse line $count.\n$line";
85             next;
86             };
87             }
88 2         9 push @res, $self->_build_code_footer();
89 2         12 return join "\n", @res;
90             }
91              
92              
93             sub _build_code_header
94             {
95 2     2   4 my $self = shift;
96 2         4 my $caller = $self->{'caller'};
97             return (
98 2         8 "\$VAR1 = sub { package $caller;",
99             );
100             }
101              
102              
103             sub _build_code_condition
104             {
105 21     21   950 my $self = shift;
106 21         25 my $line = shift;
107 21 100       99 $line =~ /^\s*CONDITION\s+/ || return;
108 7         65 $line =~ s/^\s*CONDITION\s+(\w+)\s+(.*)$/my \$cnd_$1 = do { $2 };/;
109 7         46 return $line;
110             }
111              
112              
113             sub _build_code_ret_value
114             {
115 16     16   23 my $self = shift;
116 16         18 my $line = shift;
117 16 100       77 $line =~ /^\s*RET_VALUE\s+/ || return;
118 7         51 $line =~ s/^\s*RET_VALUE\s+(\w+)\s+(.*)$/my \$ret_$1 = do { $2 };/;
119 7         43 return $line;
120             }
121              
122              
123             sub _build_code_rule
124             {
125 9     9   12 my $self = shift;
126 9         12 my $line = shift;
127 9 50       51 $line =~ /^\s*RULE\s+.+?\s+WHEN\s+.+\s*/ || return;
128              
129 9         115 my ($ret_values, $conditions) = $line =~ /^\s*RULE\s+(.+?)\s+WHEN\s+(.+?)\s*$/;
130 9         39 my @ret_values = $ret_values =~ /(\w+)/g;
131 9         32 my @conditions = $conditions =~ /(\w+)/g;
132            
133 9         15 my $code = join ' && ', map { "\$cnd_$_" } @conditions;
  16         59  
134 9         32 $code .= ' && return ( ' . join ', ', map { "\$ret_$_" } @ret_values;
  15         36  
135 9         14 $code .= ' );';
136 9         52 return $code;
137             }
138              
139              
140             sub _build_code_footer
141             {
142 2     2   6 my $self = shift;
143 2         6 return ( 'return;',
144             '};' );
145             }
146              
147              
148             1;
149              
150              
151             __END__