Source code of Windows XP (NT5)
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.

131 lines
3.8 KiB

  1. ######################################################################
  2. # File : Win32/FreeStanding.pm
  3. # Author : James A. Snyder <[email protected]>
  4. # Gurusamy Sarathy <[email protected]>
  5. # - some bug fixes and cleanup
  6. # Copyright : Copyright (c) 1998 ActiveState Tool Corp.
  7. ######################################################################
  8. package Win32::FreeStanding;
  9. #
  10. sub safe_eval {
  11. # invoke firstarg() on a slice of all the remaining args
  12. # (obfuscated by necessity--no lexicals allowed!)
  13. &{$_[0]}( @_[1..(@_-1)] );
  14. }
  15. my $old_dynaloader_bootstrap;
  16. ######################################################################
  17. sub bootstrap {
  18. my @args = @_;
  19. my $module = shift;
  20. my $version = shift;
  21. my $file ;
  22. die "Usage: Win32::FreeStanding::bootstrap(module)" unless $module;
  23. my $bootname = "boot_$module";
  24. $bootname =~ s/\W/_/g;
  25. @DynaLoader::dl_require_symbols = ($bootname);
  26. my $libref;
  27. my $res_id;
  28. $version = ${$module . '::VERSION'} unless $version;
  29. if ($version) {
  30. $version =~ s|\.|_|g;
  31. $res_id = "$module" . "_" . "$version" . ".dll";
  32. $res_id =~ s|::|_|g;
  33. }
  34. else {
  35. $res_id = $module . ".dll";
  36. $res_id =~ s|::|_|g;
  37. }
  38. ($libref, $file) = Win32::FreeStanding::ExtractAndLoadLibraryFromResource($res_id);
  39. return &$old_dynaloader_bootstrap(@args) unless $libref;
  40. push(@DynaLoader::dl_librefs,$libref); # record loaded object
  41. my @unresolved = DynaLoader::dl_undef_symbols();
  42. if (@unresolved) {
  43. die "Undefined symbols present after loading $file: @unresolved\n";
  44. }
  45. my $boot_symbol_ref = DynaLoader::dl_find_symbol($libref, $bootname);
  46. die "Can't find $bootname symbol in $file\n" unless $boot_symbol_ref;
  47. my $xs = DynaLoader::dl_install_xsub("${module}::bootstrap",
  48. $boot_symbol_ref, $file);
  49. push(@DynaLoader::dl_modules, $module); # record loaded module
  50. &$xs(@args);
  51. }
  52. ######################################################################
  53. sub require(*) {
  54. my $name = shift;
  55. my $pkg = (caller)[0];
  56. # XXX Since build 512, $name could be a GLOBref if and only if a
  57. # glob was explicitly passed. Barewords and strings are passed
  58. # through as is. So this check only exists for the sake of
  59. # earlier versions.
  60. if (ref($name) eq 'GLOB') {
  61. $name = "$$name";
  62. $name =~ s/^\*((main)?(\Q$pkg\E)?(::)?)//; # remove leading garbage
  63. }
  64. # if arg is bare number do version-check
  65. if ($name =~ /^(\d)(\.\d{3}(\d{2})?)*/) {
  66. die "Perl version $name required, this is only version $]\n"
  67. if $name > $];
  68. return 1;
  69. }
  70. if ($name =~/(\.al|\.ix)$/i) {
  71. my $oname = $name;
  72. $name =~ s/auto\///i;
  73. return 1 if safe_eval('Win32::FreeStanding::AutoLoad',$name);
  74. # this error text has to match the one output by perl.
  75. # Tk depends on this!
  76. die "Can't locate $oname in \@INC (\@INC contains: @INC)";
  77. }
  78. return 1 if safe_eval('Win32::FreeStanding::UseModule', $name);
  79. {
  80. my $oname = $name;
  81. $name = $pkg . '::' . $name;
  82. return 1 if safe_eval('Win32::FreeStanding::UseModule', $name);
  83. # this error text has to match the one output by perl.
  84. # Tk depends on this!
  85. die "Can't locate $oname in \@INC (\@INC contains: @INC)";
  86. }
  87. }
  88. ######################################################################
  89. sub do($) {
  90. my $name = shift;
  91. if (safe_eval('Win32::FreeStanding::Do', $name)) {
  92. return 1;
  93. }
  94. die "do $name Failed : $@\n";
  95. }
  96. ######################################################################
  97. *{"CORE::GLOBAL::require"} = \&Win32::FreeStanding::require;
  98. *{"CORE::GLOBAL::do"} = \&Win32::FreeStanding::do;
  99. *{"CORE::GLOBAL::exit"} = \&Win32::FreeStanding::Exit;
  100. safe_eval('Win32::FreeStanding::UseModule', 'DynaLoader');
  101. $old_dynaloader_bootstrap = \&DynaLoader::bootstrap;
  102. *{"DynaLoader::bootstrap"} = \&Win32::FreeStanding::bootstrap;
  103. 1;