File Coverage

blib/lib/SystemC/Vregs/Rules.pm
Criterion Covered Total %
statement 66 129 51.1
branch 12 46 26.0
condition 3 17 17.6
subroutine 19 47 40.4
pod 12 34 35.2
total 112 273 41.0


line stmt bran cond sub pod time code
1             # See copyright, etc in below POD section.
2             ######################################################################
3              
4             package SystemC::Vregs::Rules;
5 3     3   16 use vars qw ($Default_Self $VERSION);
  3         6  
  3         142  
6 3     3   14 use Carp;
  3         5  
  3         167  
7 3     3   14 use strict;
  3         6  
  3         5523  
8              
9             $VERSION = '1.470';
10              
11             ######################################################################
12             # Default rules
13              
14             sub _default_rules {
15             before_file_body
16             (prog=> sub {
17 0     0   0 my ($self,$name) = @_;
18 0 0       0 fprint ("#include \n") if fhandle()->{CPP};
19 0         0 fprint ("#include /*ntoh*/\n"
20             ."#include /*uint32_t*/\n"
21             ."#include \n"
22             ."#include \n"
23             );
24 1     1   10 });
25             before_defines_file
26             (prog=> sub {
27 1     1   2 my ($self,$name) = @_;
28 1 50 33     5 fprint ("#include \n") if (fhandle()->{CPP} || fhandle()->{C} || fhandle()->{Gas});
      33        
29 1         9 });
30             before_enum_end
31             (prog=> sub {
32 0     0   0 my ($self,$name) = @_;
33 0 0       0 if (fhandle()->{CPP}) {
34 0         0 fprint (" enum en m_e;\n"
35             ." inline ${name} () VREGS_ENUM_DEF_INITTER(MAX) {}\n"
36             ." inline ${name} (en _e) : m_e(_e) {}\n"
37             ." explicit inline ${name} (int _e) : m_e(static_cast(_e)) {}\n"
38             ." operator const char* () const { return ascii(); }\n"
39             ." operator en () const { return m_e; }\n"
40             ." const char* ascii() const;\n"
41             ." inline bool valid() const { return *ascii()!='?'; }\n"
42             );
43 0 0       0 if ($self->attribute_value('descfunc')) {
44 0         0 fprint (" const char* description() const;\n");
45             }
46 0   0     0 fprint (" class iterator {\n"
47             ." en m_e; public:\n"
48             ." inline iterator(en item) : m_e(item) {}\n"
49             ." iterator operator++();\n"
50             ." inline operator ${name} () const { return ${name}(m_e); }\n"
51             ." inline ${name} operator*() const { return ${name}(m_e); }\n"
52             ." };\n"
53             ." static iterator begin() { return iterator(".($self->fields_first_name||"MAX")."); }\n"
54             ." static iterator end() { return iterator(MAX); }\n"
55             );
56             }
57 1         9 });
58             before_class_dump
59             (prog => sub {
60 0     0   0 $SystemC::Vregs::Do_Dump = 1;
61 1         9 });
62             after_class_dump
63             (prog => sub {
64 0     0   0 my ($self,$name,$dumparef) = @_; my @dumps = @{$dumparef};
  0         0  
  0         0  
65 0 0       0 unshift @dumps, "(($self->{inherits}*)(this))->dump(pf)" if $self->{inherits};
66 0 0       0 if ($#dumps>=0) {
67 0         0 fprint(" lhs<<", join("\n\t<
68             }
69 1         10 });
70             after_enum_end
71             (prog=> sub {
72 0     0   0 my ($self,$name) = @_;
73 0 0       0 if (fhandle()->{CPP}) {
74 0         0 fprint(" inline bool operator== (${name} lhs, ${name} rhs) { return (lhs.m_e == rhs.m_e); }\n",
75             " inline bool operator== (${name} lhs, ${name}::en rhs) { return (lhs.m_e == rhs); }\n",
76             " inline bool operator== (${name}::en lhs, ${name} rhs) { return (lhs == rhs.m_e); }\n",
77             " inline bool operator!= (${name} lhs, ${name} rhs) { return (lhs.m_e != rhs.m_e); }\n",
78             " inline bool operator!= (${name} lhs, ${name}::en rhs) { return (lhs.m_e != rhs); }\n",
79             " inline bool operator!= (${name}::en lhs, ${name} rhs) { return (lhs != rhs.m_e); }\n",
80             " inline bool operator< (${name} lhs, ${name} rhs) { return lhs.m_e < rhs.m_e; }\n",
81             " inline OStream& operator<< (OStream& lhs, const ${name}& rhs) { return lhs << rhs.ascii(); }\n"
82             );
83             }
84 1         17 });
85             }
86              
87             ######################################################################
88             # Rules the __rules.pl file calls
89              
90 0     0 1 0 sub before_any_file { _declare_rule (rule=>'any_file_before', @_); }
91 0     0 1 0 sub after_any_file { _declare_rule (rule=>'any_file_after', @_); }
92 1     1 0 4 sub before_defines_file {_declare_rule (rule=>'defines_file_before', @_); }
93 0     0 0 0 sub after_defines_file {_declare_rule (rule=>'defines_file_after', @_); }
94 0     0 0 0 sub before_info_cpp_file{_declare_rule (rule=>'info_cpp_file_before', @_); }
95 0     0 0 0 sub after_info_cpp_file{_declare_rule (rule=>'info_cpp_file_after', @_); }
96 1     1 1 6 sub before_file_body {_declare_rule (rule=>'file_body_before', @_); }
97 0     0 1 0 sub after_file_body {_declare_rule (rule=>'file_body_after', @_); }
98 0     0 0 0 sub before_class_cpp_file{_declare_rule (rule=>'class_cpp_file_before', @_); }
99 0     0 0 0 sub after_class_cpp_file{_declare_rule (rule=>'class_cpp_file_after', @_); }
100 0     0 0 0 sub before_class_begin { _declare_rule (rule=>'class_begin_before', @_); }
101 0     0 1 0 sub after_class_begin { _declare_rule (rule=>'class_begin_after', @_); }
102 0     0 1 0 sub before_class_end { _declare_rule (rule=>'class_end_before', @_); }
103 0     0 1 0 sub after_class_end { _declare_rule (rule=>'class_end_after', @_); }
104 0     0 0 0 sub before_class_cpp { _declare_rule (rule=>'class_cpp_before', @_); }
105 0     0 0 0 sub after_class_cpp { _declare_rule (rule=>'class_cpp_after', @_); }
106 1     1 0 5 sub before_class_dump { _declare_rule (rule=>'class_dump_before', @_); }
107 1     1 0 10 sub after_class_dump { _declare_rule (rule=>'class_dump_after', @_); }
108 0     0 0 0 sub before_enum_begin { _declare_rule (rule=>'enum_begin_before', @_); }
109 0     0 1 0 sub after_enum_begin { _declare_rule (rule=>'enum_begin_after', @_); }
110 1     1 1 5 sub before_enum_end { _declare_rule (rule=>'enum_end_before', @_); }
111 1     1 1 4 sub after_enum_end { _declare_rule (rule=>'enum_end_after', @_); }
112 0     0 0 0 sub before_enum_cpp { _declare_rule (rule=>'enum_cpp_before', @_); }
113 0     0 0 0 sub after_enum_cpp { _declare_rule (rule=>'enum_cpp_after', @_); }
114              
115             ######################################################################
116             # Functions that rule subroutines may call
117              
118 3     3 0 31 sub fhandle { return $Default_Self->{filehandle}; }
119 1     1 1 4 sub fprint { fhandle()->print (@_); }
120 0     0 1 0 sub fprintf { fhandle()->printf (@_); }
121 0     0 0 0 sub protect_rdwr_only { $Default_Self->{protect_rdwr_only} = shift; }
122              
123             ######################################################################
124             # Functions called by rest of vregs program
125              
126             sub set_default_self {
127 0     0 0 0 $Default_Self = shift;
128             }
129              
130             sub new {
131 1     1 0 3 my $class = shift;
132 1         6 my $self = {rules=>{},
133             filenames=>[],
134             #filehandle=>\*STDOUT,
135             @_};
136 1         4 bless $self, $class;
137 1         2 $Default_Self = $self;
138              
139 1         5 _default_rules();
140              
141 1         10 return $self;
142             }
143              
144             sub read {
145 0 0 0 0 0 0 my $self = shift; ($self && ref $self) or croak "%Error: Not called as method,";
  0         0  
146 0         0 my $filename = shift;
147 0         0 $Default_Self = $self;
148              
149 0         0 push @{$self->{filenames}}, $filename;
  0         0  
150              
151 0 0       0 print "read_rule_file $filename\n" if $SystemC::Vregs::Debug;
152 0         0 $! = $@ = undef;
153 0         0 my %preINC = %INC;
154 0         0 my $rtn = do $filename;
155 0 0       0 (!$@) or die "%Error: $filename: $@\n";
156 0 0 0     0 (defined $rtn || !$!) or die "%Error: $filename: $!\n";
157 0         0 %INC = %preINC; # Make sure double-do's both include
158             #use Data::Dumper; print Dumper(\%Rules);
159             }
160              
161             sub filehandle {
162 1     1 0 2 my $self = shift;
163 1         5 $self->{filehandle} = shift;
164             }
165             sub filenames {
166 1     1 0 4 my $self = shift;
167 1         2 return (@{$self->{filenames}});
  1         5  
168             }
169              
170             sub execute_rule {
171 4 50   4 0 8 my $ruleself; $ruleself = (ref $_[0]) ? shift : $Default_Self;
  4         13  
172 4         6 my $rule = shift;
173 4         8 my $name = shift;
174 4         7 my $invoke_self = shift;
175 4         8 my @rest = @_;
176 4         6 $Default_Self = $ruleself;
177              
178 4 50       13 print "exec_rule $rule, $name\n" if $SystemC::Vregs::Debug;
179 4         6 foreach my $rvec (@{$ruleself->{rules}{$rule}}) {
  4         23  
180 1 50       10 if ($name =~ $rvec->{name}) {
181 1 50       5 print "Rule execute $name (self=$invoke_self)\n" if $SystemC::Vregs::Debug;
182             {
183 3     3   19 use vars qw ($self $name);
  3         5  
  3         1098  
  1         2  
184 1         3 local $self = $invoke_self;
185 1         2 &{$rvec->{prog}}($invoke_self, $name, @rest);
  1         6  
186             }
187 1 50       8 if ($rvec->{replace}) {
188 0 0       0 print " Last rule (replace)\n" if $SystemC::Vregs::Debug;
189 0         0 return;
190             }
191             }
192             }
193             }
194              
195             sub _declare_rule {
196 6 50   6   8 my $self; $self = (ref $_[0]) ? shift : $Default_Self;
  6         16  
197 6         51 my %param = (replace=>0,
198             name => qr/.*/,
199             @_);
200 6 50       20 $param{rule} or croak "%Error: no rule=> specified\n";
201 6 50 33     36 (defined $param{text} || defined $param{prog})
202             or croak "%Error: no text=> or prog=> specified\n";
203              
204 6 50       17 if (!defined $param{prog}) {
205             # Turn {text} into a prog, so we only need to support {prog}
206 0         0 my $closure_value = $param{text};
207 0     0   0 $param{prog} = sub { fprint $closure_value; };
  0         0  
208 0         0 delete $param{text};
209             }
210              
211 6 50       18 if (!ref $param{name}) {
212             # Turn name=>constant into a regexp
213 0         0 my $nometa = quotemeta $param{name};
214 0         0 $param{name} = qr/^$nometa$/;
215             }
216              
217 6 50       14 if ($param{replace}) {
218 0         0 unshift @{$self->{rules}{$param{rule}}}, \%param;
  0         0  
219             } else {
220 6         12 push @{$self->{rules}{$param{rule}}}, \%param;
  6         36  
221             }
222             }
223              
224             ######################################################################
225             #### Package return
226             1;
227             __END__