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);
46 use vars qw($opt_D $opt_d $opt_r $opt_l $opt_h $opt_a $opt_Q);
47 die "-r and -a options are mutually exclusive\n" if ($opt_r and $opt_a);
48 my @inc_dirs = inc_dirs() if $opt_a;
52 my $Dest_dir = $opt_d || $Config{installsitearch};
53 die "Destination directory $Dest_dir doesn't exist or isn't a directory\n"
56 my @isatype = split(' ',<<END);
65 @isatype{@isatype} = (1) x @isatype;
69 @ARGV = ('-') unless @ARGV;
71 build_preamble_if_necessary();
73 my ($t, $tab, %curargs, $new, $eval_index, $dir, $name, $args, $outfile);
75 while (defined (my $file = next_file())) {
76 if (-l $file and -d $file) {
77 link_if_possible($file) if ($opt_l);
81 # Recover from header files with unbalanced cpp directives
85 # $eval_index goes into ``#line'' directives, to help locate syntax errors:
92 ($outfile = $file) =~ s/\.h$/.ph/ || next;
93 print "$file -> $outfile\n" unless $opt_Q;
94 if ($file =~ m|^(.*)/|) {
96 mkpath "$Dest_dir/$dir";
99 if ($opt_a) { # automagic mode: locate header file in @inc_dirs
100 foreach (@inc_dirs) {
106 open(IN,"$file") || (($Exit = 1),(warn "Can't open $file: $!\n"),next);
107 open(OUT,">$Dest_dir/$outfile") || die "Can't create $outfile: $!\n";
110 print OUT "require '_h2ph_pre.ph';\n\n";
111 while (defined (local $_ = next_line())) {
113 if (s/^define\s+(\w+)//) {
117 if (s/^\(([\w,\s]*)\)//) {
122 foreach my $arg (split(/,\s*/,$args)) {
123 $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
126 $args =~ s/\b(\w)/\$$1/g;
127 $args = "local($args) = \@_;\n$t ";
131 $new =~ s/(["\\])/\\$1/g; #"]);
132 $new = reindent($new);
133 $args = reindent($args);
135 $new =~ s/(['\\])/\\$1/g; #']);
138 "eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
142 "eval 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
145 print OUT "unless(defined(\&$name)) {\n sub $name $proto\{\n\t${args}eval q($new);\n }\n}\n";
151 $new = 1 if $new eq '';
152 $new = reindent($new);
153 $args = reindent($args);
155 $new =~ s/(['\\])/\\$1/g; #']);
158 print OUT $t,"eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name () {",$new,";}' unless defined(\&$name);\n";
161 print OUT $t,"eval 'sub $name () {",$new,";}' unless defined(\&$name);\n";
164 # Shunt around such directives as `#define FOO FOO':
165 next if " \&$name" eq $new;
167 print OUT $t,"unless(defined(\&$name)) {\n sub $name () {\t",$new,";}\n}\n";
170 } elsif (/^(include|import)\s*[<"](.*)[>"]/) {
171 ($incl = $2) =~ s/\.h$/.ph/;
172 print OUT $t,"require '$incl';\n";
173 } elsif(/^include_next\s*[<"](.*)[>"]/) {
174 ($incl = $1) =~ s/\.h$/.ph/;
178 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
180 "my(\%INCD) = map { \$INC{\$_} => 1 } ",
181 "(grep { \$_ eq \"$incl\" } keys(\%INC));\n");
183 "my(\@REM) = map { \"\$_/$incl\" } ",
184 "(grep { not exists(\$INCD{\"\$_/$incl\"})",
185 "and -f \"\$_/$incl\" } \@INC);\n");
187 "require \"\$REM[0]\" if \@REM;\n");
189 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
193 "warn(\$\@) if \$\@;\n");
194 } elsif (/^ifdef\s+(\w+)/) {
195 print OUT $t,"if(defined(&$1)) {\n";
197 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
198 } elsif (/^ifndef\s+(\w+)/) {
199 print OUT $t,"unless(defined(&$1)) {\n";
201 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
202 } elsif (s/^if\s+//) {
207 print OUT $t,"if($new) {\n";
209 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
210 } elsif (s/^elif\s+//) {
216 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
217 print OUT $t,"}\n elsif($new) {\n";
219 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
222 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
223 print OUT $t,"} else {\n";
225 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
228 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
230 } elsif(/^undef\s+(\w+)/) {
231 print OUT $t, "undef(&$1) if defined(&$1);\n";
232 } elsif(/^error\s+(".*")/) {
233 print OUT $t, "die($1);\n";
234 } elsif(/^error\s+(.*)/) {
235 print OUT $t, "die(\"", quotemeta($1), "\");\n";
236 } elsif(/^warning\s+(.*)/) {
237 print OUT $t, "warn(\"", quotemeta($1), "\");\n";
238 } elsif(/^ident\s+(.*)/) {
239 print OUT $t, "# $1\n";
241 } elsif(/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?/) {
242 until(/\{[^}]*\}.*;/ || /;/) {
243 last unless defined ($next = next_line());
245 # drop "#define FOO FOO" in enums
246 $next =~ s/^\s*#\s*define\s+(\w+)\s+\1\s*$//;
248 print OUT "# $next\n" if $opt_D;
250 s/#\s*if.*?#\s*endif//g; # drop #ifdefs
253 next unless /^\s?(typedef\s?)?enum\s?([a-zA-Z_]\w*)?\s?\{(.*)\}\s?([a-zA-Z_]\w*)?\s?;/;
254 (my $enum_subs = $3) =~ s/\s//g;
255 my @enum_subs = split(/,/, $enum_subs);
257 foreach my $enum (@enum_subs) {
258 my ($enum_name, $enum_value) = $enum =~ /^([a-zA-Z_]\w*)(=.+)?$/;
259 $enum_value =~ s/^=//;
260 $enum_val = (length($enum_value) ? $enum_value : $enum_val + 1);
263 "eval(\"\\n#line $eval_index $outfile\\n",
264 "sub $enum_name () \{ $enum_val; \}\") ",
265 "unless defined(\&$enum_name);\n");
269 "eval(\"sub $enum_name () \{ $enum_val; \}\") ",
270 "unless defined(\&$enum_name);\n");
277 $Is_converted{$file} = 1;
278 queue_includes_from($file) if ($opt_a);
295 $joined_args = join('|', keys(%curargs));
298 s/^\&\&// && do { $new .= " &&"; next;}; # handle && operator
299 s/^\&([\(a-z\)]+)/$1/i; # hack for things that take the address of
300 s/^(\s+)// && do {$new .= ' '; next;};
301 s/^(0X[0-9A-F]+)[UL]*//i && do {$new .= lc($1); next;};
302 s/^(-?\d+\.\d+E[-+]\d+)F?//i && do {$new .= $1; next;};
303 s/^(\d+)\s*[LU]*//i && do {$new .= $1; next;};
304 s/^("(\\"|[^"])*")// && do {$new .= $1; next;};
305 s/^'((\\"|[^"])*)'// && do {
307 $new .= "ord('\$$1')";
313 # replace "sizeof(foo)" with "{foo}"
314 # also, remove * (C dereference operator) to avoid perl syntax
315 # problems. Where the %sizeof array comes from is anyone's
316 # guess (c2ph?), but this at least avoids fatal syntax errors.
317 # Behavior is undefined if sizeof() delimiters are unbalanced.
318 # This code was modified to able to handle constructs like this:
319 # sizeof(*(p)), which appear in the HP-UX 10.01 header files.
320 s/^sizeof\s*\(// && do {
322 my $lvl = 1; # already saw one open paren
323 # tack { on the front, and skip it in the loop
326 # find balanced closing paren
327 while ($index <= length($_) && $lvl > 0) {
328 $lvl++ if substr($_, $index, 1) eq "(";
329 $lvl-- if substr($_, $index, 1) eq ")";
332 # tack } on the end, replacing )
333 substr($_, $index - 1, 1) = "}";
334 # remove pesky * operators within the sizeof argument
335 substr($_, 0, $index - 1) =~ s/\*//g;
339 /\(([\w\s]+)[\*\s]*\)\s*[\w\(]/ && do {
340 foreach (split /\s+/, $1) { # Make sure all the words are types,
341 last unless ($isatype{$_} or $_ eq 'struct' or $_ eq 'union');
343 s/\([\w\s]+[\*\s]*\)// && next; # then eliminate them.
345 # struct/union member, including arrays:
346 s/^([_A-Z]\w*(\[[^\]]+\])?((\.|->)[_A-Z]\w*(\[[^\]]+\])?)+)//i && do {
348 $id =~ s/(\.|(->))([^\.\-]*)/->\{$3\}/g;
349 $id =~ s/\b([^\$])($joined_args)/$1\$$2/g if length($joined_args);
350 while($id =~ /\[\s*([^\$\&\d\]]+)\]/) {
353 if(exists($curargs{$index})) {
358 $id =~ s/\[\s*([^\$\&\d\]]+)\]/[$index]/;
362 s/^([_a-zA-Z]\w*)// && do {
364 if ($id eq 'struct' || $id eq 'union') {
368 } elsif ($id =~ /^((un)?signed)|(long)|(short)$/) {
369 while (s/^\s+(\w+)//) { $id .= ' ' . $1; }
374 $new .= '->' if /^[\[\{]/;
375 } elsif ($id eq 'defined') {
378 s/^\s*\((\w),/("$1",/ if $id =~ /^_IO[WR]*$/i; # cheat
380 } elsif ($isatype{$id}) {
381 if ($new =~ /{\s*$/) {
383 } elsif ($new =~ /\(\s*$/ && /^[\s*]*\)/) {
387 $new .= q(').$id.q(');
390 if ($inif && $new !~ /defined\s*\($/) {
391 $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
400 s/^(.)// && do { if ($1 ne '#') { $new .= $1; } next;};
408 my $pre_sub_tri_graphs = 1;
410 READ: while (not eof IN) {
413 next unless length $in;
416 if ($pre_sub_tri_graphs) {
417 # Preprocess all tri-graphs
418 # including things stuck in quoted string constants.
419 $in =~ s/\?\?=/#/g; # | ??=| #|
420 $in =~ s/\?\?\!/|/g; # | ??!| ||
421 $in =~ s/\?\?'/^/g; # | ??'| ^|
422 $in =~ s/\?\?\(/[/g; # | ??(| [|
423 $in =~ s/\?\?\)/]/g; # | ??)| ]|
424 $in =~ s/\?\?\-/~/g; # | ??-| ~|
425 $in =~ s/\?\?\//\\/g; # | ??/| \|
426 $in =~ s/\?\?</{/g; # | ??<| {|
427 $in =~ s/\?\?>/}/g; # | ??>| }|
429 if ($in =~ /^\#ifdef __LANGUAGE_PASCAL__/) {
430 # Tru64 disassembler.h evilness: mixed C and Pascal.
436 if ($in =~ s/\\$//) { # \-newline
439 } elsif ($in =~ s/^([^"'\\\/]+)//) { # Passthrough
441 } elsif ($in =~ s/^(\\.)//) { # \...
443 } elsif ($in =~ s/^('(\\.|[^'\\])*')//) { # '...
445 } elsif ($in =~ s/^("(\\.|[^"\\])*")//) { # "...
447 } elsif ($in =~ s/^\/\/.*//) { # //...
449 } elsif ($in =~ m/^\/\*/) { # /*...
450 # C comment removal adapted from perlfaq6:
451 if ($in =~ s/^\/\*[^*]*\*+([^\/*][^*]*\*+)*\///) {
453 } else { # Incomplete /* */
456 } elsif ($in =~ s/^(\/)//) { # /...
458 } elsif ($in =~ s/^([^\'\"\\\/]+)//) {
461 die "Cannot parse:\n$in\n";
465 last READ if $out =~ /\S/;
472 # Handle recursive subdirectories without getting a grotesquely big stack.
473 # Could this be implemented using File::Find?
481 if ($file eq '-' or -f $file or -l $file) {
487 print STDERR "Skipping directory `$file'\n";
492 print STDERR "Skipping `$file': not a file or directory\n";
500 # Put all the files in $directory into @ARGV for processing.
503 my ($directory) = @_;
505 $directory =~ s:/$::;
507 opendir DIR, $directory;
508 foreach (readdir DIR) {
509 next if ($_ eq '.' or $_ eq '..');
511 # expand_glob() is going to be called until $ARGV[0] isn't a
512 # directory; so push directories, and unshift everything else.
513 if (-d "$directory/$_") { push @ARGV, "$directory/$_" }
514 else { unshift @ARGV, "$directory/$_" }
520 # Given $file, a symbolic link to a directory in the C include directory,
521 # make an equivalent symbolic link in $Dest_dir, if we can figure out how.
522 # Otherwise, just duplicate the file or directory.
526 my $target = eval 'readlink($dirlink)';
528 if ($target =~ m:^\.\./: or $target =~ m:^/:) {
529 # The target of a parent or absolute link could leave the $Dest_dir
530 # hierarchy, so let's put all of the contents of $dirlink (actually,
531 # the contents of $target) into @ARGV; as a side effect down the
532 # line, $dirlink will get created as an _actual_ directory.
533 expand_glob($dirlink);
535 if (-l "$Dest_dir/$dirlink") {
536 unlink "$Dest_dir/$dirlink" or
537 print STDERR "Could not remove link $Dest_dir/$dirlink: $!\n";
540 if (eval 'symlink($target, "$Dest_dir/$dirlink")') {
541 print "Linking $target -> $Dest_dir/$dirlink\n";
543 # Make sure that the link _links_ to something:
544 if (! -e "$Dest_dir/$target") {
545 mkpath("$Dest_dir/$target", 0755) or
546 print STDERR "Could not create $Dest_dir/$target/\n";
549 print STDERR "Could not symlink $target -> $Dest_dir/$dirlink: $!\n";
555 # Push all #included files in $file onto our stack, except for STDIN
556 # and files we've already processed.
557 sub queue_includes_from
562 return if ($file eq "-");
564 open HEADER, $file or return;
565 while (defined($line = <HEADER>)) {
566 while (/\\$/) { # Handle continuation lines
571 if ($line =~ /^#\s*include\s+<(.*?)>/) {
572 push(@ARGV, $1) unless $Is_converted{$1};
579 # Determine include directories; $Config{usrinc} should be enough for (all
580 # non-GCC?) C compilers, but gcc uses an additional include directory.
583 my $from_gcc = `$Config{cc} -v 2>&1`;
584 $from_gcc =~ s:^Reading specs from (.*?)/specs\b.*:$1/include:s;
586 length($from_gcc) ? ($from_gcc, $Config{usrinc}) : ($Config{usrinc});
590 # Create "_h2ph_pre.ph", if it doesn't exist or was built by a different
592 sub build_preamble_if_necessary
594 # Increment $VERSION every time this function is modified:
596 my $preamble = "$Dest_dir/_h2ph_pre.ph";
598 # Can we skip building the preamble file?
600 # Extract version number from first line of preamble:
601 open PREAMBLE, $preamble or die "Cannot open $preamble: $!";
602 my $line = <PREAMBLE>;
603 $line =~ /(\b\d+\b)/;
604 close PREAMBLE or die "Cannot close $preamble: $!";
606 # Don't build preamble if a compatible preamble exists:
607 return if $1 == $VERSION;
610 my (%define) = _extract_cc_defines();
612 open PREAMBLE, ">$preamble" or die "Cannot open $preamble: $!";
613 print PREAMBLE "# This file was created by h2ph version $VERSION\n";
615 foreach (sort keys %define) {
617 print PREAMBLE "# $_=$define{$_}\n";
620 if ($define{$_} =~ /^(\d+)U?L{0,2}$/i) {
622 "unless (defined &$_) { sub $_() { $1 } }\n\n";
623 } elsif ($define{$_} =~ /^\w+$/) {
625 "unless (defined &$_) { sub $_() { &$define{$_} } }\n\n";
628 "unless (defined &$_) { sub $_() { \"",
629 quotemeta($define{$_}), "\" } }\n\n";
632 close PREAMBLE or die "Cannot close $preamble: $!";
636 # %Config contains information on macros that are pre-defined by the
637 # system's compiler. We need this information to make the .ph files
638 # function with perl as the .h files do with cc.
639 sub _extract_cc_defines
642 my $allsymbols = join " ",
643 @Config{'ccsymbols', 'cppsymbols', 'cppccsymbols'};
645 # Split compiler pre-definitions into `key=value' pairs:
646 foreach (split /\s+/, $allsymbols) {
647 /(.+?)=(.+)/ and $define{$1} = $2;
650 print STDERR "$_: $1 -> $2\n";
660 ##############################################################################
665 h2ph - convert .h C header files to .ph Perl header files
669 B<h2ph [-d destination directory] [-r | -a] [-l] [headerfiles]>
674 converts any C header files specified to the corresponding Perl header file
676 It is most easily run while in /usr/include:
678 cd /usr/include; h2ph * sys/*
682 cd /usr/include; h2ph -r -l .
684 The output files are placed in the hierarchy rooted at Perl's
685 architecture dependent library directory. You can specify a different
686 hierarchy with a B<-d> switch.
688 If run with no arguments, filters standard input to standard output.
694 =item -d destination_dir
696 Put the resulting B<.ph> files beneath B<destination_dir>, instead of
697 beneath the default Perl library location (C<$Config{'installsitsearch'}>).
701 Run recursively; if any of B<headerfiles> are directories, then run I<h2ph>
702 on all files in those directories (and their subdirectories, etc.). B<-r>
703 and B<-a> are mutually exclusive.
707 Run automagically; convert B<headerfiles>, as well as any B<.h> files
708 which they include. This option will search for B<.h> files in all
709 directories which your C compiler ordinarily uses. B<-a> and B<-r> are
714 Symbolic links will be replicated in the destination directory. If B<-l>
715 is not specified, then links are skipped over.
719 Put ``hints'' in the .ph files which will help in locating problems with
720 I<h2ph>. In those cases when you B<require> a B<.ph> file containing syntax
721 errors, instead of the cryptic
723 [ some error condition ] at (eval mmm) line nnn
725 you will see the slightly more helpful
727 [ some error condition ] at filename.ph line nnn
729 However, the B<.ph> files almost double in size when built using B<-h>.
733 Include the code from the B<.h> file as a comment in the B<.ph> file.
734 This is primarily used for debugging I<h2ph>.
738 ``Quiet'' mode; don't print out the names of the files being converted.
744 No environment variables are used.
763 The usual warnings if it can't read or write the files involved.
767 Doesn't construct the %sizeof array for you.
769 It doesn't handle all C constructs, but it does attempt to isolate
770 definitions inside evals so that you can get at the definitions
771 that it can translate.
773 It's only intended as a rough tool.
774 You may need to dicker with the files produced.
776 You have to run this program by hand; it's not run as part of the Perl
779 Doesn't handle complicated expressions built piecemeal, a la:
789 Doesn't necessarily locate all of your C compiler's internally-defined
796 close OUT or die "Can't close $file: $!";
797 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
798 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';