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";
118 print OUT "# $_\n" if $opt_D;
122 s/\200[^\201]*\201//g; # delete single line comments
123 if (s/\200.*//) { # begin multi-line comment?
130 if (s/^define\s+(\w+)//) {
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; #"]);
149 $new = reindent($new);
150 $args = reindent($args);
152 $new =~ s/(['\\])/\\$1/g; #']);
155 "eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
159 "eval 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n";
162 print OUT "unless(defined(\&$name)) {\n sub $name $proto\{\n\t${args}eval q($new);\n }\n}\n";
168 $new = 1 if $new eq '';
169 $new = reindent($new);
170 $args = reindent($args);
172 $new =~ s/(['\\])/\\$1/g; #']);
175 print OUT $t,"eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name () {",$new,";}' unless defined(\&$name);\n";
178 print OUT $t,"eval 'sub $name () {",$new,";}' unless defined(\&$name);\n";
181 # Shunt around such directives as `#define FOO FOO':
182 next if " \&$name" eq $new;
184 print OUT $t,"unless(defined(\&$name)) {\n sub $name () {\t",$new,";}\n}\n";
187 } elsif (/^(include|import)\s*[<"](.*)[>"]/) {
188 ($incl = $2) =~ s/\.h$/.ph/;
189 print OUT $t,"require '$incl';\n";
190 } elsif(/^include_next\s*[<"](.*)[>"]/) {
191 ($incl = $1) =~ s/\.h$/.ph/;
195 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
197 "my(\%INCD) = map { \$INC{\$_} => 1 } ",
198 "(grep { \$_ eq \"$incl\" } keys(\%INC));\n");
200 "my(\@REM) = map { \"\$_/$incl\" } ",
201 "(grep { not exists(\$INCD{\"\$_/$incl\"})",
202 "and -f \"\$_/$incl\" } \@INC);\n");
204 "require \"\$REM[0]\" if \@REM;\n");
206 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
210 "warn(\$\@) if \$\@;\n");
211 } elsif (/^ifdef\s+(\w+)/) {
212 print OUT $t,"if(defined(&$1)) {\n";
214 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
215 } elsif (/^ifndef\s+(\w+)/) {
216 print OUT $t,"unless(defined(&$1)) {\n";
218 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
219 } elsif (s/^if\s+//) {
224 print OUT $t,"if($new) {\n";
226 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
227 } elsif (s/^elif\s+//) {
233 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
234 print OUT $t,"}\n elsif($new) {\n";
236 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
239 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
240 print OUT $t,"} else {\n";
242 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
245 $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
247 } elsif(/^undef\s+(\w+)/) {
248 print OUT $t, "undef(&$1) if defined(&$1);\n";
249 } elsif(/^error\s+(".*")/) {
250 print OUT $t, "die($1);\n";
251 } elsif(/^error\s+(.*)/) {
252 print OUT $t, "die(\"", quotemeta($1), "\");\n";
253 } elsif(/^warning\s+(.*)/) {
254 print OUT $t, "warn(\"", quotemeta($1), "\");\n";
255 } elsif(/^ident\s+(.*)/) {
256 print OUT $t, "# $1\n";
258 } elsif(/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?\{/) {
262 print OUT "# $next\n" if $opt_D;
266 /^\s?(typedef\s?)?enum\s?([a-zA-Z_]\w*)?\s?\{(.*)\}\s?([a-zA-Z_]\w*)?\s?;/;
267 (my $enum_subs = $3) =~ s/\s//g;
268 my @enum_subs = split(/,/, $enum_subs);
270 foreach my $enum (@enum_subs) {
271 my ($enum_name, $enum_value) = $enum =~ /^([a-zA-Z_]\w*)(=.+)?$/;
272 $enum_value =~ s/^=//;
273 $enum_val = (length($enum_value) ? $enum_value : $enum_val + 1);
276 "eval(\"\\n#line $eval_index $outfile\\n",
277 "sub $enum_name () \{ $enum_val; \}\") ",
278 "unless defined(\&$enum_name);\n");
282 "eval(\"sub $enum_name () \{ $enum_val; \}\") ",
283 "unless defined(\&$enum_name);\n");
290 $Is_converted{$file} = 1;
291 queue_includes_from($file) if ($opt_a);
308 $joined_args = join('|', keys(%curargs));
311 s/^\&\&// && do { $new .= " &&"; next;}; # handle && operator
312 s/^\&([\(a-z\)]+)/$1/i; # hack for things that take the address of
313 s/^(\s+)// && do {$new .= ' '; next;};
314 s/^(0X[0-9A-F]+)[UL]*//i && do {$new .= lc($1); next;};
315 s/^(-?\d+\.\d+E[-+]\d+)F?//i && do {$new .= $1; next;};
316 s/^(\d+)\s*[LU]*//i && do {$new .= $1; next;};
317 s/^("(\\"|[^"])*")// && do {$new .= $1; next;};
318 s/^'((\\"|[^"])*)'// && do {
320 $new .= "ord('\$$1')";
326 # replace "sizeof(foo)" with "{foo}"
327 # also, remove * (C dereference operator) to avoid perl syntax
328 # problems. Where the %sizeof array comes from is anyone's
329 # guess (c2ph?), but this at least avoids fatal syntax errors.
330 # Behavior is undefined if sizeof() delimiters are unbalanced.
331 # This code was modified to able to handle constructs like this:
332 # sizeof(*(p)), which appear in the HP-UX 10.01 header files.
333 s/^sizeof\s*\(// && do {
335 my $lvl = 1; # already saw one open paren
336 # tack { on the front, and skip it in the loop
339 # find balanced closing paren
340 while ($index <= length($_) && $lvl > 0) {
341 $lvl++ if substr($_, $index, 1) eq "(";
342 $lvl-- if substr($_, $index, 1) eq ")";
345 # tack } on the end, replacing )
346 substr($_, $index - 1, 1) = "}";
347 # remove pesky * operators within the sizeof argument
348 substr($_, 0, $index - 1) =~ s/\*//g;
352 /\(([\w\s]+)[\*\s]*\)\s*[\w\(]/ && do {
353 foreach (split /\s+/, $1) { # Make sure all the words are types,
354 last unless ($isatype{$_} or $_ eq 'struct');
356 s/\([\w\s]+[\*\s]*\)// && next; # then eliminate them.
358 # struct/union member, including arrays:
359 s/^([_A-Z]\w*(\[[^\]]+\])?((\.|->)[_A-Z]\w*(\[[^\]]+\])?)+)//i && do {
361 $id =~ s/(\.|(->))([^\.\-]*)/->\{$3\}/g;
362 $id =~ s/\b([^\$])($joined_args)/$1\$$2/g if length($joined_args);
363 while($id =~ /\[\s*([^\$\&\d\]]+)\]/) {
366 if(exists($curargs{$index})) {
371 $id =~ s/\[\s*([^\$\&\d\]]+)\]/[$index]/;
375 s/^([_a-zA-Z]\w*)// && do {
377 if ($id eq 'struct') {
381 } elsif ($id =~ /^((un)?signed)|(long)|(short)$/) {
382 while (s/^\s+(\w+)//) { $id .= ' ' . $1; }
387 $new .= '->' if /^[\[\{]/;
388 } elsif ($id eq 'defined') {
391 s/^\((\w),/("$1",/ if $id =~ /^_IO[WR]*$/i; # cheat
393 } elsif ($isatype{$id}) {
394 if ($new =~ /{\s*$/) {
396 } elsif ($new =~ /\(\s*$/ && /^[\s*]*\)/) {
400 $new .= q(').$id.q(');
403 if ($inif && $new !~ /defined\s*\($/) {
404 $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
413 s/^(.)// && do { if ($1 ne '#') { $new .= $1; } next;};
418 # Handle recursive subdirectories without getting a grotesquely big stack.
419 # Could this be implemented using File::Find?
427 if ($file eq '-' or -f $file or -l $file) {
433 print STDERR "Skipping directory `$file'\n";
438 print STDERR "Skipping `$file': not a file or directory\n";
446 # Put all the files in $directory into @ARGV for processing.
449 my ($directory) = @_;
451 $directory =~ s:/$::;
453 opendir DIR, $directory;
454 foreach (readdir DIR) {
455 next if ($_ eq '.' or $_ eq '..');
457 # expand_glob() is going to be called until $ARGV[0] isn't a
458 # directory; so push directories, and unshift everything else.
459 if (-d "$directory/$_") { push @ARGV, "$directory/$_" }
460 else { unshift @ARGV, "$directory/$_" }
466 # Given $file, a symbolic link to a directory in the C include directory,
467 # make an equivalent symbolic link in $Dest_dir, if we can figure out how.
468 # Otherwise, just duplicate the file or directory.
472 my $target = eval 'readlink($dirlink)';
474 if ($target =~ m:^\.\./: or $target =~ m:^/:) {
475 # The target of a parent or absolute link could leave the $Dest_dir
476 # hierarchy, so let's put all of the contents of $dirlink (actually,
477 # the contents of $target) into @ARGV; as a side effect down the
478 # line, $dirlink will get created as an _actual_ directory.
479 expand_glob($dirlink);
481 if (-l "$Dest_dir/$dirlink") {
482 unlink "$Dest_dir/$dirlink" or
483 print STDERR "Could not remove link $Dest_dir/$dirlink: $!\n";
486 if (eval 'symlink($target, "$Dest_dir/$dirlink")') {
487 print "Linking $target -> $Dest_dir/$dirlink\n";
489 # Make sure that the link _links_ to something:
490 if (! -e "$Dest_dir/$target") {
491 mkpath("$Dest_dir/$target", 0755) or
492 print STDERR "Could not create $Dest_dir/$target/\n";
495 print STDERR "Could not symlink $target -> $Dest_dir/$dirlink: $!\n";
501 # Push all #included files in $file onto our stack, except for STDIN
502 # and files we've already processed.
503 sub queue_includes_from
508 return if ($file eq "-");
510 open HEADER, $file or return;
511 while (defined($line = <HEADER>)) {
512 while (/\\$/) { # Handle continuation lines
517 if ($line =~ /^#\s*include\s+<(.*?)>/) {
518 push(@ARGV, $1) unless $Is_converted{$1};
525 # Determine include directories; $Config{usrinc} should be enough for (all
526 # non-GCC?) C compilers, but gcc uses an additional include directory.
529 my $from_gcc = `$Config{cc} -v 2>&1`;
530 $from_gcc =~ s:^Reading specs from (.*?)/specs\b.*:$1/include:s;
532 length($from_gcc) ? ($from_gcc, $Config{usrinc}) : ($Config{usrinc});
536 # Create "_h2ph_pre.ph", if it doesn't exist or was built by a different
538 sub build_preamble_if_necessary
540 # Increment $VERSION every time this function is modified:
542 my $preamble = "$Dest_dir/_h2ph_pre.ph";
544 # Can we skip building the preamble file?
546 # Extract version number from first line of preamble:
547 open PREAMBLE, $preamble or die "Cannot open $preamble: $!";
548 my $line = <PREAMBLE>;
549 $line =~ /(\b\d+\b)/;
550 close PREAMBLE or die "Cannot close $preamble: $!";
552 # Don't build preamble if a compatible preamble exists:
553 return if $1 == $VERSION;
556 my (%define) = _extract_cc_defines();
558 open PREAMBLE, ">$preamble" or die "Cannot open $preamble: $!";
559 print PREAMBLE "# This file was created by h2ph version $VERSION\n";
561 foreach (sort keys %define) {
563 print PREAMBLE "# $_=$define{$_}\n";
566 if ($define{$_} =~ /^\d+$/) {
568 "unless (defined &$_) { sub $_() { $define{$_} } }\n\n";
569 } elsif ($define{$_} =~ /^\w+$/) {
571 "unless (defined &$_) { sub $_() { &$define{$_} } }\n\n";
574 "unless (defined &$_) { sub $_() { \"",
575 quotemeta($define{$_}), "\" } }\n\n";
578 close PREAMBLE or die "Cannot close $preamble: $!";
582 # %Config contains information on macros that are pre-defined by the
583 # system's compiler. We need this information to make the .ph files
584 # function with perl as the .h files do with cc.
585 sub _extract_cc_defines
588 my $allsymbols = join " ",
589 @Config{'ccsymbols', 'cppsymbols', 'cppccsymbols'};
591 # Split compiler pre-definitions into `key=value' pairs:
592 foreach (split /\s+/, $allsymbols) {
593 /(.+?)=(.+)/ and $define{$1} = $2;
596 print STDERR "$_: $1 -> $2\n";
606 ##############################################################################
611 h2ph - convert .h C header files to .ph Perl header files
615 B<h2ph [-d destination directory] [-r | -a] [-l] [headerfiles]>
620 converts any C header files specified to the corresponding Perl header file
622 It is most easily run while in /usr/include:
624 cd /usr/include; h2ph * sys/*
628 cd /usr/include; h2ph -r -l .
630 The output files are placed in the hierarchy rooted at Perl's
631 architecture dependent library directory. You can specify a different
632 hierarchy with a B<-d> switch.
634 If run with no arguments, filters standard input to standard output.
640 =item -d destination_dir
642 Put the resulting B<.ph> files beneath B<destination_dir>, instead of
643 beneath the default Perl library location (C<$Config{'installsitsearch'}>).
647 Run recursively; if any of B<headerfiles> are directories, then run I<h2ph>
648 on all files in those directories (and their subdirectories, etc.). B<-r>
649 and B<-a> are mutually exclusive.
653 Run automagically; convert B<headerfiles>, as well as any B<.h> files
654 which they include. This option will search for B<.h> files in all
655 directories which your C compiler ordinarily uses. B<-a> and B<-r> are
660 Symbolic links will be replicated in the destination directory. If B<-l>
661 is not specified, then links are skipped over.
665 Put ``hints'' in the .ph files which will help in locating problems with
666 I<h2ph>. In those cases when you B<require> a B<.ph> file containing syntax
667 errors, instead of the cryptic
669 [ some error condition ] at (eval mmm) line nnn
671 you will see the slightly more helpful
673 [ some error condition ] at filename.ph line nnn
675 However, the B<.ph> files almost double in size when built using B<-h>.
679 Include the code from the B<.h> file as a comment in the B<.ph> file.
680 This is primarily used for debugging I<h2ph>.
684 ``Quiet'' mode; don't print out the names of the files being converted.
690 No environment variables are used.
709 The usual warnings if it can't read or write the files involved.
713 Doesn't construct the %sizeof array for you.
715 It doesn't handle all C constructs, but it does attempt to isolate
716 definitions inside evals so that you can get at the definitions
717 that it can translate.
719 It's only intended as a rough tool.
720 You may need to dicker with the files produced.
722 You have to run this program by hand; it's not run as part of the Perl
725 Doesn't handle complicated expressions built piecemeal, a la:
735 Doesn't necessarily locate all of your C compiler's internally-defined
742 close OUT or die "Can't close $file: $!";
743 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
744 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';