diff options
Diffstat (limited to 'utils/h2ph.PL')
-rw-r--r-- | utils/h2ph.PL | 171 |
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: $!"; |