no
strict
'refs'
;
our
$VERSION
=
'5.78'
;
sub
_rebuild_cache {
my
(
$pkg
,
$exports
,
$cache
) =
@_
;
s/^&//
foreach
@$exports
;
@{
$cache
}{
@$exports
} = (1) x
@$exports
;
my
$ok
= \@{
"${pkg}::EXPORT_OK"
};
if
(
@$ok
) {
s/^&//
foreach
@$ok
;
@{
$cache
}{
@$ok
} = (1) x
@$ok
;
}
}
sub
heavy_export {
my
$oldwarn
=
$SIG
{__WARN__};
local
$SIG
{__WARN__} =
sub
{
local
$SIG
{__WARN__} =
$oldwarn
;
my
$text
=
shift
;
if
(
$text
=~ s/ at \S
*Exporter
\S*.pm line \d+.*\n//) {
local
$Carp::CarpLevel
= 1;
Carp::carp(
$text
);
}
else
{
warn
$text
;
}
};
local
$SIG
{__DIE__} =
sub
{
local
$Carp::CarpLevel
= 1;
Carp::croak(
"$_[0]Illegal null symbol in \@${1}::EXPORT"
)
if
$_
[0] =~ /^Unable to create
sub
named
"(.*?)::"
/;
};
my
(
$pkg
,
$callpkg
,
@imports
) =
@_
;
my
(
$type
,
$sym
,
$cache_is_current
,
$oops
);
my
(
$exports
,
$export_cache
) = (\@{
"${pkg}::EXPORT"
},
$Exporter::Cache
{
$pkg
} ||= {});
if
(
@imports
) {
if
(!
%$export_cache
) {
_rebuild_cache (
$pkg
,
$exports
,
$export_cache
);
$cache_is_current
= 1;
}
if
(
grep
m{^[/!:]},
@imports
) {
my
$tagsref
= \%{
"${pkg}::EXPORT_TAGS"
};
my
$tagdata
;
my
%imports
;
my
(
$remove
,
$spec
,
@names
,
@allexports
);
unshift
@imports
,
':DEFAULT'
if
$imports
[0] =~ m/^!/;
foreach
$spec
(
@imports
){
$remove
=
$spec
=~ s/^!//;
if
(
$spec
=~ s/^://){
if
(
$spec
eq
'DEFAULT'
){
@names
=
@$exports
;
}
elsif
(
$tagdata
=
$tagsref
->{
$spec
}) {
@names
=
@$tagdata
;
}
else
{
warn
qq["$spec" is not defined in %${pkg}::EXPORT_TAGS]
;
++
$oops
;
next
;
}
}
elsif
(
$spec
=~ m:^/(.*)/$:){
my
$patn
= $1;
@allexports
=
keys
%$export_cache
unless
@allexports
;
@names
=
grep
(/
$patn
/,
@allexports
);
}
else
{
@names
= (
$spec
);
}
warn
"Import "
.(
$remove
?
"del"
:
"add"
).
": @names "
if
$Exporter::Verbose
;
if
(
$remove
) {
foreach
$sym
(
@names
) {
delete
$imports
{
$sym
} }
}
else
{
@imports
{
@names
} = (1) x
@names
;
}
}
@imports
=
keys
%imports
;
}
my
@carp
;
foreach
$sym
(
@imports
) {
if
(!
$export_cache
->{
$sym
}) {
if
(
$sym
=~ m/^\d/) {
$pkg
->VERSION(
$sym
);
if
(
@imports
== 1) {
@imports
=
@$exports
;
last
;
}
if
(
@imports
== 2 and !
$imports
[1]) {
@imports
= ();
last
;
}
}
elsif
(
$sym
!~ s/^&// || !
$export_cache
->{
$sym
}) {
unless
(
$cache_is_current
) {
%$export_cache
= ();
_rebuild_cache (
$pkg
,
$exports
,
$export_cache
);
$cache_is_current
= 1;
}
if
(!
$export_cache
->{
$sym
}) {
push
@carp
,
qq["$sym" is not exported by the $pkg module]
;
$oops
++;
}
}
}
}
if
(
$oops
) {
Carp::croak(
join
(
"\n"
,
@carp
,
"Can't continue after import errors"
));
}
}
else
{
@imports
=
@$exports
;
}
my
(
$fail
,
$fail_cache
) = (\@{
"${pkg}::EXPORT_FAIL"
},
$Exporter::FailCache
{
$pkg
} ||= {});
if
(
@$fail
) {
if
(!
%$fail_cache
) {
my
@expanded
=
map
{ /^\w/ ? (
$_
,
'&'
.
$_
) :
$_
}
@$fail
;
warn
"${pkg}::EXPORT_FAIL cached: @expanded"
if
$Exporter::Verbose
;
@{
$fail_cache
}{
@expanded
} = (1) x
@expanded
;
}
my
@failed
;
foreach
$sym
(
@imports
) {
push
(
@failed
,
$sym
)
if
$fail_cache
->{
$sym
} }
if
(
@failed
) {
@failed
=
$pkg
->export_fail(
@failed
);
foreach
$sym
(
@failed
) {
Carp::carp(
qq["$sym" is not implemented by the $pkg module ]
,
"on this architecture"
);
}
if
(
@failed
) {
Carp::croak(
"Can't continue after import errors"
);
}
}
}
warn
"Importing into $callpkg from $pkg: "
,
join
(
", "
,
sort
@imports
)
if
$Exporter::Verbose
;
foreach
$sym
(
@imports
) {
(*{
"${callpkg}::$sym"
} = \&{
"${pkg}::$sym"
},
next
)
unless
$sym
=~ s/^(\W)//;
$type
= $1;
no
warnings
'once'
;
*{
"${callpkg}::$sym"
} =
$type
eq
'&'
? \&{
"${pkg}::$sym"
} :
$type
eq
'$'
? \${
"${pkg}::$sym"
} :
$type
eq
'@'
? \@{
"${pkg}::$sym"
} :
$type
eq
'%'
? \%{
"${pkg}::$sym"
} :
$type
eq
'*'
? *{
"${pkg}::$sym"
} :
do
{
require
Carp; Carp::croak(
"Can't export symbol: $type$sym"
) };
}
}
sub
heavy_export_to_level
{
my
$pkg
=
shift
;
my
$level
=
shift
;
(
undef
) =
shift
;
my
$callpkg
=
caller
(
$level
);
$pkg
->export(
$callpkg
,
@_
);
}
sub
_push_tags {
my
(
$pkg
,
$var
,
$syms
) =
@_
;
my
@nontag
= ();
my
$export_tags
= \%{
"${pkg}::EXPORT_TAGS"
};
push
(@{
"${pkg}::$var"
},
map
{
$export_tags
->{
$_
} ? @{
$export_tags
->{
$_
}}
:
scalar
(
push
(
@nontag
,
$_
),
$_
) }
(
@$syms
) ?
@$syms
:
keys
%$export_tags
);
if
(
@nontag
and $^W) {
Carp::carp(
join
(
", "
,
@nontag
).
" are not tags of $pkg"
);
}
}
sub
heavy_require_version {
my
(
$self
,
$wanted
) =
@_
;
my
$pkg
=
ref
$self
||
$self
;
return
${pkg}->VERSION(
$wanted
);
}
sub
heavy_export_tags {
_push_tags((
caller
)[0],
"EXPORT"
, \
@_
);
}
sub
heavy_export_ok_tags {
_push_tags((
caller
)[0],
"EXPORT_OK"
, \
@_
);
}
1;