4 use File::Basename qw(basename dirname);
7 # List explicitly here the variables you want Configure to
8 # generate. Metaconfig only looks for shell variables, so you
9 # have to mention them as if they were shell variables, not
10 # %Config entries. Thus you write
12 # to ensure Configure will look for $Config{startperl}.
15 # This forces PL files to create target in same directory as PL file.
16 # This is so that make depend always knows where to find PL derivatives.
19 $file = basename($0, '.PL');
20 $file .= '.com' if $^O eq 'VMS';
22 open OUT,">$file" or die "Can't create $file: $!";
24 print "Extracting $file (with variable substitutions)\n";
26 # In this section, perl variables will be expanded during extraction.
27 # You can use $Config{...} to use Configure variables.
29 print OUT <<"!GROK!THIS!";
31 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
32 if \$running_under_some_shell;
35 # In the following, perl variables are not expanded during extraction.
37 print OUT <<'!NO!SUBS!';
42 use File::Path qw(mkpath);
45 # Make sure read permissions for all are set:
46 if (defined umask && (umask() & 0444)) {
47 umask (umask() & ~0444);
51 use vars qw($opt_D $opt_d $opt_r $opt_l $opt_h $opt_a $opt_Q $opt_e);
52 die "-r and -a options are mutually exclusive\n" if ($opt_r and $opt_a);
53 my @inc_dirs = inc_dirs() if $opt_a;
57 my $Dest_dir = $opt_d || $Config{installsitearch};
58 die "Destination directory $Dest_dir doesn't exist or isn't a directory\n"
61 my @isatype = split(' ',<<END);
70 @isatype{@isatype} = (1) x @isatype;
75 @ARGV = ('-') unless @ARGV;
77 build_preamble_if_necessary();
86 my ($t, $tab, %curargs, $new, $eval_index, $dir, $name, $args, $outfile);
87 my ($incl, $incl_type, $next);
88 while (defined (my $file = next_file())) {
89 if (-l $file and -d $file) {
90 link_if_possible($file) if ($opt_l);
94 # Recover from header files with unbalanced cpp directives
98 # $eval_index goes into ``#line'' directives, to help locate syntax errors:
105 ($outfile = $file) =~ s/\.h$/.ph/ || next;
106 print "$file -> $outfile\n" unless $opt_Q;
107 if ($file =~ m|^(.*)/|) {
109 mkpath "$Dest_dir/$dir";
112 if ($opt_a) { # automagic mode: locate header file in @inc_dirs
113 foreach (@inc_dirs) {
119 open(IN,"$file") || (($Exit = 1),(warn "Can't open $file: $!\n"),next);
120 open(OUT,">$Dest_dir/$outfile") || die "Can't create $outfile: $!\n";
124 "require '_h2ph_pre.ph';\n\n",
125 "no warnings 'redefine';\n\n";
127 while (defined (local $_ = next_line($file))) {
129 if (s/^define\s+(\w+)//) {
133 s/\(\w+\s*\(\*\)\s*\(\w*\)\)\s*(-?\d+)/$1/; # (int (*)(foo_t))0
134 if (s/^\(([\w,\s]*)\)//) {
139 foreach my $arg (split(/,\s*/,$args)) {
140 $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
143 $args =~ s/\b(\w)/\$$1/g;
144 $args = "local($args) = \@_;\n$t ";
148 $new =~ s/(["\\])/\\$1/g; #"]);
150 $new = reindent($new);
151 $args = reindent($args);
153 $new =~ s/(['\\])/\\$1/g; #']);
156 "eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
160 "eval 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
163 print OUT "unless(defined(\&$name)) {\n sub $name $proto\{\n\t${args}eval q($new);\n }\n}\n";
169 $new = 1 if $new eq '';
170 $new = reindent($new);
171 $args = reindent($args);
173 $new =~ s/(['\\])/\\$1/g; #']);
176 print OUT $t,"eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name () {",$new,";}' unless defined(\&$name);\n";
179 print OUT $t,"eval 'sub $name () {",$new,";}' unless defined(\&$name);\n";
182 # Shunt around such directives as `#define FOO FOO':
183 next if " \&$name" eq $new;
185 print OUT $t,"unless(defined(\&$name)) {\n sub $name () {\t",$new,";}\n}\n";
188 } elsif (/^(include|import|include_next)\s*[<\"](.*)[>\"]/) {
191 if (($incl_type eq 'include_next') ||
192 ($opt_e && exists($bad_file{$incl}))) {
193 $incl =~ s/\.h$/.ph/;
197 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
198 print OUT ($t, "my(\@REM);\n");
199 if ($incl_type eq 'include_next') {
201 "my(\%INCD) = map { \$INC{\$_} => 1 } ",
202 "(grep { \$_ eq \"$incl\" } ",
205 "\@REM = map { \"\$_/$incl\" } ",
206 "(grep { not exists(\$INCD{\"\$_/$incl\"})",
207 " and -f \"\$_/$incl\" } \@INC);\n");
210 "\@REM = map { \"\$_/$incl\" } ",
211 "(grep {-r \"\$_/$incl\" } \@INC);\n");
214 "require \"\$REM[0]\" if \@REM;\n");
216 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
220 "warn(\$\@) if \$\@;\n");
222 $incl =~ s/\.h$/.ph/;
223 print OUT $t,"require '$incl';\n";
225 } elsif (/^ifdef\s+(\w+)/) {
226 print OUT $t,"if(defined(&$1)) {\n";
228 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
229 } elsif (/^ifndef\s+(\w+)/) {
230 print OUT $t,"unless(defined(&$1)) {\n";
232 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
233 } elsif (s/^if\s+//) {
238 print OUT $t,"if($new) {\n";
240 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
241 } elsif (s/^elif\s+//) {
247 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
248 print OUT $t,"}\n elsif($new) {\n";
250 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
253 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
254 print OUT $t,"} else {\n";
256 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
259 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
261 } elsif(/^undef\s+(\w+)/) {
262 print OUT $t, "undef(&$1) if defined(&$1);\n";
263 } elsif(/^error\s+(".*")/) {
264 print OUT $t, "die($1);\n";
265 } elsif(/^error\s+(.*)/) {
266 print OUT $t, "die(\"", quotemeta($1), "\");\n";
267 } elsif(/^warning\s+(.*)/) {
268 print OUT $t, "warn(\"", quotemeta($1), "\");\n";
269 } elsif(/^ident\s+(.*)/) {
270 print OUT $t, "# $1\n";
272 } elsif (/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?/) { # { for vi
273 until(/\{[^}]*\}.*;/ || /;/) {
274 last unless defined ($next = next_line($file));
276 # drop "#define FOO FOO" in enums
277 $next =~ s/^\s*#\s*define\s+(\w+)\s+\1\s*$//;
279 print OUT "# $next\n" if $opt_D;
281 s/#\s*if.*?#\s*endif//g; # drop #ifdefs
284 next unless /^\s?(typedef\s?)?enum\s?([a-zA-Z_]\w*)?\s?\{(.*)\}\s?([a-zA-Z_]\w*)?\s?;/;
285 (my $enum_subs = $3) =~ s/\s//g;
286 my @enum_subs = split(/,/, $enum_subs);
288 foreach my $enum (@enum_subs) {
289 my ($enum_name, $enum_value) = $enum =~ /^([a-zA-Z_]\w*)(=.+)?$/;
290 $enum_value =~ s/^=//;
291 $enum_val = (length($enum_value) ? $enum_value : $enum_val + 1);
294 "eval(\"\\n#line $eval_index $outfile\\n",
295 "sub $enum_name () \{ $enum_val; \}\") ",
296 "unless defined(\&$enum_name);\n");
300 "eval(\"sub $enum_name () \{ $enum_val; \}\") ",
301 "unless defined(\&$enum_name);\n");
304 } elsif (/^(?:__extension__\s+)?(?:extern|static)\s+(?:__)?inline(?:__)?\s+/) { # { for vi
305 # This is a hack to parse the inline functions in the glibc headers.
306 # Warning: massive kludge ahead. We suppose inline functions are mainly
307 # constructed like macros.
309 last unless defined ($next = next_line($file));
311 undef $_, last if $next =~ /__THROW\s*;/;
313 print OUT "# $next\n" if $opt_D;
314 last if $next =~ /^}|^{.*}\s*$/;
316 next if not defined; # because it's only a prototype
317 s/\b(__extension__|extern|static|(?:__)?inline(?:__)?)\b//g;
318 # violently drop #ifdefs
319 s/#\s*if.*?#\s*endif//g
320 and print OUT "# some #ifdef were dropped here -- fill in the blanks\n";
321 if (s/^(?:\w|\s|\*)*\s(\w+)\s*//) {
324 warn "name not found"; next; # shouldn't occur...
327 if (s/^\(([^()]*)\)\s*(\w+\s*)*//) {
328 for my $arg (split /,/, $1) {
329 if ($arg =~ /(\w+)\s*$/) {
337 ? "local(" . (join ',', map "\$$_", @args) . ") = \@_;\n$t "
340 my $proto = @args ? '' : '() ';
342 s/\breturn\b//g; # "return" doesn't occur in macros usually...
344 # try to find and perlify local C variables
345 our @local_variables = (); # needs to be a our(): (?{...}) bug workaround
347 (?:(?:un)?signed\s+)?
349 (?:long|int|float|double|char|\w+_t)\s+
351 (?{ push @local_variables, $1 })
355 (?:(?:un)?signed\s+)?
357 (?:long|int|float|double|char|\w+_t)
359 (?{ push @local_variables, $1 })
362 $new =~ s/&$_\b/\$$_/g for @local_variables;
363 $new =~ s/(["\\])/\\$1/g; #"]);
364 # now that's almost like a macro (we hope)
368 $Is_converted{$file} = 1;
369 if ($opt_e && exists($bad_file{$file})) {
370 unlink($Dest_dir . '/' . $outfile);
374 queue_includes_from($file) if $opt_a;
378 if ($opt_e && (scalar(keys %bad_file) > 0)) {
379 warn "Was unable to convert the following files:\n";
380 warn "\t" . join("\n\t",sort(keys %bad_file)) . "\n";
388 $joined_args = join('|', keys(%curargs));
391 s/^\&\&// && do { $new .= " &&"; next;}; # handle && operator
392 s/^\&([\(a-z\)]+)/$1/i; # hack for things that take the address of
393 s/^(\s+)// && do {$new .= ' '; next;};
394 s/^0X([0-9A-F]+)[UL]*//i
397 if (length $hex > 8 && !$Config{use64bitint}) {
398 # Croak if nv_preserves_uv_bits < 64 ?
399 $new .= hex(substr($hex, -8)) +
400 2**32 * hex(substr($hex, 0, -8));
401 # The above will produce "errorneus" code
402 # if the hex constant was e.g. inside UINT64_C
403 # macro, but then again, h2ph is an approximation.
405 $new .= lc("0x$hex");
408 s/^(-?\d+\.\d+E[-+]?\d+)[FL]?//i && do {$new .= $1; next;};
409 s/^(\d+)\s*[LU]*//i && do {$new .= $1; next;};
410 s/^("(\\"|[^"])*")// && do {$new .= $1; next;};
411 s/^'((\\"|[^"])*)'// && do {
413 $new .= "ord('\$$1')";
419 # replace "sizeof(foo)" with "{foo}"
420 # also, remove * (C dereference operator) to avoid perl syntax
421 # problems. Where the %sizeof array comes from is anyone's
422 # guess (c2ph?), but this at least avoids fatal syntax errors.
423 # Behavior is undefined if sizeof() delimiters are unbalanced.
424 # This code was modified to able to handle constructs like this:
425 # sizeof(*(p)), which appear in the HP-UX 10.01 header files.
426 s/^sizeof\s*\(// && do {
428 my $lvl = 1; # already saw one open paren
429 # tack { on the front, and skip it in the loop
432 # find balanced closing paren
433 while ($index <= length($_) && $lvl > 0) {
434 $lvl++ if substr($_, $index, 1) eq "(";
435 $lvl-- if substr($_, $index, 1) eq ")";
438 # tack } on the end, replacing )
439 substr($_, $index - 1, 1) = "}";
440 # remove pesky * operators within the sizeof argument
441 substr($_, 0, $index - 1) =~ s/\*//g;
445 /\(([\w\s]+)[\*\s]*\)\s*[\w\(]/ && do {
447 foreach (split /\s+/, $1) { # Make sure all the words are types,
448 unless($isatype{$_} or $_ eq 'struct' or $_ eq 'union'){
454 s/\([\w\s]+[\*\s]*\)// && next; # then eliminate them.
457 # struct/union member, including arrays:
458 s/^([_A-Z]\w*(\[[^\]]+\])?((\.|->)[_A-Z]\w*(\[[^\]]+\])?)+)//i && do {
460 $id =~ s/(\.|(->))([^\.\-]*)/->\{$3\}/g;
461 $id =~ s/\b([^\$])($joined_args)/$1\$$2/g if length($joined_args);
462 while($id =~ /\[\s*([^\$\&\d\]]+)\]/) {
465 if(exists($curargs{$index})) {
470 $id =~ s/\[\s*([^\$\&\d\]]+)\]/[$index]/;
474 s/^([_a-zA-Z]\w*)// && do {
476 if ($id eq 'struct' || $id eq 'union') {
480 } elsif ($id =~ /^((un)?signed)|(long)|(short)$/) {
481 while (s/^\s+(\w+)//) { $id .= ' ' . $1; }
486 $new .= '->' if /^[\[\{]/;
487 } elsif ($id eq 'defined') {
490 s/^\s*\((\w),/("$1",/ if $id =~ /^_IO[WR]*$/i; # cheat
492 } elsif ($isatype{$id}) {
493 if ($new =~ /{\s*$/) {
495 } elsif ($new =~ /\(\s*$/ && /^[\s*]*\)/) {
499 $new .= q(').$id.q(');
502 if ($inif && $new !~ /defined\s*\($/) {
503 $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
512 s/^(.)// && do { if ($1 ne '#') { $new .= $1; } next;};
521 my $pre_sub_tri_graphs = 1;
523 READ: while (not eof IN) {
526 next unless length $in;
529 if ($pre_sub_tri_graphs) {
530 # Preprocess all tri-graphs
531 # including things stuck in quoted string constants.
532 $in =~ s/\?\?=/#/g; # | ??=| #|
533 $in =~ s/\?\?\!/|/g; # | ??!| ||
534 $in =~ s/\?\?'/^/g; # | ??'| ^|
535 $in =~ s/\?\?\(/[/g; # | ??(| [|
536 $in =~ s/\?\?\)/]/g; # | ??)| ]|
537 $in =~ s/\?\?\-/~/g; # | ??-| ~|
538 $in =~ s/\?\?\//\\/g; # | ??/| \|
539 $in =~ s/\?\?</{/g; # | ??<| {|
540 $in =~ s/\?\?>/}/g; # | ??>| }|
542 if ($in =~ /^\#ifdef __LANGUAGE_PASCAL__/) {
543 # Tru64 disassembler.h evilness: mixed C and Pascal.
549 if ($in =~ /^extern inline / && # Inlined assembler.
550 $^O eq 'linux' && $file =~ m!(?:^|/)asm/[^/]+\.h$!) {
556 if ($in =~ s/\\$//) { # \-newline
559 } elsif ($in =~ s/^([^"'\\\/]+)//) { # Passthrough
561 } elsif ($in =~ s/^(\\.)//) { # \...
563 } elsif ($in =~ /^'/) { # '...
564 if ($in =~ s/^('(\\.|[^'\\])*')//) {
569 } elsif ($in =~ /^"/) { # "...
570 if ($in =~ s/^("(\\.|[^"\\])*")//) {
575 } elsif ($in =~ s/^\/\/.*//) { # //...
577 } elsif ($in =~ m/^\/\*/) { # /*...
578 # C comment removal adapted from perlfaq6:
579 if ($in =~ s/^\/\*[^*]*\*+([^\/*][^*]*\*+)*\///) {
581 } else { # Incomplete /* */
584 } elsif ($in =~ s/^(\/)//) { # /...
586 } elsif ($in =~ s/^([^\'\"\\\/]+)//) {
588 } elsif ($^O eq 'linux' &&
589 $file =~ m!(?:^|/)linux/byteorder/pdp_endian\.h$! &&
590 $in =~ s!\'T KNOW!!) {
591 $out =~ s!I DON$!I_DO_NOT_KNOW!;
594 warn "Cannot parse $file:\n$in\n";
595 $bad_file{$file} = 1;
600 die "Cannot parse:\n$in\n";
605 last READ if $out =~ /\S/;
612 # Handle recursive subdirectories without getting a grotesquely big stack.
613 # Could this be implemented using File::Find?
621 if ($file eq '-' or -f $file or -l $file) {
627 print STDERR "Skipping directory `$file'\n";
632 print STDERR "Skipping `$file': not a file or directory\n";
640 # Put all the files in $directory into @ARGV for processing.
643 my ($directory) = @_;
645 $directory =~ s:/$::;
647 opendir DIR, $directory;
648 foreach (readdir DIR) {
649 next if ($_ eq '.' or $_ eq '..');
651 # expand_glob() is going to be called until $ARGV[0] isn't a
652 # directory; so push directories, and unshift everything else.
653 if (-d "$directory/$_") { push @ARGV, "$directory/$_" }
654 else { unshift @ARGV, "$directory/$_" }
660 # Given $file, a symbolic link to a directory in the C include directory,
661 # make an equivalent symbolic link in $Dest_dir, if we can figure out how.
662 # Otherwise, just duplicate the file or directory.
666 my $target = eval 'readlink($dirlink)';
668 if ($target =~ m:^\.\./: or $target =~ m:^/:) {
669 # The target of a parent or absolute link could leave the $Dest_dir
670 # hierarchy, so let's put all of the contents of $dirlink (actually,
671 # the contents of $target) into @ARGV; as a side effect down the
672 # line, $dirlink will get created as an _actual_ directory.
673 expand_glob($dirlink);
675 if (-l "$Dest_dir/$dirlink") {
676 unlink "$Dest_dir/$dirlink" or
677 print STDERR "Could not remove link $Dest_dir/$dirlink: $!\n";
680 if (eval 'symlink($target, "$Dest_dir/$dirlink")') {
681 print "Linking $target -> $Dest_dir/$dirlink\n";
683 # Make sure that the link _links_ to something:
684 if (! -e "$Dest_dir/$target") {
685 mkpath("$Dest_dir/$target", 0755) or
686 print STDERR "Could not create $Dest_dir/$target/\n";
689 print STDERR "Could not symlink $target -> $Dest_dir/$dirlink: $!\n";
695 # Push all #included files in $file onto our stack, except for STDIN
696 # and files we've already processed.
697 sub queue_includes_from
702 return if ($file eq "-");
704 open HEADER, $file or return;
705 while (defined($line = <HEADER>)) {
706 while (/\\$/) { # Handle continuation lines
711 if ($line =~ /^#\s*include\s+<(.*?)>/) {
712 push(@ARGV, $1) unless $Is_converted{$1};
719 # Determine include directories; $Config{usrinc} should be enough for (all
720 # non-GCC?) C compilers, but gcc uses an additional include directory.
723 my $from_gcc = `$Config{cc} -v 2>&1`;
724 $from_gcc =~ s:^Reading specs from (.*?)/specs\b.*:$1/include:s;
726 length($from_gcc) ? ($from_gcc, $Config{usrinc}) : ($Config{usrinc});
730 # Create "_h2ph_pre.ph", if it doesn't exist or was built by a different
732 sub build_preamble_if_necessary
734 # Increment $VERSION every time this function is modified:
736 my $preamble = "$Dest_dir/_h2ph_pre.ph";
738 # Can we skip building the preamble file?
740 # Extract version number from first line of preamble:
741 open PREAMBLE, $preamble or die "Cannot open $preamble: $!";
742 my $line = <PREAMBLE>;
743 $line =~ /(\b\d+\b)/;
744 close PREAMBLE or die "Cannot close $preamble: $!";
746 # Don't build preamble if a compatible preamble exists:
747 return if $1 == $VERSION;
750 my (%define) = _extract_cc_defines();
752 open PREAMBLE, ">$preamble" or die "Cannot open $preamble: $!";
753 print PREAMBLE "# This file was created by h2ph version $VERSION\n";
755 foreach (sort keys %define) {
757 print PREAMBLE "# $_=$define{$_}\n";
760 if ($define{$_} =~ /^(\d+)U?L{0,2}$/i) {
762 "unless (defined &$_) { sub $_() { $1 } }\n\n";
763 } elsif ($define{$_} =~ /^\w+$/) {
765 "unless (defined &$_) { sub $_() { &$define{$_} } }\n\n";
768 "unless (defined &$_) { sub $_() { \"",
769 quotemeta($define{$_}), "\" } }\n\n";
772 close PREAMBLE or die "Cannot close $preamble: $!";
776 # %Config contains information on macros that are pre-defined by the
777 # system's compiler. We need this information to make the .ph files
778 # function with perl as the .h files do with cc.
779 sub _extract_cc_defines
782 my $allsymbols = join " ",
783 @Config{'ccsymbols', 'cppsymbols', 'cppccsymbols'};
785 # Split compiler pre-definitions into `key=value' pairs:
786 foreach (split /\s+/, $allsymbols) {
787 /(.+?)=(.+)/ and $define{$1} = $2;
790 print STDERR "$_: $1 -> $2\n";
800 ##############################################################################
805 h2ph - convert .h C header files to .ph Perl header files
809 B<h2ph [-d destination directory] [-r | -a] [-l] [headerfiles]>
814 converts any C header files specified to the corresponding Perl header file
816 It is most easily run while in /usr/include:
818 cd /usr/include; h2ph * sys/*
822 cd /usr/include; h2ph * sys/* arpa/* netinet/*
826 cd /usr/include; h2ph -r -l .
828 The output files are placed in the hierarchy rooted at Perl's
829 architecture dependent library directory. You can specify a different
830 hierarchy with a B<-d> switch.
832 If run with no arguments, filters standard input to standard output.
838 =item -d destination_dir
840 Put the resulting B<.ph> files beneath B<destination_dir>, instead of
841 beneath the default Perl library location (C<$Config{'installsitsearch'}>).
845 Run recursively; if any of B<headerfiles> are directories, then run I<h2ph>
846 on all files in those directories (and their subdirectories, etc.). B<-r>
847 and B<-a> are mutually exclusive.
851 Run automagically; convert B<headerfiles>, as well as any B<.h> files
852 which they include. This option will search for B<.h> files in all
853 directories which your C compiler ordinarily uses. B<-a> and B<-r> are
858 Symbolic links will be replicated in the destination directory. If B<-l>
859 is not specified, then links are skipped over.
863 Put ``hints'' in the .ph files which will help in locating problems with
864 I<h2ph>. In those cases when you B<require> a B<.ph> file containing syntax
865 errors, instead of the cryptic
867 [ some error condition ] at (eval mmm) line nnn
869 you will see the slightly more helpful
871 [ some error condition ] at filename.ph line nnn
873 However, the B<.ph> files almost double in size when built using B<-h>.
877 Include the code from the B<.h> file as a comment in the B<.ph> file.
878 This is primarily used for debugging I<h2ph>.
882 ``Quiet'' mode; don't print out the names of the files being converted.
888 No environment variables are used.
907 The usual warnings if it can't read or write the files involved.
911 Doesn't construct the %sizeof array for you.
913 It doesn't handle all C constructs, but it does attempt to isolate
914 definitions inside evals so that you can get at the definitions
915 that it can translate.
917 It's only intended as a rough tool.
918 You may need to dicker with the files produced.
920 You have to run this program by hand; it's not run as part of the Perl
923 Doesn't handle complicated expressions built piecemeal, a la:
933 Doesn't necessarily locate all of your C compiler's internally-defined
940 close OUT or die "Can't close $file: $!";
941 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
942 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';