1 package ExtUtils::Typemaps::Cmd;
7 use ExtUtils::Typemaps;
11 our @ISA = qw(Exporter);
12 our @EXPORT = qw(embeddable_typemap);
13 our %EXPORT_TAGS = (all => \@EXPORT);
15 sub embeddable_typemap {
19 my @tm_objs = map [$_, _intuit_typemap_source($_)], @tms;
21 # merge or short-circuit
24 # just one, merge would be pointless
25 $final_tm = shift(@tm_objs)->[1];
28 # multiple, need merge
29 $final_tm = ExtUtils::Typemaps->new;
30 foreach my $other_tm (@tm_objs) {
31 my ($tm_ident, $tm_obj) = @$other_tm;
33 $final_tm->merge(typemap => $tm_obj);
36 my $err = $@ || 'Zombie error';
37 die "Failed to merge typ";
42 # stringify for embedding
43 return $final_tm->as_embedded_typemap();
48 return eval "require $name; 1";
56 if (/::/) { # looks like FQ module name, try that first
57 foreach my $module ($ident, "ExtUtils::Typemaps::$ident") {
58 if (_load_module($module)) {
59 eval { $tm = $module->new }
65 foreach my $module ("ExtUtils::Typemaps::$ident", "$ident") {
66 if (_load_module($module)) {
67 eval { $tm = $module->new }
76 return unless -e $ident and -r _;
77 return ExtUtils::Typemaps->new(file => $ident);
80 # Try to find typemap either from module or file
81 sub _intuit_typemap_source {
82 my $identifier = shift;
85 if ($identifier =~ /::/ || $identifier !~ /[^\w_]/) {
86 @locate_attempts = qw(module file);
89 @locate_attempts = qw(file module);
92 foreach my $source (@locate_attempts) {
93 my $tm = $sources{$source}->($identifier);
94 return $tm if defined $tm;
97 die "Unable to find typemap for '$identifier': "
98 . "Tried to load both as file or module and failed.\n";
104 ExtUtils::Typemaps::Cmd - Quick commands for handling typemaps
110 INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd \
111 -e "print embeddable_typemap(q{Excommunicated})"
113 Loads C<ExtUtils::Typemaps::Excommunicated>, instantiates an object,
114 and dumps it as an embeddable typemap for use directly in your XS file.
118 This is a helper module for L<ExtUtils::Typemaps> for quick
119 one-liners, specifically for inclusion of shared typemaps
120 that live on CPAN into an XS file (see SYNOPSIS).
122 For this reason, the following functions are exported by default:
124 =head1 EXPORTED FUNCTIONS
126 =head2 embeddable_typemap
128 Given a list of identifiers, C<embeddable_typemap>
129 tries to load typemaps from a file of the given name(s),
130 or from a module that is an C<ExtUtils::Typemaps> subclass.
132 Returns a string representation of the merged typemaps that can
133 be included verbatim into XS. Example:
135 print embeddable_typemap(
136 "Excommunicated", "ExtUtils::Typemaps::Basic", "./typemap"
139 This will try to load a module C<ExtUtils::Typemaps::Excommunicated>
140 and use it as an C<ExtUtils::Typemaps> subclass. If that fails, it'll
141 try loading C<Excommunicated> as a module, if that fails, it'll try to
142 read a file called F<Excommunicated>. It'll work similarly for the
143 second argument, but the third will be loaded as a file first.
145 After loading all typemap files or modules, it will merge them in the
146 specified order and dump the result as an embeddable typemap.
150 L<ExtUtils::Typemaps>
156 Steffen Mueller C<<smueller@cpan.org>>
158 =head1 COPYRIGHT & LICENSE
160 Copyright 2012 Steffen Mueller
162 This program is free software; you can redistribute it and/or
163 modify it under the same terms as Perl itself.