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