File Coverage

lib/ExtUtils/Mksymlists.pm
Criterion Covered Total %
statement 15 140 10.7
branch 0 70 0.0
condition 0 26 0.0
subroutine 5 11 45.5
total 20 247 8.1


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