Don't warn on use of CCFLAGS
[p5sagit/p5-mst-13.2.git] / lib / AutoSplit.pm
CommitLineData
a0d0e21e 1package AutoSplit;
2
3require 5.000;
4require Exporter;
5
6use Config;
7use Carp;
8
9@ISA = qw(Exporter);
10@EXPORT = qw(&autosplit &autosplit_lib_modules);
3edbfbe5 11@EXPORT_OK = qw($Verbose $Keep $Maxlen $CheckForAutoloader $CheckModTime);
a0d0e21e 12
f06db76b 13=head1 NAME
14
15AutoSplit - split a package for autoloading
16
cb1a09d0 17=head1 SYNOPSIS
18
21c92a1d 19 perl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
20
21 use AutoSplit; autosplit($file, $dir, $keep, $check, $modtime);
22
23for perl versions 5.002 and later:
84dc3c4d 24
21c92a1d 25 perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], $k, $chk, $modtime)' ...
cb1a09d0 26
f06db76b 27=head1 DESCRIPTION
28
29This function will split up your program into files that the AutoLoader
21c92a1d 30module can handle. It is used by both the standard perl libraries and by
31the MakeMaker utility, to automatically configure libraries for autoloading.
32
33The C<autosplit> interface splits the specified file into a hierarchy
34rooted at the directory C<$dir>. It creates directories as needed to reflect
35class hierarchy, and creates the file F<autosplit.ix>. This file acts as
36both forward declaration of all package routines, and as timestamp for the
37last update of the hierarchy.
38
39The remaining three arguments to C<autosplit> govern other options to the
40autosplitter. If the third argument, I<$keep>, is false, then any pre-existing
41C<.al> files in the autoload directory are removed if they are no longer
42part of the module (obsoleted functions). The fourth argument, I<$check>,
43instructs C<autosplit> to check the module currently being split to ensure
44that it does include a C<use> specification for the AutoLoader module, and
45skips the module if AutoLoader is not detected. Lastly, the I<$modtime>
46argument specifies that C<autosplit> is to check the modification time of the
47module against that of the C<autosplit.ix> file, and only split the module
48if it is newer.
49
50Typical use of AutoSplit in the perl MakeMaker utility is via the command-line
51with:
52
53 perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)'
54
55Defined as a Make macro, it is invoked with file and directory arguments;
56C<autosplit> will split the specified file into the specified directory and
57delete obsolete C<.al> files, after checking first that the module does use
58the AutoLoader, and ensuring that the module is not already currently split
59in its current form (the modtime test).
60
61The C<autosplit_lib_modules> form is used in the building of perl. It takes
62as input a list of files (modules) that are assumed to reside in a directory
63B<lib> relative to the current directory. Each file is sent to the
64autosplitter one at a time, to be split into the directory B<lib/auto>.
65
66In both usages of the autosplitter, only subroutines defined following the
67perl special marker I<__END__> are split out into separate files. Some
68routines may be placed prior to this marker to force their immediate loading
69and parsing.
70
71=head1 CAVEATS
72
73Currently, C<AutoSplit> cannot handle multiple package specifications
74within one file.
75
76=head1 DIAGNOSTICS
77
78C<AutoSplit> will inform the user if it is necessary to create the top-level
79directory specified in the invocation. It is preferred that the script or
80installation process that invokes C<AutoSplit> have created the full directory
81path ahead of time. This warning may indicate that the module is being split
82into an incorrect path.
83
84C<AutoSplit> will warn the user of all subroutines whose name causes potential
85file naming conflicts on machines with drastically limited (8 characters or
86less) file name length. Since the subroutine name is used as the file name,
87these warnings can aid in portability to such systems.
88
89Warnings are issued and the file skipped if C<AutoSplit> cannot locate either
90the I<__END__> marker or a "package Name;"-style specification.
91
92C<AutoSplit> will also emit general diagnostics for inability to create
93directories or files.
f06db76b 94
95=cut
96
a0d0e21e 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
100$Keep = 0;
3edbfbe5 101$CheckForAutoloader = 1;
102$CheckModTime = 1;
a0d0e21e 103
3edbfbe5 104$IndexFile = "autosplit.ix"; # file also serves as timestamp
a0d0e21e 105$maxflen = 255;
106$maxflen = 14 if $Config{'d_flexfnam'} ne 'define';
c6538b72 107$Is_VMS = ($^O eq 'VMS');
a0d0e21e 108
3edbfbe5 109
a0d0e21e 110sub autosplit{
75f92628 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);
a0d0e21e 119}
120
121
a0d0e21e 122# This function is used during perl building/installation
21c92a1d 123# ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ...
a0d0e21e 124
125sub autosplit_lib_modules{
126 my(@modules) = @_; # list of Module names
127
128 foreach(@modules){
129 s#::#/#g; # incase specified as ABC::XYZ
4633a7c4 130 s|\\|/|g; # bug in ksh OS/2
a0d0e21e 131 s#^lib/##; # incase specified as lib/*.pm
c6538b72 132 if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs
a0d0e21e 133 my ($dir,$name) = (/(.*])(.*)/);
134 $dir =~ s/.*lib[\.\]]//;
135 $dir =~ s#[\.\]]#/#g;
136 $_ = $dir . $name;
137 }
3edbfbe5 138 autosplit_file("lib/$_", "lib/auto", $Keep, $CheckForAutoloader, $CheckModTime);
a0d0e21e 139 }
140 0;
141}
142
143
144# private functions
145
146sub autosplit_file{
147 my($filename, $autodir, $keep, $check_for_autoloader, $check_mod_time) = @_;
148 my(@names);
149
150 # where to write output files
151 $autodir = "lib/auto" unless $autodir;
f86702cc 152 if ($Is_VMS) {
153 ($autodir = VMS::Filespec::unixpath($autodir)) =~ s{/$}{};
154 $filename = VMS::Filespec::unixify($filename); # may have dirs
155 }
3edbfbe5 156 unless (-d $autodir){
157 local($", @p)="/";
158 foreach(split(/\//,$autodir)){
159 push(@p, $_);
160 next if -d "@p/";
161 mkdir("@p",0755) or die "AutoSplit unable to mkdir @p: $!";
162 }
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
196 my($modpname) = $package; $modpname =~ s#::#/#g;
197 my($al_idx_file) = "$autodir/$modpname/$IndexFile";
198
199 die "Package $package does not match filename $filename"
200 unless ($filename =~ m/$modpname.pm$/ or
55497cff 201 ($^O eq "msdos") or
c6538b72 202 $Is_VMS && $filename =~ m/$modpname.pm/i);
a0d0e21e 203
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"
208 if ($Verbose >= 2);
209 return undef; # one undef, not a list
210 }
211 }
212
213 my($from) = ($Verbose>=2) ? "$filename => " : "";
214 print "AutoSplitting $package ($from$autodir/$modpname)\n"
215 if $Verbose;
216
217 unless (-d "$autodir/$modpname"){
218 local($", @p)="/";
219 foreach(split(/\//,"$autodir/$modpname")){
220 push(@p, $_);
42793c05 221 next if -d "@p/";
a0d0e21e 222 mkdir("@p",0777) or die "AutoSplit unable to mkdir @p: $!";
223 }
224 }
225
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.
232
233 # We do not yet deal with multiple packages within one file.
234 # Ideally both of these styles should work.
235 #
236 # package NAME;
237 # __END__
238 # sub AAA { ... }
239 # package NAME::option1;
240 # sub BBB { ... }
241 # package NAME::option2;
242 # sub BBB { ... }
243 #
244 # package NAME;
245 # __END__
246 # sub AAA { ... }
247 # sub NAME::option1::BBB { ... }
248 # sub NAME::option2::BBB { ... }
249 #
250 # For now both of these produce warnings.
251
252 open(OUT,">/dev/null") || open(OUT,">nla0:"); # avoid 'not opened' warning
4633a7c4 253 my(@subnames, %proto);
96bc026d 254 my @cache = ();
255 my $caching = 1;
a0d0e21e 256 while (<IN>) {
96bc026d 257 next if /^=\w/ .. /^=cut/;
a0d0e21e 258 if (/^package ([\w:]+)\s*;/) {
259 warn "package $1; in AutoSplit section ignored. Not currently supported.";
260 }
4633a7c4 261 if (/^sub\s+([\w:]+)(\s*\(.*?\))?/) {
a0d0e21e 262 print OUT "1;\n";
4633a7c4 263 my $subname = $1;
40da2db3 264 $proto{$1} = $2 || '';
a0d0e21e 265 if ($subname =~ m/::/){
266 warn "subs with package names not currently supported in AutoSplit section";
267 }
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"
276 if ($Verbose>=1);
277 }else{
278 push(@names, $lname);
279 print " writing $lpath\n" if ($Verbose>=2);
280 }
281 print OUT "# NOTE: Derived from $filename. ",
282 "Changes made here will be lost.\n";
283 print OUT "package $package;\n\n";
96bc026d 284 print OUT @cache;
285 @cache = ();
286 $caching = 0;
287 }
288 if($caching) {
289 push(@cache, $_) if @cache || /\S/;
290 }
291 else {
292 print OUT $_;
293 }
294 if(/^}/) {
295 if($caching) {
296 print OUT @cache;
297 @cache = ();
298 }
299 print OUT "\n";
300 $caching = 1;
a0d0e21e 301 }
a0d0e21e 302 }
96bc026d 303 print OUT @cache,"1;\n";
a0d0e21e 304 close(OUT);
305 close(IN);
306
307 if (!$keep){ # don't keep any obsolete *.al files in the directory
308 my(%names);
309 @names{@names} = @names;
310 opendir(OUTDIR,"$autodir/$modpname");
311 foreach(sort readdir(OUTDIR)){
312 next unless /\.al$/;
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);
f06db76b 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;
a0d0e21e 320 }
321 closedir(OUTDIR);
322 }
323
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";
f06db76b 327 print TS "package $package;\n";
4633a7c4 328 print TS map("sub $_$proto{$_} ;\n", @subnames);
f06db76b 329 print TS "1;\n";
a0d0e21e 330 close(TS);
331
332 check_unique($package, $Maxlen, 1, @names);
333
334 @names;
335}
336
337
338sub check_unique{
339 my($module, $maxlen, $warn, @names) = @_;
340 my(%notuniq) = ();
341 my(%shorts) = ();
342 my(@toolong) = grep(length > $maxlen, @names);
343
344 foreach(@toolong){
345 my($trunc) = substr($_,0,$maxlen);
346 $notuniq{$trunc}=1 if $shorts{$trunc};
347 $shorts{$trunc} = ($shorts{$trunc}) ? "$shorts{$trunc}, $_" : $_;
348 }
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";
353 }
354 }
355 %notuniq;
356}
357
3581;
359__END__
360
361# test functions so AutoSplit.pm can be applied to itself:
362sub test1{ "test 1\n"; }
363sub test2{ "test 2\n"; }
364sub test3{ "test 3\n"; }
365sub test4{ "test 4\n"; }
366
367