This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
devel/regenerate: make sure the .fnc files don't overlap
[perl5.git] / dist / Devel-PPPort / devel / regenerate
CommitLineData
0c96388f
MHM
1#!/usr/bin/perl -w
2################################################################################
3#
4# regenerate -- regenerate baseline and todo files
5#
6################################################################################
7#
b2049988 8# Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
0c96388f
MHM
9# Version 2.x, Copyright (C) 2001, Paul Marquess.
10# Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
11#
12# This program is free software; you can redistribute it and/or
13# modify it under the same terms as Perl itself.
14#
15################################################################################
16
17use strict;
18use File::Path;
19use File::Copy;
20use Getopt::Long;
21use Pod::Usage;
22
3d7c117d 23require './devel/devtools.pl';
f100f28c 24require './parts/ppptools.pl';
0c96388f
MHM
25
26our %opt = (
ba120f6f 27 check => 1,
337a666a 28 debug => 0,
ba120f6f 29 verbose => 0,
0c96388f
MHM
30);
31
a58fa8f3 32GetOptions(\%opt, qw( check! verbose install=s blead=s blead-version=s
0f50f756 33 debug=i debug-start=s)) or die pod2usage();
0c96388f
MHM
34
35identify();
36
37unless (-e 'parts/embed.fnc' and -e 'parts/apidoc.fnc') {
38 print "\nOooops, $0 must be run from the Devel::PPPort root directory.\n";
39 quit_now();
40}
41
dfaee99f 42ask_or_quit("Are you SURE you have:\n1) updated parts/embed.fnc to latest blead?\n2) run devel/mkapidoc.sh to update parts/apidoc.fnc?\n3) run devel/mkppport_fnc.pl to update parts/ppport.fnc?\n");
0c96388f
MHM
43
44my %files = map { ($_ => [glob "parts/$_/5*"]) } qw( base todo );
45
46my(@notwr, @wr);
47for my $f (map @$_, values %files) {
48 push @{-w $f ? \@wr : \@notwr}, $f;
49}
50
51if (@notwr) {
52 if (@wr) {
53 print "\nThe following files are not writable:\n\n";
54 print " $_\n" for @notwr;
55 print "\nAre you sure you have checked out these files?\n";
56 }
57 else {
58 print "\nAll baseline / todo file are not writable.\n";
59 ask_or_quit("Do you want to try to check out these files?");
60 unless (runtool("wco", "-l", "-t", "locked by $0", @notwr)) {
61 print "\nSomething went wrong while checking out the files.\n";
62 quit_now();
63 }
64 }
65}
66
c4722602
KW
67# Check that there is only one entry in the whole system for each item
68my @embeds = parse_embed(qw(parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc));
69my %seen;
70%seen = map { $seen{$_->{name}}++; } @embeds;
71my @bads = grep { $seen{$_} > 1 } keys %seen;
72if (@bads) {
73 print "The following items have multiple entries in the part/*.fnc files.\n",
74 " Regenerate apidoc.fnc, then ppport.fnc and try again. If this\n",
75 " doesn't work, choose the best version for each symbol and delete\n",
76 " the others: ",
77 join ", ", @bads, "\n";
78 quit_now();
79}
f100f28c
KW
80
81if (-e 'ppport.h') {
82 my $blead = $opt{blead};
83 $blead = get_and_sort_perls(\%opt)->[0]->{path} unless $blead;
84
85 # Get list of things we provide
86 my %provided = map { /^(\w+)/ ? ( $1 => 1 ) : () }
87 `$blead ppport.h --list-provided`;
88
89 # Get the list of macros that are hard to test.
c4722602 90 my @unorthodox = map { exists $_->{flags}{u} ? $_->{name} : () } @embeds;
f100f28c
KW
91
92 # Keep on that list only the things we provide
93 @unorthodox = grep { exists $provided{$_} } @unorthodox;
94
95 # And get the list of known hard things.
96 my $hard_ref = &known_but_hard_to_test_for;
97
98 # If we provide something, it better be on the known things list
99 my @bad = grep { ! exists $hard_ref->{$_} } @unorthodox;
100 if (@bad) {
101 print "The following items need to be manually added to the list in",
102 " part/inc/ppptools: known_but_hard_to_test_for(): ",
103 join ", ", @bad, "\n";
104 quit_now();
105 }
106}
107
0c96388f
MHM
108for my $dir (qw( base todo )) {
109 my $cur = "parts/$dir";
110 my $old = "$cur-old";
111 if (-e $old) {
112 ask_or_quit("Do you want me to remove the old $old directory?");
113 rmtree($old);
114 }
115 mkdir $old;
116 print "\nBacking up $cur in $old.\n";
117 for my $src (@{$files{$dir}}) {
118 my $dst = $src;
744ef08f 119 $dst =~ s/\Q$cur/$old/ or die "Ooops!";
0c96388f
MHM
120 move($src, $dst) or die "Moving $src to $dst failed: $!\n";
121 }
122}
123
49ef49fe 124my @perlargs;
0f50f756 125push @perlargs, "--debug=$opt{debug}" if $opt{debug};
0ebe8a01
KW
126push @perlargs, "--install=$opt{install}" if $opt{install};
127push @perlargs, "--blead=$opt{blead}" if $opt{blead};
a58fa8f3 128push @perlargs, "--debug-start=$opt{'debug-start'}" if $opt{'debug-start'};
49ef49fe 129
0c96388f 130my $T0 = time;
ba120f6f
MHM
131my @args = ddverbose();
132push @args, '--nocheck' unless $opt{check};
0ebe8a01 133push @args, "--blead-version=$opt{'blead-version'}" if $opt{'blead-version'};
49ef49fe 134push @args, @perlargs;
0c96388f 135
dc9f335f
KW
136# Look for all the NEED_foo macros
137my @NEED;
138for my $file (all_files_in_dir('parts/inc')) {
139 my $spec = parse_partspec($file);
140 next unless $spec->{'xsinit'};
141 while ($spec->{'xsinit'} =~ / ^ ( \# \s* define \s+ NEED_ \w+ ) \s /xmg) {
142 push @NEED, "$1";
143 }
144}
145
146# Make the list available to parts/apicheck.pl
147$ENV{'DPPP_NEED'} = join "\n", sort @NEED;
148
3bb63d38 149# Find out what symbols were in what releases
0c96388f
MHM
150print "\nBuilding baseline files...\n\n";
151
ba120f6f 152unless (runperl('devel/mktodo', '--base', @args)) {
0c96388f
MHM
153 print "\nSomething went wrong while building the baseline files.\n";
154 quit_now();
155}
156
3bb63d38
KW
157# Then find out what ppport.h buys us by repeating the process above, but
158# using ppport.h
0c96388f
MHM
159print "\nBuilding todo files...\n\n";
160
ba120f6f 161unless (runperl('devel/mktodo', @args)) {
635ff94c 162 print "\nSomething went wrong while building the todo files.\n";
0c96388f
MHM
163 quit_now();
164}
165
40f4ec07 166print "\nAdding remaining info...\n\n";
0c96388f
MHM
167
168unless (runperl('Makefile.PL') and
169 runtool('make') and
49ef49fe 170 runperl('devel/scanprov', '--mode=write', @perlargs)) {
0c96388f
MHM
171 print "\nSomething went wrong while adding the baseline info.\n";
172 quit_now();
173}
174
175my($wall, $usr, $sys, $cusr, $csys) = (time - $T0, times);
176my $cpu = sprintf "%.2f", $usr + $sys + $cusr + $csys;
177$usr = sprintf "%.2f", $usr + $cusr;
178$sys = sprintf "%.2f", $sys + $csys;
179
180print <<END;
181
182API info regenerated successfully.
183
184Finished in $wall wallclock secs ($usr usr + $sys sys = $cpu CPU)
185
186Don't forget to check in the files in parts/base and parts/todo.
187
188END
189
ba120f6f
MHM
190__END__
191
192=head1 NAME
193
c4a2ac43 194regenerate - Automatically regenerate Devel::PPPort's API information
ba120f6f
MHM
195
196=head1 SYNOPSIS
197
198 regenerate [options]
199
200 --nocheck don't recheck symbols that caused an error
201 --verbose show verbose output
202
203=head1 COPYRIGHT
204
b2049988 205Copyright (c) 2006-2013, Marcus Holland-Moritz.
ba120f6f
MHM
206
207This program is free software; you can redistribute it and/or
208modify it under the same terms as Perl itself.
209
210=head1 SEE ALSO
211
212See L<Devel::PPPort> and L<HACKERS>.
213
214=cut