File Coverage

lib/ExtUtils/Mksymlists.pm
Criterion Covered Total %
statement 17 144 11.8
branch 0 72 0.0
condition 0 26 0.0
subroutine 6 12 50.0
pod 0 1 0.0
total 23 255 9.0


line stmt bran cond sub pod time code
1             package ExtUtils::Mksymlists;
2              
3 1     1   11143 use 5.006;
  1         7  
4 1     1   7 use strict qw[ subs refs ];
  1         3  
  1         68  
5             # no strict 'vars'; # until filehandles are exempted
6 1     1   14 use warnings;
  1         3  
  1         75  
7              
8 1     1   6 use Carp;
  1         2  
  1         114  
9 1     1   6 use Exporter;
  1         2  
  1         111  
10 1     1   8 use Config;
  1         3  
  1         2959  
11              
12             our @ISA = qw(Exporter);
13             our @EXPORT = qw(&Mksymlists);
14             our $VERSION = '7.78';
15             $VERSION =~ tr/_//d;
16              
17             sub Mksymlists {
18 0     0 0   my(%spec) = @_;
19 0           my($osname) = $^O;
20              
21             croak("Insufficient information specified to Mksymlists")
22             unless ( $spec{NAME} or
23 0 0 0       ($spec{FILE} and ($spec{DL_FUNCS} or $spec{FUNCLIST})) );
      0        
      0        
24              
25 0 0         $spec{DL_VARS} = [] unless $spec{DL_VARS};
26 0 0         ($spec{FILE} = $spec{NAME}) =~ s/.*::// unless $spec{FILE};
27 0 0         $spec{FUNCLIST} = [] unless $spec{FUNCLIST};
28             $spec{DL_FUNCS} = { $spec{NAME} => [] }
29 0           unless ( ($spec{DL_FUNCS} and keys %{$spec{DL_FUNCS}}) or
30 0 0 0       @{$spec{FUNCLIST}});
  0   0        
31 0 0         if (defined $spec{DL_FUNCS}) {
32 0           foreach my $package (sort keys %{$spec{DL_FUNCS}}) {
  0            
33 0           my($packprefix,$bootseen);
34 0           ($packprefix = $package) =~ s/\W/_/g;
35 0           foreach my $sym (@{$spec{DL_FUNCS}->{$package}}) {
  0            
36 0 0         if ($sym =~ /^boot_/) {
37 0           push(@{$spec{FUNCLIST}},$sym);
  0            
38 0           $bootseen++;
39             }
40             else {
41 0           push(@{$spec{FUNCLIST}},"XS_${packprefix}_$sym");
  0            
42             }
43             }
44 0 0         push(@{$spec{FUNCLIST}},"boot_$packprefix") unless $bootseen;
  0            
45             }
46             }
47              
48             # We'll need this if we ever add any OS which uses mod2fname
49             # not as pseudo-builtin.
50             # require DynaLoader;
51 0 0 0       if (defined &DynaLoader::mod2fname and not $spec{DLBASE}) {
52 0           $spec{DLBASE} = DynaLoader::mod2fname([ split(/::/,$spec{NAME}) ]);
53             }
54              
55 0 0         if ($osname eq 'aix') { _write_aix(\%spec); }
  0 0          
    0          
    0          
    0          
56 0           elsif ($osname eq 'MacOS'){ _write_aix(\%spec) }
57 0           elsif ($osname eq 'VMS') { _write_vms(\%spec) }
58 0           elsif ($osname eq 'os2') { _write_os2(\%spec) }
59 0           elsif ($osname eq 'MSWin32') { _write_win32(\%spec) }
60             else {
61 0           croak("Don't know how to create linker option file for $osname\n");
62             }
63             }
64              
65              
66             sub _write_aix {
67 0     0     my($data) = @_;
68              
69 0           rename "$data->{FILE}.exp", "$data->{FILE}.exp_old";
70              
71 0 0         open( my $exp, ">", "$data->{FILE}.exp")
72             or croak("Can't create $data->{FILE}.exp: $!\n");
73 0 0         print $exp join("\n",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
  0            
  0            
74 0 0         print $exp join("\n",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
  0            
  0            
75 0           close $exp;
76             }
77              
78              
79             sub _write_os2 {
80 0     0     my($data) = @_;
81 0           require Config;
82 0 0         my $threaded = ($Config::Config{archname} =~ /-thread/ ? " threaded" : "");
83              
84 0 0         if (not $data->{DLBASE}) {
85 0           ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
86 0           $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
87             }
88 0   0       my $distname = $data->{DISTNAME} || $data->{NAME};
89 0           $distname = "Distribution $distname";
90 0   0       my $patchlevel = " pl$Config{perl_patchlevel}" || '';
91             my $comment = sprintf "Perl (v%s%s%s) module %s",
92 0           $Config::Config{version}, $threaded, $patchlevel, $data->{NAME};
93 0           chomp $comment;
94 0 0 0       if ($data->{INSTALLDIRS} and $data->{INSTALLDIRS} eq 'perl') {
95 0           $distname = 'perl5-porters@perl.org';
96 0           $comment = "Core $comment";
97             }
98 0           $comment = "$comment (Perl-config: $Config{config_args})";
99 0 0         $comment = substr($comment, 0, 200) . "...)" if length $comment > 203;
100 0           rename "$data->{FILE}.def", "$data->{FILE}_def.old";
101              
102 0 0         open(my $def, ">", "$data->{FILE}.def")
103             or croak("Can't create $data->{FILE}.def: $!\n");
104 0           print $def "LIBRARY '$data->{DLBASE}' INITINSTANCE TERMINSTANCE\n";
105 0           print $def "DESCRIPTION '\@#$distname:$data->{VERSION}#\@ $comment'\n";
106 0           print $def "CODE LOADONCALL\n";
107 0           print $def "DATA LOADONCALL NONSHARED MULTIPLE\n";
108 0           print $def "EXPORTS\n ";
109 0 0         print $def join("\n ",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
  0            
  0            
110 0 0         print $def join("\n ",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
  0            
  0            
111 0           _print_imports($def, $data);
112 0           close $def;
113             }
114              
115             sub _print_imports {
116 0     0     my ($def, $data)= @_;
117             my $imports= $data->{IMPORTS}
118 0 0         or return;
119 0 0         if ( keys %$imports ) {
120 0           print $def "IMPORTS\n";
121 0           foreach my $name (sort keys %$imports) {
122 0           print $def " $name=$imports->{$name}\n";
123             }
124             }
125             }
126              
127             sub _write_win32 {
128 0     0     my($data) = @_;
129              
130 0           require Config;
131 0 0         if (not $data->{DLBASE}) {
132 0           ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
133 0           $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
134             }
135 0           rename "$data->{FILE}.def", "$data->{FILE}_def.old";
136              
137 0 0         open( my $def, ">", "$data->{FILE}.def" )
138             or croak("Can't create $data->{FILE}.def: $!\n");
139             # put library name in quotes (it could be a keyword, like 'Alias')
140 0 0         if ($Config::Config{'cc'} !~ /\bgcc/i) {
141 0           print $def "LIBRARY \"$data->{DLBASE}\"\n";
142             }
143 0           print $def "EXPORTS\n ";
144 0           my @syms;
145             # Export public symbols both with and without underscores to
146             # ensure compatibility between DLLs from Borland C and Visual C
147             # NOTE: DynaLoader itself only uses the names without underscores,
148             # so this is only to cover the case when the extension DLL may be
149             # linked to directly from C. GSAR 97-07-10
150              
151             #bcc dropped in 5.16, so dont create useless extra symbols for export table
152 0 0         unless("$]" >= 5.016) {
153 0 0         if ($Config::Config{'cc'} =~ /^bcc/i) {
154             push @syms, "_$_", "$_ = _$_"
155 0           for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
  0            
  0            
156             }
157             else {
158             push @syms, "$_", "_$_ = $_"
159 0           for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
  0            
  0            
160             }
161             } else {
162             push @syms, "$_"
163 0           for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
  0            
  0            
164             }
165 0 0         print $def join("\n ",@syms, "\n") if @syms;
166 0           _print_imports($def, $data);
167 0           close $def;
168             }
169              
170              
171             sub _write_vms {
172 0     0     my($data) = @_;
173              
174 0           require Config; # a reminder for once we do $^O
175 0           require ExtUtils::XSSymSet;
176              
177 0           my($isvax) = $Config::Config{'archname'} =~ /VAX/i;
178 0           my($set) = new ExtUtils::XSSymSet;
179              
180 0           rename "$data->{FILE}.opt", "$data->{FILE}.opt_old";
181              
182 0 0         open(my $opt,">", "$data->{FILE}.opt")
183             or croak("Can't create $data->{FILE}.opt: $!\n");
184              
185             # Options file declaring universal symbols
186             # Used when linking shareable image for dynamic extension,
187             # or when linking PerlShr into which we've added this package
188             # as a static extension
189             # We don't do anything to preserve order, so we won't relax
190             # the GSMATCH criteria for a dynamic extension
191              
192             print $opt "case_sensitive=yes\n"
193 0 0         if $Config::Config{d_vms_case_sensitive_symbols};
194              
195 0           foreach my $sym (@{$data->{FUNCLIST}}) {
  0            
196 0           my $safe = $set->addsym($sym);
197 0 0         if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
  0            
198 0           else { print $opt "SYMBOL_VECTOR=($safe=PROCEDURE)\n"; }
199             }
200              
201 0           foreach my $sym (@{$data->{DL_VARS}}) {
  0            
202 0           my $safe = $set->addsym($sym);
203 0           print $opt "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n";
204 0 0         if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
  0            
205 0           else { print $opt "SYMBOL_VECTOR=($safe=DATA)\n"; }
206             }
207              
208 0           close $opt;
209             }
210              
211             1;
212              
213             __END__