[win32] add archname to *sitearch in config.{b,g,v}c
[p5sagit/p5-mst-13.2.git] / lib / AutoSplit.pm
CommitLineData
a0d0e21e 1package AutoSplit;
2
3require 5.000;
4require Exporter;
5
6use Config;
7use Carp;
68dc0745 8use File::Path qw(mkpath);
a0d0e21e 9
10@ISA = qw(Exporter);
11@EXPORT = qw(&autosplit &autosplit_lib_modules);
3edbfbe5 12@EXPORT_OK = qw($Verbose $Keep $Maxlen $CheckForAutoloader $CheckModTime);
a0d0e21e 13
f06db76b 14=head1 NAME
15
16AutoSplit - split a package for autoloading
17
cb1a09d0 18=head1 SYNOPSIS
19
21c92a1d 20 perl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
21
22 use AutoSplit; autosplit($file, $dir, $keep, $check, $modtime);
23
24for perl versions 5.002 and later:
84dc3c4d 25
21c92a1d 26 perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], $k, $chk, $modtime)' ...
cb1a09d0 27
f06db76b 28=head1 DESCRIPTION
29
30This function will split up your program into files that the AutoLoader
21c92a1d 31module can handle. It is used by both the standard perl libraries and by
32the MakeMaker utility, to automatically configure libraries for autoloading.
33
34The C<autosplit> interface splits the specified file into a hierarchy
35rooted at the directory C<$dir>. It creates directories as needed to reflect
36class hierarchy, and creates the file F<autosplit.ix>. This file acts as
37both forward declaration of all package routines, and as timestamp for the
38last update of the hierarchy.
39
40The remaining three arguments to C<autosplit> govern other options to the
41autosplitter. If the third argument, I<$keep>, is false, then any pre-existing
edb45e35 42C<*.al> files in the autoload directory are removed if they are no longer
21c92a1d 43part of the module (obsoleted functions). The fourth argument, I<$check>,
44instructs C<autosplit> to check the module currently being split to ensure
45that it does include a C<use> specification for the AutoLoader module, and
46skips the module if AutoLoader is not detected. Lastly, the I<$modtime>
47argument specifies that C<autosplit> is to check the modification time of the
48module against that of the C<autosplit.ix> file, and only split the module
49if it is newer.
50
51Typical use of AutoSplit in the perl MakeMaker utility is via the command-line
52with:
53
54 perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)'
55
56Defined as a Make macro, it is invoked with file and directory arguments;
57C<autosplit> will split the specified file into the specified directory and
58delete obsolete C<.al> files, after checking first that the module does use
59the AutoLoader, and ensuring that the module is not already currently split
60in its current form (the modtime test).
61
62The C<autosplit_lib_modules> form is used in the building of perl. It takes
63as input a list of files (modules) that are assumed to reside in a directory
64B<lib> relative to the current directory. Each file is sent to the
65autosplitter one at a time, to be split into the directory B<lib/auto>.
66
67In both usages of the autosplitter, only subroutines defined following the
68perl special marker I<__END__> are split out into separate files. Some
69routines may be placed prior to this marker to force their immediate loading
70and parsing.
71
72=head1 CAVEATS
73
74Currently, C<AutoSplit> cannot handle multiple package specifications
75within one file.
76
77=head1 DIAGNOSTICS
78
79C<AutoSplit> will inform the user if it is necessary to create the top-level
80directory specified in the invocation. It is preferred that the script or
81installation process that invokes C<AutoSplit> have created the full directory
82path ahead of time. This warning may indicate that the module is being split
83into an incorrect path.
84
85C<AutoSplit> will warn the user of all subroutines whose name causes potential
86file naming conflicts on machines with drastically limited (8 characters or
87less) file name length. Since the subroutine name is used as the file name,
88these warnings can aid in portability to such systems.
89
90Warnings are issued and the file skipped if C<AutoSplit> cannot locate either
91the I<__END__> marker or a "package Name;"-style specification.
92
93C<AutoSplit> will also emit general diagnostics for inability to create
94directories or files.
f06db76b 95
96=cut
97
a0d0e21e 98# for portability warn about names longer than $maxlen
99$Maxlen = 8; # 8 for dos, 11 (14-".al") for SYSVR3
100$Verbose = 1; # 0=none, 1=minimal, 2=list .al files
101$Keep = 0;
3edbfbe5 102$CheckForAutoloader = 1;
103$CheckModTime = 1;
a0d0e21e 104
3edbfbe5 105$IndexFile = "autosplit.ix"; # file also serves as timestamp
a0d0e21e 106$maxflen = 255;
107$maxflen = 14 if $Config{'d_flexfnam'} ne 'define';
39e571d4 108if (defined (&Dos::UseLFN)) {
109 $maxflen = Dos::UseLFN() ? 255 : 11;
110}
c6538b72 111$Is_VMS = ($^O eq 'VMS');
a0d0e21e 112
3edbfbe5 113
a0d0e21e 114sub autosplit{
75f92628 115 my($file, $autodir, $k, $ckal, $ckmt) = @_;
116 # $file - the perl source file to be split (after __END__)
117 # $autodir - the ".../auto" dir below which to write split subs
118 # Handle optional flags:
119 $keep = $Keep unless defined $k;
120 $ckal = $CheckForAutoloader unless defined $ckal;
121 $ckmt = $CheckModTime unless defined $ckmt;
122 autosplit_file($file, $autodir, $keep, $ckal, $ckmt);
a0d0e21e 123}
124
125
a0d0e21e 126# This function is used during perl building/installation
21c92a1d 127# ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
a0d0e21e 128
129sub autosplit_lib_modules{
130 my(@modules) = @_; # list of Module names
131
3e3baf6d 132 while(defined($_ = shift @modules)){
a0d0e21e 133 s#::#/#g; # incase specified as ABC::XYZ
4633a7c4 134 s|\\|/|g; # bug in ksh OS/2
a0d0e21e 135 s#^lib/##; # incase specified as lib/*.pm
c6538b72 136 if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs
a0d0e21e 137 my ($dir,$name) = (/(.*])(.*)/);
138 $dir =~ s/.*lib[\.\]]//;
139 $dir =~ s#[\.\]]#/#g;
140 $_ = $dir . $name;
141 }
3edbfbe5 142 autosplit_file("lib/$_", "lib/auto", $Keep, $CheckForAutoloader, $CheckModTime);
a0d0e21e 143 }
144 0;
145}
146
147
148# private functions
149
150sub autosplit_file{
151 my($filename, $autodir, $keep, $check_for_autoloader, $check_mod_time) = @_;
152 my(@names);
6e7678af 153 local($_);
a0d0e21e 154
155 # where to write output files
156 $autodir = "lib/auto" unless $autodir;
f86702cc 157 if ($Is_VMS) {
158 ($autodir = VMS::Filespec::unixpath($autodir)) =~ s{/$}{};
159 $filename = VMS::Filespec::unixify($filename); # may have dirs
160 }
3edbfbe5 161 unless (-d $autodir){
68dc0745 162 mkpath($autodir,0,0755);
3edbfbe5 163 # We should never need to create the auto dir here. installperl
164 # (or similar) should have done it. Expecting it to exist is a valuable
165 # sanity check against autosplitting into some random directory by mistake.
166 print "Warning: AutoSplit had to create top-level $autodir unexpectedly.\n";
167 }
a0d0e21e 168
169 # allow just a package name to be used
170 $filename .= ".pm" unless ($filename =~ m/\.pm$/);
171
172 open(IN, "<$filename") || die "AutoSplit: Can't open $filename: $!\n";
173 my($pm_mod_time) = (stat($filename))[9];
174 my($autoloader_seen) = 0;
f06db76b 175 my($in_pod) = 0;
a0d0e21e 176 while (<IN>) {
f06db76b 177 # Skip pod text.
178 $in_pod = 1 if /^=/;
179 $in_pod = 0 if /^=cut/;
180 next if ($in_pod || /^=cut/);
181
a0d0e21e 182 # record last package name seen
183 $package = $1 if (m/^\s*package\s+([\w:]+)\s*;/);
3edbfbe5 184 ++$autoloader_seen if m/^\s*(use|require)\s+AutoLoader\b/;
a0d0e21e 185 ++$autoloader_seen if m/\bISA\s*=.*\bAutoLoader\b/;
186 last if /^__END__/;
187 }
3edbfbe5 188 if ($check_for_autoloader && !$autoloader_seen){
189 print "AutoSplit skipped $filename: no AutoLoader used\n" if ($Verbose>=2);
190 return 0
191 }
a0d0e21e 192 $_ or die "Can't find __END__ in $filename\n";
193
194 $package or die "Can't find 'package Name;' in $filename\n";
195
68dc0745 196 my($modpname) = $package;
197 if ($^O eq 'MSWin32') {
198 $modpname =~ s#::#\\#g;
199 } else {
200 $modpname =~ s#::#/#g;
201 }
a0d0e21e 202
68dc0745 203 die "Package $package ($modpname.pm) does not match filename $filename"
204 unless ($filename =~ m/\Q$modpname.pm\E$/ or
39e571d4 205 ($^O eq 'dos') or ($^O eq 'MSWin32') or
c6538b72 206 $Is_VMS && $filename =~ m/$modpname.pm/i);
a0d0e21e 207
68dc0745 208 my($al_idx_file) = "$autodir/$modpname/$IndexFile";
209
a0d0e21e 210 if ($check_mod_time){
211 my($al_ts_time) = (stat("$al_idx_file"))[9] || 1;
212 if ($al_ts_time >= $pm_mod_time){
213 print "AutoSplit skipped ($al_idx_file newer that $filename)\n"
214 if ($Verbose >= 2);
215 return undef; # one undef, not a list
216 }
217 }
218
219 my($from) = ($Verbose>=2) ? "$filename => " : "";
220 print "AutoSplitting $package ($from$autodir/$modpname)\n"
221 if $Verbose;
222
223 unless (-d "$autodir/$modpname"){
68dc0745 224 mkpath("$autodir/$modpname",0,0777);
a0d0e21e 225 }
226
227 # We must try to deal with some SVR3 systems with a limit of 14
228 # characters for file names. Sadly we *cannot* simply truncate all
229 # file names to 14 characters on these systems because we *must*
230 # create filenames which exactly match the names used by AutoLoader.pm.
231 # This is a problem because some systems silently truncate the file
232 # names while others treat long file names as an error.
233
234 # We do not yet deal with multiple packages within one file.
235 # Ideally both of these styles should work.
236 #
237 # package NAME;
238 # __END__
239 # sub AAA { ... }
240 # package NAME::option1;
241 # sub BBB { ... }
242 # package NAME::option2;
243 # sub BBB { ... }
244 #
245 # package NAME;
246 # __END__
247 # sub AAA { ... }
248 # sub NAME::option1::BBB { ... }
249 # sub NAME::option2::BBB { ... }
250 #
251 # For now both of these produce warnings.
252
39e571d4 253 my $Is83 = $maxflen==11; # plain, case INSENSITIVE dos filenames
254
a0d0e21e 255 open(OUT,">/dev/null") || open(OUT,">nla0:"); # avoid 'not opened' warning
4633a7c4 256 my(@subnames, %proto);
96bc026d 257 my @cache = ();
258 my $caching = 1;
a0d0e21e 259 while (<IN>) {
96bc026d 260 next if /^=\w/ .. /^=cut/;
a0d0e21e 261 if (/^package ([\w:]+)\s*;/) {
262 warn "package $1; in AutoSplit section ignored. Not currently supported.";
263 }
4633a7c4 264 if (/^sub\s+([\w:]+)(\s*\(.*?\))?/) {
a0d0e21e 265 print OUT "1;\n";
4633a7c4 266 my $subname = $1;
40da2db3 267 $proto{$1} = $2 || '';
a0d0e21e 268 if ($subname =~ m/::/){
269 warn "subs with package names not currently supported in AutoSplit section";
270 }
271 push(@subnames, $subname);
272 my($lname, $sname) = ($subname, substr($subname,0,$maxflen-3));
273 my($lpath) = "$autodir/$modpname/$lname.al";
274 my($spath) = "$autodir/$modpname/$sname.al";
275 unless(open(OUT, ">$lpath")){
276 open(OUT, ">$spath") or die "Can't create $spath: $!\n";
39e571d4 277 push(@names, $Is83 ? lc $sname : $sname);
278 print " writing $spath (with truncated name)\n" if ($Verbose>=1);
a0d0e21e 279 }else{
39e571d4 280 push(@names, $Is83 ? lc substr ($lname,0,8) : $lname);
a0d0e21e 281 print " writing $lpath\n" if ($Verbose>=2);
282 }
283 print OUT "# NOTE: Derived from $filename. ",
284 "Changes made here will be lost.\n";
285 print OUT "package $package;\n\n";
96bc026d 286 print OUT @cache;
287 @cache = ();
288 $caching = 0;
289 }
290 if($caching) {
291 push(@cache, $_) if @cache || /\S/;
292 }
293 else {
294 print OUT $_;
295 }
296 if(/^}/) {
297 if($caching) {
298 print OUT @cache;
299 @cache = ();
300 }
301 print OUT "\n";
302 $caching = 1;
a0d0e21e 303 }
a0d0e21e 304 }
96bc026d 305 print OUT @cache,"1;\n";
a0d0e21e 306 close(OUT);
307 close(IN);
308
309 if (!$keep){ # don't keep any obsolete *.al files in the directory
310 my(%names);
311 @names{@names} = @names;
312 opendir(OUTDIR,"$autodir/$modpname");
313 foreach(sort readdir(OUTDIR)){
314 next unless /\.al$/;
315 my($subname) = m/(.*)\.al$/;
316 next if $names{substr($subname,0,$maxflen-3)};
39e571d4 317 next if ($Is83 && $names{lc substr($subname,0,8)});
a0d0e21e 318 my($file) = "$autodir/$modpname/$_";
319 print " deleting $file\n" if ($Verbose>=2);
f06db76b 320 my($deleted,$thistime); # catch all versions on VMS
321 do { $deleted += ($thistime = unlink $file) } while ($thistime);
322 carp "Unable to delete $file: $!" unless $deleted;
a0d0e21e 323 }
324 closedir(OUTDIR);
325 }
326
327 open(TS,">$al_idx_file") or
328 carp "AutoSplit: unable to create timestamp file ($al_idx_file): $!";
329 print TS "# Index created by AutoSplit for $filename (file acts as timestamp)\n";
f06db76b 330 print TS "package $package;\n";
4633a7c4 331 print TS map("sub $_$proto{$_} ;\n", @subnames);
f06db76b 332 print TS "1;\n";
a0d0e21e 333 close(TS);
334
335 check_unique($package, $Maxlen, 1, @names);
336
337 @names;
338}
339
340
341sub check_unique{
342 my($module, $maxlen, $warn, @names) = @_;
343 my(%notuniq) = ();
344 my(%shorts) = ();
345 my(@toolong) = grep(length > $maxlen, @names);
346
347 foreach(@toolong){
348 my($trunc) = substr($_,0,$maxlen);
349 $notuniq{$trunc}=1 if $shorts{$trunc};
350 $shorts{$trunc} = ($shorts{$trunc}) ? "$shorts{$trunc}, $_" : $_;
351 }
352 if (%notuniq && $warn){
353 print "$module: some names are not unique when truncated to $maxlen characters:\n";
354 foreach(keys %notuniq){
355 print " $shorts{$_} truncate to $_\n";
356 }
357 }
358 %notuniq;
359}
360
3611;
362__END__
363
364# test functions so AutoSplit.pm can be applied to itself:
365sub test1{ "test 1\n"; }
366sub test2{ "test 2\n"; }
367sub test3{ "test 3\n"; }
368sub test4{ "test 4\n"; }
369
370