PageRenderTime 26ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Master/tlpkg/tlperl/lib/ExtUtils/Typemaps/Cmd.pm

https://bitbucket.org/preining/tex-live
Perl | 168 lines | 135 code | 27 blank | 6 comment | 18 complexity | 0e73d023d5a9717d923791458af39fb2 MD5 | raw file
  1. package ExtUtils::Typemaps::Cmd;
  2. use 5.006001;
  3. use strict;
  4. use warnings;
  5. our $VERSION = '3.16';
  6. use ExtUtils::Typemaps;
  7. require Exporter;
  8. our @ISA = qw(Exporter);
  9. our @EXPORT = qw(embeddable_typemap);
  10. our %EXPORT_TAGS = (all => \@EXPORT);
  11. sub embeddable_typemap {
  12. my @tms = @_;
  13. # Get typemap objects
  14. my @tm_objs = map [$_, _intuit_typemap_source($_)], @tms;
  15. # merge or short-circuit
  16. my $final_tm;
  17. if (@tm_objs == 1) {
  18. # just one, merge would be pointless
  19. $final_tm = shift(@tm_objs)->[1];
  20. }
  21. else {
  22. # multiple, need merge
  23. $final_tm = ExtUtils::Typemaps->new;
  24. foreach my $other_tm (@tm_objs) {
  25. my ($tm_ident, $tm_obj) = @$other_tm;
  26. eval {
  27. $final_tm->merge(typemap => $tm_obj);
  28. 1
  29. } or do {
  30. my $err = $@ || 'Zombie error';
  31. die "Failed to merge typ";
  32. }
  33. }
  34. }
  35. # stringify for embedding
  36. return $final_tm->as_embedded_typemap();
  37. }
  38. sub _load_module {
  39. my $name = shift;
  40. return eval "require $name; 1";
  41. }
  42. SCOPE: {
  43. my %sources = (
  44. module => sub {
  45. my $ident = shift;
  46. my $tm;
  47. if (/::/) { # looks like FQ module name, try that first
  48. foreach my $module ($ident, "ExtUtils::Typemaps::$ident") {
  49. if (_load_module($module)) {
  50. eval { $tm = $module->new }
  51. and return $tm;
  52. }
  53. }
  54. }
  55. else {
  56. foreach my $module ("ExtUtils::Typemaps::$ident", "$ident") {
  57. if (_load_module($module)) {
  58. eval { $tm = $module->new }
  59. and return $tm;
  60. }
  61. }
  62. }
  63. return();
  64. },
  65. file => sub {
  66. my $ident = shift;
  67. return unless -e $ident and -r _;
  68. return ExtUtils::Typemaps->new(file => $ident);
  69. },
  70. );
  71. # Try to find typemap either from module or file
  72. sub _intuit_typemap_source {
  73. my $identifier = shift;
  74. my @locate_attempts;
  75. if ($identifier =~ /::/ || $identifier !~ /[^\w_]/) {
  76. @locate_attempts = qw(module file);
  77. }
  78. else {
  79. @locate_attempts = qw(file module);
  80. }
  81. foreach my $source (@locate_attempts) {
  82. my $tm = $sources{$source}->($identifier);
  83. return $tm if defined $tm;
  84. }
  85. die "Unable to find typemap for '$identifier': "
  86. . "Tried to load both as file or module and failed.\n";
  87. }
  88. } # end SCOPE
  89. =head1 NAME
  90. ExtUtils::Typemaps::Cmd - Quick commands for handling typemaps
  91. =head1 SYNOPSIS
  92. From XS:
  93. INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd \
  94. -e "print embeddable_typemap(q{Excommunicated})"
  95. Loads C<ExtUtils::Typemaps::Excommunicated>, instantiates an object,
  96. and dumps it as an embeddable typemap for use directly in your XS file.
  97. =head1 DESCRIPTION
  98. This is a helper module for L<ExtUtils::Typemaps> for quick
  99. one-liners, specifically for inclusion of shared typemaps
  100. that live on CPAN into an XS file (see SYNOPSIS).
  101. For this reason, the following functions are exported by default:
  102. =head1 EXPORTED FUNCTIONS
  103. =head2 embeddable_typemap
  104. Given a list of identifiers, C<embeddable_typemap>
  105. tries to load typemaps from a file of the given name(s),
  106. or from a module that is an C<ExtUtils::Typemaps> subclass.
  107. Returns a string representation of the merged typemaps that can
  108. be included verbatim into XS. Example:
  109. print embeddable_typemap(
  110. "Excommunicated", "ExtUtils::Typemaps::Basic", "./typemap"
  111. );
  112. This will try to load a module C<ExtUtils::Typemaps::Excommunicated>
  113. and use it as an C<ExtUtils::Typemaps> subclass. If that fails, it'll
  114. try loading C<Excommunicated> as a module, if that fails, it'll try to
  115. read a file called F<Excommunicated>. It'll work similarly for the
  116. second argument, but the third will be loaded as a file first.
  117. After loading all typemap files or modules, it will merge them in the
  118. specified order and dump the result as an embeddable typemap.
  119. =head1 SEE ALSO
  120. L<ExtUtils::Typemaps>
  121. L<perlxs>
  122. =head1 AUTHOR
  123. Steffen Mueller C<<smueller@cpan.org>>
  124. =head1 COPYRIGHT & LICENSE
  125. Copyright 2012 Steffen Mueller
  126. This program is free software; you can redistribute it and/or
  127. modify it under the same terms as Perl itself.
  128. =cut
  129. 1;