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!';
40 use File::Path qw(mkpath);
44 die "-r and -a options are mutually exclusive\n" if ($opt_r and $opt_a);
45 @inc_dirs = inc_dirs() if $opt_a;
49 my $Dest_dir = $opt_d || $Config{installsitearch};
50 die "Destination directory $Dest_dir doesn't exist or isn't a directory\n"
53 @isatype = split(' ',<<END);
61 @isatype{@isatype} = (1) x @isatype;
64 @ARGV = ('-') unless @ARGV;
66 build_preamble_if_necessary();
68 while (defined ($file = next_file())) {
69 if (-l $file and -d $file) {
70 link_if_possible($file) if ($opt_l);
74 # Recover from header files with unbalanced cpp directives
78 # $eval_index goes into ``#line'' directives, to help locate syntax errors:
85 ($outfile = $file) =~ s/\.h$/.ph/ || next;
86 print "$file -> $outfile\n" unless $opt_Q;
87 if ($file =~ m|^(.*)/|) {
89 mkpath "$Dest_dir/$dir";
92 if ($opt_a) { # automagic mode: locate header file in @inc_dirs
99 open(IN,"$file") || (($Exit = 1),(warn "Can't open $file: $!\n"),next);
100 open(OUT,">$Dest_dir/$outfile") || die "Can't create $outfile: $!\n";
103 print OUT "require '_h2ph_pre.ph';\n\n";
111 print OUT "# $_\n" if $opt_D;
115 s/\200[^\201]*\201//g; # delete single line comments
116 if (s/\200.*//) { # begin multi-line comment?
123 if (s/^define\s+(\w+)//) {
127 if (s/^\(([\w,\s]*)\)//) {
132 foreach $arg (split(/,\s*/,$args)) {
133 $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
136 $args =~ s/\b(\w)/\$$1/g;
137 $args = "local($args) = \@_;\n$t ";
141 $new =~ s/(["\\])/\\$1/g; #"]);
142 $new = reindent($new);
143 $args = reindent($args);
145 $new =~ s/(['\\])/\\$1/g; #']);
148 "eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
152 "eval 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
155 print OUT "unless(defined(\&$name)) {\n sub $name $proto\{\n\t${args}eval q($new);\n }\n}\n";
161 $new = 1 if $new eq '';
162 $new = reindent($new);
163 $args = reindent($args);
165 $new =~ s/(['\\])/\\$1/g; #']);
168 print OUT $t,"eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name () {",$new,";}' unless defined(\&$name);\n";
171 print OUT $t,"eval 'sub $name () {",$new,";}' unless defined(\&$name);\n";
174 # Shunt around such directives as `#define FOO FOO':
175 next if " \&$name" eq $new;
177 print OUT $t,"unless(defined(\&$name)) {\n sub $name () {\t",$new,";}\n}\n";
180 } elsif (/^(include|import)\s*[<"](.*)[>"]/) {
181 ($incl = $2) =~ s/\.h$/.ph/;
182 print OUT $t,"require '$incl';\n";
183 } elsif(/^include_next\s*[<"](.*)[>"]/) {
184 ($incl = $1) =~ s/\.h$/.ph/;
188 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
190 "my(\%INCD) = map { \$INC{\$_} => 1 } ",
191 "(grep { \$_ eq \"$incl\" } keys(\%INC));\n");
193 "my(\@REM) = map { \"\$_/$incl\" } ",
194 "(grep { not exists(\$INCD{\"\$_/$incl\"})",
195 "and -f \"\$_/$incl\" } \@INC);\n");
197 "require \"\$REM[0]\" if \@REM;\n");
199 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
203 "warn(\$\@) if \$\@;\n");
204 } elsif (/^ifdef\s+(\w+)/) {
205 print OUT $t,"if(defined(&$1)) {\n";
207 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
208 } elsif (/^ifndef\s+(\w+)/) {
209 print OUT $t,"unless(defined(&$1)) {\n";
211 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
212 } elsif (s/^if\s+//) {
217 print OUT $t,"if($new) {\n";
219 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
220 } elsif (s/^elif\s+//) {
226 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
227 print OUT $t,"}\n elsif($new) {\n";
229 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
232 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
233 print OUT $t,"} else {\n";
235 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
238 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
240 } elsif(/^undef\s+(\w+)/) {
241 print OUT $t, "undef(&$1) if defined(&$1);\n";
242 } elsif(/^error\s+(".*")/) {
243 print OUT $t, "die($1);\n";
244 } elsif(/^error\s+(.*)/) {
245 print OUT $t, "die(\"", quotemeta($1), "\");\n";
246 } elsif(/^warning\s+(.*)/) {
247 print OUT $t, "warn(\"", quotemeta($1), "\");\n";
248 } elsif(/^ident\s+(.*)/) {
249 print OUT $t, "# $1\n";
251 } elsif(/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?\{/) {
255 print OUT "# $next\n" if $opt_D;
259 /^\s?(typedef\s?)?enum\s?([a-zA-Z_]\w*)?\s?\{(.*)\}\s?([a-zA-Z_]\w*)?\s?;/;
260 ($enum_subs = $3) =~ s/\s//g;
261 @enum_subs = split(/,/, $enum_subs);
263 for $enum (@enum_subs) {
264 ($enum_name, $enum_value) = $enum =~ /^([a-zA-Z_]\w*)(=.+)?$/;
265 $enum_value =~ s/^=//;
266 $enum_val = (length($enum_value) ? $enum_value : $enum_val + 1);
269 "eval(\"\\n#line $eval_index $outfile\\n",
270 "sub $enum_name () \{ $enum_val; \}\") ",
271 "unless defined(\&$enum_name);\n");
275 "eval(\"sub $enum_name () \{ $enum_val; \}\") ",
276 "unless defined(\&$enum_name);\n");
283 $is_converted{$file} = 1;
284 queue_includes_from($file) if ($opt_a);
298 my($joined_args) = join('|', keys(%curargs));
301 s/^\&\&// && do { $new .= " &&"; next;}; # handle && operator
302 s/^\&([\(a-z\)]+)/$1/i; # hack for things that take the address of
303 s/^(\s+)// && do {$new .= ' '; next;};
304 s/^(0X[0-9A-F]+)[UL]*//i && do {$new .= lc($1); next;};
305 s/^(-?\d+\.\d+E[-+]\d+)F?//i && do {$new .= $1; next;};
306 s/^(\d+)\s*[LU]*//i && do {$new .= $1; next;};
307 s/^("(\\"|[^"])*")// && do {$new .= $1; next;};
308 s/^'((\\"|[^"])*)'// && do {
310 $new .= "ord('\$$1')";
316 # replace "sizeof(foo)" with "{foo}"
317 # also, remove * (C dereference operator) to avoid perl syntax
318 # problems. Where the %sizeof array comes from is anyone's
319 # guess (c2ph?), but this at least avoids fatal syntax errors.
320 # Behavior is undefined if sizeof() delimiters are unbalanced.
321 # This code was modified to able to handle constructs like this:
322 # sizeof(*(p)), which appear in the HP-UX 10.01 header files.
323 s/^sizeof\s*\(// && do {
325 my $lvl = 1; # already saw one open paren
326 # tack { on the front, and skip it in the loop
329 # find balanced closing paren
330 while ($index <= length($_) && $lvl > 0) {
331 $lvl++ if substr($_, $index, 1) eq "(";
332 $lvl-- if substr($_, $index, 1) eq ")";
335 # tack } on the end, replacing )
336 substr($_, $index - 1, 1) = "}";
337 # remove pesky * operators within the sizeof argument
338 substr($_, 0, $index - 1) =~ s/\*//g;
342 /\(([\w\s]+)[\*\s]*\)\s*[\w\(]/ && do {
343 foreach (split /\s+/, $1) { # Make sure all the words are types,
344 last unless ($isatype{$_} or $_ eq 'struct');
346 s/\([\w\s]+[\*\s]*\)// && next; # then eliminate them.
348 # struct/union member, including arrays:
349 s/^([_A-Z]\w*(\[[^\]]+\])?((\.|->)[_A-Z]\w*(\[[^\]]+\])?)+)//i && do {
351 $id =~ s/(\.|(->))([^\.\-]*)/->\{$3\}/g;
352 $id =~ s/\b([^\$])($joined_args)/$1\$$2/g if length($joined_args);
353 while($id =~ /\[\s*([^\$\&\d\]]+)\]/) {
356 if(exists($curargs{$index})) {
361 $id =~ s/\[\s*([^\$\&\d\]]+)\]/[$index]/;
365 s/^([_a-zA-Z]\w*)// && do {
367 if ($id eq 'struct') {
371 } elsif ($id =~ /^((un)?signed)|(long)|(short)$/) {
372 while (s/^\s+(\w+)//) { $id .= ' ' . $1; }
377 $new .= '->' if /^[\[\{]/;
378 } elsif ($id eq 'defined') {
381 s/^\((\w),/("$1",/ if $id =~ /^_IO[WR]*$/i; # cheat
383 } elsif ($isatype{$id}) {
384 if ($new =~ /{\s*$/) {
386 } elsif ($new =~ /\(\s*$/ && /^[\s*]*\)/) {
390 $new .= q(').$id.q(');
393 if ($inif && $new !~ /defined\s*\($/) {
394 $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
403 s/^(.)// && do { if ($1 ne '#') { $new .= $1; } next;};
408 # Handle recursive subdirectories without getting a grotesquely big stack.
409 # Could this be implemented using File::Find?
417 if ($file eq '-' or -f $file or -l $file) {
423 print STDERR "Skipping directory `$file'\n";
428 print STDERR "Skipping `$file': not a file or directory\n";
436 # Put all the files in $directory into @ARGV for processing.
439 my ($directory) = @_;
441 $directory =~ s:/$::;
443 opendir DIR, $directory;
444 foreach (readdir DIR) {
445 next if ($_ eq '.' or $_ eq '..');
447 # expand_glob() is going to be called until $ARGV[0] isn't a
448 # directory; so push directories, and unshift everything else.
449 if (-d "$directory/$_") { push @ARGV, "$directory/$_" }
450 else { unshift @ARGV, "$directory/$_" }
456 # Given $file, a symbolic link to a directory in the C include directory,
457 # make an equivalent symbolic link in $Dest_dir, if we can figure out how.
458 # Otherwise, just duplicate the file or directory.
462 my $target = eval 'readlink($dirlink)';
464 if ($target =~ m:^\.\./: or $target =~ m:^/:) {
465 # The target of a parent or absolute link could leave the $Dest_dir
466 # hierarchy, so let's put all of the contents of $dirlink (actually,
467 # the contents of $target) into @ARGV; as a side effect down the
468 # line, $dirlink will get created as an _actual_ directory.
469 expand_glob($dirlink);
471 if (-l "$Dest_dir/$dirlink") {
472 unlink "$Dest_dir/$dirlink" or
473 print STDERR "Could not remove link $Dest_dir/$dirlink: $!\n";
476 if (eval 'symlink($target, "$Dest_dir/$dirlink")') {
477 print "Linking $target -> $Dest_dir/$dirlink\n";
479 # Make sure that the link _links_ to something:
480 if (! -e "$Dest_dir/$target") {
481 mkpath("$Dest_dir/$target", 0755) or
482 print STDERR "Could not create $Dest_dir/$target/\n";
485 print STDERR "Could not symlink $target -> $Dest_dir/$dirlink: $!\n";
491 # Push all #included files in $file onto our stack, except for STDIN
492 # and files we've already processed.
493 sub queue_includes_from
498 return if ($file eq "-");
500 open HEADER, $file or return;
501 while (defined($line = <HEADER>)) {
502 while (/\\$/) { # Handle continuation lines
507 if ($line =~ /^#\s*include\s+<(.*?)>/) {
508 push(@ARGV, $1) unless $is_converted{$1};
515 # Determine include directories; $Config{usrinc} should be enough for (all
516 # non-GCC?) C compilers, but gcc uses an additional include directory.
519 my $from_gcc = `$Config{cc} -v 2>&1`;
520 $from_gcc =~ s:^Reading specs from (.*?)/specs\b.*:$1/include:s;
522 length($from_gcc) ? ($from_gcc, $Config{usrinc}) : ($Config{usrinc});
526 # Create "_h2ph_pre.ph", if it doesn't exist or was built by a different
528 sub build_preamble_if_necessary
530 # Increment $VERSION every time this function is modified:
532 my $preamble = "$Dest_dir/_h2ph_pre.ph";
534 # Can we skip building the preamble file?
536 # Extract version number from first line of preamble:
537 open PREAMBLE, $preamble or die "Cannot open $preamble: $!";
538 my $line = <PREAMBLE>;
539 $line =~ /(\b\d+\b)/;
540 close PREAMBLE or die "Cannot close $preamble: $!";
542 # Don't build preamble if a compatible preamble exists:
543 return if $1 == $VERSION;
546 my (%define) = _extract_cc_defines();
548 open PREAMBLE, ">$preamble" or die "Cannot open $preamble: $!";
549 print PREAMBLE "# This file was created by h2ph version $VERSION\n";
551 foreach (sort keys %define) {
553 print PREAMBLE "# $_=$define{$_}\n";
556 if ($define{$_} =~ /^\d+$/) {
558 "unless (defined &$_) { sub $_() { $define{$_} } }\n\n";
559 } elsif ($define{$_} =~ /^\w+$/) {
561 "unless (defined &$_) { sub $_() { &$define{$_} } }\n\n";
564 "unless (defined &$_) { sub $_() { \"",
565 quotemeta($define{$_}), "\" } }\n\n";
568 close PREAMBLE or die "Cannot close $preamble: $!";
572 # %Config contains information on macros that are pre-defined by the
573 # system's compiler. We need this information to make the .ph files
574 # function with perl as the .h files do with cc.
575 sub _extract_cc_defines
578 my $allsymbols = join " ", @Config{ccsymbols, cppsymbols, cppccsymbols};
580 # Split compiler pre-definitions into `key=value' pairs:
581 foreach (split /\s+/, $allsymbols) {
582 /(.+?)=(.+)/ and $define{$1} = $2;
585 print STDERR "$_: $1 -> $2\n";
595 ##############################################################################
600 h2ph - convert .h C header files to .ph Perl header files
604 B<h2ph [-d destination directory] [-r | -a] [-l] [headerfiles]>
609 converts any C header files specified to the corresponding Perl header file
611 It is most easily run while in /usr/include:
613 cd /usr/include; h2ph * sys/*
617 cd /usr/include; h2ph -r -l .
619 The output files are placed in the hierarchy rooted at Perl's
620 architecture dependent library directory. You can specify a different
621 hierarchy with a B<-d> switch.
623 If run with no arguments, filters standard input to standard output.
629 =item -d destination_dir
631 Put the resulting B<.ph> files beneath B<destination_dir>, instead of
632 beneath the default Perl library location (C<$Config{'installsitsearch'}>).
636 Run recursively; if any of B<headerfiles> are directories, then run I<h2ph>
637 on all files in those directories (and their subdirectories, etc.). B<-r>
638 and B<-a> are mutually exclusive.
642 Run automagically; convert B<headerfiles>, as well as any B<.h> files
643 which they include. This option will search for B<.h> files in all
644 directories which your C compiler ordinarily uses. B<-a> and B<-r> are
649 Symbolic links will be replicated in the destination directory. If B<-l>
650 is not specified, then links are skipped over.
654 Put ``hints'' in the .ph files which will help in locating problems with
655 I<h2ph>. In those cases when you B<require> a B<.ph> file containing syntax
656 errors, instead of the cryptic
658 [ some error condition ] at (eval mmm) line nnn
660 you will see the slightly more helpful
662 [ some error condition ] at filename.ph line nnn
664 However, the B<.ph> files almost double in size when built using B<-h>.
668 Include the code from the B<.h> file as a comment in the B<.ph> file.
669 This is primarily used for debugging I<h2ph>.
673 ``Quiet'' mode; don't print out the names of the files being converted.
679 No environment variables are used.
698 The usual warnings if it can't read or write the files involved.
702 Doesn't construct the %sizeof array for you.
704 It doesn't handle all C constructs, but it does attempt to isolate
705 definitions inside evals so that you can get at the definitions
706 that it can translate.
708 It's only intended as a rough tool.
709 You may need to dicker with the files produced.
711 Doesn't run with C<use strict>
713 You have to run this program by hand; it's not run as part of the Perl
716 Doesn't handle complicated expressions built piecemeal, a la:
726 Doesn't necessarily locate all of your C compiler's internally-defined
733 close OUT or die "Can't close $file: $!";
734 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
735 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';