8 use File::Path qw(mkpath);
11 @EXPORT = qw(&autosplit &autosplit_lib_modules);
12 @EXPORT_OK = qw($Verbose $Keep $Maxlen $CheckForAutoloader $CheckModTime);
16 AutoSplit - split a package for autoloading
20 perl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
22 use AutoSplit; autosplit($file, $dir, $keep, $check, $modtime);
24 for perl versions 5.002 and later:
26 perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], $k, $chk, $modtime)' ...
30 This function will split up your program into files that the AutoLoader
31 module can handle. It is used by both the standard perl libraries and by
32 the MakeMaker utility, to automatically configure libraries for autoloading.
34 The C<autosplit> interface splits the specified file into a hierarchy
35 rooted at the directory C<$dir>. It creates directories as needed to reflect
36 class hierarchy, and creates the file F<autosplit.ix>. This file acts as
37 both forward declaration of all package routines, and as timestamp for the
38 last update of the hierarchy.
40 The remaining three arguments to C<autosplit> govern other options to the
41 autosplitter. If the third argument, I<$keep>, is false, then any pre-existing
42 C<*.al> files in the autoload directory are removed if they are no longer
43 part of the module (obsoleted functions). The fourth argument, I<$check>,
44 instructs C<autosplit> to check the module currently being split to ensure
45 that it does include a C<use> specification for the AutoLoader module, and
46 skips the module if AutoLoader is not detected. Lastly, the I<$modtime>
47 argument specifies that C<autosplit> is to check the modification time of the
48 module against that of the C<autosplit.ix> file, and only split the module
51 Typical use of AutoSplit in the perl MakeMaker utility is via the command-line
54 perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)'
56 Defined as a Make macro, it is invoked with file and directory arguments;
57 C<autosplit> will split the specified file into the specified directory and
58 delete obsolete C<.al> files, after checking first that the module does use
59 the AutoLoader, and ensuring that the module is not already currently split
60 in its current form (the modtime test).
62 The C<autosplit_lib_modules> form is used in the building of perl. It takes
63 as input a list of files (modules) that are assumed to reside in a directory
64 B<lib> relative to the current directory. Each file is sent to the
65 autosplitter one at a time, to be split into the directory B<lib/auto>.
67 In both usages of the autosplitter, only subroutines defined following the
68 perl special marker I<__END__> are split out into separate files. Some
69 routines may be placed prior to this marker to force their immediate loading
74 Currently, C<AutoSplit> cannot handle multiple package specifications
79 C<AutoSplit> will inform the user if it is necessary to create the top-level
80 directory specified in the invocation. It is preferred that the script or
81 installation process that invokes C<AutoSplit> have created the full directory
82 path ahead of time. This warning may indicate that the module is being split
83 into an incorrect path.
85 C<AutoSplit> will warn the user of all subroutines whose name causes potential
86 file naming conflicts on machines with drastically limited (8 characters or
87 less) file name length. Since the subroutine name is used as the file name,
88 these warnings can aid in portability to such systems.
90 Warnings are issued and the file skipped if C<AutoSplit> cannot locate either
91 the I<__END__> marker or a "package Name;"-style specification.
93 C<AutoSplit> will also emit general diagnostics for inability to create
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
102 $CheckForAutoloader = 1;
105 $IndexFile = "autosplit.ix"; # file also serves as timestamp
107 $maxflen = 14 if $Config{'d_flexfnam'} ne 'define';
108 $Is_VMS = ($^O eq 'VMS');
112 my($file, $autodir, $k, $ckal, $ckmt) = @_;
113 # $file - the perl source file to be split (after __END__)
114 # $autodir - the ".../auto" dir below which to write split subs
115 # Handle optional flags:
116 $keep = $Keep unless defined $k;
117 $ckal = $CheckForAutoloader unless defined $ckal;
118 $ckmt = $CheckModTime unless defined $ckmt;
119 autosplit_file($file, $autodir, $keep, $ckal, $ckmt);
123 # This function is used during perl building/installation
124 # ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
126 sub autosplit_lib_modules{
127 my(@modules) = @_; # list of Module names
130 s#::#/#g; # incase specified as ABC::XYZ
131 s|\\|/|g; # bug in ksh OS/2
132 s#^lib/##; # incase specified as lib/*.pm
133 if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs
134 my ($dir,$name) = (/(.*])(.*)/);
135 $dir =~ s/.*lib[\.\]]//;
136 $dir =~ s#[\.\]]#/#g;
139 autosplit_file("lib/$_", "lib/auto", $Keep, $CheckForAutoloader, $CheckModTime);
148 my($filename, $autodir, $keep, $check_for_autoloader, $check_mod_time) = @_;
151 # where to write output files
152 $autodir = "lib/auto" unless $autodir;
154 ($autodir = VMS::Filespec::unixpath($autodir)) =~ s{/$}{};
155 $filename = VMS::Filespec::unixify($filename); # may have dirs
157 unless (-d $autodir){
158 mkpath($autodir,0,0755);
159 # We should never need to create the auto dir here. installperl
160 # (or similar) should have done it. Expecting it to exist is a valuable
161 # sanity check against autosplitting into some random directory by mistake.
162 print "Warning: AutoSplit had to create top-level $autodir unexpectedly.\n";
165 # allow just a package name to be used
166 $filename .= ".pm" unless ($filename =~ m/\.pm$/);
168 open(IN, "<$filename") || die "AutoSplit: Can't open $filename: $!\n";
169 my($pm_mod_time) = (stat($filename))[9];
170 my($autoloader_seen) = 0;
175 $in_pod = 0 if /^=cut/;
176 next if ($in_pod || /^=cut/);
178 # record last package name seen
179 $package = $1 if (m/^\s*package\s+([\w:]+)\s*;/);
180 ++$autoloader_seen if m/^\s*(use|require)\s+AutoLoader\b/;
181 ++$autoloader_seen if m/\bISA\s*=.*\bAutoLoader\b/;
184 if ($check_for_autoloader && !$autoloader_seen){
185 print "AutoSplit skipped $filename: no AutoLoader used\n" if ($Verbose>=2);
188 $_ or die "Can't find __END__ in $filename\n";
190 $package or die "Can't find 'package Name;' in $filename\n";
192 my($modpname) = $package;
193 if ($^O eq 'MSWin32') {
194 $modpname =~ s#::#\\#g;
196 $modpname =~ s#::#/#g;
199 die "Package $package ($modpname.pm) does not match filename $filename"
200 unless ($filename =~ m/\Q$modpname.pm\E$/ or
201 ($^O eq "msdos") or ($^O eq 'MSWin32') or
202 $Is_VMS && $filename =~ m/$modpname.pm/i);
204 my($al_idx_file) = "$autodir/$modpname/$IndexFile";
206 if ($check_mod_time){
207 my($al_ts_time) = (stat("$al_idx_file"))[9] || 1;
208 if ($al_ts_time >= $pm_mod_time){
209 print "AutoSplit skipped ($al_idx_file newer that $filename)\n"
211 return undef; # one undef, not a list
215 my($from) = ($Verbose>=2) ? "$filename => " : "";
216 print "AutoSplitting $package ($from$autodir/$modpname)\n"
219 unless (-d "$autodir/$modpname"){
220 mkpath("$autodir/$modpname",0,0777);
223 # We must try to deal with some SVR3 systems with a limit of 14
224 # characters for file names. Sadly we *cannot* simply truncate all
225 # file names to 14 characters on these systems because we *must*
226 # create filenames which exactly match the names used by AutoLoader.pm.
227 # This is a problem because some systems silently truncate the file
228 # names while others treat long file names as an error.
230 # We do not yet deal with multiple packages within one file.
231 # Ideally both of these styles should work.
236 # package NAME::option1;
238 # package NAME::option2;
244 # sub NAME::option1::BBB { ... }
245 # sub NAME::option2::BBB { ... }
247 # For now both of these produce warnings.
249 open(OUT,">/dev/null") || open(OUT,">nla0:"); # avoid 'not opened' warning
250 my(@subnames, %proto);
254 next if /^=\w/ .. /^=cut/;
255 if (/^package ([\w:]+)\s*;/) {
256 warn "package $1; in AutoSplit section ignored. Not currently supported.";
258 if (/^sub\s+([\w:]+)(\s*\(.*?\))?/) {
261 $proto{$1} = $2 || '';
262 if ($subname =~ m/::/){
263 warn "subs with package names not currently supported in AutoSplit section";
265 push(@subnames, $subname);
266 my($lname, $sname) = ($subname, substr($subname,0,$maxflen-3));
267 my($lpath) = "$autodir/$modpname/$lname.al";
268 my($spath) = "$autodir/$modpname/$sname.al";
269 unless(open(OUT, ">$lpath")){
270 open(OUT, ">$spath") or die "Can't create $spath: $!\n";
271 push(@names, $sname);
272 print " writing $spath (with truncated name)\n"
275 push(@names, $lname);
276 print " writing $lpath\n" if ($Verbose>=2);
278 print OUT "# NOTE: Derived from $filename. ",
279 "Changes made here will be lost.\n";
280 print OUT "package $package;\n\n";
286 push(@cache, $_) if @cache || /\S/;
300 print OUT @cache,"1;\n";
304 if (!$keep){ # don't keep any obsolete *.al files in the directory
306 @names{@names} = @names;
307 opendir(OUTDIR,"$autodir/$modpname");
308 foreach(sort readdir(OUTDIR)){
310 my($subname) = m/(.*)\.al$/;
311 next if $names{substr($subname,0,$maxflen-3)};
312 my($file) = "$autodir/$modpname/$_";
313 print " deleting $file\n" if ($Verbose>=2);
314 my($deleted,$thistime); # catch all versions on VMS
315 do { $deleted += ($thistime = unlink $file) } while ($thistime);
316 carp "Unable to delete $file: $!" unless $deleted;
321 open(TS,">$al_idx_file") or
322 carp "AutoSplit: unable to create timestamp file ($al_idx_file): $!";
323 print TS "# Index created by AutoSplit for $filename (file acts as timestamp)\n";
324 print TS "package $package;\n";
325 print TS map("sub $_$proto{$_} ;\n", @subnames);
329 check_unique($package, $Maxlen, 1, @names);
336 my($module, $maxlen, $warn, @names) = @_;
339 my(@toolong) = grep(length > $maxlen, @names);
342 my($trunc) = substr($_,0,$maxlen);
343 $notuniq{$trunc}=1 if $shorts{$trunc};
344 $shorts{$trunc} = ($shorts{$trunc}) ? "$shorts{$trunc}, $_" : $_;
346 if (%notuniq && $warn){
347 print "$module: some names are not unique when truncated to $maxlen characters:\n";
348 foreach(keys %notuniq){
349 print " $shorts{$_} truncate to $_\n";
358 # test functions so AutoSplit.pm can be applied to itself:
359 sub test1{ "test 1\n"; }
360 sub test2{ "test 2\n"; }
361 sub test3{ "test 3\n"; }
362 sub test4{ "test 4\n"; }