File Coverage

blib/lib/assertions.pm
Criterion Covered Total %
statement 50 61 81.9
branch 46 60 76.6
condition 12 12 100.0
subroutine 6 7 85.7
pod 2 2 100.0
total 116 142 81.6


line stmt bran cond sub pod time code
1             package assertions;
2              
3             our $VERSION = '0.03';
4              
5             # use strict;
6             # use warnings;
7              
8             my $hint=0x01000000;
9             my $seen_hint=0x02000000;
10              
11             sub _syntax_error ($$) {
12 5     5   7 my ($expr, $why)=@_;
13 5         28 require Carp;
14 5         2616 Carp::croak("syntax error on assertion filter '$expr' ($why)");
15             }
16              
17             sub _carp {
18 2     2   10 require warnings;
19 2 50       199 if (warnings::enabled('assertions')) {
20 0         0 require Carp;
21 0         0 Carp::carp(@_);
22             }
23             }
24              
25             sub _calc_expr {
26 42     42   319 my $expr=shift;
27 42         280 my @tokens=split / \s*
28             ( && # and
29             | \|\| # or
30             | \( # parents
31             | \) )
32             \s*
33             | \s+ # spaces out
34             /x, $expr;
35              
36             # print STDERR "tokens: -", join('-',@tokens), "-\n";
37              
38 42         63 my @now=1;
39 42         68 my @op='start';
40              
41 42         61 for my $t (@tokens) {
42 161 100 100     563 next if (!defined $t or $t eq '');
43              
44 137 100       198 if ($t eq '(') {
45 13         15 unshift @now, 1;
46 13         21 unshift @op, 'start';
47             }
48             else {
49 124 100       233 if ($t eq '||') {
    100          
50 12 100       25 defined $op[0]
51             and _syntax_error $expr, 'consecutive operators';
52 11         18 $op[0]='||';
53             }
54             elsif ($t eq '&&') {
55 25 100       51 defined $op[0]
56             and _syntax_error $expr, 'consecutive operators';
57 24         39 $op[0]='&&';
58             }
59             else {
60 87 100 100     313 if ($t eq ')') {
    100          
    100          
61 13 100       44 @now==1 and
62             _syntax_error $expr, 'unbalanced parens';
63 12 50       20 defined $op[0] and
64             _syntax_error $expr, "key missing after operator '$op[0]'";
65              
66 12         18 $t=shift @now;
67 12         13 shift @op;
68             }
69             elsif ($t eq '_') {
70 8 100       25 unless ($^H & $seen_hint) {
71 2         4 _carp "assertion status '_' referenced but not previously defined";
72             }
73 8 100       20 $t=($^H & $hint) ? 1 : 0;
74             }
75             elsif ($t ne '0' and $t ne '1') {
76 22 50       38 $t = ( grep { ref $_ eq 'Regexp'
  92 100       375  
77             ? $t=~$_
78             : $_->check($t)
79             } @{^ASSERTING} ) ? 1 : 0;
80             }
81              
82 86 50       147 defined $op[0] or
83             _syntax_error $expr, 'operator expected';
84              
85 86 100       278 if ($op[0] eq 'start') {
    100          
86 54         74 $now[0]=$t;
87             }
88             elsif ($op[0] eq '||') {
89 11   100     31 $now[0]||=$t;
90             }
91             else {
92 21   100     73 $now[0]&&=$t;
93             }
94 86         148 undef $op[0];
95             }
96             }
97             }
98 39 100       91 @now==1 or _syntax_error $expr, 'unbalanced parens';
99 38 100       67 defined $op[0] and _syntax_error $expr, "expression ends on operator '$op[0]'";
100              
101 37         125 return $now[0];
102             }
103              
104              
105             sub import {
106             # print STDERR "\@_=", join("|", @_), "\n";
107 14     14   175 shift;
108 14 100       34 @_=(scalar(caller)) unless @_;
109 14         28 foreach my $expr (@_) {
110 14 100       25 unless (_calc_expr $expr) {
111             # print STDERR "assertions deactived";
112 4         9 $^H &= ~$hint;
113 4         7 $^H |= $seen_hint;
114 4         171 return;
115             }
116             }
117             # print STDERR "assertions actived";
118 10         523 $^H |= $hint|$seen_hint;
119             }
120              
121             sub unimport {
122 1 50   1   11 @_ > 1
123             and _carp($_[0]."->unimport arguments are being ignored");
124 1         1772 $^H &= ~$hint;
125             }
126              
127             sub enabled {
128 6 50   6 1 27 if (@_) {
129 0 0       0 if ($_[0]) {
130 0         0 $^H |= $hint;
131             }
132             else {
133 0         0 $^H &= ~$hint;
134             }
135 0         0 $^H |= $seen_hint;
136             }
137 6 100       19 return $^H & $hint ? 1 : 0;
138             }
139              
140             sub seen {
141 0 0   0 1   if (@_) {
142 0 0         if ($_[0]) {
143 0           $^H |= $seen_hint;
144             }
145             else {
146 0           $^H &= ~$seen_hint;
147             }
148             }
149 0 0         return $^H & $seen_hint ? 1 : 0;
150             }
151              
152             1;
153              
154             __END__