This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix ext/B/t/f_map.t failure
[perl5.git] / Porting / bisect-runner.pl
CommitLineData
6a8dbfd7
NC
1#!/usr/bin/perl -w
2use strict;
3
390a69a9 4use Getopt::Long qw(:config bundling no_auto_abbrev);
77ae6092 5use Pod::Usage;
2526f4b8 6use Config;
69bf9aba 7use Carp;
6a8dbfd7 8
2526f4b8
NC
9my @targets
10 = qw(config.sh config.h miniperl lib/Config.pm Fcntl perl test_prep);
6a8dbfd7 11
e4516dd0
NC
12my $cpus;
13if (open my $fh, '<', '/proc/cpuinfo') {
14 while (<$fh>) {
15 ++$cpus if /^processor\s+:\s+\d+$/;
16 }
d64af352
NC
17} elsif (-x '/sbin/sysctl') {
18 $cpus = 1 + $1 if `/sbin/sysctl hw.ncpu` =~ /^hw\.ncpu: (\d+)$/;
da83cd31
NC
19} elsif (-x '/usr/bin/getconf') {
20 $cpus = 1 + $1 if `/usr/bin/getconf _NPROCESSORS_ONLN` =~ /^(\d+)$/;
e4516dd0
NC
21}
22
f4800c99
NC
23my %options =
24 (
e4516dd0 25 jobs => defined $cpus ? $cpus + 1 : 2,
f4800c99
NC
26 'expect-pass' => 1,
27 clean => 1, # mostly for debugging this
28 );
6a8dbfd7 29
fdbac266
NC
30my $linux64 = `uname -sm` eq "Linux x86_64\n" ? '64' : '';
31
599ee4f7
NC
32my @paths;
33
34if ($^O eq 'linux') {
35 # This is the search logic for a multi-arch library layout
36 # added to linux.sh in commits 40f026236b9959b7 and dcffd848632af2c7.
37 my $gcc = -x '/usr/bin/gcc' ? '/usr/bin/gcc' : 'gcc';
38
39 foreach (`$gcc -print-search-dirs`) {
40 next unless /^libraries: =(.*)/;
41 foreach (split ':', $1) {
42 next if m/gcc/;
43 next unless -d $_;
44 s!/$!!;
45 push @paths, $_;
46 }
47 }
48}
49
50push @paths, map {$_ . $linux64} qw(/usr/local/lib /lib /usr/lib);
390a69a9
NC
51
52my %defines =
53 (
54 usedevel => '',
55 optimize => '-g',
63f9ec30 56 cc => (`ccache --version`, $?) ? 'cc' : 'ccache cc',
9913adee 57 ld => 'cc',
fdbac266 58 ($linux64 ? (libpth => \@paths) : ()),
390a69a9
NC
59 );
60
f4800c99 61unless(GetOptions(\%options,
32ffe018 62 'target=s', 'make=s', 'jobs|j=i', 'expect-pass=i',
f4800c99
NC
63 'expect-fail' => sub { $options{'expect-pass'} = 0; },
64 'clean!', 'one-liner|e=s', 'match=s', 'force-manifest',
7cffc32d 65 'force-regen', 'test-build', 'A=s@', 'l', 'w',
b826a648 66 'check-args', 'check-shebang!', 'usage|help|?', 'validate',
390a69a9
NC
67 'D=s@' => sub {
68 my (undef, $val) = @_;
69 if ($val =~ /\A([^=]+)=(.*)/s) {
70 $defines{$1} = length $2 ? $2 : "\0";
71 } else {
72 $defines{$val} = '';
73 }
74 },
75 'U=s@' => sub {
76 $defines{$_[1]} = undef;
77 },
6a8dbfd7 78 )) {
77ae6092 79 pod2usage(exitval => 255, verbose => 1);
6a8dbfd7
NC
80}
81
f4800c99 82my ($target, $j, $match) = @options{qw(target jobs match)};
e295b7be 83
b826a648
NC
84@ARGV = ('sh', '-c', 'cd t && ./perl TEST base/*.t')
85 if $options{validate} && !@ARGV;
86
77ae6092
NC
87pod2usage(exitval => 255, verbose => 1) if $options{usage};
88pod2usage(exitval => 255, verbose => 1)
89 unless @ARGV || $match || $options{'test-build'} || defined $options{'one-liner'};
fc4401c6
NC
90pod2usage(exitval => 255, verbose => 1)
91 if !$options{'one-liner'} && ($options{l} || $options{w});
6a8dbfd7 92
7cffc32d
NC
93check_shebang($ARGV[0]) if $options{'check-shebang'} && @ARGV;
94
f4800c99 95exit 0 if $options{'check-args'};
6a8dbfd7 96
77ae6092
NC
97=head1 NAME
98
99bisect.pl - use git bisect to pinpoint changes
100
101=head1 SYNOPSIS
102
103 # When did this become an error?
104 .../Porting/bisect.pl -e 'my $a := 2;'
71d80638 105 # When did this stop being an error?
77ae6092
NC
106 .../Porting/bisect.pl --expect-fail -e '1 // 2'
107 # When did this stop matching?
108 .../Porting/bisect.pl --match '\b(?:PL_)hash_seed_set\b'
109 # When did this start matching?
110 .../Porting/bisect.pl --expect-fail --match '\buseithreads\b'
111 # When did this test program stop working?
d398528a 112 .../Porting/bisect.pl -- ./perl -Ilib ../test_prog.pl
77ae6092
NC
113 # When did this first become valid syntax?
114 .../Porting/bisect.pl --target=miniperl --end=v5.10.0 \
115 --expect-fail -e 'my $a := 2;'
116 # What was the last revision to build with these options?
117 .../Porting/bisect.pl --test-build -Dd_dosuid
118
119=head1 DESCRIPTION
120
facd1b88 121Together F<bisect.pl> and F<bisect-runner.pl> attempt to automate the use
77ae6092
NC
122of C<git bisect> as much as possible. With one command (and no other files)
123it's easy to find out
124
125=over 4
126
127=item *
128
129Which commit caused this example code to break?
130
131=item *
132
133Which commit caused this example code to start working?
134
135=item *
136
137Which commit added the first to match this regex?
138
139=item *
140
141Which commit removed the last to match this regex?
142
143=back
144
145usually without needing to know which versions of perl to use as start and
146end revisions.
147
facd1b88 148By default F<bisect.pl> will process all options, then use the rest of the
77ae6092
NC
149command line as arguments to list C<system> to run a test case. By default,
150the test case should pass (exit with 0) on earlier perls, and fail (exit
facd1b88 151non-zero) on I<blead>. F<bisect.pl> will use F<bisect-runner.pl> to find the
77ae6092 152earliest stable perl version on which the test case passes, check that it
facd1b88 153fails on blead, and then use F<bisect-runner.pl> with C<git bisect run> to
77ae6092
NC
154find the commit which caused the failure.
155
156Because the test case is the complete argument to C<system>, it is easy to
157run something other than the F<perl> built, if necessary. If you need to run
158the perl built, you'll probably need to invoke it as C<./perl -Ilib ...>
159
5842706e
NC
160You need a clean checkout to run a bisect, and you can't use the checkout
161which contains F<Porting/bisect.pl> (because C<git bisect>) will check out
162a revision before F<Porting/bisect-runner.pl> was added, which
163C<git bisect run> needs). If your working checkout is called F<perl>, the
164simplest solution is to make a local clone, and run from that. I<i.e.>:
165
166 cd ..
167 git clone perl perl2
168 cd perl2
169 ../perl/Porting/bisect.pl ...
170
facd1b88 171By default, F<bisect-runner.pl> will automatically disable the build of
cfadff5f
NC
172L<DB_File> for commits earlier than ccb44e3bf3be2c30, as it's not practical
173to patch DB_File 1.70 and earlier to build with current Berkeley DB headers.
174(ccb44e3bf3be2c30 was in September 1999, between 5.005_62 and 5.005_63.)
175If your F<db.h> is old enough you can override this with C<-Unoextensions>.
176
77ae6092
NC
177=head1 OPTIONS
178
179=over 4
180
181=item *
182
183--start I<commit-ish>
184
185Earliest revision to test, as a I<commit-ish> (a tag, commit or anything
facd1b88 186else C<git> understands as a revision). If not specified, F<bisect.pl> will
3ffe2687
NC
187search stable perl releases until it finds one where the test case passes.
188The default is to search from 5.002 to 5.14.0. If F<bisect.pl> detects that
189the checkout is on a case insensitive file system, it will search from
1905.005 to 5.14.0
77ae6092
NC
191
192=item *
193
194--end I<commit-ish>
195
196Most recent revision to test, as a I<commit-ish>. If not specified, defaults
b4f0ec5f 197to I<blead>.
77ae6092
NC
198
199=item *
200
201--target I<target>
202
203F<Makefile> target (or equivalent) needed, to run the test case. If specified,
204this should be one of
205
206=over 4
207
208=item *
209
210I<config.sh>
211
facd1b88 212Just run F<./Configure>
77ae6092
NC
213
214=item *
215
216I<config.h>
217
218Run the various F<*.SH> files to generate F<Makefile>, F<config.h>, I<etc>.
219
220=item *
221
222I<miniperl>
223
224Build F<miniperl>.
225
226=item *
227
228I<lib/Config.pm>
229
230Use F<miniperl> to build F<lib/Config.pm>
231
232=item *
233
2526f4b8
NC
234I<Fcntl>
235
236Build F<lib/auto/Fcntl/Fnctl.so> (strictly, C<.$Config{so}>). As L<Fcntl>
237is simple XS module present since 5.000, this provides a fast test of
b4f0ec5f 238whether XS modules can be built. Note, XS modules are built by F<miniperl>,
2526f4b8
NC
239hence this target will not build F<perl>.
240
241=item *
242
77ae6092
NC
243I<perl>
244
245Build F<perl>. This also builds pure-Perl modules in F<cpan>, F<dist> and
2526f4b8
NC
246F<ext>. XS modules (such as L<Fcntl>) are not built.
247
248=item *
249
77ae6092
NC
250I<test_prep>
251
252Build everything needed to run the tests. This is the default if we're
253running test code, but is time consuming, as it means building all
b4f0ec5f 254XS modules. For older F<Makefile>s, the previous name of C<test-prep>
77ae6092
NC
255is automatically substituted. For very old F<Makefile>s, C<make test> is
256run, as there is no target provided to just get things ready, and for 5.004
257and earlier the tests run very quickly.
258
259=back
260
261=item *
262
263--one-liner 'code to run'
264
265=item *
266
267-e 'code to run'
268
a1756669 269Example code to run, just like you'd use with C<perl -e>.
77ae6092
NC
270
271This prepends C<./perl -Ilib -e 'code to run'> to the test case given,
facd1b88 272or F<./miniperl> if I<target> is C<miniperl>.
77ae6092
NC
273
274(Usually you'll use C<-e> instead of providing a test case in the
facd1b88 275non-option arguments to F<bisect.pl>)
77ae6092
NC
276
277C<-E> intentionally isn't supported, as it's an error in 5.8.0 and earlier,
278which interferes with detecting errors in the example code itself.
279
280=item *
281
fc4401c6
NC
282-l
283
284Add C<-l> to the command line with C<-e>
285
286This will automatically append a newline to every output line of your testcase.
287Note that you can't specify an argument to F<perl>'s C<-l> with this, as it's
288not feasible to emulate F<perl>'s somewhat quirky switch parsing with
289L<Getopt::Long>. If you need the full flexibility of C<-l>, you need to write
290a full test case, instead of using C<bisect.pl>'s C<-e> shortcut.
291
292=item *
293
294-w
295
296Add C<-w> to the command line with C<-e>
297
298It's not valid to pass C<-l> or C<-w> to C<bisect.pl> unless you are also
299using C<-e>
300
301=item *
302
77ae6092
NC
303--expect-fail
304
305The test case should fail for the I<start> revision, and pass for the I<end>
306revision. The bisect run will find the first commit where it passes.
307
308=item *
309
af7c500f 310-Dnoextensions=Encode
77ae6092
NC
311
312=item *
313
314-Uusedevel
315
316=item *
317
318-Accflags=-DNO_MATHOMS
319
320Arguments to pass to F<Configure>. Repeated C<-A> arguments are passed
321through as is. C<-D> and C<-U> are processed in order, and override
af7c500f
NC
322previous settings for the same parameter. F<bisect-runner.pl> emulates
323C<-Dnoextensions> when F<Configure> itself does not provide it, as it's
324often very useful to be able to disable some XS extensions.
77ae6092
NC
325
326=item *
327
32ffe018
NC
328--make I<make-prog>
329
330The C<make> command to use. If this not set, F<make> is used. If this is
331set, it also adds a C<-Dmake=...> else some recursive make invocations
332in extensions may fail. Typically one would use this as C<--make gmake>
333to use F<gmake> in place of the system F<make>.
334
335=item *
336
b4f0ec5f 337--jobs I<jobs>
77ae6092
NC
338
339=item *
340
b4f0ec5f 341-j I<jobs>
77ae6092 342
da83cd31
NC
343Number of C<make> jobs to run in parallel. If F</proc/cpuinfo> exists and
344can be parsed, or F</sbin/sysctl> exists and reports C<hw.ncpu>, or
345F</usr/bin/getconf> exists and reports C<_NPROCESSORS_ONLN> defaults to 1 +
346I<number of CPUs>. Otherwise defaults to 2.
77ae6092
NC
347
348=item *
349
b4f0ec5f 350--match pattern
77ae6092
NC
351
352Instead of running a test program to determine I<pass> or I<fail>, pass
353if the given regex matches, and hence search for the commit that removes
354the last matching file.
355
356If no I<target> is specified, the match is against all files in the
357repository (which is fast). If a I<target> is specified, that target is
358built, and the match is against only the built files. C<--expect-fail> can
359be used with C<--match> to search for a commit that adds files that match.
360
361=item *
362
363--test-build
364
365Test that the build completes, without running any test case.
366
367By default, if the build for the desired I<target> fails to complete,
368F<bisect-runner.pl> reports a I<skip> back to C<git bisect>, the assumption
369being that one wants to find a commit which changed state "builds && passes"
370to "builds && fails". If instead one is interested in which commit broke the
371build (possibly for particular F<Configure> options), use I<--test-build>
372to treat a build failure as a failure, not a "skip".
373
b4f0ec5f
NC
374Often this option isn't as useful as it first seems, because I<any> build
375failure will be reported to C<git bisect> as a failure, not just the failure
376that you're interested in. Generally, to debug a particular problem, it's
377more useful to use a I<target> that builds properly at the point of interest,
378and then a test case that runs C<make>. For example:
379
380 .../Porting/bisect.pl --start=perl-5.000 --end=perl-5.002 \
381 --expect-fail --force-manifest --target=miniperl make perl
382
facd1b88
NC
383will find the first revision capable of building L<DynaLoader> and then
384F<perl>, without becoming confused by revisions where F<miniperl> won't
b4f0ec5f
NC
385even link.
386
77ae6092
NC
387=item *
388
b4f0ec5f
NC
389--force-manifest
390
77ae6092
NC
391By default, a build will "skip" if any files listed in F<MANIFEST> are not
392present. Usually this is useful, as it avoids false-failures. However, there
393are some long ranges of commits where listed files are missing, which can
394cause a bisect to abort because all that remain are skipped revisions.
395
396In these cases, particularly if the test case uses F<miniperl> and no modules,
397it may be more useful to force the build to continue, even if files
398F<MANIFEST> are missing.
399
400=item *
401
bfa52998
NC
402--force-regen
403
404Run C<make regen_headers> before building F<miniperl>. This may fix a build
405that otherwise would skip because the generated headers at that revision
406are stale. It's not the default because it conceals this error in the true
407state of such revisions.
408
409=item *
410
77ae6092
NC
411--expect-pass [0|1]
412
413C<--expect-pass=0> is equivalent to C<--expect-fail>. I<1> is the default.
414
415=item *
416
417--no-clean
418
419Tell F<bisect-runner.pl> not to clean up after the build. This allows one
420to use F<bisect-runner.pl> to build the current particular perl revision for
421interactive testing, or for debugging F<bisect-runner.pl>.
422
423Passing this to F<bisect.pl> will likely cause the bisect to fail badly.
424
425=item *
426
195ed8b1
NC
427--validate
428
3f14869b 429Test that all stable revisions can be built. By default, attempts to build
3ffe2687
NC
430I<blead>, I<v5.14.0> .. I<perl-5.002> (or I<perl5.005> on a case insensitive
431file system). Stops at the first failure, without
3f14869b
NC
432cleaning the checkout. Use I<--start> to specify the earliest revision to
433test, I<--end> to specify the most recent. Useful for validating a new
195ed8b1
NC
434OS/CPU/compiler combination. For example
435
fc4401c6 436 ../perl/Porting/bisect.pl --validate -le 'print "Hello from $]"'
195ed8b1 437
e2760528
NC
438If no testcase is specified, the default is to use F<t/TEST> to run
439F<t/base/*.t>
440
195ed8b1
NC
441=item *
442
77ae6092
NC
443--check-args
444
445Validate the options and arguments, and exit silently if they are valid.
446
447=item *
448
7cffc32d
NC
449--check-shebang
450
451Validate that the test case isn't an executable file with a
452C<#!/usr/bin/perl> line (or similar). As F<bisect-runner.pl> does B<not>
453prepend C<./perl> to the test case, a I<#!> line specifying an external
454F<perl> binary will cause the test case to always run with I<that> F<perl>,
455not the F<perl> built by the bisect runner. Likely this is not what you
456wanted. If your test case is actually a wrapper script to run other
457commands, you should run it with an explicit interpreter, to be clear. For
458example, instead of C<../perl/Porting/bisect.pl ~/test/testcase.pl> you'd
459run C<../perl/Porting/bisect.pl /usr/bin/perl ~/test/testcase.pl>
460
461=item *
462
77ae6092
NC
463--usage
464
465=item *
466
467--help
468
469=item *
470
471-?
472
473Display the usage information and exit.
474
475=back
476
477=cut
478
0afef97d 479die "$0: Can't build $target" if defined $target && !grep {@targets} $target;
6a8dbfd7
NC
480
481$j = "-j$j" if $j =~ /\A\d+\z/;
482
32ffe018
NC
483if (exists $options{make}) {
484 if (!exists $defines{make}) {
485 $defines{make} = $options{make};
486 }
487} else {
488 $options{make} = 'make';
489}
490
0142f0ce
NC
491# Sadly, however hard we try, I don't think that it will be possible to build
492# modules in ext/ on x86_64 Linux before commit e1666bf5602ae794 on 1999/12/29,
493# which updated to MakeMaker 3.7, which changed from using a hard coded ld
494# in the Makefile to $(LD). On x86_64 Linux the "linker" is gcc.
495
69bf9aba
NC
496sub open_or_die {
497 my $file = shift;
498 my $mode = @_ ? shift : '<';
499 open my $fh, $mode, $file or croak("Can't open $file: $!");
500 ${*$fh{SCALAR}} = $file;
501 return $fh;
502}
503
504sub close_or_die {
505 my $fh = shift;
506 return if close $fh;
507 croak("Can't close: $!") unless ref $fh eq 'GLOB';
508 croak("Can't close ${*$fh{SCALAR}}: $!");
509}
510
6a8dbfd7
NC
511sub extract_from_file {
512 my ($file, $rx, $default) = @_;
69bf9aba 513 my $fh = open_or_die($file);
6a8dbfd7
NC
514 while (<$fh>) {
515 my @got = $_ =~ $rx;
516 return wantarray ? @got : $got[0]
517 if @got;
518 }
519 return $default if defined $default;
520 return;
521}
522
c59e8fd6
NC
523sub edit_file {
524 my ($file, $munger) = @_;
525 local $/;
69bf9aba 526 my $fh = open_or_die($file);
c59e8fd6
NC
527 my $orig = <$fh>;
528 die "Can't read $file: $!" unless defined $orig && close $fh;
529 my $new = $munger->($orig);
530 return if $new eq $orig;
69bf9aba 531 $fh = open_or_die($file, '>');
c59e8fd6 532 print $fh $new or die "Can't print to $file: $!";
69bf9aba 533 close_or_die($fh);
c59e8fd6
NC
534}
535
6fe55cbd
NC
536# AIX supplies a pre-historic patch program, which certainly predates Linux
537# and is probably older than NT. It can't cope with unified diffs. Meanwhile,
538# it's hard enough to get git diff to output context diffs, let alone git show,
539# and nearly all the patches embedded here are unified. So it seems that the
540# path of least resistance is to convert unified diffs to context diffs:
541
542sub process_hunk {
543 my ($from_out, $to_out, $has_from, $has_to, $delete, $add) = @_;
544 ++$$has_from if $delete;
545 ++$$has_to if $add;
546
547 if ($delete && $add) {
548 $$from_out .= "! $_\n" foreach @$delete;
549 $$to_out .= "! $_\n" foreach @$add;
550 } elsif ($delete) {
551 $$from_out .= "- $_\n" foreach @$delete;
552 } elsif ($add) {
553 $$to_out .= "+ $_\n" foreach @$add;
554 }
555}
556
557# This isn't quite general purpose, as it can't cope with
558# '\ No newline at end of file'
559sub ud2cd {
560 my $diff_in = shift;
561 my $diff_out = '';
562
563 # Stuff before the diff
564 while ($diff_in =~ s/\A(?!\*\*\* )(?!--- )([^\n]*\n?)//ms && length $1) {
565 $diff_out .= $1;
566 }
567
568 if (!length $diff_in) {
569 die "That didn't seem to be a diff";
570 }
571
572 if ($diff_in =~ /\A\*\*\* /ms) {
573 warn "Seems to be a context diff already\n";
574 return $diff_out . $diff_in;
575 }
576
577 # Loop for files
578 FILE: while (1) {
579 if ($diff_in =~ s/\A((?:diff |index )[^\n]+\n)//ms) {
580 $diff_out .= $1;
581 next;
582 }
583 if ($diff_in !~ /\A--- /ms) {
584 # Stuff after the diff;
585 return $diff_out . $diff_in;
586 }
587 $diff_in =~ s/\A([^\n]+\n?)//ms;
588 my $line = $1;
589 die "Can't parse '$line'" unless $line =~ s/\A--- /*** /ms;
590 $diff_out .= $line;
591 $diff_in =~ s/\A([^\n]+\n?)//ms;
592 $line = $1;
593 die "Can't parse '$line'" unless $line =~ s/\A\+\+\+ /--- /ms;
594 $diff_out .= $line;
595
596 # Loop for hunks
597 while (1) {
598 next FILE
599 unless $diff_in =~ s/\A\@\@ (-([0-9]+),([0-9]+) \+([0-9]+),([0-9]+)) \@\@[^\n]*\n?//;
600 my ($hunk, $from_start, $from_count, $to_start, $to_count)
601 = ($1, $2, $3, $4, $5);
602 my $from_end = $from_start + $from_count - 1;
603 my $to_end = $to_start + $to_count - 1;
604 my ($from_out, $to_out, $has_from, $has_to, $add, $delete);
605 while (length $diff_in && ($from_count || $to_count)) {
606 die "Confused in $hunk" unless $diff_in =~ s/\A([^\n]*)\n//ms;
607 my $line = $1;
608 $line = ' ' unless length $line;
609 if ($line =~ /^ .*/) {
610 process_hunk(\$from_out, \$to_out, \$has_from, \$has_to,
611 $delete, $add);
612 undef $delete;
613 undef $add;
614 $from_out .= " $line\n";
615 $to_out .= " $line\n";
616 --$from_count;
617 --$to_count;
618 } elsif ($line =~ /^-(.*)/) {
619 push @$delete, $1;
620 --$from_count;
621 } elsif ($line =~ /^\+(.*)/) {
622 push @$add, $1;
623 --$to_count;
624 } else {
625 die "Can't parse '$line' as part of hunk $hunk";
626 }
627 }
628 process_hunk(\$from_out, \$to_out, \$has_from, \$has_to,
629 $delete, $add);
630 die "No lines in hunk $hunk"
631 unless length $from_out || length $to_out;
632 die "No changes in hunk $hunk"
633 unless $has_from || $has_to;
634 $diff_out .= "***************\n";
635 $diff_out .= "*** $from_start,$from_end ****\n";
636 $diff_out .= $from_out if $has_from;
637 $diff_out .= "--- $to_start,$to_end ----\n";
638 $diff_out .= $to_out if $has_to;
639 }
640 }
641}
642
643{
644 my $use_context;
645
646 sub placate_patch_prog {
647 my $patch = shift;
648
649 if (!defined $use_context) {
650 my $version = `patch -v 2>&1`;
651 die "Can't run `patch -v`, \$?=$?, bailing out"
652 unless defined $version;
653 if ($version =~ /Free Software Foundation/) {
654 $use_context = 0;
655 } elsif ($version =~ /Header: patch\.c,v.*\blwall\b/) {
656 # The system patch is older than Linux, and probably older than
657 # Windows NT.
658 $use_context = 1;
659 } else {
660 # Don't know.
661 $use_context = 0;
662 }
663 }
664
665 return $use_context ? ud2cd($patch) : $patch;
666 }
667}
668
c59e8fd6 669sub apply_patch {
58a28a53
NC
670 my ($patch, $what, $files) = @_;
671 $what = 'patch' unless defined $what;
672 unless (defined $files) {
673 $patch =~ m!^--- a/(\S+)\n\+\+\+ b/\1!sm;
674 $files = " $1";
675 }
6fe55cbd 676 my $patch_to_use = placate_patch_prog($patch);
c59e8fd6 677 open my $fh, '|-', 'patch', '-p1' or die "Can't run patch: $!";
6fe55cbd 678 print $fh $patch_to_use;
5fceabf3
NC
679 return if close $fh;
680 print STDERR "Patch is <<'EOPATCH'\n${patch}EOPATCH\n";
6fe55cbd 681 print STDERR "\nConverted to a context diff <<'EOCONTEXT'\n${patch_to_use}EOCONTEXT\n";
58a28a53 682 die "Can't $what$files: $?, $!";
c59e8fd6
NC
683}
684
4e540a4e
NC
685sub apply_commit {
686 my ($commit, @files) = @_;
58a28a53
NC
687 my $patch = `git show $commit @files`;
688 if (!defined $patch) {
689 die "Can't get commit $commit for @files: $?" if @files;
690 die "Can't get commit $commit: $?";
691 }
692 apply_patch($patch, "patch $commit", @files ? " for @files" : '');
4e540a4e
NC
693}
694
695sub revert_commit {
696 my ($commit, @files) = @_;
58a28a53
NC
697 my $patch = `git show -R $commit @files`;
698 if (!defined $patch) {
699 die "Can't get revert commit $commit for @files: $?" if @files;
700 die "Can't get revert commit $commit: $?";
701 }
702 apply_patch($patch, "revert $commit", @files ? " for @files" : '');
4e540a4e
NC
703}
704
91ad6f8a
NC
705sub checkout_file {
706 my ($file, $commit) = @_;
707 $commit ||= 'blead';
708 system "git show $commit:$file > $file </dev/null"
709 and die "Could not extract $file at revision $commit";
710}
711
7cffc32d
NC
712sub check_shebang {
713 my $file = shift;
714 return unless -e $file;
715 if (!-x $file) {
716 die "$file is not executable.
717system($file, ...) is always going to fail.
718
719Bailing out";
720 }
721 my $fh = open_or_die($file);
722 my $line = <$fh>;
723 return unless $line =~ m{\A#!(/\S+/perl\S*)\s};
724 die "$file will always be run by $1
725It won't be tested by the ./perl we build.
726If you intended to run it with that perl binary, please change your
727test case to
728
729 $1 @ARGV
730
731If you intended to test it with the ./perl we build, please change your
732test case to
733
734 ./perl -Ilib @ARGV
735
736[You may also need to add -- before ./perl to prevent that -Ilib as being
737parsed as an argument to bisect.pl]
738
739Bailing out";
740}
741
ab4a15f9 742sub clean {
f4800c99 743 if ($options{clean}) {
ab4a15f9
NC
744 # Needed, because files that are build products in this checked out
745 # version might be in git in the next desired version.
9da8cb0a 746 system 'git clean -dxf </dev/null';
ab4a15f9
NC
747 # Needed, because at some revisions the build alters checked out files.
748 # (eg pod/perlapi.pod). Also undoes any changes to makedepend.SH
9da8cb0a 749 system 'git reset --hard HEAD </dev/null';
ab4a15f9
NC
750 }
751}
752
753sub skip {
754 my $reason = shift;
755 clean();
756 warn "skipping - $reason";
757 exit 125;
758}
759
f1050811
NC
760sub report_and_exit {
761 my ($ret, $pass, $fail, $desc) = @_;
762
763 clean();
764
f4800c99 765 my $got = ($options{'expect-pass'} ? !$ret : $ret) ? 'good' : 'bad';
f1050811
NC
766 if ($ret) {
767 print "$got - $fail $desc\n";
768 } else {
769 print "$got - $pass $desc\n";
770 }
771
772 exit($got eq 'bad');
773}
774
0afef97d
NC
775sub match_and_exit {
776 my $target = shift;
777 my $matches = 0;
778 my $re = qr/$match/;
779 my @files;
780
781 {
782 local $/ = "\0";
783 @files = defined $target ? `git ls-files -o -z`: `git ls-files -z`;
784 chomp @files;
785 }
786
787 foreach my $file (@files) {
69bf9aba 788 my $fh = open_or_die($file);
0afef97d
NC
789 while (<$fh>) {
790 if ($_ =~ $re) {
791 ++$matches;
792 if (tr/\t\r\n -~\200-\377//c) {
793 print "Binary file $file matches\n";
794 } else {
795 $_ .= "\n" unless /\n\z/;
796 print "$file: $_";
797 }
798 }
799 }
69bf9aba 800 close_or_die($fh);
0afef97d
NC
801 }
802 report_and_exit(!$matches,
803 $matches == 1 ? '1 match for' : "$matches matches for",
804 'no matches for', $match);
805}
806
6a8dbfd7 807# Not going to assume that system perl is yet new enough to have autodie
9da8cb0a 808system 'git clean -dxf </dev/null' and die;
6a8dbfd7 809
0afef97d
NC
810if (!defined $target) {
811 match_and_exit() if $match;
812 $target = 'test_prep';
bc96a05a
NC
813}
814
4b081584
NC
815skip('no Configure - is this the //depot/perlext/Compiler branch?')
816 unless -f 'Configure';
817
1f1c8096
NC
818my $case_insensitive;
819{
820 my ($dev_C, $ino_C) = stat 'Configure';
821 die "Could not stat Configure: $!" unless defined $dev_C;
822 my ($dev_c, $ino_c) = stat 'configure';
823 ++$case_insensitive
824 if defined $dev_c && $dev_C == $dev_c && $ino_C == $ino_c;
825}
826
dbcdc176
NC
827# This changes to PERL_VERSION in 4d8076ea25903dcb in 1999
828my $major
829 = extract_from_file('patchlevel.h',
830 qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/,
831 0);
832
750ce942
NC
833patch_Configure();
834patch_hints();
835
6a8dbfd7
NC
836# if Encode is not needed for the test, you can speed up the bisect by
837# excluding it from the runs with -Dnoextensions=Encode
838# ccache is an easy win. Remove it if it causes problems.
6a8dbfd7
NC
839# Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it
840# to true in hints/linux.sh
841# On dromedary, from that point on, Configure (by default) fails to find any
842# libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain
843# versioned libraries. Without -lm, the build fails.
844# Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards,
845# until commit faae14e6e968e1c0 adds it to the hints.
846# However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work,
847# because it will spot versioned libraries, pass them to the compiler, and then
848# bail out pretty early on. Configure won't let us override libswanted, but it
849# will let us override the entire libs list.
850
851unless (extract_from_file('Configure', 'ignore_versioned_solibs')) {
852 # Before 1cfa4ec74d4933da, so force the libs list.
853
854 my @libs;
855 # This is the current libswanted list from Configure, less the libs removed
856 # by current hints/linux.sh
857 foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld
858 ld sun m crypt sec util c cposix posix ucb BSD)) {
859 foreach my $dir (@paths) {
860 next unless -f "$dir/lib$lib.so";
861 push @libs, "-l$lib";
862 last;
863 }
864 }
390a69a9 865 $defines{libs} = \@libs unless exists $defines{libs};
6a8dbfd7
NC
866}
867
390a69a9
NC
868$defines{usenm} = undef
869 if $major < 2 && !exists $defines{usenm};
0142f0ce 870
05ec8abc
NC
871my ($missing, $created_dirs);
872($missing, $created_dirs) = force_manifest()
873 if $options{'force-manifest'};
67382a3b 874
af7c500f 875my @ARGS = '-dEs';
390a69a9
NC
876foreach my $key (sort keys %defines) {
877 my $val = $defines{$key};
878 if (ref $val) {
879 push @ARGS, "-D$key=@$val";
880 } elsif (!defined $val) {
881 push @ARGS, "-U$key";
882 } elsif (!length $val) {
883 push @ARGS, "-D$key";
884 } else {
885 $val = "" if $val eq "\0";
886 push @ARGS, "-D$key=$val";
887 }
888}
889push @ARGS, map {"-A$_"} @{$options{A}};
890
6a8dbfd7
NC
891# </dev/null because it seems that some earlier versions of Configure can
892# call commands in a way that now has them reading from stdin (and hanging)
893my $pid = fork;
894die "Can't fork: $!" unless defined $pid;
895if (!$pid) {
7c22f158
NC
896 open STDIN, '<', '/dev/null';
897 # If a file in MANIFEST is missing, Configure asks if you want to
898 # continue (the default being 'n'). With stdin closed or /dev/null,
899 # it exits immediately and the check for config.sh below will skip.
6a8dbfd7
NC
900 exec './Configure', @ARGS;
901 die "Failed to start Configure: $!";
902}
903waitpid $pid, 0
904 or die "wait for Configure, pid $pid failed: $!";
905
bb723266
NC
906patch_SH();
907
af7c500f 908if (-f 'config.sh') {
05ec8abc
NC
909 # Emulate noextensions if Configure doesn't support it.
910 fake_noextensions()
911 if $major < 10 && $defines{noextensions};
af7c500f
NC
912 system './Configure -S </dev/null' and die;
913}
914
0afef97d
NC
915if ($target =~ /config\.s?h/) {
916 match_and_exit($target) if $match && -f $target;
30a13282
NC
917 report_and_exit(!-f $target, 'could build', 'could not build', $target)
918 if $options{'test-build'};
919
18815322
NC
920 skip("could not build $target") unless -f $target;
921
30a13282
NC
922 my $ret = system @ARGV;
923 report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
dd4e46d7
NC
924} elsif (!-f 'config.sh') {
925 # Skip if something went wrong with Configure
926
927 skip('could not build config.sh');
928}
6a8dbfd7 929
05ec8abc
NC
930force_manifest_cleanup($missing, $created_dirs)
931 if $missing;
67382a3b 932
bfa52998
NC
933if($options{'force-regen'}
934 && extract_from_file('Makefile', qr/\bregen_headers\b/)) {
935 # regen_headers was added in e50aee73b3d4c555, patch.1m for perl5.001
936 # It's not worth faking it for earlier revisions.
937 system "make regen_headers </dev/null"
938 and die;
939}
940
bb723266 941patch_C();
f2f0a0ff 942patch_ext();
750ce942
NC
943
944# Parallel build for miniperl is safe
32ffe018 945system "$options{make} $j miniperl </dev/null";
750ce942
NC
946
947my $expected = $target =~ /^test/ ? 't/perl'
948 : $target eq 'Fcntl' ? "lib/auto/Fcntl/Fcntl.$Config{so}"
949 : $target;
950my $real_target = $target eq 'Fcntl' ? $expected : $target;
951
952if ($target ne 'miniperl') {
953 # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that.
954 $j = '' if $major < 10;
955
956 if ($real_target eq 'test_prep') {
957 if ($major < 8) {
958 # test-prep was added in 5.004_01, 3e3baf6d63945cb6.
959 # renamed to test_prep in 2001 in 5fe84fd29acaf55c.
960 # earlier than that, just make test. It will be fast enough.
961 $real_target = extract_from_file('Makefile.SH',
962 qr/^(test[-_]prep):/,
963 'test');
964 }
965 }
966
32ffe018 967 system "$options{make} $j $real_target </dev/null";
6f8c21fa
NC
968}
969
750ce942
NC
970my $missing_target = $expected =~ /perl$/ ? !-x $expected : !-r $expected;
971
972if ($options{'test-build'}) {
973 report_and_exit($missing_target, 'could build', 'could not build',
974 $real_target);
975} elsif ($missing_target) {
976 skip("could not build $real_target");
f50dca98
NC
977}
978
750ce942
NC
979match_and_exit($real_target) if $match;
980
981if (defined $options{'one-liner'}) {
982 my $exe = $target =~ /^(?:perl$|test)/ ? 'perl' : 'miniperl';
fc4401c6
NC
983 unshift @ARGV, '-e', $options{'one-liner'};
984 unshift @ARGV, '-l' if $options{l};
985 unshift @ARGV, '-w' if $options{w};
986 unshift @ARGV, "./$exe", '-Ilib';
f50dca98
NC
987}
988
750ce942
NC
989# This is what we came here to run:
990
991if (exists $Config{ldlibpthname}) {
992 require Cwd;
993 my $varname = $Config{ldlibpthname};
994 my $cwd = Cwd::getcwd();
995 if (defined $ENV{$varname}) {
996 $ENV{$varname} = $cwd . $Config{path_sep} . $ENV{$varname};
997 } else {
998 $ENV{$varname} = $cwd;
f50dca98 999 }
750ce942
NC
1000}
1001
1002my $ret = system @ARGV;
1003
1004report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
1005
f2f0a0ff
NC
1006############################################################################
1007#
05ec8abc 1008# Patching, editing and faking routines only below here.
f2f0a0ff
NC
1009#
1010############################################################################
1011
05ec8abc
NC
1012sub fake_noextensions {
1013 edit_file('config.sh', sub {
1014 my @lines = split /\n/, shift;
1015 my @ext = split /\s+/, $defines{noextensions};
1016 foreach (@lines) {
1017 next unless /^extensions=/ || /^dynamic_ext/;
1018 foreach my $ext (@ext) {
1019 s/\b$ext( )?\b/$1/;
1020 }
1021 }
1022 return join "\n", @lines;
1023 });
1024}
1025
1026sub force_manifest {
1027 my (@missing, @created_dirs);
1028 my $fh = open_or_die('MANIFEST');
1029 while (<$fh>) {
1030 next unless /^(\S+)/;
1031 # -d is special case needed (at least) between 27332437a2ed1941 and
1032 # bf3d9ec563d25054^ inclusive, as manifest contains ext/Thread/Thread
1033 push @missing, $1
1034 unless -f $1 || -d $1;
1035 }
1036 close_or_die($fh);
1037
1038 foreach my $pathname (@missing) {
1039 my @parts = split '/', $pathname;
1040 my $leaf = pop @parts;
1041 my $path = '.';
1042 while (@parts) {
1043 $path .= '/' . shift @parts;
1044 next if -d $path;
1045 mkdir $path, 0700 or die "Can't create $path: $!";
1046 unshift @created_dirs, $path;
1047 }
1048 $fh = open_or_die($pathname, '>');
1049 close_or_die($fh);
1050 chmod 0, $pathname or die "Can't chmod 0 $pathname: $!";
1051 }
1052 return \@missing, \@created_dirs;
1053}
1054
1055sub force_manifest_cleanup {
1056 my ($missing, $created_dirs) = @_;
1057 # This is probably way too paranoid:
1058 my @errors;
1059 require Fcntl;
1060 foreach my $file (@$missing) {
1061 my (undef, undef, $mode, undef, undef, undef, undef, $size)
1062 = stat $file;
1063 if (!defined $mode) {
1064 push @errors, "Added file $file has been deleted by Configure";
1065 next;
1066 }
1067 if (Fcntl::S_IMODE($mode) != 0) {
1068 push @errors,
1069 sprintf 'Added file %s had mode changed by Configure to %03o',
1070 $file, $mode;
1071 }
1072 if ($size != 0) {
1073 push @errors,
1074 "Added file $file had sized changed by Configure to $size";
1075 }
1076 unlink $file or die "Can't unlink $file: $!";
1077 }
1078 foreach my $dir (@$created_dirs) {
1079 rmdir $dir or die "Can't rmdir $dir: $!";
1080 }
1081 skip("@errors")
1082 if @errors;
1083}
1084
750ce942
NC
1085sub patch_Configure {
1086 if ($major < 1) {
1087 if (extract_from_file('Configure',
1088 qr/^\t\t\*=\*\) echo "\$1" >> \$optdef;;$/)) {
1089 # This is " Spaces now allowed in -D command line options.",
1090 # part of commit ecfc54246c2a6f42
1091 apply_patch(<<'EOPATCH');
1092diff --git a/Configure b/Configure
1093index 3d3b38d..78ffe16 100755
1094--- a/Configure
1095+++ b/Configure
1096@@ -652,7 +777,8 @@ while test $# -gt 0; do
1097 echo "$me: use '-U symbol=', not '-D symbol='." >&2
1098 echo "$me: ignoring -D $1" >&2
1099 ;;
1100- *=*) echo "$1" >> $optdef;;
1101+ *=*) echo "$1" | \
1102+ sed -e "s/'/'\"'\"'/g" -e "s/=\(.*\)/='\1'/" >> $optdef;;
1103 *) echo "$1='define'" >> $optdef;;
1104 esac
1105 shift
1106EOPATCH
1107 }
1108
1109 if (extract_from_file('Configure', qr/^if \$contains 'd_namlen' \$xinc\b/)) {
1110 # Configure's original simple "grep" for d_namlen falls foul of the
1111 # approach taken by the glibc headers:
1112 # #ifdef _DIRENT_HAVE_D_NAMLEN
1113 # # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
1114 #
1115 # where _DIRENT_HAVE_D_NAMLEN is not defined on Linux.
1116 # This is also part of commit ecfc54246c2a6f42
1117 apply_patch(<<'EOPATCH');
1118diff --git a/Configure b/Configure
1119index 3d3b38d..78ffe16 100755
1120--- a/Configure
1121+++ b/Configure
1122@@ -3935,7 +4045,8 @@ $rm -f try.c
1123
1124 : see if the directory entry stores field length
1125 echo " "
1126-if $contains 'd_namlen' $xinc >/dev/null 2>&1; then
1127+$cppstdin $cppflags $cppminus < "$xinc" > try.c
1128+if $contains 'd_namlen' try.c >/dev/null 2>&1; then
1129 echo "Good, your directory entry keeps length information in d_namlen." >&4
1130 val="$define"
1131 else
1132EOPATCH
1133 }
f50dca98 1134 }
750ce942
NC
1135
1136 if ($major < 2
1137 && !extract_from_file('Configure',
1138 qr/Try to guess additional flags to pick up local libraries/)) {
1139 my $mips = extract_from_file('Configure',
1140 qr!(''\) if (?:\./)?mips; then)!);
1141 # This is part of perl-5.001n. It's needed, to add -L/usr/local/lib to
1142 # theld flags if libraries are found there. It shifts the code to set up
1143 # libpth earlier, and then adds the code to add libpth entries to
1144 # ldflags
1145 # mips was changed to ./mips in ecfc54246c2a6f42, perl5.000 patch.0g
1146 apply_patch(sprintf <<'EOPATCH', $mips);
1147diff --git a/Configure b/Configure
1148index 53649d5..0635a6e 100755
1149--- a/Configure
1150+++ b/Configure
1151@@ -2749,6 +2749,52 @@ EOM
1152 ;;
1153 esac
f50dca98 1154
750ce942
NC
1155+: Set private lib path
1156+case "$plibpth" in
1157+'') if ./mips; then
1158+ plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
1159+ fi;;
1160+esac
1161+case "$libpth" in
1162+' ') dlist='';;
1163+'') dlist="$plibpth $glibpth";;
1164+*) dlist="$libpth";;
1165+esac
1166+
1167+: Now check and see which directories actually exist, avoiding duplicates
1168+libpth=''
1169+for xxx in $dlist
1170+do
1171+ if $test -d $xxx; then
1172+ case " $libpth " in
1173+ *" $xxx "*) ;;
1174+ *) libpth="$libpth $xxx";;
1175+ esac
1176+ fi
1177+done
1178+$cat <<'EOM'
1179+
1180+Some systems have incompatible or broken versions of libraries. Among
1181+the directories listed in the question below, please remove any you
1182+know not to be holding relevant libraries, and add any that are needed.
1183+Say "none" for none.
1184+
1185+EOM
1186+case "$libpth" in
1187+'') dflt='none';;
1188+*)
1189+ set X $libpth
1190+ shift
1191+ dflt=${1+"$@"}
1192+ ;;
1193+esac
1194+rp="Directories to use for library searches?"
1195+. ./myread
1196+case "$ans" in
1197+none) libpth=' ';;
1198+*) libpth="$ans";;
1199+esac
1200+
1201 : flags used in final linking phase
1202 case "$ldflags" in
1203 '') if ./venix; then
1204@@ -2765,6 +2811,23 @@ case "$ldflags" in
1205 ;;
1206 *) dflt="$ldflags";;
1207 esac
1208+
1209+: Possible local library directories to search.
1210+loclibpth="/usr/local/lib /opt/local/lib /usr/gnu/lib"
1211+loclibpth="$loclibpth /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib"
1212+
1213+: Try to guess additional flags to pick up local libraries.
1214+for thislibdir in $libpth; do
1215+ case " $loclibpth " in
1216+ *" $thislibdir "*)
1217+ case "$dflt " in
1218+ "-L$thislibdir ") ;;
1219+ *) dflt="$dflt -L$thislibdir" ;;
1220+ esac
1221+ ;;
1222+ esac
1223+done
1224+
1225 echo " "
1226 rp="Any additional ld flags (NOT including libraries)?"
1227 . ./myread
1228@@ -2828,52 +2891,6 @@ n) echo "OK, that should do.";;
1229 esac
1230 $rm -f try try.* core
1231
1232-: Set private lib path
1233-case "$plibpth" in
1234-%s
1235- plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
1236- fi;;
1237-esac
1238-case "$libpth" in
1239-' ') dlist='';;
1240-'') dlist="$plibpth $glibpth";;
1241-*) dlist="$libpth";;
1242-esac
1243-
1244-: Now check and see which directories actually exist, avoiding duplicates
1245-libpth=''
1246-for xxx in $dlist
1247-do
1248- if $test -d $xxx; then
1249- case " $libpth " in
1250- *" $xxx "*) ;;
1251- *) libpth="$libpth $xxx";;
1252- esac
1253- fi
1254-done
1255-$cat <<'EOM'
f50dca98 1256-
750ce942
NC
1257-Some systems have incompatible or broken versions of libraries. Among
1258-the directories listed in the question below, please remove any you
1259-know not to be holding relevant libraries, and add any that are needed.
1260-Say "none" for none.
1261-
1262-EOM
1263-case "$libpth" in
1264-'') dflt='none';;
1265-*)
1266- set X $libpth
1267- shift
1268- dflt=${1+"$@"}
1269- ;;
1270-esac
1271-rp="Directories to use for library searches?"
1272-. ./myread
1273-case "$ans" in
1274-none) libpth=' ';;
1275-*) libpth="$ans";;
1276-esac
1277-
1278 : compute shared library extension
1279 case "$so" in
1280 '')
f50dca98
NC
1281EOPATCH
1282 }
686af304 1283
750ce942
NC
1284 if ($major < 5 && extract_from_file('Configure',
1285 qr!if \$cc \$ccflags try\.c -o try >/dev/null 2>&1; then!)) {
1286 # Analogous to the more general fix of dfe9444ca7881e71
1287 # Without this flags such as -m64 may not be passed to this compile,
1288 # which results in a byteorder of '1234' instead of '12345678', which
1289 # can then cause crashes.
686af304 1290
750ce942
NC
1291 if (extract_from_file('Configure', qr/xxx_prompt=y/)) {
1292 # 8e07c86ebc651fe9 or later
1293 # ("This is my patch patch.1n for perl5.001.")
1294 apply_patch(<<'EOPATCH');
1295diff --git a/Configure b/Configure
1296index 62249dd..c5c384e 100755
1297--- a/Configure
1298+++ b/Configure
1299@@ -8247,7 +8247,7 @@ main()
1300 }
1301 EOCP
1302 xxx_prompt=y
1303- if $cc $ccflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
1304+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
1305 dflt=`./try`
1306 case "$dflt" in
1307 [1-4][1-4][1-4][1-4]|12345678|87654321)
1308EOPATCH
1309 } else {
1310 apply_patch(<<'EOPATCH');
1311diff --git a/Configure b/Configure
1312index 53649d5..f1cd64a 100755
1313--- a/Configure
1314+++ b/Configure
1315@@ -6362,7 +6362,7 @@ main()
1316 printf("\n");
1317 }
1318 EOCP
1319- if $cc $ccflags try.c -o try >/dev/null 2>&1 ; then
1320+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 ; then
1321 dflt=`./try`
1322 case "$dflt" in
1323 ????|????????) echo "(The test program ran ok.)";;
1324EOPATCH
1325 }
1326 }
9a999a97 1327
750ce942
NC
1328 if ($major < 6 && !extract_from_file('Configure',
1329 qr!^\t-A\)$!)) {
1330 # This adds the -A option to Configure, which is incredibly useful
1331 # Effectively this is commits 02e93a22d20fc9a5, 5f83a3e9d818c3ad,
1332 # bde6b06b2c493fef, f7c3111703e46e0c and 2 lines of trailing whitespace
1333 # removed by 613d6c3e99b9decc, but applied at slightly different
1334 # locations to ensure a clean patch back to 5.000
1335 # Note, if considering patching to the intermediate revisions to fix
1336 # bugs in -A handling, f7c3111703e46e0c is from 2002, and hence
1337 # $major == 8
1338
1339 # To add to the fun, early patches add -K and -O options, and it's not
1340 # trivial to get patch to put the C<. ./posthint.sh> in the right place
1341 edit_file('Configure', sub {
1342 my $code = shift;
1343 $code =~ s/(optstr = ")([^"]+";\s*# getopt-style specification)/$1A:$2/
1344 or die "Substitution failed";
1345 $code =~ s!^(: who configured the system)!
1346touch posthint.sh
1347. ./posthint.sh
2526f4b8 1348
750ce942
NC
1349$1!ms
1350 or die "Substitution failed";
1351 return $code;
1352 });
1353 apply_patch(<<'EOPATCH');
1354diff --git a/Configure b/Configure
1355index 4b55fa6..60c3c64 100755
1356--- a/Configure
1357+++ b/Configure
1358@@ -1150,6 +1150,7 @@ set X `for arg in "$@"; do echo "X$arg"; done |
1359 eval "set $*"
1360 shift
1361 rm -f options.awk
1362+rm -f posthint.sh
1363
1364 : set up default values
1365 fastread=''
1366@@ -1172,6 +1173,56 @@ while test $# -gt 0; do
1367 case "$1" in
1368 -d) shift; fastread=yes;;
1369 -e) shift; alldone=cont;;
1370+ -A)
1371+ shift
1372+ xxx=''
1373+ yyy="$1"
1374+ zzz=''
1375+ uuu=undef
1376+ case "$yyy" in
1377+ *=*) zzz=`echo "$yyy"|sed 's!=.*!!'`
1378+ case "$zzz" in
1379+ *:*) zzz='' ;;
1380+ *) xxx=append
1381+ zzz=" "`echo "$yyy"|sed 's!^[^=]*=!!'`
1382+ yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
1383+ esac
1384+ ;;
1385+ esac
1386+ case "$xxx" in
1387+ '') case "$yyy" in
1388+ *:*) xxx=`echo "$yyy"|sed 's!:.*!!'`
1389+ yyy=`echo "$yyy"|sed 's!^[^:]*:!!'`
1390+ zzz=`echo "$yyy"|sed 's!^[^=]*=!!'`
1391+ yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
1392+ *) xxx=`echo "$yyy"|sed 's!:.*!!'`
1393+ yyy=`echo "$yyy"|sed 's!^[^:]*:!!'` ;;
1394+ esac
1395+ ;;
1396+ esac
1397+ case "$xxx" in
1398+ append)
1399+ echo "$yyy=\"\${$yyy}$zzz\"" >> posthint.sh ;;
1400+ clear)
1401+ echo "$yyy=''" >> posthint.sh ;;
1402+ define)
1403+ case "$zzz" in
1404+ '') zzz=define ;;
1405+ esac
1406+ echo "$yyy='$zzz'" >> posthint.sh ;;
1407+ eval)
1408+ echo "eval \"$yyy=$zzz\"" >> posthint.sh ;;
1409+ prepend)
1410+ echo "$yyy=\"$zzz\${$yyy}\"" >> posthint.sh ;;
1411+ undef)
1412+ case "$zzz" in
1413+ '') zzz="$uuu" ;;
1414+ esac
1415+ echo "$yyy=$zzz" >> posthint.sh ;;
1416+ *) echo "$me: unknown -A command '$xxx', ignoring -A $1" >&2 ;;
1417+ esac
1418+ shift
1419+ ;;
1420 -f)
1421 shift
1422 cd ..
1423EOPATCH
1424 }
9a999a97 1425
d1ac19b7
NC
1426 if ($major < 8 && $^O eq 'aix') {
1427 edit_file('Configure', sub {
1428 my $code = shift;
1429 # Replicate commit a8c676c69574838b
1430 # Whitespace allowed at the ends of /lib/syscalls.exp lines
1431 # and half of commit c6912327ae30e6de
1432 # AIX syscalls.exp scan: the syscall might be marked 32, 3264, or 64
1433 $code =~ s{(\bsed\b.*\bsyscall)(?:\[0-9\]\*)?(\$.*/lib/syscalls\.exp)}
1434 {$1 . "[0-9]*[ \t]*" . $2}e;
1435 return $code;
1436 });
1437 }
1438
750ce942
NC
1439 if ($major < 8 && !extract_from_file('Configure',
1440 qr/^\t\tif test ! -t 0; then$/)) {
1441 # Before dfe9444ca7881e71, Configure would refuse to run if stdin was
1442 # not a tty. With that commit, the tty requirement was dropped for -de
1443 # and -dE
1444 # Commit aaeb8e512e8e9e14 dropped the tty requirement for -S
1445 # For those older versions, it's probably easiest if we simply remove
1446 # the sanity test.
1447 edit_file('Configure', sub {
1448 my $code = shift;
1449 $code =~ s/test ! -t 0/test Perl = rules/;
1450 return $code;
1451 });
6a8dbfd7 1452 }
6a8dbfd7 1453
750ce942
NC
1454 if ($major == 8 || $major == 9) {
1455 # Fix symbol detection to that of commit 373dfab3839ca168 if it's any
1456 # intermediate version 5129fff43c4fe08c or later, as the intermediate
1457 # versions don't work correctly on (at least) Sparc Linux.
1458 # 5129fff43c4fe08c adds the first mention of mistrustnm.
1459 # 373dfab3839ca168 removes the last mention of lc=""
1460 edit_file('Configure', sub {
1461 my $code = shift;
1462 return $code
1463 if $code !~ /\btc="";/; # 373dfab3839ca168 or later
1464 return $code
1465 if $code !~ /\bmistrustnm\b/; # before 5129fff43c4fe08c
1466 my $fixed = <<'EOC';
6a8dbfd7 1467
750ce942
NC
1468: is a C symbol defined?
1469csym='tlook=$1;
1470case "$3" in
1471-v) tf=libc.tmp; tdc="";;
1472-a) tf=libc.tmp; tdc="[]";;
1473*) tlook="^$1\$"; tf=libc.list; tdc="()";;
1474esac;
1475tx=yes;
1476case "$reuseval-$4" in
1477true-) ;;
1478true-*) tx=no; eval "tval=\$$4"; case "$tval" in "") tx=yes;; esac;;
1479esac;
1480case "$tx" in
1481yes)
1482 tval=false;
1483 if $test "$runnm" = true; then
1484 if $contains $tlook $tf >/dev/null 2>&1; then
1485 tval=true;
1486 elif $test "$mistrustnm" = compile -o "$mistrustnm" = run; then
1487 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
1488 $cc -o try $optimize $ccflags $ldflags try.c >/dev/null 2>&1 $libs && tval=true;
1489 $test "$mistrustnm" = run -a -x try && { $run ./try$_exe >/dev/null 2>&1 || tval=false; };
1490 $rm -f try$_exe try.c core core.* try.core;
1491 fi;
1492 else
1493 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
1494 $cc -o try $optimize $ccflags $ldflags try.c $libs >/dev/null 2>&1 && tval=true;
1495 $rm -f try$_exe try.c;
1496 fi;
1497 ;;
1498*)
1499 case "$tval" in
1500 $define) tval=true;;
1501 *) tval=false;;
1502 esac;
1503 ;;
1504esac;
1505eval "$2=$tval"'
67382a3b 1506
750ce942
NC
1507EOC
1508 $code =~ s/\n: is a C symbol defined\?\n.*?\neval "\$2=\$tval"'\n\n/$fixed/sm
1509 or die "substitution failed";
1510 return $code;
1511 });
1512 }
1513
1514 if ($major < 10
1515 && extract_from_file('Configure', qr/^set malloc\.h i_malloc$/)) {
1516 # This is commit 01d07975f7ef0e7d, trimmed, with $compile inlined as
1517 # prior to bd9b35c97ad661cc Configure had the malloc.h test before the
1518 # definition of $compile.
1519 apply_patch(<<'EOPATCH');
1520diff --git a/Configure b/Configure
1521index 3d2e8b9..6ce7766 100755
1522--- a/Configure
1523+++ b/Configure
1524@@ -6743,5 +6743,22 @@ set d_dosuid
1525
1526 : see if this is a malloc.h system
1527-set malloc.h i_malloc
1528-eval $inhdr
1529+: we want a real compile instead of Inhdr because some systems have a
1530+: malloc.h that just gives a compile error saying to use stdlib.h instead
1531+echo " "
1532+$cat >try.c <<EOCP
1533+#include <stdlib.h>
1534+#include <malloc.h>
1535+int main () { return 0; }
1536+EOCP
1537+set try
1538+if $cc $optimize $ccflags $ldflags -o try $* try.c $libs > /dev/null 2>&1; then
1539+ echo "<malloc.h> found." >&4
1540+ val="$define"
1541+else
1542+ echo "<malloc.h> NOT found." >&4
1543+ val="$undef"
1544+fi
1545+$rm -f try.c try
1546+set i_malloc
1547+eval $setvar
1548
1549EOPATCH
1550 }
67382a3b 1551}
6a8dbfd7 1552
750ce942
NC
1553sub patch_hints {
1554 if ($^O eq 'freebsd') {
1555 # There are rather too many version-specific FreeBSD hints fixes to
1556 # patch individually. Also, more than once the FreeBSD hints file has
1557 # been written in what turned out to be a rather non-future-proof style,
1558 # with case statements treating the most recent version as the
1559 # exception, instead of treating previous versions' behaviour explicitly
1560 # and changing the default to cater for the current behaviour. (As
1561 # strangely, future versions inherit the current behaviour.)
1562 checkout_file('hints/freebsd.sh');
1563 } elsif ($^O eq 'darwin') {
1564 if ($major < 8) {
1565 # We can't build on darwin without some of the data in the hints
1566 # file. Probably less surprising to use the earliest version of
1567 # hints/darwin.sh and then edit in place just below, than use
1568 # blead's version, as that would create a discontinuity at
1569 # f556e5b971932902 - before it, hints bugs would be "fixed", after
1570 # it they'd resurface. This way, we should give the illusion of
1571 # monotonic bug fixing.
1572 my $faking_it;
1573 if (!-f 'hints/darwin.sh') {
1574 checkout_file('hints/darwin.sh', 'f556e5b971932902');
1575 ++$faking_it;
1576 }
0afef97d 1577
750ce942
NC
1578 edit_file('hints/darwin.sh', sub {
1579 my $code = shift;
1580 # Part of commit 8f4f83badb7d1ba9, which mostly undoes
1581 # commit 0511a818910f476c.
1582 $code =~ s/^cppflags='-traditional-cpp';$/cppflags="\${cppflags} -no-cpp-precomp"/m;
1583 # commit 14c11978e9b52e08/803bb6cc74d36a3f
1584 # Without this, code in libperl.bundle links against op.o
1585 # in preference to opmini.o on the linker command line,
1586 # and hence miniperl tries to use File::Glob instead of
1587 # csh
1588 $code =~ s/^(lddlflags=)/ldflags="\${ldflags} -flat_namespace"\n$1/m;
1589 # f556e5b971932902 also patches Makefile.SH with some
1590 # special case code to deal with useshrplib for darwin.
1591 # Given that post 5.8.0 the darwin hints default was
1592 # changed to false, and it would be very complex to splice
1593 # in that code in various versions of Makefile.SH back
1594 # to 5.002, lets just turn it off.
1595 $code =~ s/^useshrplib='true'/useshrplib='false'/m
1596 if $faking_it;
1f1c8096
NC
1597
1598 # Part of commit d235852b65d51c44
1599 # Don't do this on a case sensitive HFS+ partition, as it
1600 # breaks the build for 5.003 and earlier.
1601 if ($case_insensitive
1602 && $code !~ /^firstmakefile=GNUmakefile/) {
1603 $code .= "\nfirstmakefile=GNUmakefile;\n";
1604 }
1605
750ce942
NC
1606 return $code;
1607 });
1608 }
1609 } elsif ($^O eq 'netbsd') {
1610 if ($major < 6) {
1611 # These are part of commit 099685bc64c7dbce
1612 edit_file('hints/netbsd.sh', sub {
1613 my $code = shift;
1614 my $fixed = <<'EOC';
1615case "$osvers" in
16160.9|0.8*)
1617 usedl="$undef"
1618 ;;
1619*)
1620 if [ -f /usr/libexec/ld.elf_so ]; then
1621 d_dlopen=$define
1622 d_dlerror=$define
1623 ccdlflags="-Wl,-E -Wl,-R${PREFIX}/lib $ccdlflags"
1624 cccdlflags="-DPIC -fPIC $cccdlflags"
1625 lddlflags="--whole-archive -shared $lddlflags"
1626 elif [ "`uname -m`" = "pmax" ]; then
9f1d18fe 1627# NetBSD 1.3 and 1.3.1 on pmax shipped an 'old' ld.so, which will not work.
750ce942
NC
1628 d_dlopen=$undef
1629 elif [ -f /usr/libexec/ld.so ]; then
1630 d_dlopen=$define
1631 d_dlerror=$define
1632 ccdlflags="-Wl,-R${PREFIX}/lib $ccdlflags"
1633# we use -fPIC here because -fpic is *NOT* enough for some of the
1634# extensions like Tk on some netbsd platforms (the sparc is one)
1635 cccdlflags="-DPIC -fPIC $cccdlflags"
1636 lddlflags="-Bforcearchive -Bshareable $lddlflags"
1637 else
1638 d_dlopen=$undef
1639 fi
1640 ;;
1641esac
1642EOC
1643 $code =~ s/^case "\$osvers" in\n0\.9\|0\.8.*?^esac\n/$fixed/ms;
1644 return $code;
1645 });
1646 }
1647 } elsif ($^O eq 'openbsd') {
1648 if ($major < 8) {
1649 checkout_file('hints/openbsd.sh', '43051805d53a3e4c')
1650 unless -f 'hints/openbsd.sh';
1651 my $which = extract_from_file('hints/openbsd.sh',
1652 qr/# from (2\.8|3\.1) onwards/,
1653 '');
1654 if ($which eq '') {
1655 my $was = extract_from_file('hints/openbsd.sh',
1656 qr/(lddlflags="(?:-Bforcearchive )?-Bshareable)/);
1657 # This is commit 154d43cbcf57271c and parts of 5c75dbfa77b0949c
1658 # and 29b5585702e5e025
1659 apply_patch(sprintf <<'EOPATCH', $was);
1660diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1661index a7d8bf2..5b79709 100644
1662--- a/hints/openbsd.sh
1663+++ b/hints/openbsd.sh
1664@@ -37,7 +37,25 @@ OpenBSD.alpha|OpenBSD.mips|OpenBSD.powerpc|OpenBSD.vax)
1665 # we use -fPIC here because -fpic is *NOT* enough for some of the
1666 # extensions like Tk on some OpenBSD platforms (ie: sparc)
1667 cccdlflags="-DPIC -fPIC $cccdlflags"
1668- %s $lddlflags"
1669+ case "$osvers" in
1670+ [01].*|2.[0-7]|2.[0-7].*)
1671+ lddlflags="-Bshareable $lddlflags"
1672+ ;;
1673+ 2.[8-9]|3.0)
1674+ ld=${cc:-cc}
1675+ lddlflags="-shared -fPIC $lddlflags"
1676+ ;;
1677+ *) # from 3.1 onwards
1678+ ld=${cc:-cc}
1679+ lddlflags="-shared -fPIC $lddlflags"
1680+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1681+ ;;
1682+ esac
1683+
1684+ # We need to force ld to export symbols on ELF platforms.
1685+ # Without this, dlopen() is crippled.
1686+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1687+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1688 ;;
1689 esac
1690
1691EOPATCH
1692 } elsif ($which eq '2.8') {
1693 # This is parts of 5c75dbfa77b0949c and 29b5585702e5e025, and
1694 # possibly eb9cd59d45ad2908
1695 my $was = extract_from_file('hints/openbsd.sh',
1696 qr/lddlflags="(-shared(?: -fPIC)?) \$lddlflags"/);
0afef97d 1697
750ce942
NC
1698 apply_patch(sprintf <<'EOPATCH', $was);
1699--- a/hints/openbsd.sh 2011-10-21 17:25:20.000000000 +0200
1700+++ b/hints/openbsd.sh 2011-10-21 16:58:43.000000000 +0200
1701@@ -44,11 +44,21 @@
1702 [01].*|2.[0-7]|2.[0-7].*)
1703 lddlflags="-Bshareable $lddlflags"
1704 ;;
1705- *) # from 2.8 onwards
1706+ 2.[8-9]|3.0)
1707 ld=${cc:-cc}
1708- lddlflags="%s $lddlflags"
1709+ lddlflags="-shared -fPIC $lddlflags"
1710+ ;;
1711+ *) # from 3.1 onwards
1712+ ld=${cc:-cc}
1713+ lddlflags="-shared -fPIC $lddlflags"
1714+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1715 ;;
1716 esac
1717+
1718+ # We need to force ld to export symbols on ELF platforms.
1719+ # Without this, dlopen() is crippled.
1720+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1721+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1722 ;;
1723 esac
1724
1725EOPATCH
1726 } elsif ($which eq '3.1'
1727 && !extract_from_file('hints/openbsd.sh',
1728 qr/We need to force ld to export symbols on ELF platforms/)) {
1729 # This is part of 29b5585702e5e025
1730 apply_patch(<<'EOPATCH');
1731diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1732index c6b6bc9..4839d04 100644
1733--- a/hints/openbsd.sh
1734+++ b/hints/openbsd.sh
1735@@ -54,6 +54,11 @@ alpha-2.[0-8]|mips-*|vax-*|powerpc-2.[0-7]|m88k-*)
1736 libswanted=`echo $libswanted | sed 's/ dl / /'`
1737 ;;
1738 esac
1739+
1740+ # We need to force ld to export symbols on ELF platforms.
1741+ # Without this, dlopen() is crippled.
1742+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1743+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1744 ;;
1745 esac
1746
1747EOPATCH
1748 }
1749 }
1750 } elsif ($^O eq 'linux') {
1751 if ($major < 1) {
1752 # sparc linux seems to need the -Dbool=char -DHAS_BOOL part of
1753 # perl5.000 patch.0n: [address Configure and build issues]
1754 edit_file('hints/linux.sh', sub {
1755 my $code = shift;
1756 $code =~ s!-I/usr/include/bsd!-Dbool=char -DHAS_BOOL!g;
1757 return $code;
1758 });
1759 }
915f531b 1760
750ce942
NC
1761 if ($major <= 9) {
1762 if (`uname -sm` =~ qr/^Linux sparc/) {
1763 if (extract_from_file('hints/linux.sh', qr/sparc-linux/)) {
1764 # Be sure to use -fPIC not -fpic on Linux/SPARC
1765 apply_commit('f6527d0ef0c13ad4');
1766 } elsif(!extract_from_file('hints/linux.sh',
1767 qr/^sparc-linux\)$/)) {
1768 my $fh = open_or_die('hints/linux.sh', '>>');
1769 print $fh <<'EOT' or die $!;
1770
1771case "`uname -m`" in
1772sparc*)
1773 case "$cccdlflags" in
1774 *-fpic*) cccdlflags="`echo $cccdlflags|sed 's/-fpic/-fPIC/'`" ;;
1775 *) cccdlflags="$cccdlflags -fPIC" ;;
1776 esac
1777 ;;
1778esac
1779EOT
1780 close_or_die($fh);
1781 }
1782 }
1783 }
915f531b
NC
1784 }
1785}
1786
bb723266
NC
1787sub patch_SH {
1788 # Cwd.xs added in commit 0d2079faa739aaa9. Cwd.pm moved to ext/ 8 years
1789 # later in commit 403f501d5b37ebf0
1790 if ($major > 0 && <*/Cwd/Cwd.xs>) {
1791 if ($major < 10
1792 && !extract_from_file('Makefile.SH', qr/^extra_dep=''$/)) {
1793 # The Makefile.PL for Unicode::Normalize needs
1794 # lib/unicore/CombiningClass.pl. Even without a parallel build, we
1795 # need a dependency to ensure that it builds. This is a variant of
1796 # commit 9f3ef600c170f61e. Putting this for earlier versions gives
1797 # us a spot on which to hang the edits below
1798 apply_patch(<<'EOPATCH');
1799diff --git a/Makefile.SH b/Makefile.SH
1800index f61d0db..6097954 100644
1801--- a/Makefile.SH
1802+++ b/Makefile.SH
1803@@ -155,10 +155,20 @@ esac
1804
1805 : Prepare dependency lists for Makefile.
1806 dynamic_list=' '
1807+extra_dep=''
1808 for f in $dynamic_ext; do
1809 : the dependency named here will never exist
1810 base=`echo "$f" | sed 's/.*\///'`
1811- dynamic_list="$dynamic_list lib/auto/$f/$base.$dlext"
1812+ this_target="lib/auto/$f/$base.$dlext"
1813+ dynamic_list="$dynamic_list $this_target"
1814+
1815+ : Parallel makes reveal that we have some interdependencies
1816+ case $f in
1817+ Math/BigInt/FastCalc) extra_dep="$extra_dep
1818+$this_target: lib/auto/List/Util/Util.$dlext" ;;
1819+ Unicode/Normalize) extra_dep="$extra_dep
1820+$this_target: lib/unicore/CombiningClass.pl" ;;
1821+ esac
1822 done
1823
1824 static_list=' '
1825@@ -987,2 +997,9 @@ n_dummy $(nonxs_ext): miniperl$(EXE_EXT) preplibrary $(DYNALOADER) FORCE
1826 @$(LDLIBPTH) sh ext/util/make_ext nonxs $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL)
1827+!NO!SUBS!
1828+
1829+$spitshell >>Makefile <<EOF
1830+$extra_dep
1831+EOF
1832+
1833+$spitshell >>Makefile <<'!NO!SUBS!'
1834
1835EOPATCH
1836 }
c0960282
NC
1837
1838 if ($major == 11) {
1839 if (extract_from_file('patchlevel.h',
1840 qr/^#include "unpushed\.h"/)) {
1841 # I had thought it easier to detect when building one of the 52
1842 # commits with the original method of incorporating the git
1843 # revision and drop parallel make flags. Commits shown by
1844 # git log 46807d8e809cc127^..dcff826f70bf3f64^ ^d4fb0a1f15d1a1c4
1845 # However, it's not actually possible to make miniperl for that
1846 # configuration as-is, because the file .patchnum is only made
1847 # as a side effect of target 'all'
1848 # I also don't think that it's "safe" to simply run
1849 # make_patchnum.sh before the build. We need the proper
1850 # dependency rules in the Makefile to *stop* it being run again
1851 # at the wrong time.
1852 # This range is important because contains the commit that
1853 # merges Schwern's y2038 work.
1854 apply_patch(<<'EOPATCH');
1855diff --git a/Makefile.SH b/Makefile.SH
1856index 9ad8b6f..106e721 100644
1857--- a/Makefile.SH
1858+++ b/Makefile.SH
1859@@ -540,9 +544,14 @@ sperl.i: perl.c $(h)
1860
1861 .PHONY: all translators utilities make_patchnum
1862
1863-make_patchnum:
1864+make_patchnum: lib/Config_git.pl
1865+
1866+lib/Config_git.pl: make_patchnum.sh
1867 sh $(shellflags) make_patchnum.sh
1868
1869+# .patchnum, unpushed.h and lib/Config_git.pl are built by make_patchnum.sh
1870+unpushed.h .patchnum: lib/Config_git.pl
1871+
1872 # make sure that we recompile perl.c if .patchnum changes
1873 perl$(OBJ_EXT): .patchnum unpushed.h
1874
1875EOPATCH
1876 } elsif (-f '.gitignore'
1877 && extract_from_file('.gitignore', qr/^\.patchnum$/)) {
1878 # 8565263ab8a47cda to 46807d8e809cc127^ inclusive.
1879 edit_file('Makefile.SH', sub {
1880 my $code = shift;
1881 $code =~ s/^make_patchnum:\n/make_patchnum: .patchnum
1882
1883.sha1: .patchnum
1884
1885.patchnum: make_patchnum.sh
1886/m;
1887 return $code;
1888 });
74adbdfa
NC
1889 } elsif (-f 'lib/.gitignore'
1890 && extract_from_file('lib/.gitignore',
1891 qr!^/Config_git.pl!)
1892 && !extract_from_file('Makefile.SH',
1893 qr/^uudmap\.h.*:bitcount.h$/)) {
1894 # Between commits and dcff826f70bf3f64 and 0f13ebd5d71f8177^
1895 edit_file('Makefile.SH', sub {
1896 my $code = shift;
1897 # Bug introduced by 344af494c35a9f0f
1898 # fixed in 0f13ebd5d71f8177
1899 $code =~ s{^(pod/perlapi\.pod) (pod/perlintern\.pod): }
1900 {$1: $2\n\n$2: }m;
1901 # Bug introduced by efa50c51e3301a2c
1902 # fixed in 0f13ebd5d71f8177
1903 $code =~ s{^(uudmap\.h) (bitcount\.h): }
1904 {$1: $2\n\n$2: }m;
93a0b6a3
NC
1905
1906 # The rats nest of getting git_version.h correct
1907
1908 if ($code =~ s{git_version\.h: stock_git_version\.h
1909\tcp stock_git_version\.h git_version\.h}
1910 {}m) {
1911 # before 486cd780047ff224
1912
1913 # We probably can't build between
1914 # 953f6acfa20ec275^ and 8565263ab8a47cda
1915 # inclusive, but all commits in that range
1916 # relate to getting make_patchnum.sh working,
1917 # so it is extremely unlikely to be an
1918 # interesting bisect target. They will skip.
1919
1920 # No, don't spawn a submake if
1921 # make_patchnum.sh or make_patchnum.pl fails
1922 $code =~ s{\|\| \$\(MAKE\) miniperl.*}
1923 {}m;
1924 $code =~ s{^\t(sh.*make_patchnum\.sh.*)}
1925 {\t-$1}m;
1926
1927 # Use an external perl to run make_patchnum.pl
1928 # because miniperl still depends on
1929 # git_version.h
1930 $code =~ s{^\t.*make_patchnum\.pl}
1931 {\t-$^X make_patchnum.pl}m;
1932
1933
1934 # "Truth in advertising" - running
1935 # make_patchnum generates 2 files.
1936 $code =~ s{^make_patchnum:.*}{
1937make_patchnum: lib/Config_git.pl
1938
1939git_version.h: lib/Config_git.pl
1940
1941perlmini\$(OBJ_EXT): git_version.h
1942
1943lib/Config_git.pl:}m;
1944 }
356fb8dd
NC
1945 # Right, now we've corrected Makefile.SH to
1946 # correctly describe how lib/Config_git.pl and
1947 # git_version.h are made, we need to fix the rest
1948
1949 # This emulates commit 2b63e250843b907e
1950 # This might duplicate the rule stating that
1951 # git_version.h depends on lib/Config_git.pl
1952 # This is harmless.
1953 $code =~ s{^(?:lib/Config_git\.pl )?git_version\.h: (.* make_patchnum\.pl.*)}
1954 {git_version.h: lib/Config_git.pl
1955
1956lib/Config_git.pl: $1}m;
1957
97897675
NC
1958 # This emulates commits 0f13ebd5d71f8177 and
1959 # and a04d4598adc57886. It ensures that
1960 # lib/Config_git.pl is built before configpm,
1961 # and that configpm is run exactly once.
1962 $code =~ s{^(\$\(.*?\) )?(\$\(CONFIGPOD\))(: .*? configpm Porting/Glossary)( lib/Config_git\.pl)?}{
1963 # If present, other files depend on $(CONFIGPOD)
1964 ($1 ? "$1: $2\n\n" : '')
1965 # Then the rule we found
1966 . $2 . $3
1967 # Add dependency if not there
1968 . ($4 ? $4 : ' lib/Config_git.pl')
1969 }me;
1970
74adbdfa
NC
1971 return $code;
1972 });
c0960282
NC
1973 }
1974 }
1975
bb723266
NC
1976 if ($major < 14) {
1977 # Commits dc0655f797469c47 and d11a62fe01f2ecb2
1978 edit_file('Makefile.SH', sub {
1979 my $code = shift;
1980 foreach my $ext (qw(Encode SDBM_File)) {
1981 next if $code =~ /\b$ext\) extra_dep=/s;
1982 $code =~ s!(\) extra_dep="\$extra_dep
1983\$this_target: .*?" ;;)
1984( esac
1985)!$1
1986 $ext) extra_dep="\$extra_dep
1987\$this_target: lib/auto/Cwd/Cwd.\$dlext" ;;
1988$2!;
1989 }
1990 return $code;
1991 });
1992 }
1993 }
1994
1995 if ($major == 7) {
1996 # Remove commits 9fec149bb652b6e9 and 5bab1179608f81d8, which add/amend
1997 # rules to automatically run regen scripts that rebuild C headers. These
1998 # cause problems because a git checkout doesn't preserve relative file
1999 # modification times, hence the regen scripts may fire. This will
2000 # obscure whether the repository had the correct generated headers
2001 # checked in.
2002 # Also, the dependency rules for running the scripts were not correct,
2003 # which could cause spurious re-builds on re-running make, and can cause
2004 # complete build failures for a parallel make.
2005 if (extract_from_file('Makefile.SH',
2006 qr/Writing it this way gives make a big hint to always run opcode\.pl before/)) {
2007 apply_commit('70c6e6715e8fec53');
2008 } elsif (extract_from_file('Makefile.SH',
2009 qr/^opcode\.h opnames\.h pp_proto\.h pp\.sym: opcode\.pl$/)) {
2010 revert_commit('9fec149bb652b6e9');
2011 }
2012 }
2013
e628fd8c
NC
2014 if ($^O eq 'aix' && $major >= 11 && $major <= 15
2015 && extract_from_file('makedef.pl', qr/^use Config/)) {
2016 edit_file('Makefile.SH', sub {
2017 # The AIX part of commit e6807d8ab22b761c
2018 # It's safe to substitute lib/Config.pm for config.sh
2019 # as lib/Config.pm depends on config.sh
2020 # If the tree is post e6807d8ab22b761c, the substitution
2021 # won't match, which is harmless.
2022 my $code = shift;
2023 $code =~ s{^(perl\.exp:.* )config\.sh(\b.*)}
2024 {$1 . '$(CONFIGPM)' . $2}me;
2025 return $code;
2026 });
2027 }
2028
bb723266
NC
2029 # There was a bug in makedepend.SH which was fixed in version 96a8704c.
2030 # Symptom was './makedepend: 1: Syntax error: Unterminated quoted string'
2031 # Remove this if you're actually bisecting a problem related to
2032 # makedepend.SH
2033 # If you do this, you may need to add in code to correct the output of older
2034 # makedepends, which don't correctly filter newer gcc output such as
2035 # <built-in>
2036 checkout_file('makedepend.SH');
2037
2038 if ($major < 4 && -f 'config.sh'
2039 && !extract_from_file('config.sh', qr/^trnl=/)) {
2040 # This seems to be necessary to avoid makedepend becoming confused,
2041 # and hanging on stdin. Seems that the code after
2042 # make shlist || ...here... is never run.
2043 edit_file('makedepend.SH', sub {
2044 my $code = shift;
2045 $code =~ s/^trnl='\$trnl'$/trnl='\\n'/m;
2046 return $code;
2047 });
2048 }
2049}
2050
2051sub patch_C {
2052 # This is ordered by $major, as it's likely that different platforms may
2053 # well want to share code.
2054
2055 if ($major == 2 && extract_from_file('perl.c', qr/^\tfclose\(e_fp\);$/)) {
2056 # need to patch perl.c to avoid calling fclose() twice on e_fp when
2057 # using -e
2058 # This diff is part of commit ab821d7fdc14a438. The second close was
2059 # introduced with perl-5.002, commit a5f75d667838e8e7
2060 # Might want a6c477ed8d4864e6 too, for the corresponding change to
2061 # pp_ctl.c (likely without this, eval will have "fun")
2062 apply_patch(<<'EOPATCH');
2063diff --git a/perl.c b/perl.c
2064index 03c4d48..3c814a2 100644
2065--- a/perl.c
2066+++ b/perl.c
2067@@ -252,6 +252,7 @@ setuid perl scripts securely.\n");
2068 #ifndef VMS /* VMS doesn't have environ array */
2069 origenviron = environ;
2070 #endif
2071+ e_tmpname = Nullch;
2072
2073 if (do_undump) {
2074
2075@@ -405,6 +406,7 @@ setuid perl scripts securely.\n");
2076 if (e_fp) {
2077 if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
2078 croak("Can't write to temp file for -e: %s", Strerror(errno));
2079+ e_fp = Nullfp;
2080 argc++,argv--;
2081 scriptname = e_tmpname;
2082 }
2083@@ -470,10 +472,10 @@ setuid perl scripts securely.\n");
2084 curcop->cop_line = 0;
2085 curstash = defstash;
2086 preprocess = FALSE;
2087- if (e_fp) {
2088- fclose(e_fp);
2089- e_fp = Nullfp;
2090+ if (e_tmpname) {
2091 (void)UNLINK(e_tmpname);
2092+ Safefree(e_tmpname);
2093+ e_tmpname = Nullch;
2094 }
2095
2096 /* now that script is parsed, we can modify record separator */
2097@@ -1369,7 +1371,7 @@ SV *sv;
2098 scriptname = xfound;
2099 }
2100
2101- origfilename = savepv(e_fp ? "-e" : scriptname);
2102+ origfilename = savepv(e_tmpname ? "-e" : scriptname);
2103 curcop->cop_filegv = gv_fetchfile(origfilename);
2104 if (strEQ(origfilename,"-"))
2105 scriptname = "";
2106
2107EOPATCH
2108 }
2109
2110 if ($major < 3 && $^O eq 'openbsd'
2111 && !extract_from_file('pp_sys.c', qr/BSD_GETPGRP/)) {
2112 # Part of commit c3293030fd1b7489
2113 apply_patch(<<'EOPATCH');
2114diff --git a/pp_sys.c b/pp_sys.c
2115index 4608a2a..f0c9d1d 100644
2116--- a/pp_sys.c
2117+++ b/pp_sys.c
2118@@ -2903,8 +2903,8 @@ PP(pp_getpgrp)
2119 pid = 0;
2120 else
2121 pid = SvIVx(POPs);
2122-#ifdef USE_BSDPGRP
2123- value = (I32)getpgrp(pid);
2124+#ifdef BSD_GETPGRP
2125+ value = (I32)BSD_GETPGRP(pid);
2126 #else
2127 if (pid != 0)
2128 DIE("POSIX getpgrp can't take an argument");
2129@@ -2933,8 +2933,8 @@ PP(pp_setpgrp)
2130 }
2131
2132 TAINT_PROPER("setpgrp");
2133-#ifdef USE_BSDPGRP
2134- SETi( setpgrp(pid, pgrp) >= 0 );
2135+#ifdef BSD_SETPGRP
2136+ SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
2137 #else
2138 if ((pgrp != 0) || (pid != 0)) {
2139 DIE("POSIX setpgrp can't take an argument");
2140EOPATCH
2141 }
2142
2143 if ($major < 4 && $^O eq 'openbsd') {
2144 my $bad;
2145 # Need changes from commit a6e633defa583ad5.
2146 # Commits c07a80fdfe3926b5 and f82b3d4130164d5f changed the same part
2147 # of perl.h
2148
2149 if (extract_from_file('perl.h',
2150 qr/^#ifdef HAS_GETPGRP2$/)) {
2151 $bad = <<'EOBAD';
2152***************
2153*** 57,71 ****
2154 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2155 #define TAINT_ENV() if (tainting) taint_env()
2156
2157! #ifdef HAS_GETPGRP2
2158! # ifndef HAS_GETPGRP
2159! # define HAS_GETPGRP
2160! # endif
2161! #endif
2162!
2163! #ifdef HAS_SETPGRP2
2164! # ifndef HAS_SETPGRP
2165! # define HAS_SETPGRP
2166! # endif
2167 #endif
2168
2169EOBAD
2170 } elsif (extract_from_file('perl.h',
2171 qr/Gack, you have one but not both of getpgrp2/)) {
2172 $bad = <<'EOBAD';
2173***************
2174*** 56,76 ****
2175 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2176 #define TAINT_ENV() if (tainting) taint_env()
2177
2178! #if defined(HAS_GETPGRP2) && defined(HAS_SETPGRP2)
2179! # define getpgrp getpgrp2
2180! # define setpgrp setpgrp2
2181! # ifndef HAS_GETPGRP
2182! # define HAS_GETPGRP
2183! # endif
2184! # ifndef HAS_SETPGRP
2185! # define HAS_SETPGRP
2186! # endif
2187! # ifndef USE_BSDPGRP
2188! # define USE_BSDPGRP
2189! # endif
2190! #else
2191! # if defined(HAS_GETPGRP2) || defined(HAS_SETPGRP2)
2192! #include "Gack, you have one but not both of getpgrp2() and setpgrp2()."
2193! # endif
2194 #endif
2195
2196EOBAD
2197 } elsif (extract_from_file('perl.h',
2198 qr/^#ifdef USE_BSDPGRP$/)) {
2199 $bad = <<'EOBAD'
2200***************
2201*** 91,116 ****
2202 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2203 #define TAINT_ENV() if (tainting) taint_env()
2204
2205! #ifdef USE_BSDPGRP
2206! # ifdef HAS_GETPGRP
2207! # define BSD_GETPGRP(pid) getpgrp((pid))
2208! # endif
2209! # ifdef HAS_SETPGRP
2210! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
2211! # endif
2212! #else
2213! # ifdef HAS_GETPGRP2
2214! # define BSD_GETPGRP(pid) getpgrp2((pid))
2215! # ifndef HAS_GETPGRP
2216! # define HAS_GETPGRP
2217! # endif
2218! # endif
2219! # ifdef HAS_SETPGRP2
2220! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
2221! # ifndef HAS_SETPGRP
2222! # define HAS_SETPGRP
2223! # endif
2224! # endif
2225 #endif
2226
2227 #ifndef _TYPES_ /* If types.h defines this it's easy. */
2228EOBAD
2229 }
2230 if ($bad) {
2231 apply_patch(<<"EOPATCH");
2232*** a/perl.h 2011-10-21 09:46:12.000000000 +0200
2233--- b/perl.h 2011-10-21 09:46:12.000000000 +0200
2234$bad--- 91,144 ----
2235 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2236 #define TAINT_ENV() if (tainting) taint_env()
2237
2238! /* XXX All process group stuff is handled in pp_sys.c. Should these
2239! defines move there? If so, I could simplify this a lot. --AD 9/96.
2240! */
2241! /* Process group stuff changed from traditional BSD to POSIX.
2242! perlfunc.pod documents the traditional BSD-style syntax, so we'll
2243! try to preserve that, if possible.
2244! */
2245! #ifdef HAS_SETPGID
2246! # define BSD_SETPGRP(pid, pgrp) setpgid((pid), (pgrp))
2247! #else
2248! # if defined(HAS_SETPGRP) && defined(USE_BSD_SETPGRP)
2249! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
2250! # else
2251! # ifdef HAS_SETPGRP2 /* DG/UX */
2252! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
2253! # endif
2254! # endif
2255! #endif
2256! #if defined(BSD_SETPGRP) && !defined(HAS_SETPGRP)
2257! # define HAS_SETPGRP /* Well, effectively it does . . . */
2258! #endif
2259!
2260! /* getpgid isn't POSIX, but at least Solaris and Linux have it, and it makes
2261! our life easier :-) so we'll try it.
2262! */
2263! #ifdef HAS_GETPGID
2264! # define BSD_GETPGRP(pid) getpgid((pid))
2265! #else
2266! # if defined(HAS_GETPGRP) && defined(USE_BSD_GETPGRP)
2267! # define BSD_GETPGRP(pid) getpgrp((pid))
2268! # else
2269! # ifdef HAS_GETPGRP2 /* DG/UX */
2270! # define BSD_GETPGRP(pid) getpgrp2((pid))
2271! # endif
2272! # endif
2273! #endif
2274! #if defined(BSD_GETPGRP) && !defined(HAS_GETPGRP)
2275! # define HAS_GETPGRP /* Well, effectively it does . . . */
2276! #endif
2277!
2278! /* These are not exact synonyms, since setpgrp() and getpgrp() may
2279! have different behaviors, but perl.h used to define USE_BSDPGRP
2280! (prior to 5.003_05) so some extension might depend on it.
2281! */
2282! #if defined(USE_BSD_SETPGRP) || defined(USE_BSD_GETPGRP)
2283! # ifndef USE_BSDPGRP
2284! # define USE_BSDPGRP
2285! # endif
2286 #endif
2287
2288 #ifndef _TYPES_ /* If types.h defines this it's easy. */
2289EOPATCH
2290 }
2291 }
2292
2293 if ($major == 4 && extract_from_file('scope.c', qr/\(SV\*\)SSPOPINT/)) {
2294 # [PATCH] 5.004_04 +MAINT_TRIAL_1 broken when sizeof(int) != sizeof(void)
2295 # Fixes a bug introduced in 161b7d1635bc830b
2296 apply_commit('9002cb76ec83ef7f');
2297 }
2298
2299 if ($major == 4 && extract_from_file('av.c', qr/AvARRAY\(av\) = 0;/)) {
2300 # Fixes a bug introduced in 1393e20655efb4bc
2301 apply_commit('e1c148c28bf3335b', 'av.c');
2302 }
2303
6626a474
NC
2304 if ($major == 4) {
2305 my $rest = extract_from_file('perl.c', qr/delimcpy(.*)/);
2306 if (defined $rest and $rest !~ /,$/) {
2307 # delimcpy added in fc36a67e8855d031, perl.c refactored to use it.
2308 # bug introduced in 2a92aaa05aa1acbf, fixed in 8490252049bf42d3
2309 # code then moved to util.c in commit 491527d0220de34e
2310 apply_patch(<<'EOPATCH');
bb723266
NC
2311diff --git a/perl.c b/perl.c
2312index 4eb69e3..54bbb00 100644
2313--- a/perl.c
2314+++ b/perl.c
2315@@ -1735,7 +1735,7 @@ SV *sv;
2316 if (len < sizeof tokenbuf)
2317 tokenbuf[len] = '\0';
2318 #else /* ! (atarist || DOSISH) */
2319- s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend
2320+ s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
2321 ':',
2322 &len);
2323 #endif /* ! (atarist || DOSISH) */
2324EOPATCH
6626a474 2325 }
bb723266
NC
2326 }
2327
2328 if ($major == 4 && $^O eq 'linux') {
2329 # Whilst this is fixed properly in f0784f6a4c3e45e1 which provides the
2330 # Configure probe, it's easier to back out the problematic changes made
2331 # in these previous commits:
2332 if (extract_from_file('doio.c',
2333 qr!^/\* XXX REALLY need metaconfig test \*/$!)) {
2334 revert_commit('4682965a1447ea44', 'doio.c');
2335 }
2336 if (my $token = extract_from_file('doio.c',
2337 qr!^#if (defined\(__sun(?:__)?\)) && defined\(__svr4__\) /\* XXX Need metaconfig test \*/$!)) {
2338 my $patch = `git show -R 9b599b2a63d2324d doio.c`;
2339 $patch =~ s/defined\(__sun__\)/$token/g;
2340 apply_patch($patch);
2341 }
2342 if (extract_from_file('doio.c',
2343 qr!^/\* linux \(and Solaris2\?\) uses :$!)) {
2344 revert_commit('8490252049bf42d3', 'doio.c');
2345 }
2346 if (extract_from_file('doio.c',
2347 qr/^ unsemds.buf = &semds;$/)) {
2348 revert_commit('8e591e46b4c6543e');
2349 }
2350 if (extract_from_file('doio.c',
2351 qr!^#ifdef __linux__ /\* XXX Need metaconfig test \*/$!)) {
2352 # Reverts part of commit 3e3baf6d63945cb6
2353 apply_patch(<<'EOPATCH');
2354diff --git b/doio.c a/doio.c
2355index 62b7de9..0d57425 100644
2356--- b/doio.c
2357+++ a/doio.c
2358@@ -1333,9 +1331,6 @@ SV **sp;
2359 char *a;
2360 I32 id, n, cmd, infosize, getinfo;
2361 I32 ret = -1;
2362-#ifdef __linux__ /* XXX Need metaconfig test */
2363- union semun unsemds;
2364-#endif
2365
2366 id = SvIVx(*++mark);
2367 n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2368@@ -1364,29 +1359,11 @@ SV **sp;
2369 infosize = sizeof(struct semid_ds);
2370 else if (cmd == GETALL || cmd == SETALL)
2371 {
2372-#ifdef __linux__ /* XXX Need metaconfig test */
2373-/* linux uses :
2374- int semctl (int semid, int semnun, int cmd, union semun arg)
2375-
2376- union semun {
2377- int val;
2378- struct semid_ds *buf;
2379- ushort *array;
2380- };
2381-*/
2382- union semun semds;
2383- if (semctl(id, 0, IPC_STAT, semds) == -1)
2384-#else
2385 struct semid_ds semds;
2386 if (semctl(id, 0, IPC_STAT, &semds) == -1)
2387-#endif
2388 return -1;
2389 getinfo = (cmd == GETALL);
2390-#ifdef __linux__ /* XXX Need metaconfig test */
2391- infosize = semds.buf->sem_nsems * sizeof(short);
2392-#else
2393 infosize = semds.sem_nsems * sizeof(short);
2394-#endif
2395 /* "short" is technically wrong but much more portable
2396 than guessing about u_?short(_t)? */
2397 }
2398@@ -1429,12 +1406,7 @@ SV **sp;
2399 #endif
2400 #ifdef HAS_SEM
2401 case OP_SEMCTL:
2402-#ifdef __linux__ /* XXX Need metaconfig test */
2403- unsemds.buf = (struct semid_ds *)a;
2404- ret = semctl(id, n, cmd, unsemds);
2405-#else
2406 ret = semctl(id, n, cmd, (struct semid_ds *)a);
2407-#endif
2408 break;
2409 #endif
2410 #ifdef HAS_SHM
2411EOPATCH
2412 }
2413 # Incorrect prototype added as part of 8ac853655d9b7447, fixed as part
2414 # of commit dc45a647708b6c54, with at least one intermediate
2415 # modification. Correct prototype for gethostbyaddr has socklen_t
2416 # second. Linux has uint32_t first for getnetbyaddr.
2417 # Easiest just to remove, instead of attempting more complex patching.
2418 # Something similar may be needed on other platforms.
2419 edit_file('pp_sys.c', sub {
2420 my $code = shift;
2421 $code =~ s/^ struct hostent \*(?:PerlSock_)?gethostbyaddr\([^)]+\);$//m;
2422 $code =~ s/^ struct netent \*getnetbyaddr\([^)]+\);$//m;
2423 return $code;
2424 });
2425 }
2426
d1ac19b7
NC
2427 if ($major < 5 && $^O eq 'aix'
2428 && !extract_from_file('pp_sys.c',
2429 qr/defined\(HOST_NOT_FOUND\) && !defined\(h_errno\)/)) {
2430 # part of commit dc45a647708b6c54
2431 # Andy Dougherty's configuration patches (Config_63-01 up to 04).
2432 apply_patch(<<'EOPATCH')
2433diff --git a/pp_sys.c b/pp_sys.c
2434index c2fcb6f..efa39fb 100644
2435--- a/pp_sys.c
2436+++ b/pp_sys.c
2437@@ -54,7 +54,7 @@ extern "C" int syscall(unsigned long,...);
2438 #endif
2439 #endif
2440
2441-#ifdef HOST_NOT_FOUND
2442+#if defined(HOST_NOT_FOUND) && !defined(h_errno)
2443 extern int h_errno;
2444 #endif
2445
2446EOPATCH
2447 }
2448
bb723266
NC
2449 if ($major < 6 && $^O eq 'netbsd'
2450 && !extract_from_file('unixish.h',
2451 qr/defined\(NSIG\).*defined\(__NetBSD__\)/)) {
2452 apply_patch(<<'EOPATCH')
2453diff --git a/unixish.h b/unixish.h
2454index 2a6cbcd..eab2de1 100644
2455--- a/unixish.h
2456+++ b/unixish.h
2457@@ -89,7 +89,7 @@
2458 */
2459 /* #define ALTERNATE_SHEBANG "#!" / **/
2460
2461-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
2462+#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) || defined(__NetBSD__)
2463 # include <signal.h>
2464 #endif
2465
2466EOPATCH
2467 }
2468
2469 if (($major >= 7 || $major <= 9) && $^O eq 'openbsd'
2470 && `uname -m` eq "sparc64\n"
2471 # added in 2000 by commit cb434fcc98ac25f5:
2472 && extract_from_file('regexec.c',
2473 qr!/\* No need to save/restore up to this paren \*/!)
2474 # re-indented in 2006 by commit 95b2444054382532:
2475 && extract_from_file('regexec.c', qr/^\t\tCURCUR cc;$/)) {
2476 # Need to work around a bug in (at least) OpenBSD's 4.6's sparc64 #
2477 # compiler ["gcc (GCC) 3.3.5 (propolice)"]. Between commits
2478 # 3ec562b0bffb8b8b (2002) and 1a4fad37125bac3e^ (2005) the darling thing
2479 # fails to compile any code for the statement cc.oldcc = PL_regcc;
2480 #
2481 # If you refactor the code to "fix" that, or force the issue using set
2482 # in the debugger, the stack smashing detection code fires on return
2483 # from S_regmatch(). Turns out that the compiler doesn't allocate any
2484 # (or at least enough) space for cc.
2485 #
2486 # Restore the "uninitialised" value for cc before function exit, and the
2487 # stack smashing code is placated. "Fix" 3ec562b0bffb8b8b (which
2488 # changes the size of auto variables used elsewhere in S_regmatch), and
2489 # the crash is visible back to bc517b45fdfb539b (which also changes
2490 # buffer sizes). "Unfix" 1a4fad37125bac3e and the crash is visible until
2491 # 5b47454deb66294b. Problem goes away if you compile with -O, or hack
2492 # the code as below.
2493 #
2494 # Hence this turns out to be a bug in (old) gcc. Not a security bug we
2495 # still need to fix.
2496 apply_patch(<<'EOPATCH');
2497diff --git a/regexec.c b/regexec.c
2498index 900b491..6251a0b 100644
2499--- a/regexec.c
2500+++ b/regexec.c
2501@@ -2958,7 +2958,11 @@ S_regmatch(pTHX_ regnode *prog)
2502 I,I
2503 *******************************************************************/
2504 case CURLYX: {
2505- CURCUR cc;
2506+ union {
2507+ CURCUR hack_cc;
2508+ char hack_buff[sizeof(CURCUR) + 1];
2509+ } hack;
2510+#define cc hack.hack_cc
2511 CHECKPOINT cp = PL_savestack_ix;
2512 /* No need to save/restore up to this paren */
2513 I32 parenfloor = scan->flags;
2514@@ -2983,6 +2987,7 @@ S_regmatch(pTHX_ regnode *prog)
2515 n = regmatch(PREVOPER(next)); /* start on the WHILEM */
2516 regcpblow(cp);
2517 PL_regcc = cc.oldcc;
2518+#undef cc
2519 saySAME(n);
2520 }
2521 /* NOT REACHED */
2522EOPATCH
2523}
2524
2525 if ($major < 8 && $^O eq 'openbsd'
2526 && !extract_from_file('perl.h', qr/include <unistd\.h>/)) {
2527 # This is part of commit 3f270f98f9305540, applied at a slightly
2528 # different location in perl.h, where the context is stable back to
2529 # 5.000
2530 apply_patch(<<'EOPATCH');
2531diff --git a/perl.h b/perl.h
2532index 9418b52..b8b1a7c 100644
2533--- a/perl.h
2534+++ b/perl.h
2535@@ -496,6 +496,10 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
2536 # include <sys/param.h>
2537 #endif
2538
2539+/* If this causes problems, set i_unistd=undef in the hint file. */
2540+#ifdef I_UNISTD
2541+# include <unistd.h>
2542+#endif
2543
2544 /* Use all the "standard" definitions? */
2545 #if defined(STANDARD_C) && defined(I_STDLIB)
2546EOPATCH
2547 }
2548}
2549
f2f0a0ff
NC
2550sub patch_ext {
2551 if (-f 'ext/POSIX/Makefile.PL'
2552 && extract_from_file('ext/POSIX/Makefile.PL',
2553 qr/Explicitly avoid including/)) {
2554 # commit 6695a346c41138df, which effectively reverts 170888cff5e2ffb7
2555
2556 # PERL5LIB is populated by make_ext.pl with paths to the modules we need
2557 # to run, don't override this with "../../lib" since that may not have
2558 # been populated yet in a parallel build.
2559 apply_commit('6695a346c41138df');
2560 }
2561
06cebb71
NC
2562 if (-f 'ext/Hash/Util/Makefile.PL'
2563 && extract_from_file('ext/Hash/Util/Makefile.PL',
2564 qr/\bDIR\b.*'FieldHash'/)) {
2565 # ext/Hash/Util/Makefile.PL should not recurse to FieldHash's Makefile.PL
2566 # *nix, VMS and Win32 all know how to (and have to) call the latter directly.
2567 # As is, targets in ext/Hash/Util/FieldHash get called twice, which may result
2568 # in race conditions, and certainly messes up make clean; make distclean;
2569 apply_commit('550428fe486b1888');
2570 }
2571
f2f0a0ff
NC
2572 if ($major < 8 && $^O eq 'darwin' && !-f 'ext/DynaLoader/dl_dyld.xs') {
2573 checkout_file('ext/DynaLoader/dl_dyld.xs', 'f556e5b971932902');
2574 apply_patch(<<'EOPATCH');
2575diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
2576--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:41:27.000000000 +0100
2577+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 21:42:20.000000000 +0100
2578@@ -41,6 +41,35 @@
2579 #include "perl.h"
2580 #include "XSUB.h"
2581
2582+#ifndef pTHX
2583+# define pTHX void
2584+# define pTHX_
2585+#endif
2586+#ifndef aTHX
2587+# define aTHX
2588+# define aTHX_
2589+#endif
2590+#ifndef dTHX
2591+# define dTHXa(a) extern int Perl___notused(void)
2592+# define dTHX extern int Perl___notused(void)
2593+#endif
2594+
2595+#ifndef Perl_form_nocontext
2596+# define Perl_form_nocontext form
2597+#endif
2598+
2599+#ifndef Perl_warn_nocontext
2600+# define Perl_warn_nocontext warn
2601+#endif
2602+
2603+#ifndef PTR2IV
2604+# define PTR2IV(p) (IV)(p)
2605+#endif
2606+
2607+#ifndef get_av
2608+# define get_av perl_get_av
2609+#endif
2610+
2611 #define DL_LOADONCEONLY
2612
2613 #include "dlutils.c" /* SaveError() etc */
2614@@ -185,7 +191,7 @@
2615 CODE:
2616 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
2617 if (flags & 0x01)
2618- Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
2619+ Perl_warn_nocontext("Can't make loaded symbols global on this platform while loading %s",filename);
2620 RETVAL = dlopen(filename, mode) ;
2621 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%x\n", RETVAL));
2622 ST(0) = sv_newmortal() ;
2623EOPATCH
2624 if ($major < 4 && !extract_from_file('util.c', qr/^form/m)) {
2625 apply_patch(<<'EOPATCH');
2626diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
2627--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:56:25.000000000 +0100
2628+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 22:00:00.000000000 +0100
2629@@ -60,6 +60,18 @@
2630 # define get_av perl_get_av
2631 #endif
2632
2633+static char *
2634+form(char *pat, ...)
2635+{
2636+ char *retval;
2637+ va_list args;
2638+ va_start(args, pat);
2639+ vasprintf(&retval, pat, &args);
2640+ va_end(args);
2641+ SAVEFREEPV(retval);
2642+ return retval;
2643+}
2644+
2645 #define DL_LOADONCEONLY
2646
2647 #include "dlutils.c" /* SaveError() etc */
2648EOPATCH
2649 }
2650 }
2651
2652 if ($major < 10) {
2653 if (!extract_from_file('ext/DB_File/DB_File.xs',
2654 qr!^#else /\* Berkeley DB Version > 2 \*/$!)) {
2655 # This DB_File.xs is really too old to patch up.
2656 # Skip DB_File, unless we're invoked with an explicit -Unoextensions
2657 if (!exists $defines{noextensions}) {
2658 $defines{noextensions} = 'DB_File';
2659 } elsif (defined $defines{noextensions}) {
2660 $defines{noextensions} .= ' DB_File';
2661 }
2662 } elsif (!extract_from_file('ext/DB_File/DB_File.xs',
2663 qr/^#ifdef AT_LEAST_DB_4_1$/)) {
2664 # This line is changed by commit 3245f0580c13b3ab
2665 my $line = extract_from_file('ext/DB_File/DB_File.xs',
2666 qr/^( status = \(?RETVAL->dbp->open\)?\(RETVAL->dbp, name, NULL, RETVAL->type, $)/);
2667 apply_patch(<<"EOPATCH");
2668diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
2669index 489ba96..fba8ded 100644
2670--- a/ext/DB_File/DB_File.xs
2671+++ b/ext/DB_File/DB_File.xs
2672\@\@ -183,4 +187,8 \@\@
2673 #endif
2674
2675+#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
2676+# define AT_LEAST_DB_4_1
2677+#endif
2678+
2679 /* map version 2 features & constants onto their version 1 equivalent */
2680
2681\@\@ -1334,7 +1419,12 \@\@ SV * sv ;
2682 #endif
2683
2684+#ifdef AT_LEAST_DB_4_1
2685+ status = (RETVAL->dbp->open)(RETVAL->dbp, NULL, name, NULL, RETVAL->type,
2686+ Flags, mode) ;
2687+#else
2688 $line
2689 Flags, mode) ;
2690+#endif
2691 /* printf("open returned %d %s\\n", status, db_strerror(status)) ; */
2692
2693EOPATCH
2694 }
2695 }
2696
2697 if ($major < 10 and -f 'ext/IPC/SysV/SysV.xs') {
2698 edit_file('ext/IPC/SysV/SysV.xs', sub {
2699 my $xs = shift;
2700 my $fixed = <<'EOFIX';
2701
2702#include <sys/types.h>
2703#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2704#ifndef HAS_SEM
2705# include <sys/ipc.h>
2706#endif
2707# ifdef HAS_MSG
2708# include <sys/msg.h>
2709# endif
2710# ifdef HAS_SHM
2711# if defined(PERL_SCO) || defined(PERL_ISC)
2712# include <sys/sysmacros.h> /* SHMLBA */
2713# endif
2714# include <sys/shm.h>
2715# ifndef HAS_SHMAT_PROTOTYPE
2716 extern Shmat_t shmat (int, char *, int);
2717# endif
2718# if defined(HAS_SYSCONF) && defined(_SC_PAGESIZE)
2719# undef SHMLBA /* not static: determined at boot time */
2720# define SHMLBA sysconf(_SC_PAGESIZE)
2721# elif defined(HAS_GETPAGESIZE)
2722# undef SHMLBA /* not static: determined at boot time */
2723# define SHMLBA getpagesize()
2724# endif
2725# endif
2726#endif
2727EOFIX
2728 $xs =~ s!
2729#include <sys/types\.h>
2730.*
2731(#ifdef newCONSTSUB|/\* Required)!$fixed$1!ms;
2732 return $xs;
2733 });
2734 }
2735}
2736
9a999a97
NC
2737# Local variables:
2738# cperl-indent-level: 4
2739# indent-tabs-mode: nil
2740# End:
2741#
2742# ex: set ts=8 sts=4 sw=4 et: