X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/6578b326867c9593ed67f77d062351ca8ddf19ce..9dce16cd064e70e66b1b719eba219ba6d0e7a001:/pod/buildtoc diff --git a/pod/buildtoc b/pod/buildtoc index de8e663..41ca6f8 100644 --- a/pod/buildtoc +++ b/pod/buildtoc @@ -1,51 +1,79 @@ #!/usr/bin/perl -w use strict; -use vars qw($masterpodfile %Build %Targets $Verbose $Up %Ignore - @Master %Readmes %Pods %Aux %Readmepods %Pragmata %Modules); +use vars qw($masterpodfile %Build %Targets $Verbose $Quiet %Ignore + @Master %Readmes %Pods %Aux %Readmepods %Pragmata %Modules + %Copies %Generated $Test); use File::Spec; use File::Find; use FindBin; use Text::Tabs; use Text::Wrap; use Getopt::Long; +use Carp; no locale; -$Up = File::Spec->updir; -$masterpodfile = File::Spec->catdir($Up, "pod.lst"); +{ + my $Top = File::Spec->catdir($FindBin::Bin, File::Spec->updir); + + sub abs_from_top { + my $path = shift; + return File::Spec->catdir($Top, split /\//, $path) if $path =~ s!/\z!!; + return File::Spec->catfile($Top, split /\//, $path); + } +} + +$masterpodfile = abs_from_top('pod.lst'); # Generate any/all of these files # --verbose gives slightly more output +# --quiet suppresses routine warnings # --build-all tries to build everything # --build-foo updates foo as follows # --showfiles shows the files to be changed +# --test exit early, exit if perl.pod, pod.lst, MANIFEST are +# consistent, die otherwise. %Targets = ( - toc => "perltoc.pod", - manifest => File::Spec->catdir($Up, "MANIFEST"), - perlpod => "perl.pod", - vms => File::Spec->catdir($Up, "vms", "descrip_mms.template"), - nmake => File::Spec->catdir($Up, "win32", "Makefile"), - dmake => File::Spec->catdir($Up, "win32", "makefile.mk"), - podmak => File::Spec->catdir($Up, "win32", "pod.mak"), - # plan9 => File::Spec->catdir($Up, "plan9", "mkfile"), + toc => 'pod/perltoc.pod', + manifest => 'MANIFEST', + perlpod => 'pod/perl.pod', + vms => 'vms/descrip_mms.template', + nmake => 'win32/Makefile', + dmake => 'win32/makefile.mk', + podmak => 'win32/pod.mak', + # plan9 => 'plan9/mkfile'), + unix => 'Makefile.SH', + # TODO: add roffitall ); +foreach (values %Targets) { + $_ = abs_from_top($_); +} + { my @files = keys %Targets; my $filesopts = join(" | ", map { "--build-$_" } "all", sort @files); my $showfiles; + my %build_these; die <<__USAGE__ $0: Usage: $0 [--verbose] [--showfiles] $filesopts __USAGE__ unless @ARGV && GetOptions (verbose => \$Verbose, + quiet => \$Quiet, showfiles => \$showfiles, - map {+"build-$_", \$Build{$_}} @files, 'all'); - # Set them all to true - @Build{@files} = @files if ($Build{all}); + test => \$Test, + map {+"build-$_", \$build_these{$_}} @files, 'all'); + if ($build_these{all}) { + %Build = %Targets; + } else { + while (my ($file, $want) = each %build_these) { + $Build{$file} = $Targets{$file} if $want; + } + } if ($showfiles) { print join(" ", @@ -58,7 +86,7 @@ __USAGE__ File::Spec->catfile(@d ? (@d == 1 && $d[0] eq '' ? () : @d) : "pod", $f); - } @Targets{grep { $_ ne 'all' && $Build{$_} } keys %Build}), + } @Targets{@files}), "\n"; exit(0); } @@ -67,30 +95,29 @@ __USAGE__ # Don't copy these top level READMEs %Ignore = ( - Y2K => 1, micro => 1, # vms => 1, ); if ($Verbose) { - print "I'm building $_\n" foreach grep {$Build{$_}} keys %Build; + print "I'm building $_\n" foreach keys %Build; } -chdir $FindBin::Bin or die "$0: Can't chdir $FindBin::Bin: $!"; - open MASTER, $masterpodfile or die "$0: Can't open $masterpodfile: $!"; +my ($delta_source, $delta_target); + foreach () { next if /^\#/; # At least one upper case letter somewhere in the first group - if (/^(\S+)\s(.*)/ && $1 =~ tr/A-Z//) { + if (/^(\S+)\s(.*)/ && $1 =~ tr/h//) { # it's a heading my $flags = $1; + $flags =~ tr/h//d; my %flags = (header => 1); - $flags{toc_omit} = 1 if $flags =~ tr/O//d; - $flags{include} = 1 if $flags =~ tr/I//d; - $flags{aux} = 1 if $flags =~ tr/A//d; + $flags{toc_omit} = 1 if $flags =~ tr/o//d; + $flags{aux} = 1 if $flags =~ tr/a//d; die "$0: Unknown flag found in heading line: $_" if length $flags; push @Master, [\%flags, $2]; @@ -100,8 +127,19 @@ foreach () { my %flags = (indent => 0); $flags{indent} = $1 if $flags =~ s/(\d+)//; - $flags{toc_omit} = 1 if $flags =~ tr/o//d; + $flags{toc_omit} = 1 if $flags =~ tr/o//d; $flags{aux} = 1 if $flags =~ tr/a//d; + + if ($flags =~ tr/D//d) { + $flags{manifest_omit} = 1; + $delta_source = "$filename.pod"; + } + if ($flags =~ tr/d//d) { + $flags{perlpod_omit} = 1; + $delta_target = "$filename.pod"; + } + $Generated{"$filename.pod"}++ if $flags =~ tr/g//d; + if ($flags =~ tr/r//d) { my $readme = $filename; $readme =~ s/^perl//; @@ -120,6 +158,18 @@ foreach () { die "$0: Malformed line: $_" if $1 =~ tr/A-Z//; } } +if (defined $delta_source) { + if (defined $delta_target) { + # This way round so that keys can act as a MANIFEST skip list + # Targets will aways be in the pod directory. Currently we can only cope + # with sources being in the same directory. + $Copies{$delta_target} = $delta_source; + } else { + die "$0: delta source defined but not target"; + } +} elsif (defined $delta_target) { + die "$0: delta target defined but not source"; +} close MASTER; @@ -136,12 +186,19 @@ close MASTER; $our_pods{"$_.pod"}++; } - # None of these filenames will be boolean false - @disk_pods = glob("*.pod"); - @disk_pods{@disk_pods} = @disk_pods; + opendir my $dh, abs_from_top('pod/'); + while (readdir $dh) { + next unless /\.pod\z/; + push @disk_pods, $_; + ++$disk_pods{$_}; + } - open(MANI, "../MANIFEST") || die "$0: opening ../MANIFEST failed: $!"; - while () { + # Things we copy from won't be in perl.pod + # Things we copy to won't be in MANIFEST + + my $filename = abs_from_top('MANIFEST'); + open my $mani, '<', $filename or die "$0: opening $filename failed: $!"; + while (<$mani>) { if (m!^pod/([^.]+\.pod)\s+!i) { push @manipods, $1; } elsif (m!^README\.(\S+)\s+!i) { @@ -149,61 +206,81 @@ close MASTER; push @manireadmes, "perl$1.pod"; } } - close(MANI); + close $mani or die $!; @manipods{@manipods} = @manipods; @manireadmes{@manireadmes} = @manireadmes; - open(PERLPOD, "perl.pod") || die "$0: opening perl.pod failed: $!\n"; - while () { + $filename = abs_from_top('pod/perl.pod'); + open my $perlpod, '<', $filename or die "$0: opening $filename failed: $!\n"; + while (<$perlpod>) { if (/^For ease of access, /../^\(If you're intending /) { if (/^\s+(perl\S*)\s+\w/) { push @perlpods, "$1.pod"; } } } - close(PERLPOD); + close $perlpod or die $!; die "$0: could not find the pod listing of perl.pod\n" unless @perlpods; @perlpods{@perlpods} = @perlpods; + my @inconsistent; foreach my $i (sort keys %disk_pods) { - warn "$0: $i exists but is unknown by buildtoc\n" + push @inconsistent, "$0: $i exists but is unknown by buildtoc\n" unless $our_pods{$i}; - warn "$0: $i exists but is unknown by ../MANIFEST\n" - if !$manipods{$i} && !$manireadmes{$i}; - warn "$0: $i exists but is unknown by perl.pod\n" - unless $perlpods{$i}; + push @inconsistent, "$0: $i exists but is unknown by ../MANIFEST\n" + if !$manipods{$i} && !$manireadmes{$i} && !$Copies{$i} && !$Generated{$i}; + push @inconsistent, "$0: $i exists but is unknown by perl.pod\n" + if !$perlpods{$i} && !exists $Copies{$i}; } + my %BuildFiles; + ++$BuildFiles{$_} foreach values %Build; + foreach my $i (sort keys %our_pods) { - warn "$0: $i is known by buildtoc but does not exist\n" - unless $disk_pods{$i}; + push @inconsistent, "$0: $i is known by buildtoc but does not exist\n" + unless $disk_pods{$i} or $BuildFiles{$i}; } foreach my $i (sort keys %manipods) { - warn "$0: $i is known by ../MANIFEST but does not exist\n" + push @inconsistent, "$0: $i is known by ../MANIFEST but does not exist\n" unless $disk_pods{$i}; + push @inconsistent, "$0: $i is known by ../MANIFEST but is marked as generated\n" + if $Generated{$i}; } foreach my $i (sort keys %perlpods) { - warn "$0: $i is known by perl.pod but does not exist\n" - unless $disk_pods{$i}; + push @inconsistent, "$0: $i is known by perl.pod but does not exist\n" + unless $disk_pods{$i} or $BuildFiles{$i}; + } + if ($Test) { + print "1..1\n"; + if (@inconsistent) { + print "not ok 1\n"; + die @inconsistent + } + print "ok 1\n"; + exit; + } + else { + warn @inconsistent if @inconsistent; } } -# Find all the mdoules -{ +# Find all the modules +if ($Build{toc}) { my @modpods; - find \&getpods => qw(../lib ../ext); + find \&getpods => abs_from_top('lib/'); sub getpods { if (/\.p(od|m)$/) { my $file = $File::Find::name; - return if $file eq '../lib/Pod/Functions.pm'; # Used only by pod itself + return if $file =~ qr!/lib/Pod/Functions.pm\z!; # Used only by pod itself return if $file =~ m!(?:^|/)t/!; return if $file =~ m!lib/Attribute/Handlers/demo/!; return if $file =~ m!lib/Net/FTP/.+\.pm!; # Hi, Graham! :-) return if $file =~ m!lib/Math/BigInt/t/!; return if $file =~ m!/Devel/PPPort/[Hh]arness|lib/Devel/Harness!i; return if $file =~ m!XS/(?:APItest|Typemap)!; - die "$0: tut $File::Find::name" if $file =~ /TUT/; + my $pod = $file; + return if $pod =~ s/pm$/pod/ && -e $pod; unless (open (F, "< $_\0")) { warn "$0: bogus <$file>: $!"; system "ls", "-l", $file; @@ -213,11 +290,12 @@ close MASTER; while ($line = ) { if ($line =~ /^=head1\s+NAME\b/) { push @modpods, $file; - #warn "GOOD $file\n"; + close F; return; } } - warn "$0: $file: cannot find =head1 NAME\n"; + close F; + warn "$0: $file: cannot find =head1 NAME\n" unless $Quiet; } } } @@ -226,40 +304,33 @@ close MASTER; my %done; for (@modpods) { - #($name) = /(\w+)\.p(m|od)$/; - my $name = path2modname($_); + my $name = $_; + $name =~ s/\.p(m|od)$//; + $name =~ s-.*?/lib/--; + $name =~ s-/-::-g; + next if $done{$name}++; + if ($name =~ /^[a-z]/) { $Pragmata{$name} = $_; } else { - if ($done{$name}++) { - # warn "already did $_\n"; - next; - } $Modules{$name} = $_; } } } -# OK. Now a lot of ancillay function definitions follow +# OK. Now a lot of ancillary function definitions follow # Main program returns at "Do stuff" -sub path2modname { - local $_ = shift; - s/\.p(m|od)$//; - s-.*?/(lib|ext)/--; - s-/-::-g; - s/(\w+)::\1/$1/; - return $_; -} - -sub output ($); +my $OUT; -sub output_perltoc { - open(OUT, ">perltoc.pod") || die "$0: creating perltoc.pod failed: $!"; +sub do_toc { + my $filename = shift; - $/ = ''; + ($_= <<"EOPOD2B") =~ s/^\t//gm and $OUT .= $_; - ($_= <<"EOPOD2B") =~ s/^\t//gm && output($_); + # !!!!!!! DO NOT EDIT THIS FILE !!!!!!! + # This file is autogenerated by buildtoc from all the other pods. + # Edit those files and run buildtoc --build-toc to effect changes. =head1 NAME @@ -277,10 +348,12 @@ EOPOD2B #' make emacs happy # All the things in the master list that happen to be pod filenames - podset(map {"$_->[1].pod"} grep {defined $_ && @$_ == 3 && !$_->[0]{toc_omit}} @Master); + foreach (grep {defined $_ && @$_ == 3 && !$_->[0]{toc_omit}} @Master) { + podset($_->[1], abs_from_top("pod/$_->[1].pod")); + } - ($_= <<"EOPOD2B") =~ s/^\t//gm && output($_); + ($_= <<"EOPOD2B") =~ s/^\t//gm and $OUT .= $_; @@ -288,9 +361,11 @@ EOPOD2B EOPOD2B - podset(sort values %Pragmata); + foreach (sort keys %Pragmata) { + podset($_, $Pragmata{$_}); + } - ($_= <<"EOPOD2B") =~ s/^\t//gm && output($_); + ($_= <<"EOPOD2B") =~ s/^\t//gm and $OUT .= $_; @@ -298,7 +373,9 @@ EOPOD2B EOPOD2B - podset( @Modules{ sort keys %Modules } ); + foreach (sort keys %Modules) { + podset($_, $Modules{$_}); + } $_= <<"EOPOD2B"; @@ -326,8 +403,14 @@ EOPOD2B EOPOD2B s/^\t//gm; - output $_; - output "\n"; # flush $LINE + $OUT .= "$_\n"; + + $OUT =~ s/\n\s+\n/\n\n/gs; + $OUT =~ s/\n{3,}/\n\n/g; + + $OUT =~ s/([^\n]+)/wrap('', '', $1)/ge; + + return $OUT; } # Below are all the auxiliary routines for generating perltoc.pod @@ -335,37 +418,39 @@ EOPOD2B my ($inhead1, $inhead2, $initem); sub podset { - local @ARGV = @_; - my $pod; + my ($pod, $file) = @_; + + local $/ = ''; - while(<>) { + open my $fh, '<', $file or die "Can't open file '$file' for $pod: $!"; + + while(<$fh>) { + tr/\015//d; if (s/^=head1 (NAME)\s*/=head2 /) { - $pod = path2modname($ARGV); unhead1(); - output "\n \n\n=head2 "; - $_ = <>; - if ( /^\s*$pod\b/ ) { + $OUT .= "\n\n=head2 "; + $_ = <$fh>; + # Remove svn keyword expansions from the Perl FAQ + s/ \(\$Revision: \d+ \$\)//g; + if ( /^\s*\Q$pod\E\b/ ) { s/$pod\.pm/$pod/; # '.pm' in NAME !? - output $_; } else { s/^/$pod, /; - output $_; } - next; } - if (s/^=head1 (.*)/=item $1/) { + elsif (s/^=head1 (.*)/=item $1/) { unhead2(); - output "=over 4\n\n" unless $inhead1; + $OUT .= "=over 4\n\n" unless $inhead1; $inhead1 = 1; - output $_; nl(); next; + $_ .= "\n"; } - if (s/^=head2 (.*)/=item $1/) { + elsif (s/^=head2 (.*)/=item $1/) { unitem(); - output "=over 4\n\n" unless $inhead2; + $OUT .= "=over 4\n\n" unless $inhead2; $inhead2 = 1; - output $_; nl(); next; + $_ .= "\n"; } - if (s/^=item ([^=].*)/$1/) { + elsif (s/^=item ([^=].*)/$1/) { next if $pod eq 'perldiag'; s/^\s*\*\s*$// && next; s/^\s*\*\s*//; @@ -373,24 +458,23 @@ sub podset { s/\s+$//; next if /^[\d.]+$/; next if $pod eq 'perlmodlib' && /^ftp:/; - ##print "=over 4\n\n" unless $initem; - output ", " if $initem; + $OUT .= ", " if $initem; $initem = 1; s/\.$//; s/^-X\b/-I/; - output $_; next; } - if (s/^=cut\s*\n//) { - unhead1(); + else { + unhead1() if /^=cut\s*\n/; next; } + $OUT .= $_; } } sub unhead1 { unhead2(); if ($inhead1) { - output "\n\n=back\n\n"; + $OUT .= "\n\n=back\n\n"; } $inhead1 = 0; } @@ -398,45 +482,18 @@ sub unhead1 { sub unhead2 { unitem(); if ($inhead2) { - output "\n\n=back\n\n"; + $OUT .= "\n\n=back\n\n"; } $inhead2 = 0; } sub unitem { if ($initem) { - output "\n\n"; - ##print "\n\n=back\n\n"; + $OUT .= "\n\n"; } $initem = 0; } -sub nl { - output "\n"; -} - -my $NEWLINE = 0; # how many newlines have we seen recently -my $LINE; # what remains to be printed - -sub output ($) { - for (split /(\n)/, shift) { - if ($_ eq "\n") { - if ($LINE) { - print OUT wrap('', '', $LINE); - $LINE = ''; - } - if (($NEWLINE) < 2) { - print OUT; - $NEWLINE++; - } - } - elsif (/\S/ && length) { - $LINE .= $_; - $NEWLINE = 0; - } - } -} - # End of original buildtoc. From here on are routines to generate new sections # for and inplace edit other files @@ -446,6 +503,7 @@ sub generate_perlpod { foreach (@Master) { my $flags = $_->[0]; next if $flags->{aux}; + next if $flags->{perlpod_omit}; if (@$_ == 2) { # Heading @@ -472,17 +530,20 @@ sub generate_perlpod { sub generate_manifest { - # Annyoingly unexpand doesn't consider it good form to replace a single + # Annoyingly, unexpand doesn't consider it good form to replace a single # space before a tab with a tab # Annoyingly (2) it returns read only values. - my @temp = unexpand (map {sprintf "%-32s%s\n", @$_} @_); + my @temp = unexpand (map {sprintf "%-32s%s", @$_} @_); map {s/ \t/\t\t/g; $_} @temp; } sub generate_manifest_pod { - generate_manifest map {["pod/$_.pod", $Pods{$_}]} sort keys %Pods; + generate_manifest map {["pod/$_.pod", $Pods{$_}]} + sort grep {!$Copies{"$_.pod"}} grep {!$Generated{"$_.pod"}} keys %Pods; } sub generate_manifest_readme { - generate_manifest map {["README.$_", $Readmes{$_}]} sort keys %Readmes; + generate_manifest sort {$a->[0] cmp $b->[0]} + ["README.vms", "Notes about installing the VMS port"], + map {["README.$_", $Readmes{$_}]} keys %Readmes; } sub generate_roffitall { @@ -500,23 +561,25 @@ sub generate_descrip_mms_1 { local $Text::Wrap::columns = 150; my $count = 0; my @lines = map {"pod" . $count++ . " = $_"} - split /\n/, wrap('', '', join " ", map "[.lib.pod]$_.pod", + split /\n/, wrap('', '', join " ", map "[.lib.pods]$_.pod", sort keys %Pods, keys %Readmepods); @lines, "pod = " . join ' ', map {"\$(pod$_)"} 0 .. $count - 1; } sub generate_descrip_mms_2 { - map {sprintf <<'SNIP', $_, $_} -[.lib.pod]%s.pod : [.pod]%s.pod - @ If F$Search("[.lib]pod.dir").eqs."" Then Create/Directory [.lib.pod] - Copy/NoConfirm/Log $(MMS$SOURCE) [.lib.pod] + map {<<"SNIP"} +[.lib.pods]$_.pod : [.pod]$_.pod + \@ If F\$Search("[.lib]pods.dir").eqs."" Then Create/Directory [.lib.pods] + Copy/NoConfirm/Log \$(MMS\$SOURCE) [.lib.pods] SNIP sort keys %Pods, keys %Readmepods; } sub generate_nmake_1 { - map {sprintf "\tcopy ..\\README.%-8s .\\perl$_.pod\n", $_} - sort keys %Readmes; + # XXX Fix this with File::Spec + (map {sprintf "\tcopy ..\\README.%-8s ..\\pod\\perl$_.pod\n", $_} + sort keys %Readmes), + (map {"\tcopy ..\\pod\\$Copies{$_} ..\\pod\\$_\n"} sort keys %Copies); } # This doesn't have a trailing newline @@ -524,8 +587,10 @@ sub generate_nmake_2 { # Spot the special case local $Text::Wrap::columns = 76; my $line = wrap ("\t ", "\t ", - join " ", sort map {"perl$_.pod"} "vms", keys %Readmes); + join " ", sort keys %Copies, keys %Generated, + map {"perl$_.pod"} keys %Readmes); $line =~ s/$/ \\/mg; + $line =~ s/ \\$//; $line; } @@ -539,32 +604,38 @@ sub generate_pod_mak { $line; } +sub verify_contiguous { + my ($name, $content, $what) = @_; + my $sections = () = $content =~ m/\0+/g; + croak("$0: $name contains no $what") if $sections < 1; + croak("$0: $name contains discontiguous $what") if $sections > 1; +} + sub do_manifest { - my $name = shift; + my ($name, $prev) = @_; my @manifest = - grep {! m!^pod/[^.]+\.pod.*\n!} - grep {! m!^README\.(\S+)! || $Ignore{$1}} @_; - # Dictionary order - fold and handle non-word chars as nothing - map { $_->[0] } - sort { $a->[1] cmp $b->[1] || $a->[0] cmp $b->[0] } - map { my $f = lc $_; $f =~ s/[^a-z0-9\s]//g; [ $_, $f ] } - @manifest, - &generate_manifest_pod(), - &generate_manifest_readme(); + grep {! m!^pod/[^.]+\.pod.*!} + grep {! m!^README\.(\S+)! || $Ignore{$1}} split "\n", $prev; + join "\n", ( + # Dictionary order - fold and handle non-word chars as nothing + map { $_->[0] } + sort { $a->[1] cmp $b->[1] || $a->[0] cmp $b->[0] } + map { my $f = lc $_; $f =~ s/[^a-z0-9\s]//g; [ $_, $f ] } + @manifest, + &generate_manifest_pod(), + &generate_manifest_readme()), ''; } sub do_nmake { - my $name = shift; - my $makefile = join '', @_; - die "$0: $name contains NUL bytes" if $makefile =~ /\0/; + my ($name, $makefile) = @_; $makefile =~ s/^\tcopy \.\.\\README.*\n/\0/gm; - my $sections = () = $makefile =~ m/\0+/g; - die "$0: $name contains no README copies" if $sections < 1; - die "$0: $name contains discontiguous README copies" if $sections > 1; - $makefile =~ s/\0+/join "", &generate_nmake_1/se; + verify_contiguous($name, $makefile, 'README copies'); + # Now remove the other copies that follow + 1 while $makefile =~ s/\0\tcopy .*\n/\0/gm; + $makefile =~ s/\0+/join ("", &generate_nmake_1)/se; - $makefile =~ s{(cd \$\(PODDIR\) && del /f [^\n]+).*?(pod2html)} - {"$1\n" . &generate_nmake_2."\n\t $2"}se; + $makefile =~ s{(-cd \$\(PODDIR\) && del /f[^\n]+).*?(-cd \.\.\\utils && del /f)} + {"$1\n" . &generate_nmake_2."\n\t$2"}se; $makefile; } @@ -572,8 +643,7 @@ sub do_nmake { *do_dmake = *do_dmake = \&do_nmake; sub do_perlpod { - my $name = shift; - my $pod = join '', @_; + my ($name, $pod) = @_; unless ($pod =~ s{(For\ ease\ of\ access,\ .*\n) (?:\s+[a-z]{4,}.*\n # fooo @@ -582,15 +652,14 @@ sub do_perlpod { )+ } {$1 . join "", &generate_perlpod}mxe) { - die "$0: Failed to insert ammendments in do_perlpod"; + die "$0: Failed to insert amendments in do_perlpod"; } $pod; } sub do_podmak { - my $name = shift; - my $body = join '', @_; - foreach my $variable qw(pod man html tex) { + my ($name, $body) = @_; + foreach my $variable (qw(pod man html tex)) { die "$0: could not find $variable in $name" unless $body =~ s{\n\U$variable\E = (?:[^\n]*\\\n)*[^\n]*} {"\n" . generate_pod_mak ($variable)}se; @@ -599,63 +668,103 @@ sub do_podmak { } sub do_vms { - my $name = shift; - my $makefile = join '', @_; - die "$0: $name contains NUL bytes" if $makefile =~ /\0/; + my ($name, $makefile) = @_; $makefile =~ s/\npod\d* =[^\n]*/\0/gs; - my $sections = () = $makefile =~ m/\0+/g; - die "$0: $name contains no pod assignments" if $sections < 1; - die "$0: $name contains $sections discontigous pod assignments" - if $sections > 1; + verify_contiguous($name, $makefile, 'pod assignments'); $makefile =~ s/\0+/join "\n", '', &generate_descrip_mms_1/se; die "$0: $name contains NUL bytes" if $makefile =~ /\0/; +# Looking for the macro defining the current perldelta: +#PERLDELTA_CURRENT = [.pod]perl5139delta.pod + + $makefile =~ s/\nPERLDELTA_CURRENT\s+=\s+\Q[.pod]perl\E\d+delta\.pod\n + /\0/sx; + verify_contiguous($name, $makefile, 'current perldelta macro'); + $makefile =~ s/\0+/join "\n", '', "PERLDELTA_CURRENT = [.pod]$delta_target", ''/se; + # Looking for rules like this -# [.lib.pod]perl.pod : [.pod]perl.pod -# @ If F$Search("[.lib]pod.dir").eqs."" Then Create/Directory [.lib.pod] -# Copy/NoConfirm/Log $(MMS$SOURCE) [.lib.pod] +# [.lib.pods]perl.pod : [.pod]perl.pod +# @ If F$Search("[.lib]pods.dir").eqs."" Then Create/Directory [.lib.pods] +# Copy/NoConfirm/Log $(MMS$SOURCE) [.lib.pods] - $makefile =~ s/\n\Q[.lib.pod]\Eperl[^\n\.]*\.pod[^\n]+\n + $makefile =~ s/\n\Q[.lib.pods]\Eperl[^\n\.]*\.pod[^\n]+\n [^\n]+\n # Another line - [^\n]+\Q[.lib.pod]\E\n # ends [.lib.pod] + [^\n]+\Q[.lib.pods]\E\n # ends [.lib.pods] /\0/gsx; - $sections = () = $makefile =~ m/\0+/g; - die "$0: $name contains no copy rules" if $sections < 1; - die "$0: $name contains $sections discontigous copy rules" - if $sections > 1; + verify_contiguous($name, $makefile, 'copy rules'); $makefile =~ s/\0+/join "\n", '', &generate_descrip_mms_2/se; + $makefile; } +sub do_unix { + my ($name, $makefile_SH) = @_; + + $makefile_SH =~ s{^(perltoc_pod_prereqs = extra.pods).*} + {join ' ', $1, map "pod/$_", + sort keys %Copies, grep {!/perltoc/} keys %Generated + }mge; + +# pod/perl511delta.pod: pod/perldelta.pod +# cd pod && $(LNS) perldelta.pod perl511delta.pod + + $makefile_SH =~ s!( +pod/perl[a-z0-9_]+\.pod: pod/perl[a-z0-9_]+\.pod + \$\(LNS\) perl[a-z0-9_]+\.pod pod/perl[a-z0-9_]+\.pod +)+!\0!gm; + + verify_contiguous($name, $makefile_SH, 'copy rules'); + + my @copy_rules = map " +pod/$_: pod/$Copies{$_} + \$(LNS) $Copies{$_} pod/$_ +", keys %Copies; + + $makefile_SH =~ s/\0+/join '', @copy_rules/se; + $makefile_SH; + +} + # Do stuff my $built; while (my ($target, $name) = each %Targets) { + print "Working on target $target\n" if $Verbose; next unless $Build{$target}; $built++; - if ($target eq "toc") { - &output_perltoc; - next; - } + my ($orig, $mode); print "Now processing $name\n" if $Verbose; - open THING, $name or die "Can't open $name: $!"; - my @orig = ; - my $orig = join '', @orig; - close THING; - my @new = do { + if ($target ne "toc") { + local $/; + open THING, $name or die "Can't open $name: $!"; + binmode THING; + $orig = ; + close THING; + die "$0: $name contains NUL bytes" if $orig =~ /\0/; + } + + my $new = do { no strict 'refs'; - &{"do_$target"}($target, @orig); + &{"do_$target"}($target, $orig); }; - my $new = join '', @new; - if ($new eq $orig) { - print "Was not modified\n" if $Verbose; - next; + + if (defined $orig) { + if ($new eq $orig) { + print "Was not modified\n" if $Verbose; + next; + } + $mode = (stat $name)[2] // die "$0: Can't stat $name: $!"; + rename $name, "$name.old" or die "$0: Can't rename $name to $name.old: $!"; } - rename $name, "$name.old" or die "$0: Can't rename $name to $name.old: $!"; + open THING, ">$name" or die "$0: Can't open $name for writing: $!"; + binmode THING; print THING $new or die "$0: print to $name failed: $!"; - close THING or die die "$0: close $name failed: $!"; + close THING or die "$0: close $name failed: $!"; + if (defined $mode) { + chmod $mode & 0777, $name or die "$0: can't chmod $mode $name: $!"; + } } warn "$0: was not instructed to build anything\n" unless $built;