File Coverage

blib/lib/Embperl/Syntax/EmbperlBlocks.pm
Criterion Covered Total %
statement 95 95 100.0
branch 21 30 70.0
condition 9 13 69.2
subroutine 10 10 100.0
pod 4 7 57.1
total 139 155 89.6


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: EmbperlBlocks.pm 1578075 2014-03-16 14:01:14Z richter $
15             #
16             ###################################################################################
17            
18              
19              
20             package Embperl::Syntax::EmbperlBlocks ;
21              
22 1     1   6 use Embperl::Syntax (':types') ;
  1         2  
  1         187  
23              
24 1     1   6 use strict ;
  1         2  
  1         31  
25 1     1   5 use vars qw{@ISA %Blocks %BlocksOutput %BlocksOutputLink} ;
  1         2  
  1         1348  
26              
27              
28              
29             @ISA = qw(Embperl::Syntax) ;
30              
31              
32             ###################################################################################
33             #
34             # Methods
35             #
36             ###################################################################################
37              
38             # ---------------------------------------------------------------------------------
39             #
40             # Create new Syntax Object
41             #
42             # ---------------------------------------------------------------------------------
43              
44             sub new
45              
46             {
47 1     1 1 2 my $self = shift ;
48 1         1 my $exchange = shift ;
49              
50 1         5 $self = Embperl::Syntax::new ($self) ;
51              
52 1 50       17 if (!$self -> {-epbBlocks})
53             {
54 1 50       12 $self -> {-epbBlocks} = $self -> CloneHash ({ %Blocks, %BlocksOutput }, ref $exchange?$exchange:undef) ;
55 1         15 $self -> {-epbBlocksLink} = $self -> CloneHash ({ %Blocks, %BlocksOutputLink }, { 'unescape' => 2 }) ;
56              
57 1         16 $self -> AddToRoot ($self -> {-epbBlocks}) ;
58              
59 1 50       11 Init ($self, ref $exchange?$exchange:undef) ;
60              
61 1         8 $self -> AddInitCode ('use Data::Dumper;') ;
62             }
63              
64 1         4 return $self ;
65             }
66              
67             # ---------------------------------------------------------------------------------
68             #
69             # Add new meta command
70             #
71             # ---------------------------------------------------------------------------------
72              
73              
74             sub AddMetaCmd
75              
76             {
77 20     20 1 34 my ($self, $cmdname, $procinfo, $taginfo) = @_ ;
78              
79 20         22 my $tagtype = 'Embperl meta command' ;
80 20         20 my $ttref ;
81 20 50       61 die "'$tagtype' unknown" if (!($ttref = $self -> {-epbBlocks}{$tagtype})) ;
82 20   100     50 my $ttfollow = ($ttref -> {'follow'} ||= {}) ;
83              
84 20 100       116 my $tag = $ttfollow -> {$cmdname} = {
85             'text' => $cmdname,
86             'nodetype' => ntypTag,
87             'cdatatype' => ntypAttrValue,
88             'forcetype' => 1,
89             'unescape' => 1,
90             (ref($taginfo) eq 'HASH'?%$taginfo:()),
91             } ;
92 20 100       76 $tag -> {'procinfo'} = { $self -> {-procinfotype} => $procinfo } if ($procinfo) ;
93              
94 20 50       57 die "'$tagtype' unknown" if (!($ttref = $self -> {-epbBlocksLink}{$tagtype})) ;
95 20   100     44 $ttfollow = ($ttref -> {'follow'} ||= {}) ;
96              
97 20 100       92 my $tag2 = $ttfollow -> {$cmdname} = {
98             'text' => $cmdname,
99             'nodetype' => ntypTag,
100             'cdatatype' => ntypAttrValue,
101             'forcetype' => 1,
102             'unescape' => 2,
103             (ref($taginfo) eq 'HASH'?%$taginfo:()),
104             } ;
105 20 100       70 $tag2 -> {'procinfo'} = { $self -> {-procinfotype} => $procinfo } if ($procinfo) ;
106              
107 20         38 return $tag ;
108             }
109              
110              
111             # ---------------------------------------------------------------------------------
112             #
113             # Add new meta command that has an corresponding end meta command
114             #
115             # ---------------------------------------------------------------------------------
116              
117              
118             sub AddMetaCmdWithEnd
119              
120             {
121 3     3 1 9 my ($self, $cmdname, $endname, $procinfo) = @_ ;
122              
123 3         16 my $tag = $self -> AddMetaCmd ($cmdname, $procinfo, {'endtag' => $endname} ) ;
124              
125 3         9 return $tag ;
126             }
127              
128             # ---------------------------------------------------------------------------------
129             #
130             # Add new meta command with start and end
131             #
132             # ---------------------------------------------------------------------------------
133              
134              
135             sub AddMetaCmdBlock
136              
137             {
138 3     3 1 8 my ($self, $cmdname, $endname, $procinfostart, $procinfoend) = @_ ;
139              
140 3         3 my $tag ;
141 3         13 my $pinfo = { %$procinfostart, 'stackname' => 'metacmd', 'push' => $cmdname };
142 3         11 $tag = $self -> AddMetaCmd ($cmdname, $pinfo, {'endtag' => $endname} ) ;
143              
144 3         15 $pinfo = { %$procinfoend, 'stackname' => 'metacmd', 'stackmatch' => $cmdname };
145 3         8 $tag = $self -> AddMetaCmd ($endname, $pinfo) ;
146              
147 3         7 return $tag ;
148             }
149              
150             # ---------------------------------------------------------------------------------
151             #
152             # Add new block
153             #
154             # ---------------------------------------------------------------------------------
155              
156              
157             sub AddMetaStartEnd
158              
159             {
160 1     1 0 3 my ($self, $cmdname, $endname, $procinfostart, $taginfostart) = @_ ;
161              
162 1         3 my $tag ;
163             my $pinfo ;
164              
165 1 50       9 $tag = $self -> AddMetaCmd ($cmdname, $procinfostart, {'nodetype' => &ntypStartTag, (ref($taginfostart) eq 'HASH'?%$taginfostart:())}) ;
166              
167 1         31 $tag = $self -> AddMetaCmd ($endname, undef, {'nodetype' => &ntypEndTag, 'starttag' => $cmdname}) ;
168              
169 1         3 return $tag ;
170             }
171              
172              
173            
174              
175             # ---------------------------------------------------------------------------------
176             #
177             # Add new simple html tag (override to add meta commands inside html tags)
178             #
179             # ---------------------------------------------------------------------------------
180              
181              
182             sub AddTag
183              
184             {
185 29     29 0 40 my $self = shift ;
186              
187 29         110 my $tag = $self -> Embperl::Syntax::HTML::AddTag (@_) ;
188              
189             #### add the Embperl Block inside the new HTML Tag ####
190              
191 29   100     101 $tag -> {inside} ||= {} ;
192 29         37 my $inside = $tag -> {inside} ;
193              
194 29         32 while (my ($k, $v) = each (%{$self -> {-epbBlocks}}))
  290         879  
195             {
196 261         502 $inside -> {$k} = $v ;
197             }
198              
199 29 100       70 if (!$self -> {-epbHTMLInit})
200             {
201             #### if not already done add the Embperl Block inside the HTML Attributes ####
202              
203 1         4 $self -> {-epbHTMLInit} = 1 ;
204              
205 1         2 my $unescape = 0 ;
206 1         3 foreach ('', 'Link')
207             {
208 2         5 my $attr = $self -> {"-htmlAssignAttr$_"} ;
209 2         4 my $blocks = $self -> {"-epbBlocks$_"} ;
210 2         9 while (my ($k1, $v1) = each %$attr)
211             {
212 2 50 33     12 if (!($k1 =~ /^-/) && ref ($v1) eq 'HASH')
213             {
214 2         4 my $follow = $v1 -> {follow} ;
215 2 50       6 if (ref($follow) eq 'HASH')
216             {
217 2         5 while (my ($k2, $v2) = each %$follow)
218             {
219 8 100       22 if (ref($v2) eq 'HASH')
220             {
221 6   50     20 $v2 -> {inside} ||= {} ;
222 6         8 my $inside = $v2 -> {inside} ;
223              
224 6         14 while (my ($k, $v) = each (%$blocks))
225             {
226 54         136 $inside -> {$k} = $v ;
227             }
228             }
229             }
230             }
231             }
232             }
233             }
234              
235 1         2 my $quotes = $self -> {"-htmlQuotes"} ;
236 1         2 my $blocks = $self -> {"-epbBlocks"} ;
237 1         5 while (my ($k2, $v2) = each %$quotes)
238             {
239 2 50       6 if (ref($v2) eq 'HASH')
240             {
241 2   50     8 $v2 -> {inside} ||= {} ;
242 2         3 my $inside = $v2 -> {inside} ;
243              
244 2         5 while (my ($k, $v) = each (%$blocks))
245             {
246 18         47 $inside -> {$k} = $v ;
247             }
248             }
249             }
250             }
251 29         75 return $tag ;
252             }
253              
254              
255              
256             ###################################################################################
257             #
258             # Definitions for Embperl Blocks
259             #
260             ###################################################################################
261              
262             sub Init
263              
264             {
265 1     1 0 3 my ($self) = @_ ;
266              
267 1         15 $self -> AddMetaCmdWithEnd ('if', 'endif',
268             {
269             perlcode => 'if (%&%) { ',
270             removenode => 10,
271             mayjump => 1,
272             stackname => 'metacmd',
273             'push' => 'if',
274             }) ;
275              
276 1         10 $self -> AddMetaCmdWithEnd ('else', 'endif',
277             {
278             perlcode => '} else {',
279             removenode => 10,
280             mayjump => 1,
281             stackname => 'metacmd',
282             stackmatch => 'if',
283             'push' => 'if',
284             }) ;
285 1         7 $self -> AddMetaCmdWithEnd ('elsif', 'endif',
286             {
287             perlcode => '} elsif (%&%) { ',
288             removenode => 10,
289             mayjump => 1,
290             stackname => 'metacmd',
291             stackmatch => 'if',
292             'push' => 'if',
293             }) ;
294 1         7 $self -> AddMetaCmd ('endif',
295             {
296             perlcode => '}',
297             removenode => 10,
298             mayjump => 1,
299             stackname => 'metacmd',
300             stackmatch => 'if',
301             }) ;
302 1         12 $self -> AddMetaCmdBlock ('while', 'endwhile',
303             {
304             perlcode => 'while (%&%) { ',
305             removenode => 10,
306             mayjump => 1,
307             },
308             {
309             perlcode => '};',
310             removenode => 10,
311             mayjump => 1,
312             }) ;
313 1         8 $self -> AddMetaCmdBlock ('foreach', 'endforeach',
314             {
315             perlcode => 'foreach %&% { ',
316             removenode => 10,
317             mayjump => 1,
318             },
319             {
320             perlcode => '};',
321             removenode => 10,
322             mayjump => 1,
323             }) ;
324 1         8 $self -> AddMetaCmdBlock ('do', 'until',
325             {
326             perlcode => 'do { ',
327             removenode => 10,
328             mayjump => 1,
329             },
330             {
331             perlcode => '} until (%&%) ; ',
332             removenode => 10,
333             mayjump => 1,
334             }) ;
335 1         7 $self -> AddMetaCmd ('var',
336             {
337             compiletimeperlcode => 'use strict ; use vars qw{%%CLEANUP %&%} ; map { $CLEANUP{substr($_,1)} = 1 } qw{%&%} ;',
338             perlcode => 'use strict ;',
339             removenode => 3,
340             }) ;
341 1         5 $self -> AddMetaCmd ('next',
342             {
343             perlcode => 'next;',
344             removenode => 3,
345             }) ;
346 1         4 $self -> AddMetaCmd ('last',
347             {
348             perlcode => 'last;',
349             removenode => 3,
350             }) ;
351 1         4 $self -> AddMetaCmd ('redo',
352             {
353             perlcode => 'redo;',
354             removenode => 3,
355             }) ;
356 1         4 $self -> AddMetaCmd ('next',
357             {
358             perlcode => 'next;',
359             removenode => 3,
360             }) ;
361 1         4 $self -> AddMetaCmd ('hidden',
362             {
363             perlcode => '_ep_hid(%$n%,%&\'%);',
364             removenode => 8,
365             }) ;
366 1         5 $self -> AddMetaCmd ('dump',
367             {
368             compiletimeperlcode => q[
369             {
370             my $line = __LINE__ - 2 ;
371             my $code ;
372             my $out ;
373             my ($dest, @vars) = split (/\s*,\s*/, %&'%) ;
374             if ($dest ne 'pre' && $dest ne 'out' && $dest ne 'log' && $dest ne 'err')
375             {
376             unshift @vars, $dest ;
377             $dest = 'pre' ;
378             }
379              
380             if ($vars[0] =~ /^\'|\"/)
381             {
382             $out = (shift @vars) . '.' ;
383             }
384             $out = "Data::Dumper -> Dump ([" . join (',', map { s/^(\@|\%%)/\\\\$1/; $_ } @vars) . "],['" . join ("','", @vars) . "'])" ;
385             if ($dest eq 'pre')
386             {
387             $code = '%$c%' . "{ local \$escmode = 0; print OUT '
' ; \$escmode = 7; my \$o = $out ; print OUT \$o, \"\\n\"; \$escmode = 0; print OUT \"
\\n\" ; }" ;  
388             }
389             elsif ($dest eq 'out')
390             {
391             $code = '%$c%' . "{my \$o = $out ; print OUT \$o, \"\\n\"; }" ;
392             }
393             elsif ($dest eq 'err')
394             {
395             $code = "{my \$o = $out . ' in " . __FILE__ . " line " . $line . "'. \"\\n\"; print STDERR \$o ;}" ;
396             }
397             elsif ($dest eq 'log')
398             {
399             $code = "{my \$o = $out . ' in " . __FILE__ . " line " . $line . "'. \"\\n\"; print LOG \$o ;}" ;
400             }
401             $Embperl::req -> component -> code ($code) ;
402             }
403             ],
404             removenode => 3,
405             compilechilds => 0,
406             }) ;
407 1         6 $self -> AddMetaCmd ('syntax',
408             {
409             compiletimeperlcode => '$Embperl::req -> component -> syntax (Embperl::Syntax::GetSyntax(%&\'%, $Embperl::req -> component -> syntax -> name));',
410             removenode => 3,
411             },
412             {
413             parsetimeperlcode => '$Embperl::req -> component -> syntax (Embperl::Syntax::GetSyntax(\'%%\', $Embperl::req -> component -> syntax -> name)) ;',
414             },
415             ) ;
416 1         14 $self -> AddMetaStartEnd ('sub', 'endsub',
417             {
418             perlcode => 'sub _ep_sub_ ',
419             compiletimeperlcode => q[
420             my $args = %&'% ;
421             if ($args =~ /^([^ ]+)\s*\((.*?)\)\s*(.*?)$/s)
422             {
423             $Embperl::req -> component -> code ("sub _ep_sub_$1 { my ($2) = \@_ ; $3 ") ;
424             }
425             else
426             {
427             $args =~ /^([^ ]+)\s*(.*?)$/s ;
428             $Embperl::req -> component -> code ("sub _ep_sub_$1 { $2 ") ;
429             }
430             ],
431             perlcodeend => ' }; sub #subname# { my @_ep_save ; Embperl::Cmd::SubStart($_ep_DomTree,%$q%,\\@_ep_save); my @_ep_ret ; my $_ep_ret ; if (wantarray()) { @_ep_ret = _ep_sub_#subname# (@_)}else {$_ep_ret = _ep_sub_#subname# (@_);} Embperl::Cmd::SubEnd($_ep_DomTree,\\@_ep_save); return wantarray()?@_ep_ret:$_ep_ret } ; $_ep_exports{%^"subname%} = \&#subname# ; ',
432             compiletimeperlcodeend => q[
433             my $args = %^'subname% ;
434             $args =~ s/\s+.+$//s ;
435             my $code = $Embperl::req -> component -> code ;
436             $code =~ s/#subname#/$args/g ;
437             $Embperl::req -> component -> code ($code);
438             ],
439             removenode => 10,
440             mayjump => 1,
441             stackname2 => 'subname',
442             push2 => '%&%',
443             switchcodetype => 2,
444             callreturn => 1,
445             },
446             {
447             addfirstchild => 1,
448             },
449             ) ;
450             }
451              
452              
453              
454             %Blocks = (
455             '-lsearch' => 1,
456             'Embperl command escape' => {
457             'text' => '[[',
458             'nodename' => '[',
459             'nodetype' => ntypCDATA,
460             },
461             'Embperl meta command' => {
462             'text' => '[$',
463             'end' => '$]',
464             'unescape' => 1,
465             },
466             'Embperl code' => {
467             'text' => '[-',
468             'end' => '-]',
469             'unescape' => 1,
470             'procinfo' => {
471             embperl => {
472             perlcode => [
473             '%$c%if (!defined (scalar(do{' . "\n" . '%#~0:$col%' . "\n" . '}))) %#~-0:$row% { if ($col == 0) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; } else { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }}',
474             '%$c%if (!defined (scalar(do{' . "\n" . '%#~0:$col%' . "\n" . '}))) { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }',
475             '%$c%if (!defined (scalar(do{' . "\n" . '%#~0:$row%' . "\n" . '}))) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; }',
476             '%$c%{' . "\n" . '%#0%' . "\n" . ';}',
477             ],
478             removenode => 3,
479             mayjump => 1,
480             compilechilds => 0,
481             },
482             },
483             },
484             'Embperl global code' => {
485             'text' => '[*',
486             'end' => '*]',
487             'unescape' => 1,
488             'procinfo' => {
489             embperl => {
490             perlcode => '%$c%' . "\n" . '%#0%',
491             removenode => 3,
492             mayjump => 1,
493             compilechilds => 0,
494             },
495             },
496             },
497             'Embperl startup code' => {
498             'text' => '[!',
499             'end' => '!]',
500             'unescape' => 1,
501             'procinfo' => {
502             embperl => {
503             compiletimeperlcode => '%#0%;',
504             removenode => 3,
505             compilechilds => 0,
506             }
507             },
508             },
509             'Embperl comment' => {
510             'text' => '[#',
511             'end' => '#]',
512             # 'inside' => \%MetaComment,
513             'procinfo' => {
514             embperl => {
515             compilechilds => 0,
516             removenode => 3,
517             },
518             },
519             },
520             'Embperl output msg id' => {
521             'text' => '[=',
522             'end' => '=]',
523             'unescape' => 1,
524             removespaces => 72,
525             'cdatatype' => ntypAttrValue,
526             'procinfo' => {
527             embperl => {
528             perlcode =>
529             [
530             '_ep_rpid(%$x%,scalar(%&\'%));',
531             ],
532             removenode => 4,
533             compilechilds => 0,
534             }
535             },
536             },
537             ) ;
538            
539             #%MetaComment = (
540             # '-lsearch' => 1,
541             # 'Embperl comment' => {
542             # 'text' => '[#',
543             # 'end' => '#]',
544             # 'inside' => \%MetaComment
545             # },
546             #) ;
547              
548              
549             %BlocksOutput =
550             (
551             'Embperl output code' => {
552             'text' => '[+',
553             'end' => '+]',
554             'unescape' => 1,
555             'procinfo' => {
556             embperl => {
557             perlcode =>
558             [
559             'if (!defined (_ep_rp(%$x%,scalar(%#~0:$col%)))) %#~-0:$row% { if ($col == 0) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; } else { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }}',
560             'if (!defined (_ep_rp(%$x%,scalar(%#~0:$col%)))) { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }',
561             'if (!defined (_ep_rp(%$x%,scalar(%#~0:$row%)))) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; }',
562             '_ep_rp(%$x%,scalar(%#0%));',
563             ],
564             removenode => 4,
565             mayjump => '%#~0:$col|$row|$cnt% %?*htmlrow% %?*htmltable%',
566             compilechilds => 0,
567             }
568             },
569             },
570             ) ;
571              
572             %BlocksOutputLink =
573             (
574             'Embperl output code URL' => {
575             'text' => '[+',
576             'nodename' => '[+url',
577             'end' => '+]',
578             'unescape' => 2,
579             'procinfo' => {
580             embperl => {
581             perlcode =>
582             [
583             'if (!defined (_ep_rpurl(%$x%,scalar(%#~0:$col%)))) %#~-0:$row% { if ($col == 0) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; } else { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }}',
584             'if (!defined (_ep_rpurl(%$x%,scalar(%#~0:$col%)))) { _ep_dcp (%^*htmlrow%) ; last l%^*htmlrow% ; }',
585             'if (!defined (_ep_rpurl(%$x%,scalar(%#~0:$row%)))) { _ep_dcp (%^*htmltable%) ; last l%^*htmltable% ; }',
586             '_ep_rpurl(%$x%,scalar(%#0%));',
587             ],
588             removenode => 4,
589             mayjump => '%#~0:$col|$row|$cnt% %?*htmlrow% %?*htmltable%',
590             compilechilds => 0,
591             }
592             },
593             },
594             ) ;
595              
596              
597             1;
598              
599              
600             __END__