summaryrefslogtreecommitdiff
path: root/utils/h2ph.PL
diff options
context:
space:
mode:
Diffstat (limited to 'utils/h2ph.PL')
-rw-r--r--utils/h2ph.PL171
1 files changed, 105 insertions, 66 deletions
diff --git a/utils/h2ph.PL b/utils/h2ph.PL
index 370aa87213..3471300c87 100644
--- a/utils/h2ph.PL
+++ b/utils/h2ph.PL
@@ -13,10 +13,9 @@ use File::Basename qw(&basename &dirname);
# This forces PL files to create target in same directory as PL file.
# This is so that make depend always knows where to find PL derivatives.
-chdir(dirname($0));
-($file = basename($0)) =~ s/\.PL$//;
-$file =~ s/\.pl$//
- if ($^O eq 'VMS' or $^O eq 'os2'); # "case-forgiving"
+chdir dirname($0);
+$file = basename($0, '.PL');
+$file .= '.com' if $^O eq 'VMS';
open OUT,">$file" or die "Can't create $file: $!";
@@ -26,23 +25,25 @@ print "Extracting $file (with variable substitutions)\n";
# You can use $Config{...} to use Configure variables.
print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
- eval 'exec perl -S \$0 "\$@"'
- if 0;
-
-'di ';
-'ds 00 \"';
-'ig 00 ';
-
-\$perlincl = "$Config{archlibexp}";
-
+$Config{startperl}
+ eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+ if \$running_under_some_shell;
!GROK!THIS!
# In the following, perl variables are not expanded during extraction.
print OUT <<'!NO!SUBS!';
-chdir '/usr/include' || die "Can't cd /usr/include";
+use Config;
+use File::Path qw(mkpath);
+
+my $Exit = 0;
+
+my $Dest_dir = (@ARGV && $ARGV[0] =~ s/^-d//)
+ ? shift || shift
+ : $Config{installsitearch};
+die "Destination directory $Dest_dir doesn't exist or isn't a directory\n"
+ unless -d $Dest_dir;
@isatype = split(' ',<<END);
char uchar u_char
@@ -58,6 +59,10 @@ $inif = 0;
@ARGV = ('-') unless @ARGV;
foreach $file (@ARGV) {
+ # Recover from header files with unbalanced cpp directives
+ $t = '';
+ $tab = 0;
+
if ($file eq '-') {
open(IN, "-");
open(OUT, ">-");
@@ -67,12 +72,10 @@ foreach $file (@ARGV) {
print "$file -> $outfile\n";
if ($file =~ m|^(.*)/|) {
$dir = $1;
- if (!-d "$perlincl/$dir") {
- mkdir("$perlincl/$dir",0777);
- }
+ mkpath "$Dest_dir/$dir";
}
- open(IN,"$file") || ((warn "Can't open $file: $!\n"),next);
- open(OUT,">$perlincl/$outfile") || die "Can't create $outfile: $!\n";
+ open(IN,"$file") || (($Exit = 1),(warn "Can't open $file: $!\n"),next);
+ open(OUT,">$Dest_dir/$outfile") || die "Can't create $outfile: $!\n";
}
while (<IN>) {
chop;
@@ -97,7 +100,9 @@ foreach $file (@ARGV) {
s/\s+$//;
if (s/^\(([\w,\s]*)\)//) {
$args = $1;
+ my $proto = '() ';
if ($args ne '') {
+ $proto = '';
foreach $arg (split(/,\s*/,$args)) {
$arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
$curargs{$arg} = 1;
@@ -106,28 +111,28 @@ foreach $file (@ARGV) {
$args = "local($args) = \@_;\n$t ";
}
s/^\s+//;
- do expr();
+ expr();
$new =~ s/(["\\])/\\$1/g;
if ($t ne '') {
$new =~ s/(['\\])/\\$1/g;
print OUT $t,
- "eval 'sub $name {\n$t ${args}eval \"$new\";\n$t}';\n";
+ "eval 'sub $name $proto\{\n$t ${args}eval \"$new\";\n$t}';\n";
}
else {
- print OUT "sub $name {\n ${args}eval \"$new\";\n}\n";
+ print OUT "sub $name $proto\{\n ${args}eval \"$new\";\n}\n";
}
%curargs = ();
}
else {
s/^\s+//;
- do expr();
+ expr();
$new = 1 if $new eq '';
if ($t ne '') {
$new =~ s/(['\\])/\\$1/g;
- print OUT $t,"eval 'sub $name {",$new,";}';\n";
+ print OUT $t,"eval 'sub $name () {",$new,";}';\n";
}
else {
- print OUT $t,"sub $name {",$new,";}\n";
+ print OUT $t,"sub $name () {",$new,";}\n";
}
}
}
@@ -148,7 +153,7 @@ foreach $file (@ARGV) {
elsif (s/^if\s+//) {
$new = '';
$inif = 1;
- do expr();
+ expr();
$inif = 0;
print OUT $t,"if ($new) {\n";
$tab += 4;
@@ -157,7 +162,7 @@ foreach $file (@ARGV) {
elsif (s/^elif\s+//) {
$new = '';
$inif = 1;
- do expr();
+ expr();
$inif = 0;
$tab -= 4;
$t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
@@ -182,6 +187,8 @@ foreach $file (@ARGV) {
print OUT "1;\n";
}
+exit $Exit;
+
sub expr {
while ($_ ne '') {
s/^(\s+)// && do {$new .= ' '; next;};
@@ -197,10 +204,31 @@ sub expr {
}
next;
};
- s/^sizeof\s*\(([^)]+)\)/{$1}/ && do {
- $new .= '$sizeof';
- next;
- };
+ # replace "sizeof(foo)" with "{foo}"
+ # also, remove * (C dereference operator) to avoid perl syntax
+ # problems. Where the %sizeof array comes from is anyone's
+ # guess (c2ph?), but this at least avoids fatal syntax errors.
+ # Behavior is undefined if sizeof() delimiters are unbalanced.
+ # This code was modified to able to handle constructs like this:
+ # sizeof(*(p)), which appear in the HP-UX 10.01 header files.
+ s/^sizeof\s*\(// && do {
+ $new .= '$sizeof';
+ my $lvl = 1; # already saw one open paren
+ # tack { on the front, and skip it in the loop
+ $_ = "{" . "$_";
+ my $index = 1;
+ # find balanced closing paren
+ while ($index <= length($_) && $lvl > 0) {
+ $lvl++ if substr($_, $index, 1) eq "(";
+ $lvl-- if substr($_, $index, 1) eq ")";
+ $index++;
+ }
+ # tack } on the end, replacing )
+ substr($_, $index - 1, 1) = "}";
+ # remove pesky * operators within the sizeof argument
+ substr($_, 0, $index - 1) =~ s/\*//g;
+ next;
+ };
s/^([_a-zA-Z]\w*)// && do {
$id = $1;
if ($id eq 'struct') {
@@ -208,7 +236,7 @@ sub expr {
$id .= ' ' . $1;
$isatype{$id} = 1;
}
- elsif ($id eq 'unsigned') {
+ elsif ($id eq 'unsigned' || $id eq 'long') {
s/^\s+(\w+)//;
$id .= ' ' . $1;
$isatype{$id} = 1;
@@ -238,8 +266,8 @@ sub expr {
else {
if ($inif && $new !~ /defined\s*\($/) {
$new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
- }
- elsif (/^\[/) {
+ }
+ elsif (/^\[/) {
$new .= ' $' . $id;
}
else {
@@ -252,56 +280,67 @@ sub expr {
}
}
##############################################################################
+__END__
+
+=head1 NAME
+
+h2ph - convert .h C header files to .ph Perl header files
- # These next few lines are legal in both Perl and nroff.
-
-.00 ; # finish .ig
-
-'di \" finish diversion--previous line must be blank
-.nr nl 0-1 \" fake up transition to first page again
-.nr % 0 \" start at page 1
-'; __END__ ############# From here on it's a standard manual page ############
-.TH H2PH 1 "August 8, 1990"
-.AT 3
-.SH NAME
-h2ph \- convert .h C header files to .ph Perl header files
-.SH SYNOPSIS
-.B h2ph [headerfiles]
-.SH DESCRIPTION
-.I h2ph
+=head1 SYNOPSIS
+
+B<h2ph [headerfiles]>
+
+=head1 DESCRIPTION
+
+I<h2ph>
converts any C header files specified to the corresponding Perl header file
format.
It is most easily run while in /usr/include:
-.nf
cd /usr/include; h2ph * sys/*
-.fi
+The output files are placed in the hierarchy rooted at Perl's
+architecture dependent library directory. You can specify a different
+hierarchy with a B<-d> switch.
+
If run with no arguments, filters standard input to standard output.
-.SH ENVIRONMENT
+
+=head1 ENVIRONMENT
+
No environment variables are used.
-.SH FILES
-/usr/include/*.h
-.br
-/usr/include/sys/*.h
-.br
+
+=head1 FILES
+
+ /usr/include/*.h
+ /usr/include/sys/*.h
+
etc.
-.SH AUTHOR
+
+=head1 AUTHOR
+
Larry Wall
-.SH "SEE ALSO"
+
+=head1 SEE ALSO
+
perl(1)
-.SH DIAGNOSTICS
+
+=head1 DIAGNOSTICS
+
The usual warnings if it can't read or write the files involved.
-.SH BUGS
+
+=head1 BUGS
+
Doesn't construct the %sizeof array for you.
-.PP
+
It doesn't handle all C constructs, but it does attempt to isolate
definitions inside evals so that you can get at the definitions
that it can translate.
-.PP
+
It's only intended as a rough tool.
You may need to dicker with the files produced.
-.ex
+
+=cut
+
!NO!SUBS!
close OUT or die "Can't close $file: $!";