10 @EXPORT = qw(&autosplit &autosplit_lib_modules);
11 @EXPORT_OK = qw($Verbose $Keep $Maxlen $CheckForAutoloader $CheckModTime);
15 AutoSplit - split a package for autoloading
19 perl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
21 use AutoSplit; autosplit($file, $dir, $keep, $check, $modtime);
23 for perl versions 5.002 and later:
25 perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], $k, $chk, $modtime)' ...
29 This function will split up your program into files that the AutoLoader
30 module can handle. It is used by both the standard perl libraries and by
31 the MakeMaker utility, to automatically configure libraries for autoloading.
33 The C<autosplit> interface splits the specified file into a hierarchy
34 rooted at the directory C<$dir>. It creates directories as needed to reflect
35 class hierarchy, and creates the file F<autosplit.ix>. This file acts as
36 both forward declaration of all package routines, and as timestamp for the
37 last update of the hierarchy.
39 The remaining three arguments to C<autosplit> govern other options to the
40 autosplitter. If the third argument, I<$keep>, is false, then any pre-existing
41 C<.al> files in the autoload directory are removed if they are no longer
42 part of the module (obsoleted functions). The fourth argument, I<$check>,
43 instructs C<autosplit> to check the module currently being split to ensure
44 that it does include a C<use> specification for the AutoLoader module, and
45 skips the module if AutoLoader is not detected. Lastly, the I<$modtime>
46 argument specifies that C<autosplit> is to check the modification time of the
47 module against that of the C<autosplit.ix> file, and only split the module
50 Typical use of AutoSplit in the perl MakeMaker utility is via the command-line
53 perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)'
55 Defined as a Make macro, it is invoked with file and directory arguments;
56 C<autosplit> will split the specified file into the specified directory and
57 delete obsolete C<.al> files, after checking first that the module does use
58 the AutoLoader, and ensuring that the module is not already currently split
59 in its current form (the modtime test).
61 The C<autosplit_lib_modules> form is used in the building of perl. It takes
62 as input a list of files (modules) that are assumed to reside in a directory
63 B<lib> relative to the current directory. Each file is sent to the
64 autosplitter one at a time, to be split into the directory B<lib/auto>.
66 In both usages of the autosplitter, only subroutines defined following the
67 perl special marker I<__END__> are split out into separate files. Some
68 routines may be placed prior to this marker to force their immediate loading
73 Currently, C<AutoSplit> cannot handle multiple package specifications
78 C<AutoSplit> will inform the user if it is necessary to create the top-level
79 directory specified in the invocation. It is preferred that the script or
80 installation process that invokes C<AutoSplit> have created the full directory
81 path ahead of time. This warning may indicate that the module is being split
82 into an incorrect path.
84 C<AutoSplit> will warn the user of all subroutines whose name causes potential
85 file naming conflicts on machines with drastically limited (8 characters or
86 less) file name length. Since the subroutine name is used as the file name,
87 these warnings can aid in portability to such systems.
89 Warnings are issued and the file skipped if C<AutoSplit> cannot locate either
90 the I<__END__> marker or a "package Name;"-style specification.
92 C<AutoSplit> will also emit general diagnostics for inability to create
97 # for portability warn about names longer than $maxlen
98 $Maxlen = 8; # 8 for dos, 11 (14-".al") for SYSVR3
99 $Verbose = 1; # 0=none, 1=minimal, 2=list .al files
101 $CheckForAutoloader = 1;
104 $IndexFile = "autosplit.ix"; # file also serves as timestamp
106 $maxflen = 14 if $Config{'d_flexfnam'} ne 'define';
107 $Is_VMS = ($^O eq 'VMS');
111 my($file, $autodir, $k, $ckal, $ckmt) = @_;
112 # $file - the perl source file to be split (after __END__)
113 # $autodir - the ".../auto" dir below which to write split subs
114 # Handle optional flags:
115 $keep = $Keep unless defined $k;
116 $ckal = $CheckForAutoloader unless defined $ckal;
117 $ckmt = $CheckModTime unless defined $ckmt;
118 autosplit_file($file, $autodir, $keep, $ckal, $ckmt);
122 # This function is used during perl building/installation
123 # ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
125 sub autosplit_lib_modules{
126 my(@modules) = @_; # list of Module names
129 s#::#/#g; # incase specified as ABC::XYZ
130 s|\\|/|g; # bug in ksh OS/2
131 s#^lib/##; # incase specified as lib/*.pm
132 if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs
133 my ($dir,$name) = (/(.*])(.*)/);
134 $dir =~ s/.*lib[\.\]]//;
135 $dir =~ s#[\.\]]#/#g;
138 autosplit_file("lib/$_", "lib/auto", $Keep, $CheckForAutoloader, $CheckModTime);
147 my($filename, $autodir, $keep, $check_for_autoloader, $check_mod_time) = @_;
150 # where to write output files
151 $autodir = "lib/auto" unless $autodir;
153 ($autodir = VMS::Filespec::unixpath($autodir)) =~ s{/$}{};
154 $filename = VMS::Filespec::unixify($filename); # may have dirs
156 unless (-d $autodir){
158 foreach(split(/\//,$autodir)){
161 mkdir("@p",0755) or die "AutoSplit unable to mkdir @p: $!";
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";
169 # allow just a package name to be used
170 $filename .= ".pm" unless ($filename =~ m/\.pm$/);
172 open(IN, "<$filename") || die "AutoSplit: Can't open $filename: $!\n";
173 my($pm_mod_time) = (stat($filename))[9];
174 my($autoloader_seen) = 0;
179 $in_pod = 0 if /^=cut/;
180 next if ($in_pod || /^=cut/);
182 # record last package name seen
183 $package = $1 if (m/^\s*package\s+([\w:]+)\s*;/);
184 ++$autoloader_seen if m/^\s*(use|require)\s+AutoLoader\b/;
185 ++$autoloader_seen if m/\bISA\s*=.*\bAutoLoader\b/;
188 if ($check_for_autoloader && !$autoloader_seen){
189 print "AutoSplit skipped $filename: no AutoLoader used\n" if ($Verbose>=2);
192 $_ or die "Can't find __END__ in $filename\n";
194 $package or die "Can't find 'package Name;' in $filename\n";
196 my($modpname) = $package; $modpname =~ s#::#/#g;
197 my($al_idx_file) = "$autodir/$modpname/$IndexFile";
199 die "Package $package does not match filename $filename"
200 unless ($filename =~ m/$modpname.pm$/ or
202 $Is_VMS && $filename =~ m/$modpname.pm/i);
204 if ($check_mod_time){
205 my($al_ts_time) = (stat("$al_idx_file"))[9] || 1;
206 if ($al_ts_time >= $pm_mod_time){
207 print "AutoSplit skipped ($al_idx_file newer that $filename)\n"
209 return undef; # one undef, not a list
213 my($from) = ($Verbose>=2) ? "$filename => " : "";
214 print "AutoSplitting $package ($from$autodir/$modpname)\n"
217 unless (-d "$autodir/$modpname"){
219 foreach(split(/\//,"$autodir/$modpname")){
222 mkdir("@p",0777) or die "AutoSplit unable to mkdir @p: $!";
226 # We must try to deal with some SVR3 systems with a limit of 14
227 # characters for file names. Sadly we *cannot* simply truncate all
228 # file names to 14 characters on these systems because we *must*
229 # create filenames which exactly match the names used by AutoLoader.pm.
230 # This is a problem because some systems silently truncate the file
231 # names while others treat long file names as an error.
233 # We do not yet deal with multiple packages within one file.
234 # Ideally both of these styles should work.
239 # package NAME::option1;
241 # package NAME::option2;
247 # sub NAME::option1::BBB { ... }
248 # sub NAME::option2::BBB { ... }
250 # For now both of these produce warnings.
252 open(OUT,">/dev/null") || open(OUT,">nla0:"); # avoid 'not opened' warning
253 my(@subnames, %proto);
257 next if /^=\w/ .. /^=cut/;
258 if (/^package ([\w:]+)\s*;/) {
259 warn "package $1; in AutoSplit section ignored. Not currently supported.";
261 if (/^sub\s+([\w:]+)(\s*\(.*?\))?/) {
264 $proto{$1} = $2 || '';
265 if ($subname =~ m/::/){
266 warn "subs with package names not currently supported in AutoSplit section";
268 push(@subnames, $subname);
269 my($lname, $sname) = ($subname, substr($subname,0,$maxflen-3));
270 my($lpath) = "$autodir/$modpname/$lname.al";
271 my($spath) = "$autodir/$modpname/$sname.al";
272 unless(open(OUT, ">$lpath")){
273 open(OUT, ">$spath") or die "Can't create $spath: $!\n";
274 push(@names, $sname);
275 print " writing $spath (with truncated name)\n"
278 push(@names, $lname);
279 print " writing $lpath\n" if ($Verbose>=2);
281 print OUT "# NOTE: Derived from $filename. ",
282 "Changes made here will be lost.\n";
283 print OUT "package $package;\n\n";
289 push(@cache, $_) if @cache || /\S/;
303 print OUT @cache,"1;\n";
307 if (!$keep){ # don't keep any obsolete *.al files in the directory
309 @names{@names} = @names;
310 opendir(OUTDIR,"$autodir/$modpname");
311 foreach(sort readdir(OUTDIR)){
313 my($subname) = m/(.*)\.al$/;
314 next if $names{substr($subname,0,$maxflen-3)};
315 my($file) = "$autodir/$modpname/$_";
316 print " deleting $file\n" if ($Verbose>=2);
317 my($deleted,$thistime); # catch all versions on VMS
318 do { $deleted += ($thistime = unlink $file) } while ($thistime);
319 carp "Unable to delete $file: $!" unless $deleted;
324 open(TS,">$al_idx_file") or
325 carp "AutoSplit: unable to create timestamp file ($al_idx_file): $!";
326 print TS "# Index created by AutoSplit for $filename (file acts as timestamp)\n";
327 print TS "package $package;\n";
328 print TS map("sub $_$proto{$_} ;\n", @subnames);
332 check_unique($package, $Maxlen, 1, @names);
339 my($module, $maxlen, $warn, @names) = @_;
342 my(@toolong) = grep(length > $maxlen, @names);
345 my($trunc) = substr($_,0,$maxlen);
346 $notuniq{$trunc}=1 if $shorts{$trunc};
347 $shorts{$trunc} = ($shorts{$trunc}) ? "$shorts{$trunc}, $_" : $_;
349 if (%notuniq && $warn){
350 print "$module: some names are not unique when truncated to $maxlen characters:\n";
351 foreach(keys %notuniq){
352 print " $shorts{$_} truncate to $_\n";
361 # test functions so AutoSplit.pm can be applied to itself:
362 sub test1{ "test 1\n"; }
363 sub test2{ "test 2\n"; }
364 sub test3{ "test 3\n"; }
365 sub test4{ "test 4\n"; }