Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.7 KiB

  1. package Exporter;
  2. =head1 NAME
  3. Exporter::Heavy - Exporter guts
  4. =head1 SYNOPIS
  5. (internal use only)
  6. =head1 DESCRIPTION
  7. No user-serviceable parts inside.
  8. =cut
  9. #
  10. # We go to a lot of trouble not to 'require Carp' at file scope,
  11. # because Carp requires Exporter, and something has to give.
  12. #
  13. sub heavy_export {
  14. # First make import warnings look like they're coming from the "use".
  15. local $SIG{__WARN__} = sub {
  16. my $text = shift;
  17. if ($text =~ s/ at \S*Exporter\S*.pm line \d+.*\n//) {
  18. require Carp;
  19. local $Carp::CarpLevel = 1; # ignore package calling us too.
  20. Carp::carp($text);
  21. }
  22. else {
  23. warn $text;
  24. }
  25. };
  26. local $SIG{__DIE__} = sub {
  27. require Carp;
  28. local $Carp::CarpLevel = 1; # ignore package calling us too.
  29. Carp::croak("$_[0]Illegal null symbol in \@${1}::EXPORT")
  30. if $_[0] =~ /^Unable to create sub named "(.*?)::"/;
  31. };
  32. my($pkg, $callpkg, @imports) = @_;
  33. my($type, $sym, $oops);
  34. *exports = *{"${pkg}::EXPORT"};
  35. if (@imports) {
  36. if (!%exports) {
  37. grep(s/^&//, @exports);
  38. @exports{@exports} = (1) x @exports;
  39. my $ok = \@{"${pkg}::EXPORT_OK"};
  40. if (@$ok) {
  41. grep(s/^&//, @$ok);
  42. @exports{@$ok} = (1) x @$ok;
  43. }
  44. }
  45. if ($imports[0] =~ m#^[/!:]#){
  46. my $tagsref = \%{"${pkg}::EXPORT_TAGS"};
  47. my $tagdata;
  48. my %imports;
  49. my($remove, $spec, @names, @allexports);
  50. # negated first item implies starting with default set:
  51. unshift @imports, ':DEFAULT' if $imports[0] =~ m/^!/;
  52. foreach $spec (@imports){
  53. $remove = $spec =~ s/^!//;
  54. if ($spec =~ s/^://){
  55. if ($spec eq 'DEFAULT'){
  56. @names = @exports;
  57. }
  58. elsif ($tagdata = $tagsref->{$spec}) {
  59. @names = @$tagdata;
  60. }
  61. else {
  62. warn qq["$spec" is not defined in %${pkg}::EXPORT_TAGS];
  63. ++$oops;
  64. next;
  65. }
  66. }
  67. elsif ($spec =~ m:^/(.*)/$:){
  68. my $patn = $1;
  69. @allexports = keys %exports unless @allexports; # only do keys once
  70. @names = grep(/$patn/, @allexports); # not anchored by default
  71. }
  72. else {
  73. @names = ($spec); # is a normal symbol name
  74. }
  75. warn "Import ".($remove ? "del":"add").": @names "
  76. if $Verbose;
  77. if ($remove) {
  78. foreach $sym (@names) { delete $imports{$sym} }
  79. }
  80. else {
  81. @imports{@names} = (1) x @names;
  82. }
  83. }
  84. @imports = keys %imports;
  85. }
  86. foreach $sym (@imports) {
  87. if (!$exports{$sym}) {
  88. if ($sym =~ m/^\d/) {
  89. $pkg->require_version($sym);
  90. # If the version number was the only thing specified
  91. # then we should act as if nothing was specified:
  92. if (@imports == 1) {
  93. @imports = @exports;
  94. last;
  95. }
  96. # We need a way to emulate 'use Foo ()' but still
  97. # allow an easy version check: "use Foo 1.23, ''";
  98. if (@imports == 2 and !$imports[1]) {
  99. @imports = ();
  100. last;
  101. }
  102. } elsif ($sym !~ s/^&// || !$exports{$sym}) {
  103. require Carp;
  104. Carp::carp(qq["$sym" is not exported by the $pkg module]);
  105. $oops++;
  106. }
  107. }
  108. }
  109. if ($oops) {
  110. require Carp;
  111. Carp::croak("Can't continue after import errors");
  112. }
  113. }
  114. else {
  115. @imports = @exports;
  116. }
  117. *fail = *{"${pkg}::EXPORT_FAIL"};
  118. if (@fail) {
  119. if (!%fail) {
  120. # Build cache of symbols. Optimise the lookup by adding
  121. # barewords twice... both with and without a leading &.
  122. # (Technique could be applied to %exports cache at cost of memory)
  123. my @expanded = map { /^\w/ ? ($_, '&'.$_) : $_ } @fail;
  124. warn "${pkg}::EXPORT_FAIL cached: @expanded" if $Verbose;
  125. @fail{@expanded} = (1) x @expanded;
  126. }
  127. my @failed;
  128. foreach $sym (@imports) { push(@failed, $sym) if $fail{$sym} }
  129. if (@failed) {
  130. @failed = $pkg->export_fail(@failed);
  131. foreach $sym (@failed) {
  132. require Carp;
  133. Carp::carp(qq["$sym" is not implemented by the $pkg module ],
  134. "on this architecture");
  135. }
  136. if (@failed) {
  137. require Carp;
  138. Carp::croak("Can't continue after import errors");
  139. }
  140. }
  141. }
  142. warn "Importing into $callpkg from $pkg: ",
  143. join(", ",sort @imports) if $Verbose;
  144. foreach $sym (@imports) {
  145. # shortcut for the common case of no type character
  146. (*{"${callpkg}::$sym"} = \&{"${pkg}::$sym"}, next)
  147. unless $sym =~ s/^(\W)//;
  148. $type = $1;
  149. *{"${callpkg}::$sym"} =
  150. $type eq '&' ? \&{"${pkg}::$sym"} :
  151. $type eq '$' ? \${"${pkg}::$sym"} :
  152. $type eq '@' ? \@{"${pkg}::$sym"} :
  153. $type eq '%' ? \%{"${pkg}::$sym"} :
  154. $type eq '*' ? *{"${pkg}::$sym"} :
  155. do { require Carp; Carp::croak("Can't export symbol: $type$sym") };
  156. }
  157. }
  158. sub heavy_export_to_level
  159. {
  160. my $pkg = shift;
  161. my $level = shift;
  162. (undef) = shift; # XXX redundant arg
  163. my $callpkg = caller($level);
  164. $pkg->export($callpkg, @_);
  165. }
  166. # Utility functions
  167. sub _push_tags {
  168. my($pkg, $var, $syms) = @_;
  169. my $nontag;
  170. *export_tags = \%{"${pkg}::EXPORT_TAGS"};
  171. push(@{"${pkg}::$var"},
  172. map { $export_tags{$_} ? @{$export_tags{$_}} : scalar(++$nontag,$_) }
  173. (@$syms) ? @$syms : keys %export_tags);
  174. if ($nontag and $^W) {
  175. # This may change to a die one day
  176. require Carp;
  177. Carp::carp("Some names are not tags");
  178. }
  179. }
  180. # Default methods
  181. sub export_fail {
  182. my $self = shift;
  183. @_;
  184. }
  185. sub require_version {
  186. my($self, $wanted) = @_;
  187. my $pkg = ref $self || $self;
  188. my $version = ${"${pkg}::VERSION"};
  189. if (!$version or $version < $wanted) {
  190. $version ||= "(undef)";
  191. # %INC contains slashes, but $pkg contains double-colons.
  192. my $file = (map {s,::,/,g; $INC{$_}} "$pkg.pm")[0];
  193. $file &&= " ($file)";
  194. require Carp;
  195. Carp::croak("$pkg $wanted required--this is only version $version$file")
  196. }
  197. $version;
  198. }
  199. 1;