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