File Coverage

blib/lib/MarpaX/Languages/PowerBuilder/base.pm
Criterion Covered Total %
statement 73 77 94.8
branch 8 12 66.6
condition 5 11 45.4
subroutine 16 16 100.0
pod 0 6 0.0
total 102 122 83.6


line stmt bran cond sub pod time code
1             package MarpaX::Languages::PowerBuilder::base;
2 4     4   742 use strict;
  4         8  
  4         87  
3 4     4   18 use warnings;
  4         6  
  4         83  
4 4     4   1520 use File::BOM qw(open_bom);
  4         77147  
  4         212  
5 4     4   22 use Encode qw(decode);
  4         7  
  4         141  
6 4     4   19 use File::Basename qw(dirname basename);
  4         5  
  4         215  
7 4     4   1298 use Marpa::R2;
  4         426734  
  4         138  
8 4     4   27 use Data::Dumper;
  4         8  
  4         696  
9              
10             our $AUTO_DECODE = 1; #used to auto decode input passed to the parse method
11              
12             sub slurp{
13 3     3 0 6 my $input = shift;
14 3         12 local $/;
15 3     3   93 open my $IN, '<:via(File::BOM)', $input;
  3         19  
  3         5  
  3         18  
16 3         2294 my $data = <$IN>;
17 3         528 close $IN;
18 3         64 $data;
19             }
20              
21             sub new{
22 3     3 0 1308 my $class = shift;
23            
24 3         9 my $self = bless {}, $class;
25            
26 3 50       26 unless($self->can('grammar')){
27 3         8 my $pkg = ref $self;
28 3         17 my $grammar = do{
29 3         232 my $path = dirname(__FILE__);
30 3         12 my $file = lc $pkg;
31 3         50 $file =~ s/.*:://g;
32 3         14 my $dsl = slurp( "$path/$file.marpa");
33 3         24 Marpa::R2::Scanless::G->new( { source => \$dsl } );
34             };
35             #inject grammar method
36             {
37 4     4   26 no strict 'refs';
  4         8  
  4         1373  
  3         642331  
38 3     3   22 *{$pkg.'::grammar'} = sub { $grammar };
  3         29  
  3         22  
39             }
40             }
41              
42 3         14 return $self;
43             }
44              
45             sub parse{
46 3     3 0 2083 my $self = shift;
47 3 50 33     33 die "forget to call new() ?" unless ref($self) && $self->can('grammar');
48 3         10 my $input = shift;
49 3         7 my $opts = shift;
50             #3 ways to pass inputs: glob, file-name, full-string
51 3 50 33     31 if(ref $input eq 'GLOB'){
    50          
52 0         0 $input = File::BOM::decode_from_bom( do{ local $/=undef; <$input> } );
  0         0  
  0         0  
53             }
54             elsif($input!~/\n/ && -f $input){
55 0         0 $input = slurp $input;
56             }
57            
58 3 100 66     34 if($AUTO_DECODE and $input=~/^\s*HA\$/i){
59 2         13 $input = $self->hexascii_decode( $input );
60             }
61            
62 3         14 my $recce = Marpa::R2::Scanless::R->new({
63             grammar => $self->grammar(),
64             semantics_package => ref($self)
65             } );
66 3         856 my $parsed = bless { recce => $recce, input => \$input, opts => $opts }, ref($self);
67 3         6 eval{ $recce->read( \$input ) };
  3         10  
68 3         47080 $parsed->{error} = $@;
69 3         11 return $parsed;
70             }
71              
72             sub value{
73 32     32 0 1778 my $self = shift;
74 32 100       69 unless(exists $self->{__value__}){
75 2   50     5 $self->{__value__} = ${ $self->{recce}->value // \{} };
  2         8  
76             }
77 32         194 return $self->{__value__};
78             }
79              
80             sub hadecode_hexseq{
81 2     2 0 5 my $codes = shift;
82            
83 2         22 return decode('utf16le', pack 'H*', $codes);
84             }
85              
86             sub hexascii_decode{
87 2     2 0 5 my $self = shift;
88 2         4 my $str = shift;
89            
90 2         33 $str =~ s/\$\$HEX\d+\$\$([a-fA-F0-9]+)\$\$ENDHEX\$\$/hadecode_hexseq($1)/ge;
  2         8  
91            
92 2         1095 return $str;
93             }
94              
95             1;