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