File Coverage

blib/lib/Marpa/R2.pm
Criterion Covered Total %
statement 42 59 71.1
branch 6 16 37.5
condition 0 3 0.0
subroutine 12 15 80.0
pod 0 2 0.0
total 60 95 63.1


line stmt bran cond sub pod time code
1             # Copyright 2022 Jeffrey Kegler
2             # This file is part of Marpa::R2. Marpa::R2 is free software: you can
3             # redistribute it and/or modify it under the terms of the GNU Lesser
4             # General Public License as published by the Free Software Foundation,
5             # either version 3 of the License, or (at your option) any later version.
6             #
7             # Marpa::R2 is distributed in the hope that it will be useful,
8             # but WITHOUT ANY WARRANTY; without even the implied warranty of
9             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10             # Lesser General Public License for more details.
11             #
12             # You should have received a copy of the GNU Lesser
13             # General Public License along with Marpa::R2. If not, see
14             # http://www.gnu.org/licenses/.
15              
16             package Marpa::R2;
17              
18 132     132   1178944 use 5.010001;
  132         574  
19 132     132   771 use strict;
  132         294  
  132         2707  
20 132     132   766 use warnings;
  132         290  
  132         4203  
21              
22 132     132   698 use vars qw($VERSION $STRING_VERSION @ISA $DEBUG);
  132         272  
  132         14264  
23             $VERSION = '12.000000';
24             $STRING_VERSION = $VERSION;
25             ## no critic (BuiltinFunctions::ProhibitStringyEval)
26             $VERSION = eval $VERSION;
27             ## use critic
28             $DEBUG = 0;
29              
30 132     132   934 use Carp;
  132         320  
  132         9026  
31 132     132   24530 use English qw( -no_match_vars );
  132         183629  
  132         937  
32 132     132   48198 use XSLoader;
  132         356  
  132         3714  
33              
34 132     132   56578 use Marpa::R2::Version;
  132         359  
  132         64150  
35              
36             $Marpa::R2::USING_XS = 1;
37             $Marpa::R2::USING_PP = 0;
38             $Marpa::R2::LIBMARPA_FILE = '[built-in]';
39              
40             LOAD_EXPLICIT_LIBRARY: {
41             last LOAD_EXPLICIT_LIBRARY if not $ENV{'MARPA_AUTHOR_TEST'};
42             my $file = $ENV{MARPA_LIBRARY};
43             last LOAD_EXPLICIT_LIBRARY if not $file;
44              
45             require DynaLoader;
46             package DynaLoader;
47             my $bs = $file;
48             $bs =~ s/(\.\w+)?(;\d*)?$/\.bs/; # look for .bs 'beside' the library
49              
50             if (-s $bs) { # only read file if it's not empty
51             # print STDERR "BS: $bs ($^O, $dlsrc)\n" if $dl_debug;
52             eval { do $bs; };
53             warn "$bs: $@\n" if $@;
54             }
55              
56             my $bootname = "marpa_g_new";
57             @DynaLoader::dl_require_symbols = ($bootname);
58              
59             my $libref = dl_load_file($file, 0) or do {
60             require Carp;
61             Carp::croak("Can't load libmarpa library: '$file'" . dl_error());
62             };
63             push(@DynaLoader::dl_librefs,$libref); # record loaded object
64              
65             my @unresolved = dl_undef_symbols();
66             if (@unresolved) {
67             require Carp;
68             Carp::carp("Undefined symbols present after loading $file: @unresolved\n");
69             }
70              
71             dl_find_symbol($libref, $bootname) or do {
72             require Carp;
73             Carp::croak("Can't find '$bootname' symbol in $file\n");
74             };
75              
76             push(@DynaLoader::dl_shared_objects, $file); # record files loaded
77             $Marpa::R2::LIBMARPA_FILE = $file;
78             }
79              
80             XSLoader::load( 'Marpa::R2', $Marpa::R2::STRING_VERSION );
81              
82             if ( not $ENV{'MARPA_AUTHOR_TEST'} ) {
83             $Marpa::R2::DEBUG = 0;
84             }
85             else {
86             Marpa::R2::Thin::debug_level_set(1);
87             $Marpa::R2::DEBUG = 1;
88             }
89              
90             sub version_ok {
91 1320     1320 0 3771 my ($sub_module_version) = @_;
92 1320 50       4292 return 'not defined' if not defined $sub_module_version;
93 1320 50       4293 return "$sub_module_version does not match Marpa::R2::VERSION " . $VERSION
94             if $sub_module_version != $VERSION;
95 1320         6236 return;
96             } ## end sub version_ok
97              
98             # Set up the error values
99             my @error_names = Marpa::R2::Thin::error_names();
100             for ( my $error = 0; $error <= $#error_names; ) {
101             my $current_error = $error;
102             (my $name = $error_names[$error] ) =~ s/\A MARPA_ERR_//xms;
103 132     132   1015 no strict 'refs';
  132         349  
  132         73574  
104             *{ "Marpa::R2::Error::$name" } = \$current_error;
105             # This shuts up the "used only once" warning
106             my $dummy = eval q{$} . 'Marpa::R2::Error::' . $name;
107             $error++;
108             }
109              
110             my $version_result;
111             require Marpa::R2::Internal;
112             ( $version_result = version_ok($Marpa::R2::Internal::VERSION) )
113             and die 'Marpa::R2::Internal::VERSION ', $version_result;
114              
115             require Marpa::R2::Grammar;
116             ( $version_result = version_ok($Marpa::R2::Grammar::VERSION) )
117             and die 'Marpa::R2::Grammar::VERSION ', $version_result;
118              
119             require Marpa::R2::Recognizer;
120             ( $version_result = version_ok($Marpa::R2::Recognizer::VERSION) )
121             and die 'Marpa::R2::Recognizer::VERSION ', $version_result;
122              
123             require Marpa::R2::Value;
124             ( $version_result = version_ok($Marpa::R2::Value::VERSION) )
125             and die 'Marpa::R2::Value::VERSION ', $version_result;
126              
127             require Marpa::R2::MetaG;
128             ( $version_result = version_ok($Marpa::R2::MetaG::VERSION) )
129             and die 'Marpa::R2::MetaG::VERSION ', $version_result;
130              
131             require Marpa::R2::SLG;
132             ( $version_result = version_ok($Marpa::R2::Scanless::G::VERSION) )
133             and die 'Marpa::R2::Scanless::G::VERSION ', $version_result;
134              
135             require Marpa::R2::SLR;
136             ( $version_result = version_ok($Marpa::R2::Scanless::R::VERSION) )
137             and die 'Marpa::R2::Scanless::R::VERSION ', $version_result;
138              
139             require Marpa::R2::MetaAST;
140             ( $version_result = version_ok($Marpa::R2::MetaAST::VERSION) )
141             and die 'Marpa::R2::MetaAST::VERSION ', $version_result;
142              
143             require Marpa::R2::Stuifzand;
144             ( $version_result = version_ok($Marpa::R2::Stuifzand::VERSION) )
145             and die 'Marpa::R2::Stuifzand::VERSION ', $version_result;
146              
147             require Marpa::R2::ASF;
148             ( $version_result = version_ok($Marpa::R2::ASF::VERSION) )
149             and die 'Marpa::R2::ASF::VERSION ', $version_result;
150              
151             sub Marpa::R2::exception {
152 45     45 0 191 my $exception = join q{}, @_;
153 45         871 $exception =~ s/ \n* \z /\n/xms;
154 45 50       154 die($exception) if $Marpa::R2::JUST_DIE;
155 45         126 CALLER: for ( my $i = 0; 1; $i++) {
156 163         974 my ($package ) = caller($i);
157 163 50       458 last CALLER if not $package;
158 163 100       442 last CALLER if not 'Marpa::R2::' eq substr $package, 0, 11;
159 118         259 $Carp::Internal{ $package } = 1;
160             }
161 45         6688 Carp::croak($exception, q{Marpa::R2 exception});
162             }
163              
164             package Marpa::R2::Internal::X;
165              
166             use overload (
167             q{""} => sub {
168 0     0   0 my ($self) = @_;
169 0   0     0 return $self->{message} // $self->{fallback_message};
170             },
171 132         1228 fallback => 1
172 132     132   160162 );
  132         128923  
173              
174             sub new {
175 0     0     my ( $class, @hash_ref_args ) = @_;
176 0           my %x_object = ();
177 0           for my $hash_ref_arg (@hash_ref_args) {
178 0 0         if ( ref $hash_ref_arg ne "HASH" ) {
179 0           my $ref_type = ref $hash_ref_arg;
180 0 0         my $ref_desc = $ref_type ? "ref to $ref_type" : "not a ref";
181 0           die
182             "Internal error: args to Marpa::R2::Internal::X->new is $ref_desc -- it should be hash ref";
183             } ## end if ( ref $hash_ref_arg ne "HASH" )
184 0           $x_object{$_} = $hash_ref_arg->{$_} for keys %{$hash_ref_arg};
  0            
185             } ## end for my $hash_ref_arg (@hash_ref_args)
186 0           my $name = $x_object{name};
187 0 0         die("Internal error: an excepion must have a name") if not $name;
188 0           $x_object{fallback_message} = qq{Exception "$name" thrown};
189 0           return bless \%x_object, $class;
190             } ## end sub new
191              
192             sub name {
193 0     0     my ($self) = @_;
194 0           return $self->{name};
195             }
196              
197             1;
198              
199             # vim: set expandtab shiftwidth=4: