File Coverage

blib/lib/Embperl/Syntax.pm
Criterion Covered Total %
statement 132 146 90.4
branch 26 38 68.4
condition 8 11 72.7
subroutine 27 28 96.4
pod 6 6 100.0
total 199 229 86.9


line stmt bran cond sub pod time code
1              
2             ###################################################################################
3             #
4             # Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh www.ecos.de
5             # Embperl - Copyright (c) 2008-2014 Gerald Richter
6             #
7             # You may distribute under the terms of either the GNU General Public
8             # License or the Artistic License, as specified in the Perl README file.
9             #
10             # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
11             # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12             # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13             #
14             # $Id: Syntax.pm 1578075 2014-03-16 14:01:14Z richter $
15             #
16             ###################################################################################
17            
18              
19              
20             package Embperl::Syntax ;
21              
22 1     1   5 use strict ;
  1         3  
  1         42  
23 1     1   5 use vars qw{@ISA @EXPORT_OK %EXPORT_TAGS %DocumentRoot %Syntax} ;
  1         1  
  1         89  
24              
25             @ISA = qw{Exporter} ;
26              
27 1     1   5 use constant ntypTag => 1 ;
  1         1  
  1         66  
28 1     1   5 use constant ntypStartTag => 1 + 0x20 ;
  1         1  
  1         41  
29 1     1   4 use constant ntypStartEndTag => 1 + 0x80 ;
  1         2  
  1         48  
30 1     1   10 use constant ntypEndTag => 1 + 0x40 ;
  1         2  
  1         49  
31 1     1   5 use constant ntypEndStartTag => 1 + 0x60 ;
  1         2  
  1         313  
32 1     1   24 use constant ntypAttr => 2 ;
  1         3  
  1         221  
33 1     1   12 use constant ntypAttrValue => 2 + 0x20 ;
  1         1  
  1         67  
34 1     1   4 use constant ntypText => 3 ;
  1         1  
  1         109  
35 1     1   5 use constant ntypCDATA => 4 ;
  1         2  
  1         65  
36 1     1   4 use constant ntypEntityRef => 5 ;
  1         1  
  1         31  
37 1     1   4 use constant ntypEntity => 6 ;
  1         1  
  1         51  
38 1     1   4 use constant ntypProcessingInstr => 7 ;
  1         1  
  1         36  
39 1     1   3 use constant ntypComment => 8 ;
  1         2  
  1         31  
40 1     1   20 use constant ntypDocument => 9 ;
  1         2  
  1         33  
41 1     1   4 use constant ntypDocumentType => 10 ;
  1         1  
  1         37  
42 1     1   23 use constant ntypDocumentFraq => 11 ;
  1         1  
  1         161  
43 1     1   7 use constant ntypNotation => 12 ;
  1         3  
  1         73  
44              
45 1     1   119 use constant aflgSingleQuote => 8 ;
  1         2  
  1         1177  
46              
47              
48             @EXPORT_OK = qw{
49             ntypTag
50             ntypStartTag
51             ntypStartEndTag
52             ntypEndTag
53             ntypEndStartTag
54             ntypAttr
55             ntypAttrValue
56             ntypText
57             ntypCDATA
58             ntypEntityRef
59             ntypEntity
60             ntypProcessingInstr
61             ntypComment
62             ntypDocument
63             ntypDocumentType
64             ntypDocumentFraq
65             ntypNotation
66              
67             aflgSingleQuote
68             } ;
69              
70              
71              
72             %EXPORT_TAGS = (
73             types => \@EXPORT_OK,
74             ) ;
75              
76              
77             ###################################################################################
78             #
79             # Methods
80             #
81             ###################################################################################
82              
83             # ---------------------------------------------------------------------------------
84             #
85             # Create new Syntax Object
86             #
87             # ---------------------------------------------------------------------------------
88              
89             sub new
90              
91             {
92 4     4 1 8 my $class = shift ;
93              
94 4         9 my $self = $class ;
95 4 100       14 if (!ref $class)
96             {
97 3         29 $self = {
98             -root => $class -> CloneHash (\%DocumentRoot) ,
99             -procinfotype => 'embperl',
100             } ;
101              
102 3         12 bless $self, $class ;
103             }
104              
105 4         13 return $self ;
106             }
107              
108              
109              
110             # ---------------------------------------------------------------------------------
111             #
112             # Add new elemets to root
113             #
114             # ---------------------------------------------------------------------------------
115              
116              
117             sub AddToRoot
118              
119             {
120 3     3 1 7 my ($self, $elements) = @_ ;
121            
122 3         8 my $root = $self -> {-root} ;
123              
124 3         23 while (my ($k, $v) = each (%$elements))
125             {
126 11         45 $root -> {$k} = $v ;
127             }
128             }
129              
130             # ---------------------------------------------------------------------------------
131             #
132             # Adds code that is execute everytime after the compile of a document
133             # start and end of the execution of a document
134             #
135             # ---------------------------------------------------------------------------------
136              
137              
138             sub AddInitCode
139              
140             {
141 4     4 1 12 my ($self, $compiletimecode, $initcode, $termcode, $procinfo) = @_ ;
142            
143 4         9 my $root = $self -> {-root} ;
144 4         7 my $ttref ;
145 4         9 foreach my $tagtype ('Document', 'DocumentFraq')
146             {
147 8 50       28 die "'$tagtype' unknown" if (!($ttref = $self -> {-root}{$tagtype})) ;
148 8   50     28 my $pinfo = ($ttref -> {'procinfo'}{$self -> {-procinfotype}} ||= {}) ;
149 8 100       29 $pinfo -> {'compiletimeperlcode'} .= $compiletimecode if ($compiletimecode) ;
150 8 100       17 $pinfo -> {'perlcode'} .= $initcode if ($initcode) ;
151 8 50       17 $pinfo -> {'perlcodeend'} .= $termcode if ($termcode) ;
152 8 100       23 if ($procinfo)
153             {
154 2         7 while (my ($k, $v) = each (%$procinfo))
155             {
156 4         14 $pinfo -> {$k} = $v ;
157             }
158             }
159             }
160             }
161              
162              
163              
164             # ---------------------------------------------------------------------------------
165             #
166             # Get root
167             #
168             # ---------------------------------------------------------------------------------
169              
170              
171             sub GetRoot
172              
173             {
174 0     0 1 0 my ($self) = @_ ;
175            
176 0         0 return $self -> {-root} ;
177             }
178              
179              
180             # ---------------------------------------------------------------------------------
181             #
182             # Get/create named syntax
183             #
184             # ---------------------------------------------------------------------------------
185              
186              
187             sub GetSyntax
188              
189             {
190 62     62 1 182 my ($name, $oldname) = @_ ;
191              
192 62         101 my %names ;
193 62         121 my $op = '' ;
194 62 50       337 if ($name =~ /^(\+|\-)\s*(.*?)$/)
195             {
196 0         0 $op = $1 ;
197 0         0 $name = $2;
198             }
199 62 50       183 $name = "$oldname $name" if ($op eq '+') ;
200              
201 62         256 my @split = split (/\s/, $name) ;
202 62 50       191 if ($op eq '-')
203             {
204 0 0       0 my @mnames = map { /::/?$_:'Embperl::Syntax::'. $_ } @split ;
  0         0  
205 0         0 foreach (@mnames)
206             {
207 0         0 $names{$_} = 1 ;
208             }
209 0         0 @split = split (/\s/, $oldname) ;
210             }
211            
212 62 50       143 my @xnames = map { /::/?$_:'Embperl::Syntax::'. $_ } @split ;
  62         376  
213 62         107 my @names ;
214 62         162 foreach (@xnames)
215             {
216 62 50 33     723 push @names, $1 if (!$names{$_} && (/^\s*([a-zA-Z_0-9:]+)\s*$/)) ;
217 62         199 $names{$_} = 1 ;
218             }
219            
220 62         176 $name = join (' ', @names) ;
221              
222 62         371 print Embperl::LOG "[$$]SYNTAX: switch to $name\n" ;
223              
224 62 50       191 return undef if (!$name) ;
225 62 100       262533 return $Syntax{$name} if (exists ($Syntax{$name})) ;
226              
227 3         8 foreach my $n (@names)
228             {
229 3         293 eval "require $n" ;
230 3 50       22 if ($@)
231             {
232 0         0 warn $@ ;
233 0         0 return undef ;
234             }
235             }
236              
237 3         9 my $first = shift @names ;
238              
239 3         20 my $self = $first -> new ;
240              
241 3         12 foreach my $n (@names)
242             {
243 1     1   5 no strict ;
  1         2  
  1         45  
244 0         0 &{"${n}::new"}($self) ;
  0         0  
245 1     1   4 use strict ;
  1         1  
  1         6518  
246             }
247              
248 3         13 $self -> {-name} = $name ;
249              
250 3         22289 BuildTokenTable ($self) ;
251 3         19 $Syntax{$name} = $self ;
252 3         5111 return $self ;
253             }
254              
255             # ---------------------------------------------------------------------------------
256             #
257             # Deep clone a hash and make replacements
258             #
259             # ---------------------------------------------------------------------------------
260              
261             sub CloneHash
262             {
263 93     93 1 152 my ($self, $old, $replace, $seen, $new) = @_ ;
264              
265              
266 93   100     202 $new ||= {} ;
267 93   100     170 $replace ||= {} ;
268 93   100     186 $seen ||= {$old => $new} ;
269              
270 93         94 my ($v, $k) ;
271            
272              
273 93         312 while (($k, $v) = each (%$old))
274             {
275 304 100       536 if ($replace -> {$k})
276             {
277 6         26 $new -> {$k} = $replace -> {$k} ;
278             }
279             else
280             {
281 298 100       611 if (ref ($v) eq 'HASH')
    100          
282             {
283 82 50       202 if ($seen -> {$v})
284             {
285 0         0 $new -> {$k} = $seen -> {$v} ;
286             }
287             else
288             {
289 82         109 my $sub = {} ;
290 82         192 $seen -> {$v} = $sub ;
291 82         183 $self -> CloneHash ($v, $replace, $seen, $sub) ;
292 82         306 $new -> {$k} = $sub ;
293             }
294             }
295             elsif (ref ($v) eq 'ARRAY')
296             {
297 6         32 $new -> {$k} = [@$v] ;
298             }
299             else
300             {
301 210         668 $new -> {$k} = $v ;
302             }
303             }
304             }
305              
306 93         228 return $new ;
307             }
308              
309              
310              
311             ###################################################################################
312             #
313             # Definitions for documents
314             #
315             ###################################################################################
316              
317              
318             %DocumentRoot = (
319             '-lsearch' => 1,
320              
321             # The document node is generated always and is not parserd, but can be used to include code
322             'Document' => {
323             'nodename' => 'Document',
324             'nodetype' => ntypDocument,
325             'procinfo' => {
326             embperl => {
327             perlcode => q{
328             # any initialisation could be put here
329             #$DB::single = 1 ;
330             $maxrow=100;$maxcol=10;
331             },
332             compiletimeperlcode => q{
333             use vars ('$_ep_DomTree', '@ISA', '@param') ;
334             *_ep_rp=\\&XML::Embperl::DOM::Node::iReplaceChildWithCDATA;
335             *_ep_rpid=\\&XML::Embperl::DOM::Node::iReplaceChildWithMsgId;
336             *_ep_rpurl=\\&XML::Embperl::DOM::Node::iReplaceChildWithUrlDATA;
337             *_ep_cp=\\&XML::Embperl::DOM::Tree::iCheckpoint;
338             *_ep_dcp=\\&XML::Embperl::DOM::Tree::iDiscardAfterCheckpoint;
339             *_ep_opt=\\&Embperl::Cmd::Option;
340             *_ep_hid=\\&Embperl::Cmd::Hidden;
341             *_ep_ac=\\&XML::Embperl::DOM::Node::iAppendChild;
342             *_ep_sa=\\&XML::Embperl::DOM::Element::iSetAttribut;
343             Embperl::Util::CreateAliases ;
344             },
345             perlcodeend => q{# Include here any cleanup code
346             $DB::single = 0 ;
347             },
348             stackname => 'metacmd',
349             stackmatch => 'Document',
350             'push' => 'Document',
351             mayjump => 1,
352             }
353             },
354             },
355             # The document fraq node is generated always and is not parserd, but can be used to include code
356             'DocumentFraq' => {
357             'nodename' => 'DocumentFraq',
358             'nodetype' => ntypDocumentFraq,
359             'procinfo' => {
360             embperl => {
361             perlcode => q{
362             #my $_ep_param_save = \@param ;
363             #*param = $Embperl::req -> component -> param -> param || [];
364             },
365             compiletimeperlcode => q{
366             use vars ('$_ep_DomTree', '@ISA', '@param') ;
367             *_ep_rp=\\&XML::Embperl::DOM::Node::iReplaceChildWithCDATA;
368             *_ep_rpid=\\&XML::Embperl::DOM::Node::iReplaceChildWithMsgId;
369             *_ep_rpurl=\\&XML::Embperl::DOM::Node::iReplaceChildWithUrlDATA;
370             *_ep_cp=\\&XML::Embperl::DOM::Tree::iCheckpoint;
371             *_ep_dcp=\\&XML::Embperl::DOM::Tree::iDiscardAfterCheckpoint;
372             *_ep_opt=\\&Embperl::Cmd::Option;
373             *_ep_hid=\\&Embperl::Cmd::Hidden;
374             *_ep_ac=\\&XML::Embperl::DOM::Node::iAppendChild;
375             *_ep_sa=\\&XML::Embperl::DOM::Element::iSetAttribut;
376             Embperl::Util::CreateAliases ;
377             },
378             perlcodeend => q{
379             #*param = $_ep_param_save ;
380             },
381             stackname => 'metacmd',
382             stackmatch => 'DocumentFraq',
383             'push' => 'DocumentFraq',
384             mayjump => 1,
385             }
386             },
387             },
388             ) ;
389              
390             1;
391              
392             __END__